1 /* 2 | ee (easy editor) 3 | 4 | An easy to use, simple screen oriented editor. 5 | 6 | written by Hugh Mahon 7 | 8 | 9 | Copyright (c) 2009, Hugh Mahon 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions 14 | are met: 15 | 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above 19 | copyright notice, this list of conditions and the following 20 | disclaimer in the documentation and/or other materials provided 21 | with the distribution. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 | POSSIBILITY OF SUCH DAMAGE. 35 | 36 | -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 37 | 38 | This editor was purposely developed to be simple, both in 39 | interface and implementation. This editor was developed to 40 | address a specific audience: the user who is new to computers 41 | (especially UNIX). 42 | 43 | ee is not aimed at technical users; for that reason more 44 | complex features were intentionally left out. In addition, 45 | ee is intended to be compiled by people with little computer 46 | experience, which means that it needs to be small, relatively 47 | simple in implementation, and portable. 48 | 49 | This software and documentation contains 50 | proprietary information which is protected by 51 | copyright. All rights are reserved. 52 | 53 | $Header: /home/hugh/sources/old_ae/RCS/ee.c,v 1.102 2009/02/17 03:22:50 hugh Exp hugh $ 54 | 55 */ 56 57 #include <sys/cdefs.h> 58 __FBSDID("$FreeBSD$"); 59 60 char *ee_copyright_message = 61 "Copyright (c) 1986, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 2009 Hugh Mahon "; 62 63 #include "ee_version.h" 64 65 char *version = "@(#) ee, version " EE_VERSION " $Revision: 1.102 $"; 66 67 #ifdef NCURSE 68 #include "new_curse.h" 69 #elif HAS_NCURSES 70 #include <ncurses.h> 71 #else 72 #include <curses.h> 73 #endif 74 75 #ifdef HAS_CTYPE 76 #include <ctype.h> 77 #endif 78 79 #include <signal.h> 80 #include <fcntl.h> 81 #include <sys/types.h> 82 #include <sys/stat.h> 83 #include <errno.h> 84 #include <string.h> 85 #include <pwd.h> 86 87 #ifdef HAS_SYS_WAIT 88 #include <sys/wait.h> 89 #endif 90 91 #ifdef HAS_STDLIB 92 #include <stdlib.h> 93 #endif 94 95 #ifdef HAS_STDARG 96 #include <stdarg.h> 97 #endif 98 99 #ifdef HAS_UNISTD 100 #include <unistd.h> 101 #endif 102 103 104 #ifndef NO_CATGETS 105 #include <locale.h> 106 #include <nl_types.h> 107 108 nl_catd catalog; 109 #else 110 #define catgetlocal(a, b) (b) 111 #endif /* NO_CATGETS */ 112 113 #ifndef SIGCHLD 114 #define SIGCHLD SIGCLD 115 #endif 116 117 #define TAB 9 118 #define max(a, b) (a > b ? a : b) 119 #define min(a, b) (a < b ? a : b) 120 121 /* 122 | defines for type of data to show in info window 123 */ 124 125 #define CONTROL_KEYS 1 126 #define COMMANDS 2 127 128 struct text { 129 unsigned char *line; /* line of characters */ 130 int line_number; /* line number */ 131 int line_length; /* actual number of characters in the line */ 132 int max_length; /* maximum number of characters the line handles */ 133 struct text *next_line; /* next line of text */ 134 struct text *prev_line; /* previous line of text */ 135 }; 136 137 struct text *first_line; /* first line of current buffer */ 138 struct text *dlt_line; /* structure for info on deleted line */ 139 struct text *curr_line; /* current line cursor is on */ 140 struct text *tmp_line; /* temporary line pointer */ 141 struct text *srch_line; /* temporary pointer for search routine */ 142 143 struct files { /* structure to store names of files to be edited*/ 144 unsigned char *name; /* name of file */ 145 struct files *next_name; 146 }; 147 148 struct files *top_of_stack = NULL; 149 150 int d_wrd_len; /* length of deleted word */ 151 int position; /* offset in bytes from begin of line */ 152 int scr_pos; /* horizontal position */ 153 int scr_vert; /* vertical position on screen */ 154 int scr_horz; /* horizontal position on screen */ 155 int absolute_lin; /* number of lines from top */ 156 int tmp_vert, tmp_horz; 157 int input_file; /* indicate to read input file */ 158 int recv_file; /* indicate reading a file */ 159 int edit; /* continue executing while true */ 160 int gold; /* 'gold' function key pressed */ 161 int fildes; /* file descriptor */ 162 int case_sen; /* case sensitive search flag */ 163 int last_line; /* last line for text display */ 164 int last_col; /* last column for text display */ 165 int horiz_offset = 0; /* offset from left edge of text */ 166 int clear_com_win; /* flag to indicate com_win needs clearing */ 167 int text_changes = FALSE; /* indicate changes have been made to text */ 168 int get_fd; /* file descriptor for reading a file */ 169 int info_window = TRUE; /* flag to indicate if help window visible */ 170 int info_type = CONTROL_KEYS; /* flag to indicate type of info to display */ 171 int expand_tabs = TRUE; /* flag for expanding tabs */ 172 int right_margin = 0; /* the right margin */ 173 int observ_margins = TRUE; /* flag for whether margins are observed */ 174 int shell_fork; 175 int temp_stdin; /* temporary storage for stdin */ 176 int temp_stdout; /* temp storage for stdout descriptor */ 177 int temp_stderr; /* temp storage for stderr descriptor */ 178 int pipe_out[2]; /* pipe file desc for output */ 179 int pipe_in[2]; /* pipe file descriptors for input */ 180 int out_pipe; /* flag that info is piped out */ 181 int in_pipe; /* flag that info is piped in */ 182 int formatted = FALSE; /* flag indicating paragraph formatted */ 183 int auto_format = FALSE; /* flag for auto_format mode */ 184 int restricted = FALSE; /* flag to indicate restricted mode */ 185 int nohighlight = FALSE; /* turns off highlighting */ 186 int eightbit = TRUE; /* eight bit character flag */ 187 int local_LINES = 0; /* copy of LINES, to detect when win resizes */ 188 int local_COLS = 0; /* copy of COLS, to detect when win resizes */ 189 int curses_initialized = FALSE; /* flag indicating if curses has been started*/ 190 int emacs_keys_mode = FALSE; /* mode for if emacs key binings are used */ 191 int ee_chinese = FALSE; /* allows handling of multi-byte characters */ 192 /* by checking for high bit in a byte the */ 193 /* code recognizes a two-byte character */ 194 /* sequence */ 195 196 unsigned char *point; /* points to current position in line */ 197 unsigned char *srch_str; /* pointer for search string */ 198 unsigned char *u_srch_str; /* pointer to non-case sensitive search */ 199 unsigned char *srch_1; /* pointer to start of suspect string */ 200 unsigned char *srch_2; /* pointer to next character of string */ 201 unsigned char *srch_3; 202 unsigned char *in_file_name = NULL; /* name of input file */ 203 char *tmp_file; /* temporary file name */ 204 unsigned char *d_char; /* deleted character */ 205 unsigned char *d_word; /* deleted word */ 206 unsigned char *d_line; /* deleted line */ 207 char in_string[513]; /* buffer for reading a file */ 208 unsigned char *print_command = (unsigned char *)"lpr"; /* string to use for the print command */ 209 unsigned char *start_at_line = NULL; /* move to this line at start of session*/ 210 int in; /* input character */ 211 212 FILE *temp_fp; /* temporary file pointer */ 213 FILE *bit_bucket; /* file pointer to /dev/null */ 214 215 char *table[] = { 216 "^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G", "^H", "\t", "^J", 217 "^K", "^L", "^M", "^N", "^O", "^P", "^Q", "^R", "^S", "^T", "^U", 218 "^V", "^W", "^X", "^Y", "^Z", "^[", "^\\", "^]", "^^", "^_" 219 }; 220 221 WINDOW *com_win; 222 WINDOW *text_win; 223 WINDOW *help_win; 224 WINDOW *info_win; 225 226 #if defined(__STDC__) || defined(__cplusplus) 227 #define P_(s) s 228 #else 229 #define P_(s) () 230 #endif 231 232 233 /* 234 | The following structure allows menu items to be flexibly declared. 235 | The first item is the string describing the selection, the second 236 | is the address of the procedure to call when the item is selected, 237 | and the third is the argument for the procedure. 238 | 239 | For those systems with i18n, the string should be accompanied by a 240 | catalog number. The 'int *' should be replaced with 'void *' on 241 | systems with that type. 242 | 243 | The first menu item will be the title of the menu, with NULL 244 | parameters for the procedure and argument, followed by the menu items. 245 | 246 | If the procedure value is NULL, the menu item is displayed, but no 247 | procedure is called when the item is selected. The number of the 248 | item will be returned. If the third (argument) parameter is -1, no 249 | argument is given to the procedure when it is called. 250 */ 251 252 struct menu_entries { 253 char *item_string; 254 int (*procedure)P_((struct menu_entries *)); 255 struct menu_entries *ptr_argument; 256 int (*iprocedure)P_((int)); 257 void (*nprocedure)P_((void)); 258 int argument; 259 }; 260 261 int main P_((int argc, char *argv[])); 262 unsigned char *resiz_line P_((int factor, struct text *rline, int rpos)); 263 void insert P_((int character)); 264 void delete P_((int disp)); 265 void scanline P_((unsigned char *pos)); 266 int tabshift P_((int temp_int)); 267 int out_char P_((WINDOW *window, int character, int column)); 268 int len_char P_((int character, int column)); 269 void draw_line P_((int vertical, int horiz, unsigned char *ptr, int t_pos, int length)); 270 void insert_line P_((int disp)); 271 struct text *txtalloc P_((void)); 272 struct files *name_alloc P_((void)); 273 unsigned char *next_word P_((unsigned char *string)); 274 void prev_word P_((void)); 275 void control P_((void)); 276 void emacs_control P_((void)); 277 void bottom P_((void)); 278 void top P_((void)); 279 void nextline P_((void)); 280 void prevline P_((void)); 281 void left P_((int disp)); 282 void right P_((int disp)); 283 void find_pos P_((void)); 284 void up P_((void)); 285 void down P_((void)); 286 void function_key P_((void)); 287 void print_buffer P_((void)); 288 void command_prompt P_((void)); 289 void command P_((char *cmd_str1)); 290 int scan P_((char *line, int offset, int column)); 291 char *get_string P_((char *prompt, int advance)); 292 int compare P_((char *string1, char *string2, int sensitive)); 293 void goto_line P_((char *cmd_str)); 294 void midscreen P_((int line, unsigned char *pnt)); 295 void get_options P_((int numargs, char *arguments[])); 296 void check_fp P_((void)); 297 void get_file P_((char *file_name)); 298 void get_line P_((int length, unsigned char *in_string, int *append)); 299 void draw_screen P_((void)); 300 void finish P_((void)); 301 int quit P_((int noverify)); 302 void edit_abort P_((int arg)); 303 void delete_text P_((void)); 304 int write_file P_((char *file_name, int warn_if_exists)); 305 int search P_((int display_message)); 306 void search_prompt P_((void)); 307 void del_char P_((void)); 308 void undel_char P_((void)); 309 void del_word P_((void)); 310 void undel_word P_((void)); 311 void del_line P_((void)); 312 void undel_line P_((void)); 313 void adv_word P_((void)); 314 void move_rel P_((char *direction, int lines)); 315 void eol P_((void)); 316 void bol P_((void)); 317 void adv_line P_((void)); 318 void sh_command P_((char *string)); 319 void set_up_term P_((void)); 320 void resize_check P_((void)); 321 int menu_op P_((struct menu_entries *)); 322 void paint_menu P_((struct menu_entries menu_list[], int max_width, int max_height, int list_size, int top_offset, WINDOW *menu_win, int off_start, int vert_size)); 323 void help P_((void)); 324 void paint_info_win P_((void)); 325 void no_info_window P_((void)); 326 void create_info_window P_((void)); 327 int file_op P_((int arg)); 328 void shell_op P_((void)); 329 void leave_op P_((void)); 330 void redraw P_((void)); 331 int Blank_Line P_((struct text *test_line)); 332 void Format P_((void)); 333 void ee_init P_((void)); 334 void dump_ee_conf P_((void)); 335 void echo_string P_((char *string)); 336 void spell_op P_((void)); 337 void ispell_op P_((void)); 338 int first_word_len P_((struct text *test_line)); 339 void Auto_Format P_((void)); 340 void modes_op P_((void)); 341 char *is_in_string P_((char *string, char *substring)); 342 char *resolve_name P_((char *name)); 343 int restrict_mode P_((void)); 344 int unique_test P_((char *string, char *list[])); 345 void strings_init P_((void)); 346 347 #undef P_ 348 /* 349 | allocate space here for the strings that will be in the menu 350 */ 351 352 struct menu_entries modes_menu[] = { 353 {"", NULL, NULL, NULL, NULL, 0}, /* title */ 354 {"", NULL, NULL, NULL, NULL, -1}, /* 1. tabs to spaces */ 355 {"", NULL, NULL, NULL, NULL, -1}, /* 2. case sensitive search*/ 356 {"", NULL, NULL, NULL, NULL, -1}, /* 3. margins observed */ 357 {"", NULL, NULL, NULL, NULL, -1}, /* 4. auto-paragraph */ 358 {"", NULL, NULL, NULL, NULL, -1}, /* 5. eightbit characters*/ 359 {"", NULL, NULL, NULL, NULL, -1}, /* 6. info window */ 360 {"", NULL, NULL, NULL, NULL, -1}, /* 7. emacs key bindings*/ 361 {"", NULL, NULL, NULL, NULL, -1}, /* 8. right margin */ 362 {"", NULL, NULL, NULL, NULL, -1}, /* 9. chinese text */ 363 {"", NULL, NULL, NULL, dump_ee_conf, -1}, /* 10. save editor config */ 364 {NULL, NULL, NULL, NULL, NULL, -1} /* terminator */ 365 }; 366 367 char *mode_strings[11]; 368 369 #define NUM_MODES_ITEMS 10 370 371 struct menu_entries config_dump_menu[] = { 372 {"", NULL, NULL, NULL, NULL, 0}, 373 {"", NULL, NULL, NULL, NULL, -1}, 374 {"", NULL, NULL, NULL, NULL, -1}, 375 {NULL, NULL, NULL, NULL, NULL, -1} 376 }; 377 378 struct menu_entries leave_menu[] = { 379 {"", NULL, NULL, NULL, NULL, -1}, 380 {"", NULL, NULL, NULL, finish, -1}, 381 {"", NULL, NULL, quit, NULL, TRUE}, 382 {NULL, NULL, NULL, NULL, NULL, -1} 383 }; 384 385 #define READ_FILE 1 386 #define WRITE_FILE 2 387 #define SAVE_FILE 3 388 389 struct menu_entries file_menu[] = { 390 {"", NULL, NULL, NULL, NULL, -1}, 391 {"", NULL, NULL, file_op, NULL, READ_FILE}, 392 {"", NULL, NULL, file_op, NULL, WRITE_FILE}, 393 {"", NULL, NULL, file_op, NULL, SAVE_FILE}, 394 {"", NULL, NULL, NULL, print_buffer, -1}, 395 {NULL, NULL, NULL, NULL, NULL, -1} 396 }; 397 398 struct menu_entries search_menu[] = { 399 {"", NULL, NULL, NULL, NULL, 0}, 400 {"", NULL, NULL, NULL, search_prompt, -1}, 401 {"", NULL, NULL, search, NULL, TRUE}, 402 {NULL, NULL, NULL, NULL, NULL, -1} 403 }; 404 405 struct menu_entries spell_menu[] = { 406 {"", NULL, NULL, NULL, NULL, -1}, 407 {"", NULL, NULL, NULL, spell_op, -1}, 408 {"", NULL, NULL, NULL, ispell_op, -1}, 409 {NULL, NULL, NULL, NULL, NULL, -1} 410 }; 411 412 struct menu_entries misc_menu[] = { 413 {"", NULL, NULL, NULL, NULL, -1}, 414 {"", NULL, NULL, NULL, Format, -1}, 415 {"", NULL, NULL, NULL, shell_op, -1}, 416 {"", menu_op, spell_menu, NULL, NULL, -1}, 417 {NULL, NULL, NULL, NULL, NULL, -1} 418 }; 419 420 struct menu_entries main_menu[] = { 421 {"", NULL, NULL, NULL, NULL, -1}, 422 {"", NULL, NULL, NULL, leave_op, -1}, 423 {"", NULL, NULL, NULL, help, -1}, 424 {"", menu_op, file_menu, NULL, NULL, -1}, 425 {"", NULL, NULL, NULL, redraw, -1}, 426 {"", NULL, NULL, NULL, modes_op, -1}, 427 {"", menu_op, search_menu, NULL, NULL, -1}, 428 {"", menu_op, misc_menu, NULL, NULL, -1}, 429 {NULL, NULL, NULL, NULL, NULL, -1} 430 }; 431 432 char *help_text[23]; 433 char *control_keys[5]; 434 435 char *emacs_help_text[22]; 436 char *emacs_control_keys[5]; 437 438 char *command_strings[5]; 439 char *commands[32]; 440 char *init_strings[22]; 441 442 #define MENU_WARN 1 443 444 #define max_alpha_char 36 445 446 /* 447 | Declarations for strings for localization 448 */ 449 450 char *com_win_message; /* to be shown in com_win if no info window */ 451 char *no_file_string; 452 char *ascii_code_str; 453 char *printer_msg_str; 454 char *command_str; 455 char *file_write_prompt_str; 456 char *file_read_prompt_str; 457 char *char_str; 458 char *unkn_cmd_str; 459 char *non_unique_cmd_msg; 460 char *line_num_str; 461 char *line_len_str; 462 char *current_file_str; 463 char *usage0; 464 char *usage1; 465 char *usage2; 466 char *usage3; 467 char *usage4; 468 char *file_is_dir_msg; 469 char *new_file_msg; 470 char *cant_open_msg; 471 char *open_file_msg; 472 char *file_read_fin_msg; 473 char *reading_file_msg; 474 char *read_only_msg; 475 char *file_read_lines_msg; 476 char *save_file_name_prompt; 477 char *file_not_saved_msg; 478 char *changes_made_prompt; 479 char *yes_char; 480 char *file_exists_prompt; 481 char *create_file_fail_msg; 482 char *writing_file_msg; 483 char *file_written_msg; 484 char *searching_msg; 485 char *str_not_found_msg; 486 char *search_prompt_str; 487 char *exec_err_msg; 488 char *continue_msg; 489 char *menu_cancel_msg; 490 char *menu_size_err_msg; 491 char *press_any_key_msg; 492 char *shell_prompt; 493 char *formatting_msg; 494 char *shell_echo_msg; 495 char *spell_in_prog_msg; 496 char *margin_prompt; 497 char *restricted_msg; 498 char *ON; 499 char *OFF; 500 char *HELP; 501 char *WRITE; 502 char *READ; 503 char *LINE; 504 char *FILE_str; 505 char *CHARACTER; 506 char *REDRAW; 507 char *RESEQUENCE; 508 char *AUTHOR; 509 char *VERSION; 510 char *CASE; 511 char *NOCASE; 512 char *EXPAND; 513 char *NOEXPAND; 514 char *Exit_string; 515 char *QUIT_string; 516 char *INFO; 517 char *NOINFO; 518 char *MARGINS; 519 char *NOMARGINS; 520 char *AUTOFORMAT; 521 char *NOAUTOFORMAT; 522 char *Echo; 523 char *PRINTCOMMAND; 524 char *RIGHTMARGIN; 525 char *HIGHLIGHT; 526 char *NOHIGHLIGHT; 527 char *EIGHTBIT; 528 char *NOEIGHTBIT; 529 char *EMACS_string; 530 char *NOEMACS_string; 531 char *conf_dump_err_msg; 532 char *conf_dump_success_msg; 533 char *conf_not_saved_msg; 534 char *ree_no_file_msg; 535 char *cancel_string; 536 char *menu_too_lrg_msg; 537 char *more_above_str, *more_below_str; 538 char *separator = "==============================================================================="; 539 540 char *chinese_cmd, *nochinese_cmd; 541 542 #ifndef __STDC__ 543 #ifndef HAS_STDLIB 544 extern char *malloc(); 545 extern char *realloc(); 546 extern char *getenv(); 547 FILE *fopen(); /* declaration for open function */ 548 #endif /* HAS_STDLIB */ 549 #endif /* __STDC__ */ 550 551 int 552 main(argc, argv) /* beginning of main program */ 553 int argc; 554 char *argv[]; 555 { 556 int counter; 557 558 for (counter = 1; counter < 24; counter++) 559 signal(counter, SIG_IGN); 560 561 signal(SIGCHLD, SIG_DFL); 562 signal(SIGSEGV, SIG_DFL); 563 signal(SIGINT, edit_abort); 564 d_char = malloc(3); /* provide a buffer for multi-byte chars */ 565 d_word = malloc(150); 566 *d_word = '\0'; 567 d_line = NULL; 568 dlt_line = txtalloc(); 569 dlt_line->line = d_line; 570 dlt_line->line_length = 0; 571 curr_line = first_line = txtalloc(); 572 curr_line->line = point = malloc(10); 573 curr_line->line_length = 1; 574 curr_line->max_length = 10; 575 curr_line->prev_line = NULL; 576 curr_line->next_line = NULL; 577 curr_line->line_number = 1; 578 srch_str = NULL; 579 u_srch_str = NULL; 580 position = 1; 581 scr_pos =0; 582 scr_vert = 0; 583 scr_horz = 0; 584 absolute_lin = 1; 585 bit_bucket = fopen("/dev/null", "w"); 586 edit = TRUE; 587 gold = case_sen = FALSE; 588 shell_fork = TRUE; 589 strings_init(); 590 ee_init(); 591 if (argc > 0 ) 592 get_options(argc, argv); 593 set_up_term(); 594 if (right_margin == 0) 595 right_margin = COLS - 1; 596 if (top_of_stack == NULL) 597 { 598 if (restrict_mode()) 599 { 600 wmove(com_win, 0, 0); 601 werase(com_win); 602 wprintw(com_win, ree_no_file_msg); 603 wrefresh(com_win); 604 edit_abort(0); 605 } 606 wprintw(com_win, no_file_string); 607 wrefresh(com_win); 608 } 609 else 610 check_fp(); 611 612 clear_com_win = TRUE; 613 614 counter = 0; 615 616 while(edit) 617 { 618 /* 619 | display line and column information 620 */ 621 if (info_window) 622 { 623 if (!nohighlight) 624 wstandout(info_win); 625 wmove(info_win, 5, 0); 626 wprintw(info_win, separator); 627 wmove(info_win, 5, 5); 628 wprintw(info_win, "line %d col %d lines from top %d ", 629 curr_line->line_number, scr_horz, absolute_lin); 630 wstandend(info_win); 631 wrefresh(info_win); 632 } 633 634 wrefresh(text_win); 635 in = wgetch(text_win); 636 if (in == -1) 637 exit(0); /* without this exit ee will go into an 638 infinite loop if the network 639 session detaches */ 640 641 resize_check(); 642 643 if (clear_com_win) 644 { 645 clear_com_win = FALSE; 646 wmove(com_win, 0, 0); 647 werase(com_win); 648 if (!info_window) 649 { 650 wprintw(com_win, "%s", com_win_message); 651 } 652 wrefresh(com_win); 653 } 654 655 if (in > 255) 656 function_key(); 657 else if ((in == '\10') || (in == 127)) 658 { 659 in = 8; /* make sure key is set to backspace */ 660 delete(TRUE); 661 } 662 else if ((in > 31) || (in == 9)) 663 insert(in); 664 else if ((in >= 0) && (in <= 31)) 665 { 666 if (emacs_keys_mode) 667 emacs_control(); 668 else 669 control(); 670 } 671 } 672 return(0); 673 } 674 675 unsigned char * 676 resiz_line(factor, rline, rpos) /* resize the line to length + factor*/ 677 int factor; /* resize factor */ 678 struct text *rline; /* position in line */ 679 int rpos; 680 { 681 unsigned char *rpoint; 682 int resiz_var; 683 684 rline->max_length += factor; 685 rpoint = rline->line = realloc(rline->line, rline->max_length ); 686 for (resiz_var = 1 ; (resiz_var < rpos) ; resiz_var++) 687 rpoint++; 688 return(rpoint); 689 } 690 691 void 692 insert(character) /* insert character into line */ 693 int character; /* new character */ 694 { 695 int counter; 696 int value; 697 unsigned char *temp; /* temporary pointer */ 698 unsigned char *temp2; /* temporary pointer */ 699 700 if ((character == '\011') && (expand_tabs)) 701 { 702 counter = len_char('\011', scr_horz); 703 for (; counter > 0; counter--) 704 insert(' '); 705 if (auto_format) 706 Auto_Format(); 707 return; 708 } 709 text_changes = TRUE; 710 if ((curr_line->max_length - curr_line->line_length) < 5) 711 point = resiz_line(10, curr_line, position); 712 curr_line->line_length++; 713 temp = point; 714 counter = position; 715 while (counter < curr_line->line_length) /* find end of line */ 716 { 717 counter++; 718 temp++; 719 } 720 temp++; /* increase length of line by one */ 721 while (point < temp) 722 { 723 temp2=temp - 1; 724 *temp= *temp2; /* shift characters over by one */ 725 temp--; 726 } 727 *point = character; /* insert new character */ 728 wclrtoeol(text_win); 729 if (((character >= 0) && (character < ' ')) || (character >= 127)) /* check for TAB character*/ 730 { 731 scr_pos = scr_horz += out_char(text_win, character, scr_horz); 732 point++; 733 position++; 734 } 735 else 736 { 737 waddch(text_win, character); 738 scr_pos = ++scr_horz; 739 point++; 740 position ++; 741 } 742 743 if ((observ_margins) && (right_margin < scr_pos)) 744 { 745 counter = position; 746 while (scr_pos > right_margin) 747 prev_word(); 748 if (scr_pos == 0) 749 { 750 while (position < counter) 751 right(TRUE); 752 } 753 else 754 { 755 counter -= position; 756 insert_line(TRUE); 757 for (value = 0; value < counter; value++) 758 right(TRUE); 759 } 760 } 761 762 if ((scr_horz - horiz_offset) > last_col) 763 { 764 horiz_offset += 8; 765 midscreen(scr_vert, point); 766 } 767 768 if ((auto_format) && (character == ' ') && (!formatted)) 769 Auto_Format(); 770 else if ((character != ' ') && (character != '\t')) 771 formatted = FALSE; 772 773 draw_line(scr_vert, scr_horz, point, position, curr_line->line_length); 774 } 775 776 void 777 delete(disp) /* delete character */ 778 int disp; 779 { 780 unsigned char *tp; 781 unsigned char *temp2; 782 struct text *temp_buff; 783 int temp_vert; 784 int temp_pos; 785 int del_width = 1; 786 787 if (point != curr_line->line) /* if not at beginning of line */ 788 { 789 text_changes = TRUE; 790 temp2 = tp = point; 791 if ((ee_chinese) && (position >= 2) && (*(point - 2) > 127)) 792 { 793 del_width = 2; 794 } 795 tp -= del_width; 796 point -= del_width; 797 position -= del_width; 798 temp_pos = position; 799 curr_line->line_length -= del_width; 800 if ((*tp < ' ') || (*tp >= 127)) /* check for TAB */ 801 scanline(tp); 802 else 803 scr_horz -= del_width; 804 scr_pos = scr_horz; 805 if (in == 8) 806 { 807 if (del_width == 1) 808 *d_char = *point; /* save deleted character */ 809 else 810 { 811 d_char[0] = *point; 812 d_char[1] = *(point + 1); 813 } 814 d_char[del_width] = '\0'; 815 } 816 while (temp_pos <= curr_line->line_length) 817 { 818 temp_pos++; 819 *tp = *temp2; 820 tp++; 821 temp2++; 822 } 823 if (scr_horz < horiz_offset) 824 { 825 horiz_offset -= 8; 826 midscreen(scr_vert, point); 827 } 828 } 829 else if (curr_line->prev_line != NULL) 830 { 831 absolute_lin--; 832 text_changes = TRUE; 833 left(disp); /* go to previous line */ 834 temp_buff = curr_line->next_line; 835 point = resiz_line(temp_buff->line_length, curr_line, position); 836 if (temp_buff->next_line != NULL) 837 temp_buff->next_line->prev_line = curr_line; 838 curr_line->next_line = temp_buff->next_line; 839 temp2 = temp_buff->line; 840 if (in == 8) 841 { 842 d_char[0] = '\n'; 843 d_char[1] = '\0'; 844 } 845 tp = point; 846 temp_pos = 1; 847 while (temp_pos < temp_buff->line_length) 848 { 849 curr_line->line_length++; 850 temp_pos++; 851 *tp = *temp2; 852 tp++; 853 temp2++; 854 } 855 *tp = '\0'; 856 free(temp_buff->line); 857 free(temp_buff); 858 temp_buff = curr_line; 859 temp_vert = scr_vert; 860 scr_pos = scr_horz; 861 if (scr_vert < last_line) 862 { 863 wmove(text_win, scr_vert + 1, 0); 864 wdeleteln(text_win); 865 } 866 while ((temp_buff != NULL) && (temp_vert < last_line)) 867 { 868 temp_buff = temp_buff->next_line; 869 temp_vert++; 870 } 871 if ((temp_vert == last_line) && (temp_buff != NULL)) 872 { 873 tp = temp_buff->line; 874 wmove(text_win, last_line,0); 875 wclrtobot(text_win); 876 draw_line(last_line, 0, tp, 1, temp_buff->line_length); 877 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 878 } 879 } 880 draw_line(scr_vert, scr_horz, point, position, curr_line->line_length); 881 formatted = FALSE; 882 } 883 884 void 885 scanline(pos) /* find the proper horizontal position for the pointer */ 886 unsigned char *pos; 887 { 888 int temp; 889 unsigned char *ptr; 890 891 ptr = curr_line->line; 892 temp = 0; 893 while (ptr < pos) 894 { 895 if (*ptr <= 8) 896 temp += 2; 897 else if (*ptr == 9) 898 temp += tabshift(temp); 899 else if ((*ptr >= 10) && (*ptr <= 31)) 900 temp += 2; 901 else if ((*ptr >= 32) && (*ptr < 127)) 902 temp++; 903 else if (*ptr == 127) 904 temp += 2; 905 else if (!eightbit) 906 temp += 5; 907 else 908 temp++; 909 ptr++; 910 } 911 scr_horz = temp; 912 if ((scr_horz - horiz_offset) > last_col) 913 { 914 horiz_offset = (scr_horz - (scr_horz % 8)) - (COLS - 8); 915 midscreen(scr_vert, point); 916 } 917 else if (scr_horz < horiz_offset) 918 { 919 horiz_offset = max(0, (scr_horz - (scr_horz % 8))); 920 midscreen(scr_vert, point); 921 } 922 } 923 924 int 925 tabshift(temp_int) /* give the number of spaces to shift */ 926 int temp_int; 927 { 928 int leftover; 929 930 leftover = ((temp_int + 1) % 8); 931 if (leftover == 0) 932 return (1); 933 else 934 return (9 - leftover); 935 } 936 937 int 938 out_char(window, character, column) /* output non-printing character */ 939 WINDOW *window; 940 int character; 941 int column; 942 { 943 int i1, i2; 944 char *string; 945 char string2[8]; 946 947 if (character == TAB) 948 { 949 i1 = tabshift(column); 950 for (i2 = 0; 951 (i2 < i1) && (((column+i2+1)-horiz_offset) < last_col); i2++) 952 { 953 waddch(window, ' '); 954 } 955 return(i1); 956 } 957 else if ((character >= '\0') && (character < ' ')) 958 { 959 string = table[(int) character]; 960 } 961 else if ((character < 0) || (character >= 127)) 962 { 963 if (character == 127) 964 string = "^?"; 965 else if (!eightbit) 966 { 967 sprintf(string2, "<%d>", (character < 0) ? (character + 256) : character); 968 string = string2; 969 } 970 else 971 { 972 waddch(window, (char)character ); 973 return(1); 974 } 975 } 976 else 977 { 978 waddch(window, (char)character); 979 return(1); 980 } 981 for (i2 = 0; (string[i2] != '\0') && (((column+i2+1)-horiz_offset) < last_col); i2++) 982 waddch(window, string[i2]); 983 return(strlen(string)); 984 } 985 986 int 987 len_char(character, column) /* return the length of the character */ 988 int character; 989 int column; /* the column must be known to provide spacing for tabs */ 990 { 991 int length; 992 993 if (character == '\t') 994 length = tabshift(column); 995 else if ((character >= 0) && (character < 32)) 996 length = 2; 997 else if ((character >= 32) && (character <= 126)) 998 length = 1; 999 else if (character == 127) 1000 length = 2; 1001 else if (((character > 126) || (character < 0)) && (!eightbit)) 1002 length = 5; 1003 else 1004 length = 1; 1005 1006 return(length); 1007 } 1008 1009 void 1010 draw_line(vertical, horiz, ptr, t_pos, length) /* redraw line from current position */ 1011 int vertical; /* current vertical position on screen */ 1012 int horiz; /* current horizontal position on screen */ 1013 unsigned char *ptr; /* pointer to line */ 1014 int t_pos; /* current position (offset in bytes) from bol */ 1015 int length; /* length (in bytes) of line */ 1016 { 1017 int d; /* partial length of special or tab char to display */ 1018 unsigned char *temp; /* temporary pointer to position in line */ 1019 int abs_column; /* offset in screen units from begin of line */ 1020 int column; /* horizontal position on screen */ 1021 int row; /* vertical position on screen */ 1022 int posit; /* temporary position indicator within line */ 1023 1024 abs_column = horiz; 1025 column = horiz - horiz_offset; 1026 row = vertical; 1027 temp = ptr; 1028 d = 0; 1029 posit = t_pos; 1030 if (column < 0) 1031 { 1032 wmove(text_win, row, 0); 1033 wclrtoeol(text_win); 1034 } 1035 while (column < 0) 1036 { 1037 d = len_char(*temp, abs_column); 1038 abs_column += d; 1039 column += d; 1040 posit++; 1041 temp++; 1042 } 1043 wmove(text_win, row, column); 1044 wclrtoeol(text_win); 1045 while ((posit < length) && (column <= last_col)) 1046 { 1047 if ((*temp < 32) || (*temp >= 127)) 1048 { 1049 column += len_char(*temp, abs_column); 1050 abs_column += out_char(text_win, *temp, abs_column); 1051 } 1052 else 1053 { 1054 abs_column++; 1055 column++; 1056 waddch(text_win, *temp); 1057 } 1058 posit++; 1059 temp++; 1060 } 1061 if (column < last_col) 1062 wclrtoeol(text_win); 1063 wmove(text_win, vertical, (horiz - horiz_offset)); 1064 } 1065 1066 void 1067 insert_line(disp) /* insert new line */ 1068 int disp; 1069 { 1070 int temp_pos; 1071 int temp_pos2; 1072 unsigned char *temp; 1073 unsigned char *extra; 1074 struct text *temp_nod; 1075 1076 text_changes = TRUE; 1077 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 1078 wclrtoeol(text_win); 1079 temp_nod= txtalloc(); 1080 temp_nod->line = extra= malloc(10); 1081 temp_nod->line_length = 1; 1082 temp_nod->max_length = 10; 1083 temp_nod->line_number = curr_line->line_number + 1; 1084 temp_nod->next_line = curr_line->next_line; 1085 if (temp_nod->next_line != NULL) 1086 temp_nod->next_line->prev_line = temp_nod; 1087 temp_nod->prev_line = curr_line; 1088 curr_line->next_line = temp_nod; 1089 temp_pos2 = position; 1090 temp = point; 1091 if (temp_pos2 < curr_line->line_length) 1092 { 1093 temp_pos = 1; 1094 while (temp_pos2 < curr_line->line_length) 1095 { 1096 if ((temp_nod->max_length - temp_nod->line_length)< 5) 1097 extra = resiz_line(10, temp_nod, temp_pos); 1098 temp_nod->line_length++; 1099 temp_pos++; 1100 temp_pos2++; 1101 *extra= *temp; 1102 extra++; 1103 temp++; 1104 } 1105 temp=point; 1106 *temp = '\0'; 1107 temp = resiz_line((1 - temp_nod->line_length), curr_line, position); 1108 curr_line->line_length = 1 + temp - curr_line->line; 1109 } 1110 curr_line->line_length = position; 1111 absolute_lin++; 1112 curr_line = temp_nod; 1113 *extra = '\0'; 1114 position = 1; 1115 point= curr_line->line; 1116 if (disp) 1117 { 1118 if (scr_vert < last_line) 1119 { 1120 scr_vert++; 1121 wclrtoeol(text_win); 1122 wmove(text_win, scr_vert, 0); 1123 winsertln(text_win); 1124 } 1125 else 1126 { 1127 wmove(text_win, 0,0); 1128 wdeleteln(text_win); 1129 wmove(text_win, last_line,0); 1130 wclrtobot(text_win); 1131 } 1132 scr_pos = scr_horz = 0; 1133 if (horiz_offset) 1134 { 1135 horiz_offset = 0; 1136 midscreen(scr_vert, point); 1137 } 1138 draw_line(scr_vert, scr_horz, point, position, 1139 curr_line->line_length); 1140 } 1141 } 1142 1143 struct text *txtalloc() /* allocate space for line structure */ 1144 { 1145 return((struct text *) malloc(sizeof( struct text))); 1146 } 1147 1148 struct files *name_alloc() /* allocate space for file name list node */ 1149 { 1150 return((struct files *) malloc(sizeof( struct files))); 1151 } 1152 1153 unsigned char *next_word(string) /* move to next word in string */ 1154 unsigned char *string; 1155 { 1156 while ((*string != '\0') && ((*string != 32) && (*string != 9))) 1157 string++; 1158 while ((*string != '\0') && ((*string == 32) || (*string == 9))) 1159 string++; 1160 return(string); 1161 } 1162 1163 void 1164 prev_word() /* move to start of previous word in text */ 1165 { 1166 if (position != 1) 1167 { 1168 if ((position != 1) && ((point[-1] == ' ') || (point[-1] == '\t'))) 1169 { /* if at the start of a word */ 1170 while ((position != 1) && ((*point != ' ') && (*point != '\t'))) 1171 left(TRUE); 1172 } 1173 while ((position != 1) && ((*point == ' ') || (*point == '\t'))) 1174 left(TRUE); 1175 while ((position != 1) && ((*point != ' ') && (*point != '\t'))) 1176 left(TRUE); 1177 if ((position != 1) && ((*point == ' ') || (*point == '\t'))) 1178 right(TRUE); 1179 } 1180 else 1181 left(TRUE); 1182 } 1183 1184 void 1185 control() /* use control for commands */ 1186 { 1187 char *string; 1188 1189 if (in == 1) /* control a */ 1190 { 1191 string = get_string(ascii_code_str, TRUE); 1192 if (*string != '\0') 1193 { 1194 in = atoi(string); 1195 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 1196 insert(in); 1197 } 1198 free(string); 1199 } 1200 else if (in == 2) /* control b */ 1201 bottom(); 1202 else if (in == 3) /* control c */ 1203 { 1204 command_prompt(); 1205 } 1206 else if (in == 4) /* control d */ 1207 down(); 1208 else if (in == 5) /* control e */ 1209 search_prompt(); 1210 else if (in == 6) /* control f */ 1211 undel_char(); 1212 else if (in == 7) /* control g */ 1213 bol(); 1214 else if (in == 8) /* control h */ 1215 delete(TRUE); 1216 else if (in == 9) /* control i */ 1217 ; 1218 else if (in == 10) /* control j */ 1219 insert_line(TRUE); 1220 else if (in == 11) /* control k */ 1221 del_char(); 1222 else if (in == 12) /* control l */ 1223 left(TRUE); 1224 else if (in == 13) /* control m */ 1225 insert_line(TRUE); 1226 else if (in == 14) /* control n */ 1227 move_rel("d", max(5, (last_line - 5))); 1228 else if (in == 15) /* control o */ 1229 eol(); 1230 else if (in == 16) /* control p */ 1231 move_rel("u", max(5, (last_line - 5))); 1232 else if (in == 17) /* control q */ 1233 ; 1234 else if (in == 18) /* control r */ 1235 right(TRUE); 1236 else if (in == 19) /* control s */ 1237 ; 1238 else if (in == 20) /* control t */ 1239 top(); 1240 else if (in == 21) /* control u */ 1241 up(); 1242 else if (in == 22) /* control v */ 1243 undel_word(); 1244 else if (in == 23) /* control w */ 1245 del_word(); 1246 else if (in == 24) /* control x */ 1247 search(TRUE); 1248 else if (in == 25) /* control y */ 1249 del_line(); 1250 else if (in == 26) /* control z */ 1251 undel_line(); 1252 else if (in == 27) /* control [ (escape) */ 1253 { 1254 menu_op(main_menu); 1255 } 1256 } 1257 1258 /* 1259 | Emacs control-key bindings 1260 */ 1261 1262 void 1263 emacs_control() 1264 { 1265 char *string; 1266 1267 if (in == 1) /* control a */ 1268 bol(); 1269 else if (in == 2) /* control b */ 1270 left(TRUE); 1271 else if (in == 3) /* control c */ 1272 { 1273 command_prompt(); 1274 } 1275 else if (in == 4) /* control d */ 1276 del_char(); 1277 else if (in == 5) /* control e */ 1278 eol(); 1279 else if (in == 6) /* control f */ 1280 right(TRUE); 1281 else if (in == 7) /* control g */ 1282 move_rel("u", max(5, (last_line - 5))); 1283 else if (in == 8) /* control h */ 1284 delete(TRUE); 1285 else if (in == 9) /* control i */ 1286 ; 1287 else if (in == 10) /* control j */ 1288 undel_char(); 1289 else if (in == 11) /* control k */ 1290 del_line(); 1291 else if (in == 12) /* control l */ 1292 undel_line(); 1293 else if (in == 13) /* control m */ 1294 insert_line(TRUE); 1295 else if (in == 14) /* control n */ 1296 down(); 1297 else if (in == 15) /* control o */ 1298 { 1299 string = get_string(ascii_code_str, TRUE); 1300 if (*string != '\0') 1301 { 1302 in = atoi(string); 1303 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 1304 insert(in); 1305 } 1306 free(string); 1307 } 1308 else if (in == 16) /* control p */ 1309 up(); 1310 else if (in == 17) /* control q */ 1311 ; 1312 else if (in == 18) /* control r */ 1313 undel_word(); 1314 else if (in == 19) /* control s */ 1315 ; 1316 else if (in == 20) /* control t */ 1317 top(); 1318 else if (in == 21) /* control u */ 1319 bottom(); 1320 else if (in == 22) /* control v */ 1321 move_rel("d", max(5, (last_line - 5))); 1322 else if (in == 23) /* control w */ 1323 del_word(); 1324 else if (in == 24) /* control x */ 1325 search(TRUE); 1326 else if (in == 25) /* control y */ 1327 search_prompt(); 1328 else if (in == 26) /* control z */ 1329 adv_word(); 1330 else if (in == 27) /* control [ (escape) */ 1331 { 1332 menu_op(main_menu); 1333 } 1334 } 1335 1336 void 1337 bottom() /* go to bottom of file */ 1338 { 1339 while (curr_line->next_line != NULL) 1340 { 1341 curr_line = curr_line->next_line; 1342 absolute_lin++; 1343 } 1344 point = curr_line->line; 1345 if (horiz_offset) 1346 horiz_offset = 0; 1347 position = 1; 1348 midscreen(last_line, point); 1349 scr_pos = scr_horz; 1350 } 1351 1352 void 1353 top() /* go to top of file */ 1354 { 1355 while (curr_line->prev_line != NULL) 1356 { 1357 curr_line = curr_line->prev_line; 1358 absolute_lin--; 1359 } 1360 point = curr_line->line; 1361 if (horiz_offset) 1362 horiz_offset = 0; 1363 position = 1; 1364 midscreen(0, point); 1365 scr_pos = scr_horz; 1366 } 1367 1368 void 1369 nextline() /* move pointers to start of next line */ 1370 { 1371 curr_line = curr_line->next_line; 1372 absolute_lin++; 1373 point = curr_line->line; 1374 position = 1; 1375 if (scr_vert == last_line) 1376 { 1377 wmove(text_win, 0,0); 1378 wdeleteln(text_win); 1379 wmove(text_win, last_line,0); 1380 wclrtobot(text_win); 1381 draw_line(last_line,0,point,1,curr_line->line_length); 1382 } 1383 else 1384 scr_vert++; 1385 } 1386 1387 void 1388 prevline() /* move pointers to start of previous line*/ 1389 { 1390 curr_line = curr_line->prev_line; 1391 absolute_lin--; 1392 point = curr_line->line; 1393 position = 1; 1394 if (scr_vert == 0) 1395 { 1396 winsertln(text_win); 1397 draw_line(0,0,point,1,curr_line->line_length); 1398 } 1399 else 1400 scr_vert--; 1401 while (position < curr_line->line_length) 1402 { 1403 position++; 1404 point++; 1405 } 1406 } 1407 1408 void 1409 left(disp) /* move left one character */ 1410 int disp; 1411 { 1412 if (point != curr_line->line) /* if not at begin of line */ 1413 { 1414 if ((ee_chinese) && (position >= 2) && (*(point - 2) > 127)) 1415 { 1416 point--; 1417 position--; 1418 } 1419 point--; 1420 position--; 1421 scanline(point); 1422 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 1423 scr_pos = scr_horz; 1424 } 1425 else if (curr_line->prev_line != NULL) 1426 { 1427 if (!disp) 1428 { 1429 absolute_lin--; 1430 curr_line = curr_line->prev_line; 1431 point = curr_line->line + curr_line->line_length; 1432 position = curr_line->line_length; 1433 return; 1434 } 1435 position = 1; 1436 prevline(); 1437 scanline(point); 1438 scr_pos = scr_horz; 1439 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 1440 } 1441 } 1442 1443 void 1444 right(disp) /* move right one character */ 1445 int disp; 1446 { 1447 if (position < curr_line->line_length) 1448 { 1449 if ((ee_chinese) && (*point > 127) && 1450 ((curr_line->line_length - position) >= 2)) 1451 { 1452 point++; 1453 position++; 1454 } 1455 point++; 1456 position++; 1457 scanline(point); 1458 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 1459 scr_pos = scr_horz; 1460 } 1461 else if (curr_line->next_line != NULL) 1462 { 1463 if (!disp) 1464 { 1465 absolute_lin++; 1466 curr_line = curr_line->next_line; 1467 point = curr_line->line; 1468 position = 1; 1469 return; 1470 } 1471 nextline(); 1472 scr_pos = scr_horz = 0; 1473 if (horiz_offset) 1474 { 1475 horiz_offset = 0; 1476 midscreen(scr_vert, point); 1477 } 1478 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 1479 position = 1; 1480 } 1481 } 1482 1483 void 1484 find_pos() /* move to the same column as on other line */ 1485 { 1486 scr_horz = 0; 1487 position = 1; 1488 while ((scr_horz < scr_pos) && (position < curr_line->line_length)) 1489 { 1490 if (*point == 9) 1491 scr_horz += tabshift(scr_horz); 1492 else if (*point < ' ') 1493 scr_horz += 2; 1494 else if ((ee_chinese) && (*point > 127) && 1495 ((curr_line->line_length - position) >= 2)) 1496 { 1497 scr_horz += 2; 1498 point++; 1499 position++; 1500 } 1501 else 1502 scr_horz++; 1503 position++; 1504 point++; 1505 } 1506 if ((scr_horz - horiz_offset) > last_col) 1507 { 1508 horiz_offset = (scr_horz - (scr_horz % 8)) - (COLS - 8); 1509 midscreen(scr_vert, point); 1510 } 1511 else if (scr_horz < horiz_offset) 1512 { 1513 horiz_offset = max(0, (scr_horz - (scr_horz % 8))); 1514 midscreen(scr_vert, point); 1515 } 1516 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 1517 } 1518 1519 void 1520 up() /* move up one line */ 1521 { 1522 if (curr_line->prev_line != NULL) 1523 { 1524 prevline(); 1525 point = curr_line->line; 1526 find_pos(); 1527 } 1528 } 1529 1530 void 1531 down() /* move down one line */ 1532 { 1533 if (curr_line->next_line != NULL) 1534 { 1535 nextline(); 1536 find_pos(); 1537 } 1538 } 1539 1540 void 1541 function_key() /* process function key */ 1542 { 1543 if (in == KEY_LEFT) 1544 left(TRUE); 1545 else if (in == KEY_RIGHT) 1546 right(TRUE); 1547 else if (in == KEY_HOME) 1548 bol(); 1549 else if (in == KEY_END) 1550 eol(); 1551 else if (in == KEY_UP) 1552 up(); 1553 else if (in == KEY_DOWN) 1554 down(); 1555 else if (in == KEY_NPAGE) 1556 move_rel("d", max( 5, (last_line - 5))); 1557 else if (in == KEY_PPAGE) 1558 move_rel("u", max(5, (last_line - 5))); 1559 else if (in == KEY_DL) 1560 del_line(); 1561 else if (in == KEY_DC) 1562 del_char(); 1563 else if (in == KEY_BACKSPACE) 1564 delete(TRUE); 1565 else if (in == KEY_IL) 1566 { /* insert a line before current line */ 1567 insert_line(TRUE); 1568 left(TRUE); 1569 } 1570 else if (in == KEY_F(1)) 1571 gold = !gold; 1572 else if (in == KEY_F(2)) 1573 { 1574 if (gold) 1575 { 1576 gold = FALSE; 1577 undel_line(); 1578 } 1579 else 1580 undel_char(); 1581 } 1582 else if (in == KEY_F(3)) 1583 { 1584 if (gold) 1585 { 1586 gold = FALSE; 1587 undel_word(); 1588 } 1589 else 1590 del_word(); 1591 } 1592 else if (in == KEY_F(4)) 1593 { 1594 if (gold) 1595 { 1596 gold = FALSE; 1597 paint_info_win(); 1598 midscreen(scr_vert, point); 1599 } 1600 else 1601 adv_word(); 1602 } 1603 else if (in == KEY_F(5)) 1604 { 1605 if (gold) 1606 { 1607 gold = FALSE; 1608 search_prompt(); 1609 } 1610 else 1611 search(TRUE); 1612 } 1613 else if (in == KEY_F(6)) 1614 { 1615 if (gold) 1616 { 1617 gold = FALSE; 1618 bottom(); 1619 } 1620 else 1621 top(); 1622 } 1623 else if (in == KEY_F(7)) 1624 { 1625 if (gold) 1626 { 1627 gold = FALSE; 1628 eol(); 1629 } 1630 else 1631 bol(); 1632 } 1633 else if (in == KEY_F(8)) 1634 { 1635 if (gold) 1636 { 1637 gold = FALSE; 1638 command_prompt(); 1639 } 1640 else 1641 adv_line(); 1642 } 1643 } 1644 1645 void 1646 print_buffer() 1647 { 1648 char buffer[256]; 1649 1650 sprintf(buffer, ">!%s", print_command); 1651 wmove(com_win, 0, 0); 1652 wclrtoeol(com_win); 1653 wprintw(com_win, printer_msg_str, print_command); 1654 wrefresh(com_win); 1655 command(buffer); 1656 } 1657 1658 void 1659 command_prompt() 1660 { 1661 char *cmd_str; 1662 int result; 1663 1664 info_type = COMMANDS; 1665 paint_info_win(); 1666 cmd_str = get_string(command_str, TRUE); 1667 if ((result = unique_test(cmd_str, commands)) != 1) 1668 { 1669 werase(com_win); 1670 wmove(com_win, 0, 0); 1671 if (result == 0) 1672 wprintw(com_win, unkn_cmd_str, cmd_str); 1673 else 1674 wprintw(com_win, non_unique_cmd_msg); 1675 1676 wrefresh(com_win); 1677 1678 info_type = CONTROL_KEYS; 1679 paint_info_win(); 1680 1681 if (cmd_str != NULL) 1682 free(cmd_str); 1683 return; 1684 } 1685 command(cmd_str); 1686 wrefresh(com_win); 1687 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 1688 info_type = CONTROL_KEYS; 1689 paint_info_win(); 1690 if (cmd_str != NULL) 1691 free(cmd_str); 1692 } 1693 1694 void 1695 command(cmd_str1) /* process commands from keyboard */ 1696 char *cmd_str1; 1697 { 1698 char *cmd_str2 = NULL; 1699 char *cmd_str = cmd_str1; 1700 1701 clear_com_win = TRUE; 1702 if (compare(cmd_str, HELP, FALSE)) 1703 help(); 1704 else if (compare(cmd_str, WRITE, FALSE)) 1705 { 1706 if (restrict_mode()) 1707 { 1708 return; 1709 } 1710 cmd_str = next_word(cmd_str); 1711 if (*cmd_str == '\0') 1712 { 1713 cmd_str = cmd_str2 = get_string(file_write_prompt_str, TRUE); 1714 } 1715 tmp_file = resolve_name(cmd_str); 1716 write_file(tmp_file, 1); 1717 if (tmp_file != cmd_str) 1718 free(tmp_file); 1719 } 1720 else if (compare(cmd_str, READ, FALSE)) 1721 { 1722 if (restrict_mode()) 1723 { 1724 return; 1725 } 1726 cmd_str = next_word(cmd_str); 1727 if (*cmd_str == '\0') 1728 { 1729 cmd_str = cmd_str2 = get_string(file_read_prompt_str, TRUE); 1730 } 1731 tmp_file = cmd_str; 1732 recv_file = TRUE; 1733 tmp_file = resolve_name(cmd_str); 1734 check_fp(); 1735 if (tmp_file != cmd_str) 1736 free(tmp_file); 1737 } 1738 else if (compare(cmd_str, LINE, FALSE)) 1739 { 1740 wmove(com_win, 0, 0); 1741 wclrtoeol(com_win); 1742 wprintw(com_win, line_num_str, curr_line->line_number); 1743 wprintw(com_win, line_len_str, curr_line->line_length); 1744 } 1745 else if (compare(cmd_str, FILE_str, FALSE)) 1746 { 1747 wmove(com_win, 0, 0); 1748 wclrtoeol(com_win); 1749 if (in_file_name == NULL) 1750 wprintw(com_win, no_file_string); 1751 else 1752 wprintw(com_win, current_file_str, in_file_name); 1753 } 1754 else if ((*cmd_str >= '0') && (*cmd_str <= '9')) 1755 goto_line(cmd_str); 1756 else if (compare(cmd_str, CHARACTER, FALSE)) 1757 { 1758 wmove(com_win, 0, 0); 1759 wclrtoeol(com_win); 1760 wprintw(com_win, char_str, *point); 1761 } 1762 else if (compare(cmd_str, REDRAW, FALSE)) 1763 redraw(); 1764 else if (compare(cmd_str, RESEQUENCE, FALSE)) 1765 { 1766 tmp_line = first_line->next_line; 1767 while (tmp_line != NULL) 1768 { 1769 tmp_line->line_number = tmp_line->prev_line->line_number + 1; 1770 tmp_line = tmp_line->next_line; 1771 } 1772 } 1773 else if (compare(cmd_str, AUTHOR, FALSE)) 1774 { 1775 wmove(com_win, 0, 0); 1776 wclrtoeol(com_win); 1777 wprintw(com_win, "written by Hugh Mahon"); 1778 } 1779 else if (compare(cmd_str, VERSION, FALSE)) 1780 { 1781 wmove(com_win, 0, 0); 1782 wclrtoeol(com_win); 1783 wprintw(com_win, "%s", version); 1784 } 1785 else if (compare(cmd_str, CASE, FALSE)) 1786 case_sen = TRUE; 1787 else if (compare(cmd_str, NOCASE, FALSE)) 1788 case_sen = FALSE; 1789 else if (compare(cmd_str, EXPAND, FALSE)) 1790 expand_tabs = TRUE; 1791 else if (compare(cmd_str, NOEXPAND, FALSE)) 1792 expand_tabs = FALSE; 1793 else if (compare(cmd_str, Exit_string, FALSE)) 1794 finish(); 1795 else if (compare(cmd_str, chinese_cmd, FALSE)) 1796 { 1797 ee_chinese = TRUE; 1798 #ifdef NCURSE 1799 nc_setattrib(A_NC_BIG5); 1800 #endif /* NCURSE */ 1801 } 1802 else if (compare(cmd_str, nochinese_cmd, FALSE)) 1803 { 1804 ee_chinese = FALSE; 1805 #ifdef NCURSE 1806 nc_clearattrib(A_NC_BIG5); 1807 #endif /* NCURSE */ 1808 } 1809 else if (compare(cmd_str, QUIT_string, FALSE)) 1810 quit(0); 1811 else if (*cmd_str == '!') 1812 { 1813 cmd_str++; 1814 if ((*cmd_str == ' ') || (*cmd_str == 9)) 1815 cmd_str = next_word(cmd_str); 1816 sh_command(cmd_str); 1817 } 1818 else if ((*cmd_str == '<') && (!in_pipe)) 1819 { 1820 in_pipe = TRUE; 1821 shell_fork = FALSE; 1822 cmd_str++; 1823 if ((*cmd_str == ' ') || (*cmd_str == '\t')) 1824 cmd_str = next_word(cmd_str); 1825 command(cmd_str); 1826 in_pipe = FALSE; 1827 shell_fork = TRUE; 1828 } 1829 else if ((*cmd_str == '>') && (!out_pipe)) 1830 { 1831 out_pipe = TRUE; 1832 cmd_str++; 1833 if ((*cmd_str == ' ') || (*cmd_str == '\t')) 1834 cmd_str = next_word(cmd_str); 1835 command(cmd_str); 1836 out_pipe = FALSE; 1837 } 1838 else 1839 { 1840 wmove(com_win, 0, 0); 1841 wclrtoeol(com_win); 1842 wprintw(com_win, unkn_cmd_str, cmd_str); 1843 } 1844 if (cmd_str2 != NULL) 1845 free(cmd_str2); 1846 } 1847 1848 int 1849 scan(line, offset, column) /* determine horizontal position for get_string */ 1850 char *line; 1851 int offset; 1852 int column; 1853 { 1854 char *stemp; 1855 int i; 1856 int j; 1857 1858 stemp = line; 1859 i = 0; 1860 j = column; 1861 while (i < offset) 1862 { 1863 i++; 1864 j += len_char(*stemp, j); 1865 stemp++; 1866 } 1867 return(j); 1868 } 1869 1870 char * 1871 get_string(prompt, advance) /* read string from input on command line */ 1872 char *prompt; /* string containing user prompt message */ 1873 int advance; /* if true, skip leading spaces and tabs */ 1874 { 1875 char *string; 1876 char *tmp_string; 1877 char *nam_str; 1878 char *g_point; 1879 int tmp_int; 1880 int g_horz, g_position, g_pos; 1881 int esc_flag; 1882 1883 g_point = tmp_string = malloc(512); 1884 wmove(com_win,0,0); 1885 wclrtoeol(com_win); 1886 waddstr(com_win, prompt); 1887 wrefresh(com_win); 1888 nam_str = tmp_string; 1889 clear_com_win = TRUE; 1890 g_horz = g_position = scan(prompt, strlen(prompt), 0); 1891 g_pos = 0; 1892 do 1893 { 1894 esc_flag = FALSE; 1895 in = wgetch(com_win); 1896 if (in == -1) 1897 exit(0); 1898 if (((in == 8) || (in == 127) || (in == KEY_BACKSPACE)) && (g_pos > 0)) 1899 { 1900 tmp_int = g_horz; 1901 g_pos--; 1902 g_horz = scan(g_point, g_pos, g_position); 1903 tmp_int = tmp_int - g_horz; 1904 for (; 0 < tmp_int; tmp_int--) 1905 { 1906 if ((g_horz+tmp_int) < (last_col - 1)) 1907 { 1908 waddch(com_win, '\010'); 1909 waddch(com_win, ' '); 1910 waddch(com_win, '\010'); 1911 } 1912 } 1913 nam_str--; 1914 } 1915 else if ((in != 8) && (in != 127) && (in != '\n') && (in != '\r') && (in < 256)) 1916 { 1917 if (in == '\026') /* control-v, accept next character verbatim */ 1918 { /* allows entry of ^m, ^j, and ^h */ 1919 esc_flag = TRUE; 1920 in = wgetch(com_win); 1921 if (in == -1) 1922 exit(0); 1923 } 1924 *nam_str = in; 1925 g_pos++; 1926 if (((in < ' ') || (in > 126)) && (g_horz < (last_col - 1))) 1927 g_horz += out_char(com_win, in, g_horz); 1928 else 1929 { 1930 g_horz++; 1931 if (g_horz < (last_col - 1)) 1932 waddch(com_win, in); 1933 } 1934 nam_str++; 1935 } 1936 wrefresh(com_win); 1937 if (esc_flag) 1938 in = '\0'; 1939 } while ((in != '\n') && (in != '\r')); 1940 *nam_str = '\0'; 1941 nam_str = tmp_string; 1942 if (((*nam_str == ' ') || (*nam_str == 9)) && (advance)) 1943 nam_str = next_word(nam_str); 1944 string = malloc(strlen(nam_str) + 1); 1945 strcpy(string, nam_str); 1946 free(tmp_string); 1947 wrefresh(com_win); 1948 return(string); 1949 } 1950 1951 int 1952 compare(string1, string2, sensitive) /* compare two strings */ 1953 char *string1; 1954 char *string2; 1955 int sensitive; 1956 { 1957 char *strng1; 1958 char *strng2; 1959 int tmp; 1960 int equal; 1961 1962 strng1 = string1; 1963 strng2 = string2; 1964 tmp = 0; 1965 if ((strng1 == NULL) || (strng2 == NULL) || (*strng1 == '\0') || (*strng2 == '\0')) 1966 return(FALSE); 1967 equal = TRUE; 1968 while (equal) 1969 { 1970 if (sensitive) 1971 { 1972 if (*strng1 != *strng2) 1973 equal = FALSE; 1974 } 1975 else 1976 { 1977 if (toupper(*strng1) != toupper(*strng2)) 1978 equal = FALSE; 1979 } 1980 strng1++; 1981 strng2++; 1982 if ((*strng1 == '\0') || (*strng2 == '\0') || (*strng1 == ' ') || (*strng2 == ' ')) 1983 break; 1984 tmp++; 1985 } 1986 return(equal); 1987 } 1988 1989 void 1990 goto_line(cmd_str) 1991 char *cmd_str; 1992 { 1993 int number; 1994 int i; 1995 char *ptr; 1996 char *direction = NULL; 1997 struct text *t_line; 1998 1999 ptr = cmd_str; 2000 i= 0; 2001 while ((*ptr >='0') && (*ptr <= '9')) 2002 { 2003 i= i * 10 + (*ptr - '0'); 2004 ptr++; 2005 } 2006 number = i; 2007 i = 0; 2008 t_line = curr_line; 2009 while ((t_line->line_number > number) && (t_line->prev_line != NULL)) 2010 { 2011 i++; 2012 t_line = t_line->prev_line; 2013 direction = "u"; 2014 } 2015 while ((t_line->line_number < number) && (t_line->next_line != NULL)) 2016 { 2017 i++; 2018 direction = "d"; 2019 t_line = t_line->next_line; 2020 } 2021 if ((i < 30) && (i > 0)) 2022 { 2023 move_rel(direction, i); 2024 } 2025 else 2026 { 2027 if (!strcmp(direction, "d")) 2028 { 2029 absolute_lin += i; 2030 } 2031 else 2032 { 2033 absolute_lin -= i; 2034 } 2035 curr_line = t_line; 2036 point = curr_line->line; 2037 position = 1; 2038 midscreen((last_line / 2), point); 2039 scr_pos = scr_horz; 2040 } 2041 wmove(com_win, 0, 0); 2042 wclrtoeol(com_win); 2043 wprintw(com_win, line_num_str, curr_line->line_number); 2044 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 2045 } 2046 2047 void 2048 midscreen(line, pnt) /* put current line in middle of screen */ 2049 int line; 2050 unsigned char *pnt; 2051 { 2052 struct text *mid_line; 2053 int i; 2054 2055 line = min(line, last_line); 2056 mid_line = curr_line; 2057 for (i = 0; ((i < line) && (curr_line->prev_line != NULL)); i++) 2058 curr_line = curr_line->prev_line; 2059 scr_vert = scr_horz = 0; 2060 wmove(text_win, 0, 0); 2061 draw_screen(); 2062 scr_vert = i; 2063 curr_line = mid_line; 2064 scanline(pnt); 2065 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 2066 } 2067 2068 void 2069 get_options(numargs, arguments) /* get arguments from command line */ 2070 int numargs; 2071 char *arguments[]; 2072 { 2073 char *buff; 2074 int count; 2075 struct files *temp_names = NULL; 2076 char *name; 2077 char *ptr; 2078 int no_more_opts = FALSE; 2079 2080 /* 2081 | see if editor was invoked as 'ree' (restricted mode) 2082 */ 2083 2084 if (!(name = strrchr(arguments[0], '/'))) 2085 name = arguments[0]; 2086 else 2087 name++; 2088 if (!strcmp(name, "ree")) 2089 restricted = TRUE; 2090 2091 top_of_stack = NULL; 2092 input_file = FALSE; 2093 recv_file = FALSE; 2094 count = 1; 2095 while ((count < numargs)&& (!no_more_opts)) 2096 { 2097 buff = arguments[count]; 2098 if (!strcmp("-i", buff)) 2099 { 2100 info_window = FALSE; 2101 } 2102 else if (!strcmp("-e", buff)) 2103 { 2104 expand_tabs = FALSE; 2105 } 2106 else if (!strcmp("-h", buff)) 2107 { 2108 nohighlight = TRUE; 2109 } 2110 else if (!strcmp("-?", buff)) 2111 { 2112 fprintf(stderr, usage0, arguments[0]); 2113 fprintf(stderr, usage1); 2114 fprintf(stderr, usage2); 2115 fprintf(stderr, usage3); 2116 fprintf(stderr, usage4); 2117 exit(1); 2118 } 2119 else if ((*buff == '+') && (start_at_line == NULL)) 2120 { 2121 buff++; 2122 start_at_line = buff; 2123 } 2124 else if (!(strcmp("--", buff))) 2125 no_more_opts = TRUE; 2126 else 2127 { 2128 count--; 2129 no_more_opts = TRUE; 2130 } 2131 count++; 2132 } 2133 while (count < numargs) 2134 { 2135 buff = arguments[count]; 2136 if (top_of_stack == NULL) 2137 { 2138 temp_names = top_of_stack = name_alloc(); 2139 } 2140 else 2141 { 2142 temp_names->next_name = name_alloc(); 2143 temp_names = temp_names->next_name; 2144 } 2145 ptr = temp_names->name = malloc(strlen(buff) + 1); 2146 while (*buff != '\0') 2147 { 2148 *ptr = *buff; 2149 buff++; 2150 ptr++; 2151 } 2152 *ptr = '\0'; 2153 temp_names->next_name = NULL; 2154 input_file = TRUE; 2155 recv_file = TRUE; 2156 count++; 2157 } 2158 } 2159 2160 void 2161 check_fp() /* open or close files according to flags */ 2162 { 2163 int line_num; 2164 int temp; 2165 struct stat buf; 2166 2167 clear_com_win = TRUE; 2168 tmp_vert = scr_vert; 2169 tmp_horz = scr_horz; 2170 tmp_line = curr_line; 2171 if (input_file) 2172 { 2173 in_file_name = tmp_file = top_of_stack->name; 2174 top_of_stack = top_of_stack->next_name; 2175 } 2176 temp = stat(tmp_file, &buf); 2177 buf.st_mode &= ~07777; 2178 if ((temp != -1) && (buf.st_mode != 0100000) && (buf.st_mode != 0)) 2179 { 2180 wprintw(com_win, file_is_dir_msg, tmp_file); 2181 wrefresh(com_win); 2182 if (input_file) 2183 { 2184 quit(0); 2185 return; 2186 } 2187 else 2188 return; 2189 } 2190 if ((get_fd = open(tmp_file, O_RDONLY)) == -1) 2191 { 2192 wmove(com_win, 0, 0); 2193 wclrtoeol(com_win); 2194 if (input_file) 2195 wprintw(com_win, new_file_msg, tmp_file); 2196 else 2197 wprintw(com_win, cant_open_msg, tmp_file); 2198 wrefresh(com_win); 2199 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 2200 wrefresh(text_win); 2201 recv_file = FALSE; 2202 input_file = FALSE; 2203 return; 2204 } 2205 else 2206 get_file(tmp_file); 2207 2208 recv_file = FALSE; 2209 line_num = curr_line->line_number; 2210 scr_vert = tmp_vert; 2211 scr_horz = tmp_horz; 2212 if (input_file) 2213 curr_line= first_line; 2214 else 2215 curr_line = tmp_line; 2216 point = curr_line->line; 2217 draw_screen(); 2218 if (input_file) 2219 { 2220 input_file = FALSE; 2221 if (start_at_line != NULL) 2222 { 2223 line_num = atoi(start_at_line) - 1; 2224 move_rel("d", line_num); 2225 line_num = 0; 2226 start_at_line = NULL; 2227 } 2228 } 2229 else 2230 { 2231 wmove(com_win, 0, 0); 2232 wclrtoeol(com_win); 2233 text_changes = TRUE; 2234 if ((tmp_file != NULL) && (*tmp_file != '\0')) 2235 wprintw(com_win, file_read_fin_msg, tmp_file); 2236 } 2237 wrefresh(com_win); 2238 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 2239 wrefresh(text_win); 2240 } 2241 2242 void 2243 get_file(file_name) /* read specified file into current buffer */ 2244 char *file_name; 2245 { 2246 int can_read; /* file has at least one character */ 2247 int length; /* length of line read by read */ 2248 int append; /* should text be appended to current line */ 2249 struct text *temp_line; 2250 char ro_flag = FALSE; 2251 2252 if (recv_file) /* if reading a file */ 2253 { 2254 wmove(com_win, 0, 0); 2255 wclrtoeol(com_win); 2256 wprintw(com_win, reading_file_msg, file_name); 2257 if (access(file_name, 2)) /* check permission to write */ 2258 { 2259 if ((errno == ENOTDIR) || (errno == EACCES) || (errno == EROFS) || (errno == ETXTBSY) || (errno == EFAULT)) 2260 { 2261 wprintw(com_win, read_only_msg); 2262 ro_flag = TRUE; 2263 } 2264 } 2265 wrefresh(com_win); 2266 } 2267 if (curr_line->line_length > 1) /* if current line is not blank */ 2268 { 2269 insert_line(FALSE); 2270 left(FALSE); 2271 append = FALSE; 2272 } 2273 else 2274 append = TRUE; 2275 can_read = FALSE; /* test if file has any characters */ 2276 while (((length = read(get_fd, in_string, 512)) != 0) && (length != -1)) 2277 { 2278 can_read = TRUE; /* if set file has at least 1 character */ 2279 get_line(length, in_string, &append); 2280 } 2281 if ((can_read) && (curr_line->line_length == 1)) 2282 { 2283 temp_line = curr_line->prev_line; 2284 temp_line->next_line = curr_line->next_line; 2285 if (temp_line->next_line != NULL) 2286 temp_line->next_line->prev_line = temp_line; 2287 if (curr_line->line != NULL) 2288 free(curr_line->line); 2289 free(curr_line); 2290 curr_line = temp_line; 2291 } 2292 if (input_file) /* if this is the file to be edited display number of lines */ 2293 { 2294 wmove(com_win, 0, 0); 2295 wclrtoeol(com_win); 2296 wprintw(com_win, file_read_lines_msg, in_file_name, curr_line->line_number); 2297 if (ro_flag) 2298 wprintw(com_win, read_only_msg); 2299 wrefresh(com_win); 2300 } 2301 else if (can_read) /* not input_file and file is non-zero size */ 2302 text_changes = TRUE; 2303 2304 if (recv_file) /* if reading a file */ 2305 { 2306 in = EOF; 2307 } 2308 } 2309 2310 void 2311 get_line(length, in_string, append) /* read string and split into lines */ 2312 int length; /* length of string read by read */ 2313 unsigned char *in_string; /* string read by read */ 2314 int *append; /* TRUE if must append more text to end of current line */ 2315 { 2316 unsigned char *str1; 2317 unsigned char *str2; 2318 int num; /* offset from start of string */ 2319 int char_count; /* length of new line (or added portion */ 2320 int temp_counter; /* temporary counter value */ 2321 struct text *tline; /* temporary pointer to new line */ 2322 int first_time; /* if TRUE, the first time through the loop */ 2323 2324 str2 = in_string; 2325 num = 0; 2326 first_time = TRUE; 2327 while (num < length) 2328 { 2329 if (!first_time) 2330 { 2331 if (num < length) 2332 { 2333 str2++; 2334 num++; 2335 } 2336 } 2337 else 2338 first_time = FALSE; 2339 str1 = str2; 2340 char_count = 1; 2341 /* find end of line */ 2342 while ((*str2 != '\n') && (num < length)) 2343 { 2344 str2++; 2345 num++; 2346 char_count++; 2347 } 2348 if (!(*append)) /* if not append to current line, insert new one */ 2349 { 2350 tline = txtalloc(); /* allocate data structure for next line */ 2351 tline->line_number = curr_line->line_number + 1; 2352 tline->next_line = curr_line->next_line; 2353 tline->prev_line = curr_line; 2354 curr_line->next_line = tline; 2355 if (tline->next_line != NULL) 2356 tline->next_line->prev_line = tline; 2357 curr_line = tline; 2358 curr_line->line = point = (unsigned char *) malloc(char_count); 2359 curr_line->line_length = char_count; 2360 curr_line->max_length = char_count; 2361 } 2362 else 2363 { 2364 point = resiz_line(char_count, curr_line, curr_line->line_length); 2365 curr_line->line_length += (char_count - 1); 2366 } 2367 for (temp_counter = 1; temp_counter < char_count; temp_counter++) 2368 { 2369 *point = *str1; 2370 point++; 2371 str1++; 2372 } 2373 *point = '\0'; 2374 *append = FALSE; 2375 if ((num == length) && (*str2 != '\n')) 2376 *append = TRUE; 2377 } 2378 } 2379 2380 void 2381 draw_screen() /* redraw the screen from current postion */ 2382 { 2383 struct text *temp_line; 2384 unsigned char *line_out; 2385 int temp_vert; 2386 2387 temp_line = curr_line; 2388 temp_vert = scr_vert; 2389 wclrtobot(text_win); 2390 while ((temp_line != NULL) && (temp_vert <= last_line)) 2391 { 2392 line_out = temp_line->line; 2393 draw_line(temp_vert, 0, line_out, 1, temp_line->line_length); 2394 temp_vert++; 2395 temp_line = temp_line->next_line; 2396 } 2397 wmove(text_win, temp_vert, 0); 2398 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 2399 } 2400 2401 void 2402 finish() /* prepare to exit edit session */ 2403 { 2404 char *file_name = in_file_name; 2405 2406 /* 2407 | changes made here should be reflected in the 'save' 2408 | portion of file_op() 2409 */ 2410 2411 if ((file_name == NULL) || (*file_name == '\0')) 2412 file_name = get_string(save_file_name_prompt, TRUE); 2413 2414 if ((file_name == NULL) || (*file_name == '\0')) 2415 { 2416 wmove(com_win, 0, 0); 2417 wprintw(com_win, file_not_saved_msg); 2418 wclrtoeol(com_win); 2419 wrefresh(com_win); 2420 clear_com_win = TRUE; 2421 return; 2422 } 2423 2424 tmp_file = resolve_name(file_name); 2425 if (tmp_file != file_name) 2426 { 2427 free(file_name); 2428 file_name = tmp_file; 2429 } 2430 2431 if (write_file(file_name, 1)) 2432 { 2433 text_changes = FALSE; 2434 quit(0); 2435 } 2436 } 2437 2438 int 2439 quit(noverify) /* exit editor */ 2440 int noverify; 2441 { 2442 char *ans; 2443 2444 touchwin(text_win); 2445 wrefresh(text_win); 2446 if ((text_changes) && (!noverify)) 2447 { 2448 ans = get_string(changes_made_prompt, TRUE); 2449 if (toupper(*ans) == toupper(*yes_char)) 2450 text_changes = FALSE; 2451 else 2452 return(0); 2453 free(ans); 2454 } 2455 if (top_of_stack == NULL) 2456 { 2457 if (info_window) 2458 wrefresh(info_win); 2459 wrefresh(com_win); 2460 resetty(); 2461 endwin(); 2462 putchar('\n'); 2463 exit(0); 2464 } 2465 else 2466 { 2467 delete_text(); 2468 recv_file = TRUE; 2469 input_file = TRUE; 2470 check_fp(); 2471 } 2472 return(0); 2473 } 2474 2475 void 2476 edit_abort(arg) 2477 int arg; 2478 { 2479 wrefresh(com_win); 2480 resetty(); 2481 endwin(); 2482 putchar('\n'); 2483 exit(1); 2484 } 2485 2486 void 2487 delete_text() 2488 { 2489 while (curr_line->next_line != NULL) 2490 curr_line = curr_line->next_line; 2491 while (curr_line != first_line) 2492 { 2493 free(curr_line->line); 2494 curr_line = curr_line->prev_line; 2495 absolute_lin--; 2496 free(curr_line->next_line); 2497 } 2498 curr_line->next_line = NULL; 2499 *curr_line->line = '\0'; 2500 curr_line->line_length = 1; 2501 curr_line->line_number = 1; 2502 point = curr_line->line; 2503 scr_pos = scr_vert = scr_horz = 0; 2504 position = 1; 2505 } 2506 2507 int 2508 write_file(file_name, warn_if_exists) 2509 char *file_name; 2510 int warn_if_exists; 2511 { 2512 char cr; 2513 char *tmp_point; 2514 struct text *out_line; 2515 int lines, charac; 2516 int temp_pos; 2517 int write_flag = TRUE; 2518 2519 charac = lines = 0; 2520 if (warn_if_exists && 2521 ((in_file_name == NULL) || strcmp(in_file_name, file_name))) 2522 { 2523 if ((temp_fp = fopen(file_name, "r"))) 2524 { 2525 tmp_point = get_string(file_exists_prompt, TRUE); 2526 if (toupper(*tmp_point) == toupper(*yes_char)) 2527 write_flag = TRUE; 2528 else 2529 write_flag = FALSE; 2530 fclose(temp_fp); 2531 free(tmp_point); 2532 } 2533 } 2534 2535 clear_com_win = TRUE; 2536 2537 if (write_flag) 2538 { 2539 if ((temp_fp = fopen(file_name, "w")) == NULL) 2540 { 2541 clear_com_win = TRUE; 2542 wmove(com_win,0,0); 2543 wclrtoeol(com_win); 2544 wprintw(com_win, create_file_fail_msg, file_name); 2545 wrefresh(com_win); 2546 return(FALSE); 2547 } 2548 else 2549 { 2550 wmove(com_win,0,0); 2551 wclrtoeol(com_win); 2552 wprintw(com_win, writing_file_msg, file_name); 2553 wrefresh(com_win); 2554 cr = '\n'; 2555 out_line = first_line; 2556 while (out_line != NULL) 2557 { 2558 temp_pos = 1; 2559 tmp_point= out_line->line; 2560 while (temp_pos < out_line->line_length) 2561 { 2562 putc(*tmp_point, temp_fp); 2563 tmp_point++; 2564 temp_pos++; 2565 } 2566 charac += out_line->line_length; 2567 out_line = out_line->next_line; 2568 putc(cr, temp_fp); 2569 lines++; 2570 } 2571 fclose(temp_fp); 2572 wmove(com_win,0,0); 2573 wclrtoeol(com_win); 2574 wprintw(com_win, file_written_msg, file_name, lines, charac); 2575 wrefresh(com_win); 2576 return(TRUE); 2577 } 2578 } 2579 else 2580 return(FALSE); 2581 } 2582 2583 int 2584 search(display_message) /* search for string in srch_str */ 2585 int display_message; 2586 { 2587 int lines_moved; 2588 int iter; 2589 int found; 2590 2591 if ((srch_str == NULL) || (*srch_str == '\0')) 2592 return(FALSE); 2593 if (display_message) 2594 { 2595 wmove(com_win, 0, 0); 2596 wclrtoeol(com_win); 2597 wprintw(com_win, searching_msg); 2598 wrefresh(com_win); 2599 clear_com_win = TRUE; 2600 } 2601 lines_moved = 0; 2602 found = FALSE; 2603 srch_line = curr_line; 2604 srch_1 = point; 2605 if (position < curr_line->line_length) 2606 srch_1++; 2607 iter = position + 1; 2608 while ((!found) && (srch_line != NULL)) 2609 { 2610 while ((iter < srch_line->line_length) && (!found)) 2611 { 2612 srch_2 = srch_1; 2613 if (case_sen) /* if case sensitive */ 2614 { 2615 srch_3 = srch_str; 2616 while ((*srch_2 == *srch_3) && (*srch_3 != '\0')) 2617 { 2618 found = TRUE; 2619 srch_2++; 2620 srch_3++; 2621 } /* end while */ 2622 } 2623 else /* if not case sensitive */ 2624 { 2625 srch_3 = u_srch_str; 2626 while ((toupper(*srch_2) == *srch_3) && (*srch_3 != '\0')) 2627 { 2628 found = TRUE; 2629 srch_2++; 2630 srch_3++; 2631 } 2632 } /* end else */ 2633 if (!((*srch_3 == '\0') && (found))) 2634 { 2635 found = FALSE; 2636 if (iter < srch_line->line_length) 2637 srch_1++; 2638 iter++; 2639 } 2640 } 2641 if (!found) 2642 { 2643 srch_line = srch_line->next_line; 2644 if (srch_line != NULL) 2645 srch_1 = srch_line->line; 2646 iter = 1; 2647 lines_moved++; 2648 } 2649 } 2650 if (found) 2651 { 2652 if (display_message) 2653 { 2654 wmove(com_win, 0, 0); 2655 wclrtoeol(com_win); 2656 wrefresh(com_win); 2657 } 2658 if (lines_moved == 0) 2659 { 2660 while (position < iter) 2661 right(TRUE); 2662 } 2663 else 2664 { 2665 if (lines_moved < 30) 2666 { 2667 move_rel("d", lines_moved); 2668 while (position < iter) 2669 right(TRUE); 2670 } 2671 else 2672 { 2673 absolute_lin += lines_moved; 2674 curr_line = srch_line; 2675 point = srch_1; 2676 position = iter; 2677 scanline(point); 2678 scr_pos = scr_horz; 2679 midscreen((last_line / 2), point); 2680 } 2681 } 2682 } 2683 else 2684 { 2685 if (display_message) 2686 { 2687 wmove(com_win, 0, 0); 2688 wclrtoeol(com_win); 2689 wprintw(com_win, str_not_found_msg, srch_str); 2690 wrefresh(com_win); 2691 } 2692 wmove(text_win, scr_vert,(scr_horz - horiz_offset)); 2693 } 2694 return(found); 2695 } 2696 2697 void 2698 search_prompt() /* prompt and read search string (srch_str) */ 2699 { 2700 if (srch_str != NULL) 2701 free(srch_str); 2702 if ((u_srch_str != NULL) && (*u_srch_str != '\0')) 2703 free(u_srch_str); 2704 srch_str = get_string(search_prompt_str, FALSE); 2705 gold = FALSE; 2706 srch_3 = srch_str; 2707 srch_1 = u_srch_str = malloc(strlen(srch_str) + 1); 2708 while (*srch_3 != '\0') 2709 { 2710 *srch_1 = toupper(*srch_3); 2711 srch_1++; 2712 srch_3++; 2713 } 2714 *srch_1 = '\0'; 2715 search(TRUE); 2716 } 2717 2718 void 2719 del_char() /* delete current character */ 2720 { 2721 in = 8; /* backspace */ 2722 if (position < curr_line->line_length) /* if not end of line */ 2723 { 2724 if ((ee_chinese) && (*point > 127) && 2725 ((curr_line->line_length - position) >= 2)) 2726 { 2727 point++; 2728 position++; 2729 } 2730 position++; 2731 point++; 2732 scanline(point); 2733 delete(TRUE); 2734 } 2735 else 2736 { 2737 right(FALSE); 2738 delete(FALSE); 2739 } 2740 } 2741 2742 void 2743 undel_char() /* undelete last deleted character */ 2744 { 2745 if (d_char[0] == '\n') /* insert line if last del_char deleted eol */ 2746 insert_line(TRUE); 2747 else 2748 { 2749 in = d_char[0]; 2750 insert(in); 2751 if (d_char[1] != '\0') 2752 { 2753 in = d_char[1]; 2754 insert(in); 2755 } 2756 } 2757 } 2758 2759 void 2760 del_word() /* delete word in front of cursor */ 2761 { 2762 int tposit; 2763 int difference; 2764 unsigned char *d_word2; 2765 unsigned char *d_word3; 2766 unsigned char tmp_char[3]; 2767 2768 if (d_word != NULL) 2769 free(d_word); 2770 d_word = malloc(curr_line->line_length); 2771 tmp_char[0] = d_char[0]; 2772 tmp_char[1] = d_char[1]; 2773 tmp_char[2] = d_char[2]; 2774 d_word3 = point; 2775 d_word2 = d_word; 2776 tposit = position; 2777 while ((tposit < curr_line->line_length) && 2778 ((*d_word3 != ' ') && (*d_word3 != '\t'))) 2779 { 2780 tposit++; 2781 *d_word2 = *d_word3; 2782 d_word2++; 2783 d_word3++; 2784 } 2785 while ((tposit < curr_line->line_length) && 2786 ((*d_word3 == ' ') || (*d_word3 == '\t'))) 2787 { 2788 tposit++; 2789 *d_word2 = *d_word3; 2790 d_word2++; 2791 d_word3++; 2792 } 2793 *d_word2 = '\0'; 2794 d_wrd_len = difference = d_word2 - d_word; 2795 d_word2 = point; 2796 while (tposit < curr_line->line_length) 2797 { 2798 tposit++; 2799 *d_word2 = *d_word3; 2800 d_word2++; 2801 d_word3++; 2802 } 2803 curr_line->line_length -= difference; 2804 *d_word2 = '\0'; 2805 draw_line(scr_vert, scr_horz,point,position,curr_line->line_length); 2806 d_char[0] = tmp_char[0]; 2807 d_char[1] = tmp_char[1]; 2808 d_char[2] = tmp_char[2]; 2809 text_changes = TRUE; 2810 formatted = FALSE; 2811 } 2812 2813 void 2814 undel_word() /* undelete last deleted word */ 2815 { 2816 int temp; 2817 int tposit; 2818 unsigned char *tmp_old_ptr; 2819 unsigned char *tmp_space; 2820 unsigned char *tmp_ptr; 2821 unsigned char *d_word_ptr; 2822 2823 /* 2824 | resize line to handle undeleted word 2825 */ 2826 if ((curr_line->max_length - (curr_line->line_length + d_wrd_len)) < 5) 2827 point = resiz_line(d_wrd_len, curr_line, position); 2828 tmp_ptr = tmp_space = malloc(curr_line->line_length + d_wrd_len); 2829 d_word_ptr = d_word; 2830 temp = 1; 2831 /* 2832 | copy d_word contents into temp space 2833 */ 2834 while (temp <= d_wrd_len) 2835 { 2836 temp++; 2837 *tmp_ptr = *d_word_ptr; 2838 tmp_ptr++; 2839 d_word_ptr++; 2840 } 2841 tmp_old_ptr = point; 2842 tposit = position; 2843 /* 2844 | copy contents of line from curent position to eol into 2845 | temp space 2846 */ 2847 while (tposit < curr_line->line_length) 2848 { 2849 temp++; 2850 tposit++; 2851 *tmp_ptr = *tmp_old_ptr; 2852 tmp_ptr++; 2853 tmp_old_ptr++; 2854 } 2855 curr_line->line_length += d_wrd_len; 2856 tmp_old_ptr = point; 2857 *tmp_ptr = '\0'; 2858 tmp_ptr = tmp_space; 2859 tposit = 1; 2860 /* 2861 | now copy contents from temp space back to original line 2862 */ 2863 while (tposit < temp) 2864 { 2865 tposit++; 2866 *tmp_old_ptr = *tmp_ptr; 2867 tmp_ptr++; 2868 tmp_old_ptr++; 2869 } 2870 *tmp_old_ptr = '\0'; 2871 free(tmp_space); 2872 draw_line(scr_vert, scr_horz, point, position, curr_line->line_length); 2873 } 2874 2875 void 2876 del_line() /* delete from cursor to end of line */ 2877 { 2878 unsigned char *dl1; 2879 unsigned char *dl2; 2880 int tposit; 2881 2882 if (d_line != NULL) 2883 free(d_line); 2884 d_line = malloc(curr_line->line_length); 2885 dl1 = d_line; 2886 dl2 = point; 2887 tposit = position; 2888 while (tposit < curr_line->line_length) 2889 { 2890 *dl1 = *dl2; 2891 dl1++; 2892 dl2++; 2893 tposit++; 2894 } 2895 dlt_line->line_length = 1 + tposit - position; 2896 *dl1 = '\0'; 2897 *point = '\0'; 2898 curr_line->line_length = position; 2899 wclrtoeol(text_win); 2900 if (curr_line->next_line != NULL) 2901 { 2902 right(FALSE); 2903 delete(FALSE); 2904 } 2905 text_changes = TRUE; 2906 } 2907 2908 void 2909 undel_line() /* undelete last deleted line */ 2910 { 2911 unsigned char *ud1; 2912 unsigned char *ud2; 2913 int tposit; 2914 2915 if (dlt_line->line_length == 0) 2916 return; 2917 2918 insert_line(TRUE); 2919 left(TRUE); 2920 point = resiz_line(dlt_line->line_length, curr_line, position); 2921 curr_line->line_length += dlt_line->line_length - 1; 2922 ud1 = point; 2923 ud2 = d_line; 2924 tposit = 1; 2925 while (tposit < dlt_line->line_length) 2926 { 2927 tposit++; 2928 *ud1 = *ud2; 2929 ud1++; 2930 ud2++; 2931 } 2932 *ud1 = '\0'; 2933 draw_line(scr_vert, scr_horz,point,position,curr_line->line_length); 2934 } 2935 2936 void 2937 adv_word() /* advance to next word */ 2938 { 2939 while ((position < curr_line->line_length) && ((*point != 32) && (*point != 9))) 2940 right(TRUE); 2941 while ((position < curr_line->line_length) && ((*point == 32) || (*point == 9))) 2942 right(TRUE); 2943 } 2944 2945 void 2946 move_rel(direction, lines) /* move relative to current line */ 2947 char *direction; 2948 int lines; 2949 { 2950 int i; 2951 char *tmp; 2952 2953 if (*direction == 'u') 2954 { 2955 scr_pos = 0; 2956 while (position > 1) 2957 left(TRUE); 2958 for (i = 0; i < lines; i++) 2959 { 2960 up(); 2961 } 2962 if ((last_line > 5) && ( scr_vert < 4)) 2963 { 2964 tmp = point; 2965 tmp_line = curr_line; 2966 for (i= 0;(i<5)&&(curr_line->prev_line != NULL); i++) 2967 { 2968 up(); 2969 } 2970 scr_vert = scr_vert + i; 2971 curr_line = tmp_line; 2972 absolute_lin += i; 2973 point = tmp; 2974 scanline(point); 2975 } 2976 } 2977 else 2978 { 2979 if ((position != 1) && (curr_line->next_line != NULL)) 2980 { 2981 nextline(); 2982 scr_pos = scr_horz = 0; 2983 if (horiz_offset) 2984 { 2985 horiz_offset = 0; 2986 midscreen(scr_vert, point); 2987 } 2988 } 2989 else 2990 adv_line(); 2991 for (i = 1; i < lines; i++) 2992 { 2993 down(); 2994 } 2995 if ((last_line > 10) && (scr_vert > (last_line - 5))) 2996 { 2997 tmp = point; 2998 tmp_line = curr_line; 2999 for (i=0; (i<5) && (curr_line->next_line != NULL); i++) 3000 { 3001 down(); 3002 } 3003 absolute_lin -= i; 3004 scr_vert = scr_vert - i; 3005 curr_line = tmp_line; 3006 point = tmp; 3007 scanline(point); 3008 } 3009 } 3010 wmove(text_win, scr_vert, (scr_horz - horiz_offset)); 3011 } 3012 3013 void 3014 eol() /* go to end of line */ 3015 { 3016 if (position < curr_line->line_length) 3017 { 3018 while (position < curr_line->line_length) 3019 right(TRUE); 3020 } 3021 else if (curr_line->next_line != NULL) 3022 { 3023 right(TRUE); 3024 while (position < curr_line->line_length) 3025 right(TRUE); 3026 } 3027 } 3028 3029 void 3030 bol() /* move to beginning of line */ 3031 { 3032 if (point != curr_line->line) 3033 { 3034 while (point != curr_line->line) 3035 left(TRUE); 3036 } 3037 else if (curr_line->prev_line != NULL) 3038 { 3039 scr_pos = 0; 3040 up(); 3041 } 3042 } 3043 3044 void 3045 adv_line() /* advance to beginning of next line */ 3046 { 3047 if ((point != curr_line->line) || (scr_pos > 0)) 3048 { 3049 while (position < curr_line->line_length) 3050 right(TRUE); 3051 right(TRUE); 3052 } 3053 else if (curr_line->next_line != NULL) 3054 { 3055 scr_pos = 0; 3056 down(); 3057 } 3058 } 3059 3060 void 3061 from_top() 3062 { 3063 struct text *tmpline = first_line; 3064 int x = 1; 3065 3066 while ((tmpline != NULL) && (tmpline != curr_line)) 3067 { 3068 x++; 3069 tmpline = tmpline->next_line; 3070 } 3071 absolute_lin = x; 3072 } 3073 3074 void 3075 sh_command(string) /* execute shell command */ 3076 char *string; /* string containing user command */ 3077 { 3078 char *temp_point; 3079 char *last_slash; 3080 char *path; /* directory path to executable */ 3081 int parent; /* zero if child, child's pid if parent */ 3082 int value; 3083 int return_val; 3084 struct text *line_holder; 3085 3086 if (restrict_mode()) 3087 { 3088 return; 3089 } 3090 3091 if (!(path = getenv("SHELL"))) 3092 path = "/bin/sh"; 3093 last_slash = temp_point = path; 3094 while (*temp_point != '\0') 3095 { 3096 if (*temp_point == '/') 3097 last_slash = ++temp_point; 3098 else 3099 temp_point++; 3100 } 3101 3102 /* 3103 | if in_pipe is true, then output of the shell operation will be 3104 | read by the editor, and curses doesn't need to be turned off 3105 */ 3106 3107 if (!in_pipe) 3108 { 3109 keypad(com_win, FALSE); 3110 keypad(text_win, FALSE); 3111 echo(); 3112 nl(); 3113 noraw(); 3114 resetty(); 3115 3116 #ifndef NCURSE 3117 endwin(); 3118 #endif 3119 } 3120 3121 if (in_pipe) 3122 { 3123 pipe(pipe_in); /* create a pipe */ 3124 parent = fork(); 3125 if (!parent) /* if the child */ 3126 { 3127 /* 3128 | child process which will fork and exec shell command (if shell output is 3129 | to be read by editor) 3130 */ 3131 in_pipe = FALSE; 3132 /* 3133 | redirect stdout to pipe 3134 */ 3135 temp_stdout = dup(1); 3136 close(1); 3137 dup(pipe_in[1]); 3138 /* 3139 | redirect stderr to pipe 3140 */ 3141 temp_stderr = dup(2); 3142 close(2); 3143 dup(pipe_in[1]); 3144 close(pipe_in[1]); 3145 /* 3146 | child will now continue down 'if (!in_pipe)' 3147 | path below 3148 */ 3149 } 3150 else /* if the parent */ 3151 { 3152 /* 3153 | prepare editor to read from the pipe 3154 */ 3155 signal(SIGCHLD, SIG_IGN); 3156 line_holder = curr_line; 3157 tmp_vert = scr_vert; 3158 close(pipe_in[1]); 3159 get_fd = pipe_in[0]; 3160 get_file(""); 3161 close(pipe_in[0]); 3162 scr_vert = tmp_vert; 3163 scr_horz = scr_pos = 0; 3164 position = 1; 3165 curr_line = line_holder; 3166 from_top(); 3167 point = curr_line->line; 3168 out_pipe = FALSE; 3169 signal(SIGCHLD, SIG_DFL); 3170 /* 3171 | since flag "in_pipe" is still TRUE, the path which waits for the child 3172 | process to die will be avoided. 3173 | (the pipe is closed, no more output can be expected) 3174 */ 3175 } 3176 } 3177 if (!in_pipe) 3178 { 3179 signal(SIGINT, SIG_IGN); 3180 if (out_pipe) 3181 { 3182 pipe(pipe_out); 3183 } 3184 /* 3185 | fork process which will exec command 3186 */ 3187 parent = fork(); 3188 if (!parent) /* if the child */ 3189 { 3190 if (shell_fork) 3191 putchar('\n'); 3192 if (out_pipe) 3193 { 3194 /* 3195 | prepare the child process (soon to exec a shell command) to read from the 3196 | pipe (which will be output from the editor's buffer) 3197 */ 3198 close(0); 3199 dup(pipe_out[0]); 3200 close(pipe_out[0]); 3201 close(pipe_out[1]); 3202 } 3203 for (value = 1; value < 24; value++) 3204 signal(value, SIG_DFL); 3205 execl(path, last_slash, "-c", string, NULL); 3206 fprintf(stderr, exec_err_msg, path); 3207 exit(-1); 3208 } 3209 else /* if the parent */ 3210 { 3211 if (out_pipe) 3212 { 3213 /* 3214 | output the contents of the buffer to the pipe (to be read by the 3215 | process forked and exec'd above as stdin) 3216 */ 3217 close(pipe_out[0]); 3218 line_holder = first_line; 3219 while (line_holder != NULL) 3220 { 3221 write(pipe_out[1], line_holder->line, (line_holder->line_length-1)); 3222 write(pipe_out[1], "\n", 1); 3223 line_holder = line_holder->next_line; 3224 } 3225 close(pipe_out[1]); 3226 out_pipe = FALSE; 3227 } 3228 do 3229 { 3230 return_val = wait((int *) 0); 3231 } 3232 while ((return_val != parent) && (return_val != -1)); 3233 /* 3234 | if this process is actually the child of the editor, exit. Here's how it 3235 | works: 3236 | The editor forks a process. If output must be sent to the command to be 3237 | exec'd another process is forked, and that process (the child's child) 3238 | will exec the command. In this case, "shell_fork" will be FALSE. If no 3239 | output is to be performed to the shell command, "shell_fork" will be TRUE. 3240 | If this is the editor process, shell_fork will be true, otherwise this is 3241 | the child of the edit process. 3242 */ 3243 if (!shell_fork) 3244 exit(0); 3245 } 3246 signal(SIGINT, edit_abort); 3247 } 3248 if (shell_fork) 3249 { 3250 printf(continue_msg); 3251 fflush(stdout); 3252 while ((in = getchar()) != '\n') 3253 ; 3254 } 3255 3256 if (!in_pipe) 3257 { 3258 fixterm(); 3259 noecho(); 3260 nonl(); 3261 raw(); 3262 keypad(text_win, TRUE); 3263 keypad(com_win, TRUE); 3264 if (info_window) 3265 clearok(info_win, TRUE); 3266 } 3267 3268 redraw(); 3269 } 3270 3271 void 3272 set_up_term() /* set up the terminal for operating with ae */ 3273 { 3274 if (!curses_initialized) 3275 { 3276 initscr(); 3277 savetty(); 3278 noecho(); 3279 raw(); 3280 nonl(); 3281 curses_initialized = TRUE; 3282 } 3283 3284 if (((LINES > 15) && (COLS >= 80)) && info_window) 3285 last_line = LINES - 8; 3286 else 3287 { 3288 info_window = FALSE; 3289 last_line = LINES - 2; 3290 } 3291 3292 idlok(stdscr, TRUE); 3293 com_win = newwin(1, COLS, (LINES - 1), 0); 3294 keypad(com_win, TRUE); 3295 idlok(com_win, TRUE); 3296 wrefresh(com_win); 3297 if (!info_window) 3298 text_win = newwin((LINES - 1), COLS, 0, 0); 3299 else 3300 text_win = newwin((LINES - 7), COLS, 6, 0); 3301 keypad(text_win, TRUE); 3302 idlok(text_win, TRUE); 3303 wrefresh(text_win); 3304 help_win = newwin((LINES - 1), COLS, 0, 0); 3305 keypad(help_win, TRUE); 3306 idlok(help_win, TRUE); 3307 if (info_window) 3308 { 3309 info_type = CONTROL_KEYS; 3310 info_win = newwin(6, COLS, 0, 0); 3311 werase(info_win); 3312 paint_info_win(); 3313 } 3314 3315 last_col = COLS - 1; 3316 local_LINES = LINES; 3317 local_COLS = COLS; 3318 3319 #ifdef NCURSE 3320 if (ee_chinese) 3321 nc_setattrib(A_NC_BIG5); 3322 #endif /* NCURSE */ 3323 3324 } 3325 3326 void 3327 resize_check() 3328 { 3329 if ((LINES == local_LINES) && (COLS == local_COLS)) 3330 return; 3331 3332 if (info_window) 3333 delwin(info_win); 3334 delwin(text_win); 3335 delwin(com_win); 3336 delwin(help_win); 3337 set_up_term(); 3338 redraw(); 3339 wrefresh(text_win); 3340 } 3341 3342 static char item_alpha[] = "abcdefghijklmnopqrstuvwxyz0123456789 "; 3343 3344 int 3345 menu_op(menu_list) 3346 struct menu_entries menu_list[]; 3347 { 3348 WINDOW *temp_win; 3349 int max_width, max_height; 3350 int x_off, y_off; 3351 int counter; 3352 int length; 3353 int input; 3354 int temp; 3355 int list_size; 3356 int top_offset; /* offset from top where menu items start */ 3357 int vert_pos; /* vertical position */ 3358 int vert_size; /* vertical size for menu list item display */ 3359 int off_start = 1; /* offset from start of menu items to start display */ 3360 3361 3362 /* 3363 | determine number and width of menu items 3364 */ 3365 3366 list_size = 1; 3367 while (menu_list[list_size + 1].item_string != NULL) 3368 list_size++; 3369 max_width = 0; 3370 for (counter = 0; counter <= list_size; counter++) 3371 { 3372 if ((length = strlen(menu_list[counter].item_string)) > max_width) 3373 max_width = length; 3374 } 3375 max_width += 3; 3376 max_width = max(max_width, strlen(menu_cancel_msg)); 3377 max_width = max(max_width, max(strlen(more_above_str), strlen(more_below_str))); 3378 max_width += 6; 3379 3380 /* 3381 | make sure that window is large enough to handle menu 3382 | if not, print error message and return to calling function 3383 */ 3384 3385 if (max_width > COLS) 3386 { 3387 wmove(com_win, 0, 0); 3388 werase(com_win); 3389 wprintw(com_win, menu_too_lrg_msg); 3390 wrefresh(com_win); 3391 clear_com_win = TRUE; 3392 return(0); 3393 } 3394 3395 top_offset = 0; 3396 3397 if (list_size > LINES) 3398 { 3399 max_height = LINES; 3400 if (max_height > 11) 3401 vert_size = max_height - 8; 3402 else 3403 vert_size = max_height; 3404 } 3405 else 3406 { 3407 vert_size = list_size; 3408 max_height = list_size; 3409 } 3410 3411 if (LINES >= (vert_size + 8)) 3412 { 3413 if (menu_list[0].argument != MENU_WARN) 3414 max_height = vert_size + 8; 3415 else 3416 max_height = vert_size + 7; 3417 top_offset = 4; 3418 } 3419 x_off = (COLS - max_width) / 2; 3420 y_off = (LINES - max_height - 1) / 2; 3421 temp_win = newwin(max_height, max_width, y_off, x_off); 3422 keypad(temp_win, TRUE); 3423 3424 paint_menu(menu_list, max_width, max_height, list_size, top_offset, temp_win, off_start, vert_size); 3425 3426 counter = 1; 3427 vert_pos = 0; 3428 do 3429 { 3430 if (off_start > 2) 3431 wmove(temp_win, (1 + counter + top_offset - off_start), 3); 3432 else 3433 wmove(temp_win, (counter + top_offset - off_start), 3); 3434 3435 wrefresh(temp_win); 3436 in = wgetch(temp_win); 3437 input = in; 3438 if (input == -1) 3439 exit(0); 3440 3441 if (((tolower(input) >= 'a') && (tolower(input) <= 'z')) || 3442 ((input >= '0') && (input <= '9'))) 3443 { 3444 if ((tolower(input) >= 'a') && (tolower(input) <= 'z')) 3445 { 3446 temp = 1 + tolower(input) - 'a'; 3447 } 3448 else if ((input >= '0') && (input <= '9')) 3449 { 3450 temp = (2 + 'z' - 'a') + (input - '0'); 3451 } 3452 3453 if (temp <= list_size) 3454 { 3455 input = '\n'; 3456 counter = temp; 3457 } 3458 } 3459 else 3460 { 3461 switch (input) 3462 { 3463 case ' ': /* space */ 3464 case '\004': /* ^d, down */ 3465 case KEY_RIGHT: 3466 case KEY_DOWN: 3467 counter++; 3468 if (counter > list_size) 3469 counter = 1; 3470 break; 3471 case '\010': /* ^h, backspace*/ 3472 case '\025': /* ^u, up */ 3473 case 127: /* ^?, delete */ 3474 case KEY_BACKSPACE: 3475 case KEY_LEFT: 3476 case KEY_UP: 3477 counter--; 3478 if (counter == 0) 3479 counter = list_size; 3480 break; 3481 case '\033': /* escape key */ 3482 if (menu_list[0].argument != MENU_WARN) 3483 counter = 0; 3484 break; 3485 case '\014': /* ^l */ 3486 case '\022': /* ^r, redraw */ 3487 paint_menu(menu_list, max_width, max_height, 3488 list_size, top_offset, temp_win, 3489 off_start, vert_size); 3490 break; 3491 default: 3492 break; 3493 } 3494 } 3495 3496 if (((list_size - off_start) >= (vert_size - 1)) && 3497 (counter > (off_start + vert_size - 3)) && 3498 (off_start > 1)) 3499 { 3500 if (counter == list_size) 3501 off_start = (list_size - vert_size) + 2; 3502 else 3503 off_start++; 3504 3505 paint_menu(menu_list, max_width, max_height, 3506 list_size, top_offset, temp_win, off_start, 3507 vert_size); 3508 } 3509 else if ((list_size != vert_size) && 3510 (counter > (off_start + vert_size - 2))) 3511 { 3512 if (counter == list_size) 3513 off_start = 2 + (list_size - vert_size); 3514 else if (off_start == 1) 3515 off_start = 3; 3516 else 3517 off_start++; 3518 3519 paint_menu(menu_list, max_width, max_height, 3520 list_size, top_offset, temp_win, off_start, 3521 vert_size); 3522 } 3523 else if (counter < off_start) 3524 { 3525 if (counter <= 2) 3526 off_start = 1; 3527 else 3528 off_start = counter; 3529 3530 paint_menu(menu_list, max_width, max_height, 3531 list_size, top_offset, temp_win, off_start, 3532 vert_size); 3533 } 3534 } 3535 while ((input != '\r') && (input != '\n') && (counter != 0)); 3536 3537 werase(temp_win); 3538 wrefresh(temp_win); 3539 delwin(temp_win); 3540 3541 if ((menu_list[counter].procedure != NULL) || 3542 (menu_list[counter].iprocedure != NULL) || 3543 (menu_list[counter].nprocedure != NULL)) 3544 { 3545 if (menu_list[counter].argument != -1) 3546 (*menu_list[counter].iprocedure)(menu_list[counter].argument); 3547 else if (menu_list[counter].ptr_argument != NULL) 3548 (*menu_list[counter].procedure)(menu_list[counter].ptr_argument); 3549 else 3550 (*menu_list[counter].nprocedure)(); 3551 } 3552 3553 if (info_window) 3554 paint_info_win(); 3555 redraw(); 3556 3557 return(counter); 3558 } 3559 3560 void 3561 paint_menu(menu_list, max_width, max_height, list_size, top_offset, menu_win, 3562 off_start, vert_size) 3563 struct menu_entries menu_list[]; 3564 int max_width, max_height, list_size, top_offset; 3565 WINDOW *menu_win; 3566 int off_start, vert_size; 3567 { 3568 int counter, temp_int; 3569 3570 werase(menu_win); 3571 3572 /* 3573 | output top and bottom portions of menu box only if window 3574 | large enough 3575 */ 3576 3577 if (max_height > vert_size) 3578 { 3579 wmove(menu_win, 1, 1); 3580 if (!nohighlight) 3581 wstandout(menu_win); 3582 waddch(menu_win, '+'); 3583 for (counter = 0; counter < (max_width - 4); counter++) 3584 waddch(menu_win, '-'); 3585 waddch(menu_win, '+'); 3586 3587 wmove(menu_win, (max_height - 2), 1); 3588 waddch(menu_win, '+'); 3589 for (counter = 0; counter < (max_width - 4); counter++) 3590 waddch(menu_win, '-'); 3591 waddch(menu_win, '+'); 3592 wstandend(menu_win); 3593 wmove(menu_win, 2, 3); 3594 waddstr(menu_win, menu_list[0].item_string); 3595 wmove(menu_win, (max_height - 3), 3); 3596 if (menu_list[0].argument != MENU_WARN) 3597 waddstr(menu_win, menu_cancel_msg); 3598 } 3599 if (!nohighlight) 3600 wstandout(menu_win); 3601 3602 for (counter = 0; counter < (vert_size + top_offset); counter++) 3603 { 3604 if (top_offset == 4) 3605 { 3606 temp_int = counter + 2; 3607 } 3608 else 3609 temp_int = counter; 3610 3611 wmove(menu_win, temp_int, 1); 3612 waddch(menu_win, '|'); 3613 wmove(menu_win, temp_int, (max_width - 2)); 3614 waddch(menu_win, '|'); 3615 } 3616 wstandend(menu_win); 3617 3618 if (list_size > vert_size) 3619 { 3620 if (off_start >= 3) 3621 { 3622 temp_int = 1; 3623 wmove(menu_win, top_offset, 3); 3624 waddstr(menu_win, more_above_str); 3625 } 3626 else 3627 temp_int = 0; 3628 3629 for (counter = off_start; 3630 ((temp_int + counter - off_start) < (vert_size - 1)); 3631 counter++) 3632 { 3633 wmove(menu_win, (top_offset + temp_int + 3634 (counter - off_start)), 3); 3635 if (list_size > 1) 3636 wprintw(menu_win, "%c) ", item_alpha[min((counter - 1), max_alpha_char)]); 3637 waddstr(menu_win, menu_list[counter].item_string); 3638 } 3639 3640 wmove(menu_win, (top_offset + (vert_size - 1)), 3); 3641 3642 if (counter == list_size) 3643 { 3644 if (list_size > 1) 3645 wprintw(menu_win, "%c) ", item_alpha[min((counter - 1), max_alpha_char)]); 3646 wprintw(menu_win, menu_list[counter].item_string); 3647 } 3648 else 3649 wprintw(menu_win, more_below_str); 3650 } 3651 else 3652 { 3653 for (counter = 1; counter <= list_size; counter++) 3654 { 3655 wmove(menu_win, (top_offset + counter - 1), 3); 3656 if (list_size > 1) 3657 wprintw(menu_win, "%c) ", item_alpha[min((counter - 1), max_alpha_char)]); 3658 waddstr(menu_win, menu_list[counter].item_string); 3659 } 3660 } 3661 } 3662 3663 void 3664 help() 3665 { 3666 int counter; 3667 3668 werase(help_win); 3669 clearok(help_win, TRUE); 3670 for (counter = 0; counter < 22; counter++) 3671 { 3672 wmove(help_win, counter, 0); 3673 waddstr(help_win, (emacs_keys_mode) ? 3674 emacs_help_text[counter] : help_text[counter]); 3675 } 3676 wrefresh(help_win); 3677 werase(com_win); 3678 wmove(com_win, 0, 0); 3679 wprintw(com_win, press_any_key_msg); 3680 wrefresh(com_win); 3681 counter = wgetch(com_win); 3682 if (counter == -1) 3683 exit(0); 3684 werase(com_win); 3685 wmove(com_win, 0, 0); 3686 werase(help_win); 3687 wrefresh(help_win); 3688 wrefresh(com_win); 3689 redraw(); 3690 } 3691 3692 void 3693 paint_info_win() 3694 { 3695 int counter; 3696 3697 if (!info_window) 3698 return; 3699 3700 werase(info_win); 3701 for (counter = 0; counter < 5; counter++) 3702 { 3703 wmove(info_win, counter, 0); 3704 wclrtoeol(info_win); 3705 if (info_type == CONTROL_KEYS) 3706 waddstr(info_win, (emacs_keys_mode) ? 3707 emacs_control_keys[counter] : control_keys[counter]); 3708 else if (info_type == COMMANDS) 3709 waddstr(info_win, command_strings[counter]); 3710 } 3711 wmove(info_win, 5, 0); 3712 if (!nohighlight) 3713 wstandout(info_win); 3714 waddstr(info_win, separator); 3715 wstandend(info_win); 3716 wrefresh(info_win); 3717 } 3718 3719 void 3720 no_info_window() 3721 { 3722 if (!info_window) 3723 return; 3724 delwin(info_win); 3725 delwin(text_win); 3726 info_window = FALSE; 3727 last_line = LINES - 2; 3728 text_win = newwin((LINES - 1), COLS, 0, 0); 3729 keypad(text_win, TRUE); 3730 idlok(text_win, TRUE); 3731 clearok(text_win, TRUE); 3732 midscreen(scr_vert, point); 3733 wrefresh(text_win); 3734 clear_com_win = TRUE; 3735 } 3736 3737 void 3738 create_info_window() 3739 { 3740 if (info_window) 3741 return; 3742 last_line = LINES - 8; 3743 delwin(text_win); 3744 text_win = newwin((LINES - 7), COLS, 6, 0); 3745 keypad(text_win, TRUE); 3746 idlok(text_win, TRUE); 3747 werase(text_win); 3748 info_window = TRUE; 3749 info_win = newwin(6, COLS, 0, 0); 3750 werase(info_win); 3751 info_type = CONTROL_KEYS; 3752 midscreen(min(scr_vert, last_line), point); 3753 clearok(info_win, TRUE); 3754 paint_info_win(); 3755 wrefresh(text_win); 3756 clear_com_win = TRUE; 3757 } 3758 3759 int 3760 file_op(arg) 3761 int arg; 3762 { 3763 char *string; 3764 int flag; 3765 3766 if (restrict_mode()) 3767 { 3768 return(0); 3769 } 3770 3771 if (arg == READ_FILE) 3772 { 3773 string = get_string(file_read_prompt_str, TRUE); 3774 recv_file = TRUE; 3775 tmp_file = resolve_name(string); 3776 check_fp(); 3777 if (tmp_file != string) 3778 free(tmp_file); 3779 free(string); 3780 } 3781 else if (arg == WRITE_FILE) 3782 { 3783 string = get_string(file_write_prompt_str, TRUE); 3784 tmp_file = resolve_name(string); 3785 write_file(tmp_file, 1); 3786 if (tmp_file != string) 3787 free(tmp_file); 3788 free(string); 3789 } 3790 else if (arg == SAVE_FILE) 3791 { 3792 /* 3793 | changes made here should be reflected in finish() 3794 */ 3795 3796 if (in_file_name) 3797 flag = TRUE; 3798 else 3799 flag = FALSE; 3800 3801 string = in_file_name; 3802 if ((string == NULL) || (*string == '\0')) 3803 string = get_string(save_file_name_prompt, TRUE); 3804 if ((string == NULL) || (*string == '\0')) 3805 { 3806 wmove(com_win, 0, 0); 3807 wprintw(com_win, file_not_saved_msg); 3808 wclrtoeol(com_win); 3809 wrefresh(com_win); 3810 clear_com_win = TRUE; 3811 return(0); 3812 } 3813 if (!flag) 3814 { 3815 tmp_file = resolve_name(string); 3816 if (tmp_file != string) 3817 { 3818 free(string); 3819 string = tmp_file; 3820 } 3821 } 3822 if (write_file(string, 1)) 3823 { 3824 in_file_name = string; 3825 text_changes = FALSE; 3826 } 3827 else if (!flag) 3828 free(string); 3829 } 3830 return(0); 3831 } 3832 3833 void 3834 shell_op() 3835 { 3836 char *string; 3837 3838 if (((string = get_string(shell_prompt, TRUE)) != NULL) && 3839 (*string != '\0')) 3840 { 3841 sh_command(string); 3842 free(string); 3843 } 3844 } 3845 3846 void 3847 leave_op() 3848 { 3849 if (text_changes) 3850 { 3851 menu_op(leave_menu); 3852 } 3853 else 3854 quit(TRUE); 3855 } 3856 3857 void 3858 redraw() 3859 { 3860 if (info_window) 3861 { 3862 clearok(info_win, TRUE); 3863 paint_info_win(); 3864 } 3865 else 3866 clearok(text_win, TRUE); 3867 midscreen(scr_vert, point); 3868 } 3869 3870 /* 3871 | The following routines will "format" a paragraph (as defined by a 3872 | block of text with blank lines before and after the block). 3873 */ 3874 3875 int 3876 Blank_Line(test_line) /* test if line has any non-space characters */ 3877 struct text *test_line; 3878 { 3879 unsigned char *line; 3880 int length; 3881 3882 if (test_line == NULL) 3883 return(TRUE); 3884 3885 length = 1; 3886 line = test_line->line; 3887 3888 /* 3889 | To handle troff/nroff documents, consider a line with a 3890 | period ('.') in the first column to be blank. To handle mail 3891 | messages with included text, consider a line with a '>' blank. 3892 */ 3893 3894 if ((*line == '.') || (*line == '>')) 3895 return(TRUE); 3896 3897 while (((*line == ' ') || (*line == '\t')) && (length < test_line->line_length)) 3898 { 3899 length++; 3900 line++; 3901 } 3902 if (length != test_line->line_length) 3903 return(FALSE); 3904 else 3905 return(TRUE); 3906 } 3907 3908 void 3909 Format() /* format the paragraph according to set margins */ 3910 { 3911 int string_count; 3912 int offset; 3913 int temp_case; 3914 int status; 3915 int tmp_af; 3916 int counter; 3917 unsigned char *line; 3918 unsigned char *tmp_srchstr; 3919 unsigned char *temp1, *temp2; 3920 unsigned char *temp_dword; 3921 unsigned char temp_d_char[3]; 3922 3923 temp_d_char[0] = d_char[0]; 3924 temp_d_char[1] = d_char[1]; 3925 temp_d_char[2] = d_char[2]; 3926 3927 /* 3928 | if observ_margins is not set, or the current line is blank, 3929 | do not format the current paragraph 3930 */ 3931 3932 if ((!observ_margins) || (Blank_Line(curr_line))) 3933 return; 3934 3935 /* 3936 | save the currently set flags, and clear them 3937 */ 3938 3939 wmove(com_win, 0, 0); 3940 wclrtoeol(com_win); 3941 wprintw(com_win, formatting_msg); 3942 wrefresh(com_win); 3943 3944 /* 3945 | get current position in paragraph, so after formatting, the cursor 3946 | will be in the same relative position 3947 */ 3948 3949 tmp_af = auto_format; 3950 auto_format = FALSE; 3951 offset = position; 3952 if (position != 1) 3953 prev_word(); 3954 temp_dword = d_word; 3955 d_word = NULL; 3956 temp_case = case_sen; 3957 case_sen = TRUE; 3958 tmp_srchstr = srch_str; 3959 temp2 = srch_str = (unsigned char *) malloc(1 + curr_line->line_length - position); 3960 if ((*point == ' ') || (*point == '\t')) 3961 adv_word(); 3962 offset -= position; 3963 counter = position; 3964 line = temp1 = point; 3965 while ((*temp1 != '\0') && (*temp1 != ' ') && (*temp1 != '\t') && (counter < curr_line->line_length)) 3966 { 3967 *temp2 = *temp1; 3968 temp2++; 3969 temp1++; 3970 counter++; 3971 } 3972 *temp2 = '\0'; 3973 if (position != 1) 3974 bol(); 3975 while (!Blank_Line(curr_line->prev_line)) 3976 bol(); 3977 string_count = 0; 3978 status = TRUE; 3979 while ((line != point) && (status)) 3980 { 3981 status = search(FALSE); 3982 string_count++; 3983 } 3984 3985 wmove(com_win, 0, 0); 3986 wclrtoeol(com_win); 3987 wprintw(com_win, formatting_msg); 3988 wrefresh(com_win); 3989 3990 /* 3991 | now get back to the start of the paragraph to start formatting 3992 */ 3993 3994 if (position != 1) 3995 bol(); 3996 while (!Blank_Line(curr_line->prev_line)) 3997 bol(); 3998 3999 observ_margins = FALSE; 4000 4001 /* 4002 | Start going through lines, putting spaces at end of lines if they do 4003 | not already exist. Append lines together to get one long line, and 4004 | eliminate spacing at begin of lines. 4005 */ 4006 4007 while (!Blank_Line(curr_line->next_line)) 4008 { 4009 eol(); 4010 left(TRUE); 4011 if (*point != ' ') 4012 { 4013 right(TRUE); 4014 insert(' '); 4015 } 4016 else 4017 right(TRUE); 4018 del_char(); 4019 if ((*point == ' ') || (*point == '\t')) 4020 del_word(); 4021 } 4022 4023 /* 4024 | Now there is one long line. Eliminate extra spaces within the line 4025 | after the first word (so as not to blow away any indenting the user 4026 | may have put in). 4027 */ 4028 4029 bol(); 4030 adv_word(); 4031 while (position < curr_line->line_length) 4032 { 4033 if ((*point == ' ') && (*(point + 1) == ' ')) 4034 del_char(); 4035 else 4036 right(TRUE); 4037 } 4038 4039 /* 4040 | Now make sure there are two spaces after a '.'. 4041 */ 4042 4043 bol(); 4044 while (position < curr_line->line_length) 4045 { 4046 if ((*point == '.') && (*(point + 1) == ' ')) 4047 { 4048 right(TRUE); 4049 insert(' '); 4050 insert(' '); 4051 while (*point == ' ') 4052 del_char(); 4053 } 4054 right(TRUE); 4055 } 4056 4057 observ_margins = TRUE; 4058 bol(); 4059 4060 wmove(com_win, 0, 0); 4061 wclrtoeol(com_win); 4062 wprintw(com_win, formatting_msg); 4063 wrefresh(com_win); 4064 4065 /* 4066 | create lines between margins 4067 */ 4068 4069 while (position < curr_line->line_length) 4070 { 4071 while ((scr_pos < right_margin) && (position < curr_line->line_length)) 4072 right(TRUE); 4073 if (position < curr_line->line_length) 4074 { 4075 prev_word(); 4076 if (position == 1) 4077 adv_word(); 4078 insert_line(TRUE); 4079 } 4080 } 4081 4082 /* 4083 | go back to begin of paragraph, put cursor back to original position 4084 */ 4085 4086 bol(); 4087 while (!Blank_Line(curr_line->prev_line)) 4088 bol(); 4089 4090 /* 4091 | find word cursor was in 4092 */ 4093 4094 while ((status) && (string_count > 0)) 4095 { 4096 search(FALSE); 4097 string_count--; 4098 } 4099 4100 /* 4101 | offset the cursor to where it was before from the start of the word 4102 */ 4103 4104 while (offset > 0) 4105 { 4106 offset--; 4107 right(TRUE); 4108 } 4109 4110 /* 4111 | reset flags and strings to what they were before formatting 4112 */ 4113 4114 if (d_word != NULL) 4115 free(d_word); 4116 d_word = temp_dword; 4117 case_sen = temp_case; 4118 free(srch_str); 4119 srch_str = tmp_srchstr; 4120 d_char[0] = temp_d_char[0]; 4121 d_char[1] = temp_d_char[1]; 4122 d_char[2] = temp_d_char[2]; 4123 auto_format = tmp_af; 4124 4125 midscreen(scr_vert, point); 4126 werase(com_win); 4127 wrefresh(com_win); 4128 } 4129 4130 unsigned char *init_name[3] = { 4131 "/usr/share/misc/init.ee", 4132 NULL, 4133 ".init.ee" 4134 }; 4135 4136 void 4137 ee_init() /* check for init file and read it if it exists */ 4138 { 4139 FILE *init_file; 4140 unsigned char *string; 4141 unsigned char *str1; 4142 unsigned char *str2; 4143 char *home; 4144 int counter; 4145 int temp_int; 4146 4147 string = getenv("HOME"); 4148 if (string == NULL) 4149 string = "/tmp"; 4150 str1 = home = malloc(strlen(string)+10); 4151 strcpy(home, string); 4152 strcat(home, "/.init.ee"); 4153 init_name[1] = home; 4154 string = malloc(512); 4155 4156 for (counter = 0; counter < 3; counter++) 4157 { 4158 if (!(access(init_name[counter], 4))) 4159 { 4160 init_file = fopen(init_name[counter], "r"); 4161 while ((str2 = fgets(string, 512, init_file)) != NULL) 4162 { 4163 str1 = str2 = string; 4164 while (*str2 != '\n') 4165 str2++; 4166 *str2 = '\0'; 4167 4168 if (unique_test(string, init_strings) != 1) 4169 continue; 4170 4171 if (compare(str1, CASE, FALSE)) 4172 case_sen = TRUE; 4173 else if (compare(str1, NOCASE, FALSE)) 4174 case_sen = FALSE; 4175 else if (compare(str1, EXPAND, FALSE)) 4176 expand_tabs = TRUE; 4177 else if (compare(str1, NOEXPAND, FALSE)) 4178 expand_tabs = FALSE; 4179 else if (compare(str1, INFO, FALSE)) 4180 info_window = TRUE; 4181 else if (compare(str1, NOINFO, FALSE)) 4182 info_window = FALSE; 4183 else if (compare(str1, MARGINS, FALSE)) 4184 observ_margins = TRUE; 4185 else if (compare(str1, NOMARGINS, FALSE)) 4186 observ_margins = FALSE; 4187 else if (compare(str1, AUTOFORMAT, FALSE)) 4188 { 4189 auto_format = TRUE; 4190 observ_margins = TRUE; 4191 } 4192 else if (compare(str1, NOAUTOFORMAT, FALSE)) 4193 auto_format = FALSE; 4194 else if (compare(str1, Echo, FALSE)) 4195 { 4196 str1 = next_word(str1); 4197 if (*str1 != '\0') 4198 echo_string(str1); 4199 } 4200 else if (compare(str1, PRINTCOMMAND, FALSE)) 4201 { 4202 str1 = next_word(str1); 4203 print_command = malloc(strlen(str1)+1); 4204 strcpy(print_command, str1); 4205 } 4206 else if (compare(str1, RIGHTMARGIN, FALSE)) 4207 { 4208 str1 = next_word(str1); 4209 if ((*str1 >= '0') && (*str1 <= '9')) 4210 { 4211 temp_int = atoi(str1); 4212 if (temp_int > 0) 4213 right_margin = temp_int; 4214 } 4215 } 4216 else if (compare(str1, HIGHLIGHT, FALSE)) 4217 nohighlight = FALSE; 4218 else if (compare(str1, NOHIGHLIGHT, FALSE)) 4219 nohighlight = TRUE; 4220 else if (compare(str1, EIGHTBIT, FALSE)) 4221 eightbit = TRUE; 4222 else if (compare(str1, NOEIGHTBIT, FALSE)) 4223 { 4224 eightbit = FALSE; 4225 ee_chinese = FALSE; 4226 } 4227 else if (compare(str1, EMACS_string, FALSE)) 4228 emacs_keys_mode = TRUE; 4229 else if (compare(str1, NOEMACS_string, FALSE)) 4230 emacs_keys_mode = FALSE; 4231 else if (compare(str1, chinese_cmd, FALSE)) 4232 { 4233 ee_chinese = TRUE; 4234 eightbit = TRUE; 4235 } 4236 else if (compare(str1, nochinese_cmd, FALSE)) 4237 ee_chinese = FALSE; 4238 } 4239 fclose(init_file); 4240 } 4241 } 4242 free(string); 4243 free(home); 4244 4245 string = getenv("LANG"); 4246 if (string != NULL) 4247 { 4248 if (strcmp(string, "zh_TW.big5") == 0) 4249 { 4250 ee_chinese = TRUE; 4251 eightbit = TRUE; 4252 } 4253 } 4254 } 4255 4256 /* 4257 | Save current configuration to .init.ee file in the current directory. 4258 */ 4259 4260 void 4261 dump_ee_conf() 4262 { 4263 FILE *init_file; 4264 FILE *old_init_file = NULL; 4265 char *file_name = ".init.ee"; 4266 char *home_dir = "~/.init.ee"; 4267 char buffer[512]; 4268 struct stat buf; 4269 char *string; 4270 int length; 4271 int option = 0; 4272 4273 if (restrict_mode()) 4274 { 4275 return; 4276 } 4277 4278 option = menu_op(config_dump_menu); 4279 4280 werase(com_win); 4281 wmove(com_win, 0, 0); 4282 4283 if (option == 0) 4284 { 4285 wprintw(com_win, conf_not_saved_msg); 4286 wrefresh(com_win); 4287 return; 4288 } 4289 else if (option == 2) 4290 file_name = resolve_name(home_dir); 4291 4292 /* 4293 | If a .init.ee file exists, move it to .init.ee.old. 4294 */ 4295 4296 if (stat(file_name, &buf) != -1) 4297 { 4298 sprintf(buffer, "%s.old", file_name); 4299 unlink(buffer); 4300 link(file_name, buffer); 4301 unlink(file_name); 4302 old_init_file = fopen(buffer, "r"); 4303 } 4304 4305 init_file = fopen(file_name, "w"); 4306 if (init_file == NULL) 4307 { 4308 wprintw(com_win, conf_dump_err_msg); 4309 wrefresh(com_win); 4310 return; 4311 } 4312 4313 if (old_init_file != NULL) 4314 { 4315 /* 4316 | Copy non-configuration info into new .init.ee file. 4317 */ 4318 while ((string = fgets(buffer, 512, old_init_file)) != NULL) 4319 { 4320 length = strlen(string); 4321 string[length - 1] = '\0'; 4322 4323 if (unique_test(string, init_strings) == 1) 4324 { 4325 if (compare(string, Echo, FALSE)) 4326 { 4327 fprintf(init_file, "%s\n", string); 4328 } 4329 } 4330 else 4331 fprintf(init_file, "%s\n", string); 4332 } 4333 4334 fclose(old_init_file); 4335 } 4336 4337 fprintf(init_file, "%s\n", case_sen ? CASE : NOCASE); 4338 fprintf(init_file, "%s\n", expand_tabs ? EXPAND : NOEXPAND); 4339 fprintf(init_file, "%s\n", info_window ? INFO : NOINFO ); 4340 fprintf(init_file, "%s\n", observ_margins ? MARGINS : NOMARGINS ); 4341 fprintf(init_file, "%s\n", auto_format ? AUTOFORMAT : NOAUTOFORMAT ); 4342 fprintf(init_file, "%s %s\n", PRINTCOMMAND, print_command); 4343 fprintf(init_file, "%s %d\n", RIGHTMARGIN, right_margin); 4344 fprintf(init_file, "%s\n", nohighlight ? NOHIGHLIGHT : HIGHLIGHT ); 4345 fprintf(init_file, "%s\n", eightbit ? EIGHTBIT : NOEIGHTBIT ); 4346 fprintf(init_file, "%s\n", emacs_keys_mode ? EMACS_string : NOEMACS_string ); 4347 fprintf(init_file, "%s\n", ee_chinese ? chinese_cmd : nochinese_cmd ); 4348 4349 fclose(init_file); 4350 4351 wprintw(com_win, conf_dump_success_msg, file_name); 4352 wrefresh(com_win); 4353 4354 if ((option == 2) && (file_name != home_dir)) 4355 { 4356 free(file_name); 4357 } 4358 } 4359 4360 void 4361 echo_string(string) /* echo the given string */ 4362 char *string; 4363 { 4364 char *temp; 4365 int Counter; 4366 4367 temp = string; 4368 while (*temp != '\0') 4369 { 4370 if (*temp == '\\') 4371 { 4372 temp++; 4373 if (*temp == 'n') 4374 putchar('\n'); 4375 else if (*temp == 't') 4376 putchar('\t'); 4377 else if (*temp == 'b') 4378 putchar('\b'); 4379 else if (*temp == 'r') 4380 putchar('\r'); 4381 else if (*temp == 'f') 4382 putchar('\f'); 4383 else if ((*temp == 'e') || (*temp == 'E')) 4384 putchar('\033'); /* escape */ 4385 else if (*temp == '\\') 4386 putchar('\\'); 4387 else if (*temp == '\'') 4388 putchar('\''); 4389 else if ((*temp >= '0') && (*temp <= '9')) 4390 { 4391 Counter = 0; 4392 while ((*temp >= '0') && (*temp <= '9')) 4393 { 4394 Counter = (8 * Counter) + (*temp - '0'); 4395 temp++; 4396 } 4397 putchar(Counter); 4398 temp--; 4399 } 4400 temp++; 4401 } 4402 else 4403 { 4404 putchar(*temp); 4405 temp++; 4406 } 4407 } 4408 4409 fflush(stdout); 4410 } 4411 4412 void 4413 spell_op() /* check spelling of words in the editor */ 4414 { 4415 if (restrict_mode()) 4416 { 4417 return; 4418 } 4419 top(); /* go to top of file */ 4420 insert_line(FALSE); /* create two blank lines */ 4421 insert_line(FALSE); 4422 top(); 4423 command(shell_echo_msg); 4424 adv_line(); 4425 wmove(com_win, 0, 0); 4426 wprintw(com_win, spell_in_prog_msg); 4427 wrefresh(com_win); 4428 command("<>!spell"); /* send contents of buffer to command 'spell' 4429 and read the results back into the editor */ 4430 } 4431 4432 void 4433 ispell_op() 4434 { 4435 char template[128], *name; 4436 char string[256]; 4437 int fd; 4438 4439 if (restrict_mode()) 4440 { 4441 return; 4442 } 4443 (void)sprintf(template, "/tmp/ee.XXXXXXXX"); 4444 fd = mkstemp(template); 4445 if (fd < 0) { 4446 wmove(com_win, 0, 0); 4447 wprintw(com_win, create_file_fail_msg, name); 4448 wrefresh(com_win); 4449 return; 4450 } 4451 close(fd); 4452 if (write_file(name, 0)) 4453 { 4454 sprintf(string, "ispell %s", name); 4455 sh_command(string); 4456 delete_text(); 4457 tmp_file = name; 4458 recv_file = TRUE; 4459 check_fp(); 4460 unlink(name); 4461 } 4462 } 4463 4464 int 4465 first_word_len(test_line) 4466 struct text *test_line; 4467 { 4468 int counter; 4469 unsigned char *pnt; 4470 4471 if (test_line == NULL) 4472 return(0); 4473 4474 pnt = test_line->line; 4475 if ((pnt == NULL) || (*pnt == '\0') || 4476 (*pnt == '.') || (*pnt == '>')) 4477 return(0); 4478 4479 if ((*pnt == ' ') || (*pnt == '\t')) 4480 { 4481 pnt = next_word(pnt); 4482 } 4483 4484 if (*pnt == '\0') 4485 return(0); 4486 4487 counter = 0; 4488 while ((*pnt != '\0') && ((*pnt != ' ') && (*pnt != '\t'))) 4489 { 4490 pnt++; 4491 counter++; 4492 } 4493 while ((*pnt != '\0') && ((*pnt == ' ') || (*pnt == '\t'))) 4494 { 4495 pnt++; 4496 counter++; 4497 } 4498 return(counter); 4499 } 4500 4501 void 4502 Auto_Format() /* format the paragraph according to set margins */ 4503 { 4504 int string_count; 4505 int offset; 4506 int temp_case; 4507 int word_len; 4508 int temp_dwl; 4509 int tmp_d_line_length; 4510 int leave_loop = FALSE; 4511 int status; 4512 int counter; 4513 char not_blank; 4514 unsigned char *line; 4515 unsigned char *tmp_srchstr; 4516 unsigned char *temp1, *temp2; 4517 unsigned char *temp_dword; 4518 unsigned char temp_d_char[3]; 4519 unsigned char *tmp_d_line; 4520 4521 4522 temp_d_char[0] = d_char[0]; 4523 temp_d_char[1] = d_char[1]; 4524 temp_d_char[2] = d_char[2]; 4525 4526 /* 4527 | if observ_margins is not set, or the current line is blank, 4528 | do not format the current paragraph 4529 */ 4530 4531 if ((!observ_margins) || (Blank_Line(curr_line))) 4532 return; 4533 4534 /* 4535 | get current position in paragraph, so after formatting, the cursor 4536 | will be in the same relative position 4537 */ 4538 4539 tmp_d_line = d_line; 4540 tmp_d_line_length = dlt_line->line_length; 4541 d_line = NULL; 4542 auto_format = FALSE; 4543 offset = position; 4544 if ((position != 1) && ((*point == ' ') || (*point == '\t') || (position == curr_line->line_length) || (*point == '\0'))) 4545 prev_word(); 4546 temp_dword = d_word; 4547 temp_dwl = d_wrd_len; 4548 d_wrd_len = 0; 4549 d_word = NULL; 4550 temp_case = case_sen; 4551 case_sen = TRUE; 4552 tmp_srchstr = srch_str; 4553 temp2 = srch_str = (unsigned char *) malloc(1 + curr_line->line_length - position); 4554 if ((*point == ' ') || (*point == '\t')) 4555 adv_word(); 4556 offset -= position; 4557 counter = position; 4558 line = temp1 = point; 4559 while ((*temp1 != '\0') && (*temp1 != ' ') && (*temp1 != '\t') && (counter < curr_line->line_length)) 4560 { 4561 *temp2 = *temp1; 4562 temp2++; 4563 temp1++; 4564 counter++; 4565 } 4566 *temp2 = '\0'; 4567 if (position != 1) 4568 bol(); 4569 while (!Blank_Line(curr_line->prev_line)) 4570 bol(); 4571 string_count = 0; 4572 status = TRUE; 4573 while ((line != point) && (status)) 4574 { 4575 status = search(FALSE); 4576 string_count++; 4577 } 4578 4579 /* 4580 | now get back to the start of the paragraph to start checking 4581 */ 4582 4583 if (position != 1) 4584 bol(); 4585 while (!Blank_Line(curr_line->prev_line)) 4586 bol(); 4587 4588 /* 4589 | Start going through lines, putting spaces at end of lines if they do 4590 | not already exist. Check line length, and move words to the next line 4591 | if they cross the margin. Then get words from the next line if they 4592 | will fit in before the margin. 4593 */ 4594 4595 counter = 0; 4596 4597 while (!leave_loop) 4598 { 4599 if (position != curr_line->line_length) 4600 eol(); 4601 left(TRUE); 4602 if (*point != ' ') 4603 { 4604 right(TRUE); 4605 insert(' '); 4606 } 4607 else 4608 right(TRUE); 4609 4610 not_blank = FALSE; 4611 4612 /* 4613 | fill line if first word on next line will fit 4614 | in the line without crossing the margin 4615 */ 4616 4617 while ((curr_line->next_line != NULL) && 4618 ((word_len = first_word_len(curr_line->next_line)) > 0) 4619 && ((scr_pos + word_len) < right_margin)) 4620 { 4621 adv_line(); 4622 if ((*point == ' ') || (*point == '\t')) 4623 adv_word(); 4624 del_word(); 4625 if (position != 1) 4626 bol(); 4627 4628 /* 4629 | We know this line was not blank before, so 4630 | make sure that it doesn't have one of the 4631 | leading characters that indicate the line 4632 | should not be modified. 4633 | 4634 | We also know that this character should not 4635 | be left as the first character of this line. 4636 */ 4637 4638 if ((Blank_Line(curr_line)) && 4639 (curr_line->line[0] != '.') && 4640 (curr_line->line[0] != '>')) 4641 { 4642 del_line(); 4643 not_blank = FALSE; 4644 } 4645 else 4646 not_blank = TRUE; 4647 4648 /* 4649 | go to end of previous line 4650 */ 4651 left(TRUE); 4652 undel_word(); 4653 eol(); 4654 /* 4655 | make sure there's a space at the end of the line 4656 */ 4657 left(TRUE); 4658 if (*point != ' ') 4659 { 4660 right(TRUE); 4661 insert(' '); 4662 } 4663 else 4664 right(TRUE); 4665 } 4666 4667 /* 4668 | make sure line does not cross right margin 4669 */ 4670 4671 while (right_margin <= scr_pos) 4672 { 4673 prev_word(); 4674 if (position != 1) 4675 { 4676 del_word(); 4677 if (Blank_Line(curr_line->next_line)) 4678 insert_line(TRUE); 4679 else 4680 adv_line(); 4681 if ((*point == ' ') || (*point == '\t')) 4682 adv_word(); 4683 undel_word(); 4684 not_blank = TRUE; 4685 if (position != 1) 4686 bol(); 4687 left(TRUE); 4688 } 4689 } 4690 4691 if ((!Blank_Line(curr_line->next_line)) || (not_blank)) 4692 { 4693 adv_line(); 4694 counter++; 4695 } 4696 else 4697 leave_loop = TRUE; 4698 } 4699 4700 /* 4701 | go back to begin of paragraph, put cursor back to original position 4702 */ 4703 4704 if (position != 1) 4705 bol(); 4706 while ((counter-- > 0) || (!Blank_Line(curr_line->prev_line))) 4707 bol(); 4708 4709 /* 4710 | find word cursor was in 4711 */ 4712 4713 status = TRUE; 4714 while ((status) && (string_count > 0)) 4715 { 4716 status = search(FALSE); 4717 string_count--; 4718 } 4719 4720 /* 4721 | offset the cursor to where it was before from the start of the word 4722 */ 4723 4724 while (offset > 0) 4725 { 4726 offset--; 4727 right(TRUE); 4728 } 4729 4730 if ((string_count > 0) && (offset < 0)) 4731 { 4732 while (offset < 0) 4733 { 4734 offset++; 4735 left(TRUE); 4736 } 4737 } 4738 4739 /* 4740 | reset flags and strings to what they were before formatting 4741 */ 4742 4743 if (d_word != NULL) 4744 free(d_word); 4745 d_word = temp_dword; 4746 d_wrd_len = temp_dwl; 4747 case_sen = temp_case; 4748 free(srch_str); 4749 srch_str = tmp_srchstr; 4750 d_char[0] = temp_d_char[0]; 4751 d_char[1] = temp_d_char[1]; 4752 d_char[2] = temp_d_char[2]; 4753 auto_format = TRUE; 4754 dlt_line->line_length = tmp_d_line_length; 4755 d_line = tmp_d_line; 4756 4757 formatted = TRUE; 4758 midscreen(scr_vert, point); 4759 } 4760 4761 void 4762 modes_op() 4763 { 4764 int ret_value; 4765 int counter; 4766 char *string; 4767 4768 do 4769 { 4770 sprintf(modes_menu[1].item_string, "%s %s", mode_strings[1], 4771 (expand_tabs ? ON : OFF)); 4772 sprintf(modes_menu[2].item_string, "%s %s", mode_strings[2], 4773 (case_sen ? ON : OFF)); 4774 sprintf(modes_menu[3].item_string, "%s %s", mode_strings[3], 4775 (observ_margins ? ON : OFF)); 4776 sprintf(modes_menu[4].item_string, "%s %s", mode_strings[4], 4777 (auto_format ? ON : OFF)); 4778 sprintf(modes_menu[5].item_string, "%s %s", mode_strings[5], 4779 (eightbit ? ON : OFF)); 4780 sprintf(modes_menu[6].item_string, "%s %s", mode_strings[6], 4781 (info_window ? ON : OFF)); 4782 sprintf(modes_menu[7].item_string, "%s %s", mode_strings[7], 4783 (emacs_keys_mode ? ON : OFF)); 4784 sprintf(modes_menu[8].item_string, "%s %d", mode_strings[8], 4785 right_margin); 4786 sprintf(modes_menu[9].item_string, "%s %s", mode_strings[9], 4787 (ee_chinese ? ON : OFF)); 4788 4789 ret_value = menu_op(modes_menu); 4790 4791 switch (ret_value) 4792 { 4793 case 1: 4794 expand_tabs = !expand_tabs; 4795 break; 4796 case 2: 4797 case_sen = !case_sen; 4798 break; 4799 case 3: 4800 observ_margins = !observ_margins; 4801 break; 4802 case 4: 4803 auto_format = !auto_format; 4804 if (auto_format) 4805 observ_margins = TRUE; 4806 break; 4807 case 5: 4808 eightbit = !eightbit; 4809 if (!eightbit) 4810 ee_chinese = FALSE; 4811 #ifdef NCURSE 4812 if (ee_chinese) 4813 nc_setattrib(A_NC_BIG5); 4814 else 4815 nc_clearattrib(A_NC_BIG5); 4816 #endif /* NCURSE */ 4817 4818 redraw(); 4819 wnoutrefresh(text_win); 4820 break; 4821 case 6: 4822 if (info_window) 4823 no_info_window(); 4824 else 4825 create_info_window(); 4826 break; 4827 case 7: 4828 emacs_keys_mode = !emacs_keys_mode; 4829 if (info_window) 4830 paint_info_win(); 4831 break; 4832 case 8: 4833 string = get_string(margin_prompt, TRUE); 4834 if (string != NULL) 4835 { 4836 counter = atoi(string); 4837 if (counter > 0) 4838 right_margin = counter; 4839 free(string); 4840 } 4841 break; 4842 case 9: 4843 ee_chinese = !ee_chinese; 4844 if (ee_chinese != FALSE) 4845 eightbit = TRUE; 4846 #ifdef NCURSE 4847 if (ee_chinese) 4848 nc_setattrib(A_NC_BIG5); 4849 else 4850 nc_clearattrib(A_NC_BIG5); 4851 #endif /* NCURSE */ 4852 redraw(); 4853 break; 4854 default: 4855 break; 4856 } 4857 } 4858 while (ret_value != 0); 4859 } 4860 4861 char * 4862 is_in_string(string, substring) /* a strchr() look-alike for systems without 4863 strchr() */ 4864 char * string, *substring; 4865 { 4866 char *full, *sub; 4867 4868 for (sub = substring; (sub != NULL) && (*sub != '\0'); sub++) 4869 { 4870 for (full = string; (full != NULL) && (*full != '\0'); 4871 full++) 4872 { 4873 if (*sub == *full) 4874 return(full); 4875 } 4876 } 4877 return(NULL); 4878 } 4879 4880 /* 4881 | handle names of the form "~/file", "~user/file", 4882 | "$HOME/foo", "~/$FOO", etc. 4883 */ 4884 4885 char * 4886 resolve_name(name) 4887 char *name; 4888 { 4889 char long_buffer[1024]; 4890 char short_buffer[128]; 4891 char *buffer; 4892 char *slash; 4893 char *tmp; 4894 char *start_of_var; 4895 int offset; 4896 int index; 4897 int counter; 4898 struct passwd *user; 4899 4900 if (name[0] == '~') 4901 { 4902 if (name[1] == '/') 4903 { 4904 index = getuid(); 4905 user = (struct passwd *) getpwuid(index); 4906 slash = name + 1; 4907 } 4908 else 4909 { 4910 slash = strchr(name, '/'); 4911 if (slash == NULL) 4912 return(name); 4913 *slash = '\0'; 4914 user = (struct passwd *) getpwnam((name + 1)); 4915 *slash = '/'; 4916 } 4917 if (user == NULL) 4918 { 4919 return(name); 4920 } 4921 buffer = malloc(strlen(user->pw_dir) + strlen(slash) + 1); 4922 strcpy(buffer, user->pw_dir); 4923 strcat(buffer, slash); 4924 } 4925 else 4926 buffer = name; 4927 4928 if (is_in_string(buffer, "$")) 4929 { 4930 tmp = buffer; 4931 index = 0; 4932 4933 while ((*tmp != '\0') && (index < 1024)) 4934 { 4935 4936 while ((*tmp != '\0') && (*tmp != '$') && 4937 (index < 1024)) 4938 { 4939 long_buffer[index] = *tmp; 4940 tmp++; 4941 index++; 4942 } 4943 4944 if ((*tmp == '$') && (index < 1024)) 4945 { 4946 counter = 0; 4947 start_of_var = tmp; 4948 tmp++; 4949 if (*tmp == '{') /* } */ /* bracketed variable name */ 4950 { 4951 tmp++; /* { */ 4952 while ((*tmp != '\0') && 4953 (*tmp != '}') && 4954 (counter < 128)) 4955 { 4956 short_buffer[counter] = *tmp; 4957 counter++; 4958 tmp++; 4959 } /* { */ 4960 if (*tmp == '}') 4961 tmp++; 4962 } 4963 else 4964 { 4965 while ((*tmp != '\0') && 4966 (*tmp != '/') && 4967 (*tmp != '$') && 4968 (counter < 128)) 4969 { 4970 short_buffer[counter] = *tmp; 4971 counter++; 4972 tmp++; 4973 } 4974 } 4975 short_buffer[counter] = '\0'; 4976 if ((slash = getenv(short_buffer)) != NULL) 4977 { 4978 offset = strlen(slash); 4979 if ((offset + index) < 1024) 4980 strcpy(&long_buffer[index], slash); 4981 index += offset; 4982 } 4983 else 4984 { 4985 while ((start_of_var != tmp) && (index < 1024)) 4986 { 4987 long_buffer[index] = *start_of_var; 4988 start_of_var++; 4989 index++; 4990 } 4991 } 4992 } 4993 } 4994 4995 if (index == 1024) 4996 return(buffer); 4997 else 4998 long_buffer[index] = '\0'; 4999 5000 if (name != buffer) 5001 free(buffer); 5002 buffer = malloc(index + 1); 5003 strcpy(buffer, long_buffer); 5004 } 5005 5006 return(buffer); 5007 } 5008 5009 int 5010 restrict_mode() 5011 { 5012 if (!restricted) 5013 return(FALSE); 5014 5015 wmove(com_win, 0, 0); 5016 wprintw(com_win, restricted_msg); 5017 wclrtoeol(com_win); 5018 wrefresh(com_win); 5019 clear_com_win = TRUE; 5020 return(TRUE); 5021 } 5022 5023 /* 5024 | The following routine tests the input string against the list of 5025 | strings, to determine if the string is a unique match with one of the 5026 | valid values. 5027 */ 5028 5029 int 5030 unique_test(string, list) 5031 char *string; 5032 char *list[]; 5033 { 5034 int counter; 5035 int num_match; 5036 int result; 5037 5038 num_match = 0; 5039 counter = 0; 5040 while (list[counter] != NULL) 5041 { 5042 result = compare(string, list[counter], FALSE); 5043 if (result) 5044 num_match++; 5045 counter++; 5046 } 5047 return(num_match); 5048 } 5049 5050 #ifndef NO_CATGETS 5051 /* 5052 | Get the catalog entry, and if it got it from the catalog, 5053 | make a copy, since the buffer will be overwritten by the 5054 | next call to catgets(). 5055 */ 5056 5057 char * 5058 catgetlocal(number, string) 5059 int number; 5060 char *string; 5061 { 5062 char *temp1; 5063 char *temp2; 5064 5065 temp1 = catgets(catalog, 1, number, string); 5066 if (temp1 != string) 5067 { 5068 temp2 = malloc(strlen(temp1) + 1); 5069 strcpy(temp2, temp1); 5070 temp1 = temp2; 5071 } 5072 return(temp1); 5073 } 5074 #endif /* NO_CATGETS */ 5075 5076 /* 5077 | The following is to allow for using message catalogs which allow 5078 | the software to be 'localized', that is, to use different languages 5079 | all with the same binary. For more information, see your system 5080 | documentation, or the X/Open Internationalization Guide. 5081 */ 5082 5083 void 5084 strings_init() 5085 { 5086 int counter; 5087 5088 #ifndef NO_CATGETS 5089 setlocale(LC_ALL, ""); 5090 catalog = catopen("ee", NL_CAT_LOCALE); 5091 #endif /* NO_CATGETS */ 5092 5093 modes_menu[0].item_string = catgetlocal( 1, "modes menu"); 5094 mode_strings[1] = catgetlocal( 2, "tabs to spaces "); 5095 mode_strings[2] = catgetlocal( 3, "case sensitive search"); 5096 mode_strings[3] = catgetlocal( 4, "margins observed "); 5097 mode_strings[4] = catgetlocal( 5, "auto-paragraph format"); 5098 mode_strings[5] = catgetlocal( 6, "eightbit characters "); 5099 mode_strings[6] = catgetlocal( 7, "info window "); 5100 mode_strings[8] = catgetlocal( 8, "right margin "); 5101 leave_menu[0].item_string = catgetlocal( 9, "leave menu"); 5102 leave_menu[1].item_string = catgetlocal( 10, "save changes"); 5103 leave_menu[2].item_string = catgetlocal( 11, "no save"); 5104 file_menu[0].item_string = catgetlocal( 12, "file menu"); 5105 file_menu[1].item_string = catgetlocal( 13, "read a file"); 5106 file_menu[2].item_string = catgetlocal( 14, "write a file"); 5107 file_menu[3].item_string = catgetlocal( 15, "save file"); 5108 file_menu[4].item_string = catgetlocal( 16, "print editor contents"); 5109 search_menu[0].item_string = catgetlocal( 17, "search menu"); 5110 search_menu[1].item_string = catgetlocal( 18, "search for ..."); 5111 search_menu[2].item_string = catgetlocal( 19, "search"); 5112 spell_menu[0].item_string = catgetlocal( 20, "spell menu"); 5113 spell_menu[1].item_string = catgetlocal( 21, "use 'spell'"); 5114 spell_menu[2].item_string = catgetlocal( 22, "use 'ispell'"); 5115 misc_menu[0].item_string = catgetlocal( 23, "miscellaneous menu"); 5116 misc_menu[1].item_string = catgetlocal( 24, "format paragraph"); 5117 misc_menu[2].item_string = catgetlocal( 25, "shell command"); 5118 misc_menu[3].item_string = catgetlocal( 26, "check spelling"); 5119 main_menu[0].item_string = catgetlocal( 27, "main menu"); 5120 main_menu[1].item_string = catgetlocal( 28, "leave editor"); 5121 main_menu[2].item_string = catgetlocal( 29, "help"); 5122 main_menu[3].item_string = catgetlocal( 30, "file operations"); 5123 main_menu[4].item_string = catgetlocal( 31, "redraw screen"); 5124 main_menu[5].item_string = catgetlocal( 32, "settings"); 5125 main_menu[6].item_string = catgetlocal( 33, "search"); 5126 main_menu[7].item_string = catgetlocal( 34, "miscellaneous"); 5127 help_text[0] = catgetlocal( 35, "Control keys: "); 5128 help_text[1] = catgetlocal( 36, "^a ascii code ^i tab ^r right "); 5129 help_text[2] = catgetlocal( 37, "^b bottom of text ^j newline ^t top of text "); 5130 help_text[3] = catgetlocal( 38, "^c command ^k delete char ^u up "); 5131 help_text[4] = catgetlocal( 39, "^d down ^l left ^v undelete word "); 5132 help_text[5] = catgetlocal( 40, "^e search prompt ^m newline ^w delete word "); 5133 help_text[6] = catgetlocal( 41, "^f undelete char ^n next page ^x search "); 5134 help_text[7] = catgetlocal( 42, "^g begin of line ^o end of line ^y delete line "); 5135 help_text[8] = catgetlocal( 43, "^h backspace ^p prev page ^z undelete line "); 5136 help_text[9] = catgetlocal( 44, "^[ (escape) menu ESC-Enter: exit ee "); 5137 help_text[10] = catgetlocal( 45, " "); 5138 help_text[11] = catgetlocal( 46, "Commands: "); 5139 help_text[12] = catgetlocal( 47, "help : get this info file : print file name "); 5140 help_text[13] = catgetlocal( 48, "read : read a file char : ascii code of char "); 5141 help_text[14] = catgetlocal( 49, "write : write a file case : case sensitive search "); 5142 help_text[15] = catgetlocal( 50, "exit : leave and save nocase : case insensitive search "); 5143 help_text[16] = catgetlocal( 51, "quit : leave, no save !cmd : execute \"cmd\" in shell "); 5144 help_text[17] = catgetlocal( 52, "line : display line # 0-9 : go to line \"#\" "); 5145 help_text[18] = catgetlocal( 53, "expand : expand tabs noexpand: do not expand tabs "); 5146 help_text[19] = catgetlocal( 54, " "); 5147 help_text[20] = catgetlocal( 55, " ee [+#] [-i] [-e] [-h] [file(s)] "); 5148 help_text[21] = catgetlocal( 56, "+# :go to line # -i :no info window -e : don't expand tabs -h :no highlight"); 5149 control_keys[0] = catgetlocal( 57, "^[ (escape) menu ^e search prompt ^y delete line ^u up ^p prev page "); 5150 control_keys[1] = catgetlocal( 58, "^a ascii code ^x search ^z undelete line ^d down ^n next page "); 5151 control_keys[2] = catgetlocal( 59, "^b bottom of text ^g begin of line ^w delete word ^l left "); 5152 control_keys[3] = catgetlocal( 60, "^t top of text ^o end of line ^v undelete word ^r right "); 5153 control_keys[4] = catgetlocal( 61, "^c command ^k delete char ^f undelete char ESC-Enter: exit ee "); 5154 command_strings[0] = catgetlocal( 62, "help : get help info |file : print file name |line : print line # "); 5155 command_strings[1] = catgetlocal( 63, "read : read a file |char : ascii code of char |0-9 : go to line \"#\""); 5156 command_strings[2] = catgetlocal( 64, "write: write a file |case : case sensitive search |exit : leave and save "); 5157 command_strings[3] = catgetlocal( 65, "!cmd : shell \"cmd\" |nocase: ignore case in search |quit : leave, no save"); 5158 command_strings[4] = catgetlocal( 66, "expand: expand tabs |noexpand: do not expand tabs "); 5159 com_win_message = catgetlocal( 67, " press Escape (^[) for menu"); 5160 no_file_string = catgetlocal( 68, "no file"); 5161 ascii_code_str = catgetlocal( 69, "ascii code: "); 5162 printer_msg_str = catgetlocal( 70, "sending contents of buffer to \"%s\" "); 5163 command_str = catgetlocal( 71, "command: "); 5164 file_write_prompt_str = catgetlocal( 72, "name of file to write: "); 5165 file_read_prompt_str = catgetlocal( 73, "name of file to read: "); 5166 char_str = catgetlocal( 74, "character = %d"); 5167 unkn_cmd_str = catgetlocal( 75, "unknown command \"%s\""); 5168 non_unique_cmd_msg = catgetlocal( 76, "entered command is not unique"); 5169 line_num_str = catgetlocal( 77, "line %d "); 5170 line_len_str = catgetlocal( 78, "length = %d"); 5171 current_file_str = catgetlocal( 79, "current file is \"%s\" "); 5172 usage0 = catgetlocal( 80, "usage: %s [-i] [-e] [-h] [+line_number] [file(s)]\n"); 5173 usage1 = catgetlocal( 81, " -i turn off info window\n"); 5174 usage2 = catgetlocal( 82, " -e do not convert tabs to spaces\n"); 5175 usage3 = catgetlocal( 83, " -h do not use highlighting\n"); 5176 file_is_dir_msg = catgetlocal( 84, "file \"%s\" is a directory"); 5177 new_file_msg = catgetlocal( 85, "new file \"%s\""); 5178 cant_open_msg = catgetlocal( 86, "can't open \"%s\""); 5179 open_file_msg = catgetlocal( 87, "file \"%s\", %d lines"); 5180 file_read_fin_msg = catgetlocal( 88, "finished reading file \"%s\""); 5181 reading_file_msg = catgetlocal( 89, "reading file \"%s\""); 5182 read_only_msg = catgetlocal( 90, ", read only"); 5183 file_read_lines_msg = catgetlocal( 91, "file \"%s\", %d lines"); 5184 save_file_name_prompt = catgetlocal( 92, "enter name of file: "); 5185 file_not_saved_msg = catgetlocal( 93, "no filename entered: file not saved"); 5186 changes_made_prompt = catgetlocal( 94, "changes have been made, are you sure? (y/n [n]) "); 5187 yes_char = catgetlocal( 95, "y"); 5188 file_exists_prompt = catgetlocal( 96, "file already exists, overwrite? (y/n) [n] "); 5189 create_file_fail_msg = catgetlocal( 97, "unable to create file \"%s\""); 5190 writing_file_msg = catgetlocal( 98, "writing file \"%s\""); 5191 file_written_msg = catgetlocal( 99, "\"%s\" %d lines, %d characters"); 5192 searching_msg = catgetlocal( 100, " ...searching"); 5193 str_not_found_msg = catgetlocal( 101, "string \"%s\" not found"); 5194 search_prompt_str = catgetlocal( 102, "search for: "); 5195 exec_err_msg = catgetlocal( 103, "could not exec %s\n"); 5196 continue_msg = catgetlocal( 104, "press return to continue "); 5197 menu_cancel_msg = catgetlocal( 105, "press Esc to cancel"); 5198 menu_size_err_msg = catgetlocal( 106, "menu too large for window"); 5199 press_any_key_msg = catgetlocal( 107, "press any key to continue "); 5200 shell_prompt = catgetlocal( 108, "shell command: "); 5201 formatting_msg = catgetlocal( 109, "...formatting paragraph..."); 5202 shell_echo_msg = catgetlocal( 110, "<!echo 'list of unrecognized words'; echo -=-=-=-=-=-"); 5203 spell_in_prog_msg = catgetlocal( 111, "sending contents of edit buffer to 'spell'"); 5204 margin_prompt = catgetlocal( 112, "right margin is: "); 5205 restricted_msg = catgetlocal( 113, "restricted mode: unable to perform requested operation"); 5206 ON = catgetlocal( 114, "ON"); 5207 OFF = catgetlocal( 115, "OFF"); 5208 HELP = catgetlocal( 116, "HELP"); 5209 WRITE = catgetlocal( 117, "WRITE"); 5210 READ = catgetlocal( 118, "READ"); 5211 LINE = catgetlocal( 119, "LINE"); 5212 FILE_str = catgetlocal( 120, "FILE"); 5213 CHARACTER = catgetlocal( 121, "CHARACTER"); 5214 REDRAW = catgetlocal( 122, "REDRAW"); 5215 RESEQUENCE = catgetlocal( 123, "RESEQUENCE"); 5216 AUTHOR = catgetlocal( 124, "AUTHOR"); 5217 VERSION = catgetlocal( 125, "VERSION"); 5218 CASE = catgetlocal( 126, "CASE"); 5219 NOCASE = catgetlocal( 127, "NOCASE"); 5220 EXPAND = catgetlocal( 128, "EXPAND"); 5221 NOEXPAND = catgetlocal( 129, "NOEXPAND"); 5222 Exit_string = catgetlocal( 130, "EXIT"); 5223 QUIT_string = catgetlocal( 131, "QUIT"); 5224 INFO = catgetlocal( 132, "INFO"); 5225 NOINFO = catgetlocal( 133, "NOINFO"); 5226 MARGINS = catgetlocal( 134, "MARGINS"); 5227 NOMARGINS = catgetlocal( 135, "NOMARGINS"); 5228 AUTOFORMAT = catgetlocal( 136, "AUTOFORMAT"); 5229 NOAUTOFORMAT = catgetlocal( 137, "NOAUTOFORMAT"); 5230 Echo = catgetlocal( 138, "ECHO"); 5231 PRINTCOMMAND = catgetlocal( 139, "PRINTCOMMAND"); 5232 RIGHTMARGIN = catgetlocal( 140, "RIGHTMARGIN"); 5233 HIGHLIGHT = catgetlocal( 141, "HIGHLIGHT"); 5234 NOHIGHLIGHT = catgetlocal( 142, "NOHIGHLIGHT"); 5235 EIGHTBIT = catgetlocal( 143, "EIGHTBIT"); 5236 NOEIGHTBIT = catgetlocal( 144, "NOEIGHTBIT"); 5237 /* 5238 | additions 5239 */ 5240 mode_strings[7] = catgetlocal( 145, "emacs key bindings "); 5241 emacs_help_text[0] = help_text[0]; 5242 emacs_help_text[1] = catgetlocal( 146, "^a beginning of line ^i tab ^r restore word "); 5243 emacs_help_text[2] = catgetlocal( 147, "^b back 1 char ^j undel char ^t top of text "); 5244 emacs_help_text[3] = catgetlocal( 148, "^c command ^k delete line ^u bottom of text "); 5245 emacs_help_text[4] = catgetlocal( 149, "^d delete char ^l undelete line ^v next page "); 5246 emacs_help_text[5] = catgetlocal( 150, "^e end of line ^m newline ^w delete word "); 5247 emacs_help_text[6] = catgetlocal( 151, "^f forward 1 char ^n next line ^x search "); 5248 emacs_help_text[7] = catgetlocal( 152, "^g go back 1 page ^o ascii char insert ^y search prompt "); 5249 emacs_help_text[8] = catgetlocal( 153, "^h backspace ^p prev line ^z next word "); 5250 emacs_help_text[9] = help_text[9]; 5251 emacs_help_text[10] = help_text[10]; 5252 emacs_help_text[11] = help_text[11]; 5253 emacs_help_text[12] = help_text[12]; 5254 emacs_help_text[13] = help_text[13]; 5255 emacs_help_text[14] = help_text[14]; 5256 emacs_help_text[15] = help_text[15]; 5257 emacs_help_text[16] = help_text[16]; 5258 emacs_help_text[17] = help_text[17]; 5259 emacs_help_text[18] = help_text[18]; 5260 emacs_help_text[19] = help_text[19]; 5261 emacs_help_text[20] = help_text[20]; 5262 emacs_help_text[21] = help_text[21]; 5263 emacs_control_keys[0] = catgetlocal( 154, "^[ (escape) menu ^y search prompt ^k delete line ^p prev li ^g prev page"); 5264 emacs_control_keys[1] = catgetlocal( 155, "^o ascii code ^x search ^l undelete line ^n next li ^v next page"); 5265 emacs_control_keys[2] = catgetlocal( 156, "^u end of file ^a begin of line ^w delete word ^b back 1 char ^z next word"); 5266 emacs_control_keys[3] = catgetlocal( 157, "^t top of text ^e end of line ^r restore word ^f forward char "); 5267 emacs_control_keys[4] = catgetlocal( 158, "^c command ^d delete char ^j undelete char ESC-Enter: exit"); 5268 EMACS_string = catgetlocal( 159, "EMACS"); 5269 NOEMACS_string = catgetlocal( 160, "NOEMACS"); 5270 usage4 = catgetlocal( 161, " +# put cursor at line #\n"); 5271 conf_dump_err_msg = catgetlocal( 162, "unable to open .init.ee for writing, no configuration saved!"); 5272 conf_dump_success_msg = catgetlocal( 163, "ee configuration saved in file %s"); 5273 modes_menu[10].item_string = catgetlocal( 164, "save editor configuration"); 5274 config_dump_menu[0].item_string = catgetlocal( 165, "save ee configuration"); 5275 config_dump_menu[1].item_string = catgetlocal( 166, "save in current directory"); 5276 config_dump_menu[2].item_string = catgetlocal( 167, "save in home directory"); 5277 conf_not_saved_msg = catgetlocal( 168, "ee configuration not saved"); 5278 ree_no_file_msg = catgetlocal( 169, "must specify a file when invoking ree"); 5279 menu_too_lrg_msg = catgetlocal( 180, "menu too large for window"); 5280 more_above_str = catgetlocal( 181, "^^more^^"); 5281 more_below_str = catgetlocal( 182, "VVmoreVV"); 5282 mode_strings[9] = catgetlocal( 183, "16 bit characters "); 5283 chinese_cmd = catgetlocal( 184, "16BIT"); 5284 nochinese_cmd = catgetlocal( 185, "NO16BIT"); 5285 5286 commands[0] = HELP; 5287 commands[1] = WRITE; 5288 commands[2] = READ; 5289 commands[3] = LINE; 5290 commands[4] = FILE_str; 5291 commands[5] = REDRAW; 5292 commands[6] = RESEQUENCE; 5293 commands[7] = AUTHOR; 5294 commands[8] = VERSION; 5295 commands[9] = CASE; 5296 commands[10] = NOCASE; 5297 commands[11] = EXPAND; 5298 commands[12] = NOEXPAND; 5299 commands[13] = Exit_string; 5300 commands[14] = QUIT_string; 5301 commands[15] = "<"; 5302 commands[16] = ">"; 5303 commands[17] = "!"; 5304 commands[18] = "0"; 5305 commands[19] = "1"; 5306 commands[20] = "2"; 5307 commands[21] = "3"; 5308 commands[22] = "4"; 5309 commands[23] = "5"; 5310 commands[24] = "6"; 5311 commands[25] = "7"; 5312 commands[26] = "8"; 5313 commands[27] = "9"; 5314 commands[28] = CHARACTER; 5315 commands[29] = chinese_cmd; 5316 commands[30] = nochinese_cmd; 5317 commands[31] = NULL; 5318 init_strings[0] = CASE; 5319 init_strings[1] = NOCASE; 5320 init_strings[2] = EXPAND; 5321 init_strings[3] = NOEXPAND; 5322 init_strings[4] = INFO; 5323 init_strings[5] = NOINFO; 5324 init_strings[6] = MARGINS; 5325 init_strings[7] = NOMARGINS; 5326 init_strings[8] = AUTOFORMAT; 5327 init_strings[9] = NOAUTOFORMAT; 5328 init_strings[10] = Echo; 5329 init_strings[11] = PRINTCOMMAND; 5330 init_strings[12] = RIGHTMARGIN; 5331 init_strings[13] = HIGHLIGHT; 5332 init_strings[14] = NOHIGHLIGHT; 5333 init_strings[15] = EIGHTBIT; 5334 init_strings[16] = NOEIGHTBIT; 5335 init_strings[17] = EMACS_string; 5336 init_strings[18] = NOEMACS_string; 5337 init_strings[19] = chinese_cmd; 5338 init_strings[20] = nochinese_cmd; 5339 init_strings[21] = NULL; 5340 5341 /* 5342 | allocate space for strings here for settings menu 5343 */ 5344 5345 for (counter = 1; counter < NUM_MODES_ITEMS; counter++) 5346 { 5347 modes_menu[counter].item_string = malloc(80); 5348 } 5349 5350 #ifndef NO_CATGETS 5351 catclose(catalog); 5352 #endif /* NO_CATGETS */ 5353 } 5354 5355