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