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