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