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