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