ee.c revision 196751
1/* 2 | ee (easy editor) 3 | 4 | An easy to use, simple screen oriented editor. 5 | 6 | written by Hugh Mahon 7 | 8 | 9 | Copyright (c) 2009, Hugh Mahon 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions 14 | are met: 15 | 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | * Redistributions in binary form must reproduce the above 19 | copyright notice, this list of conditions and the following 20 | disclaimer in the documentation and/or other materials provided 21 | with the distribution. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 | POSSIBILITY OF SUCH DAMAGE. 35 | 36 | -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 37 | 38 | This editor was purposely developed to be simple, both in 39 | interface and implementation. This editor was developed to 40 | address a specific audience: the user who is new to computers 41 | (especially UNIX). 42 | 43 | ee is not aimed at technical users; for that reason more 44 | complex features were intentionally left out. In addition, 45 | ee is intended to be compiled by people with little computer 46 | experience, which means that it needs to be small, relatively 47 | simple in implementation, and portable. 48 | 49 | This software and documentation contains 50 | proprietary information which is protected by 51 | copyright. All rights are reserved. 52 | 53 | $Header: /home/hugh/sources/old_ae/RCS/ee.c,v 1.102 2009/02/17 03:22:50 hugh Exp hugh $ 54 | 55 */ 56 57#include <sys/cdefs.h> 58__FBSDID("$FreeBSD: head/contrib/ee/ee.c 196751 2009-09-02 04:43:46Z ache $"); 59 60char *ee_copyright_message = 61"Copyright (c) 1986, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 2009 Hugh Mahon "; 62 63#include "ee_version.h" 64 65char *version = "@(#) ee, version " EE_VERSION " $Revision: 1.102 $"; 66 67#ifdef NCURSE 68#include "new_curse.h" 69#elif HAS_NCURSES 70#include <ncurses.h> 71#else 72#include <curses.h> 73#endif 74 75#ifdef HAS_CTYPE 76#include <ctype.h> 77#endif 78 79#include <signal.h> 80#include <fcntl.h> 81#include <sys/types.h> 82#include <sys/stat.h> 83#include <errno.h> 84#include <string.h> 85#include <pwd.h> 86#include <locale.h> 87 88#ifdef HAS_SYS_WAIT 89#include <sys/wait.h> 90#endif 91 92#ifdef HAS_STDLIB 93#include <stdlib.h> 94#endif 95 96#ifdef HAS_STDARG 97#include <stdarg.h> 98#endif 99 100#ifdef HAS_UNISTD 101#include <unistd.h> 102#endif 103 104#ifndef NO_CATGETS 105#include <nl_types.h> 106 107nl_catd catalog; 108#else 109#define catgetlocal(a, b) (b) 110#endif /* NO_CATGETS */ 111 112#ifndef SIGCHLD 113#define SIGCHLD SIGCLD 114#endif 115 116#define TAB 9 117#define max(a, b) (a > b ? a : b) 118#define min(a, b) (a < b ? a : b) 119 120/* 121 | defines for type of data to show in info window 122 */ 123 124#define CONTROL_KEYS 1 125#define COMMANDS 2 126 127struct text { 128 unsigned char *line; /* line of characters */ 129 int line_number; /* line number */ 130 int line_length; /* actual number of characters in the line */ 131 int max_length; /* maximum number of characters the line handles */ 132 struct text *next_line; /* next line of text */ 133 struct text *prev_line; /* previous line of text */ 134 }; 135 136struct text *first_line; /* first line of current buffer */ 137struct text *dlt_line; /* structure for info on deleted line */ 138struct text *curr_line; /* current line cursor is on */ 139struct text *tmp_line; /* temporary line pointer */ 140struct text *srch_line; /* temporary pointer for search routine */ 141 142struct files { /* structure to store names of files to be edited*/ 143 unsigned char *name; /* name of file */ 144 struct files *next_name; 145 }; 146 147struct files *top_of_stack = NULL; 148 149int d_wrd_len; /* length of deleted word */ 150int position; /* offset in bytes from begin of line */ 151int scr_pos; /* horizontal position */ 152int scr_vert; /* vertical position on screen */ 153int scr_horz; /* horizontal position on screen */ 154int absolute_lin; /* number of lines from top */ 155int tmp_vert, tmp_horz; 156int input_file; /* indicate to read input file */ 157int recv_file; /* indicate reading a file */ 158int edit; /* continue executing while true */ 159int gold; /* 'gold' function key pressed */ 160int fildes; /* file descriptor */ 161int case_sen; /* case sensitive search flag */ 162int last_line; /* last line for text display */ 163int last_col; /* last column for text display */ 164int horiz_offset = 0; /* offset from left edge of text */ 165int clear_com_win; /* flag to indicate com_win needs clearing */ 166int text_changes = FALSE; /* indicate changes have been made to text */ 167int get_fd; /* file descriptor for reading a file */ 168int info_window = TRUE; /* flag to indicate if help window visible */ 169int info_type = CONTROL_KEYS; /* flag to indicate type of info to display */ 170int expand_tabs = TRUE; /* flag for expanding tabs */ 171int right_margin = 0; /* the right margin */ 172int observ_margins = TRUE; /* flag for whether margins are observed */ 173int shell_fork; 174int temp_stdin; /* temporary storage for stdin */ 175int temp_stdout; /* temp storage for stdout descriptor */ 176int temp_stderr; /* temp storage for stderr descriptor */ 177int pipe_out[2]; /* pipe file desc for output */ 178int pipe_in[2]; /* pipe file descriptors for input */ 179int out_pipe; /* flag that info is piped out */ 180int in_pipe; /* flag that info is piped in */ 181int formatted = FALSE; /* flag indicating paragraph formatted */ 182int auto_format = FALSE; /* flag for auto_format mode */ 183int restricted = FALSE; /* flag to indicate restricted mode */ 184int nohighlight = FALSE; /* turns off highlighting */ 185int eightbit = TRUE; /* eight bit character flag */ 186int local_LINES = 0; /* copy of LINES, to detect when win resizes */ 187int local_COLS = 0; /* copy of COLS, to detect when win resizes */ 188int curses_initialized = FALSE; /* flag indicating if curses has been started*/ 189int emacs_keys_mode = FALSE; /* mode for if emacs key binings are used */ 190int ee_chinese = FALSE; /* allows handling of multi-byte characters */ 191 /* by checking for high bit in a byte the */ 192 /* code recognizes a two-byte character */ 193 /* sequence */ 194 195unsigned char *point; /* points to current position in line */ 196unsigned char *srch_str; /* pointer for search string */ 197unsigned char *u_srch_str; /* pointer to non-case sensitive search */ 198unsigned char *srch_1; /* pointer to start of suspect string */ 199unsigned char *srch_2; /* pointer to next character of string */ 200unsigned char *srch_3; 201unsigned char *in_file_name = NULL; /* name of input file */ 202char *tmp_file; /* temporary file name */ 203unsigned char *d_char; /* deleted character */ 204unsigned char *d_word; /* deleted word */ 205unsigned char *d_line; /* deleted line */ 206char in_string[513]; /* buffer for reading a file */ 207unsigned char *print_command = (unsigned char *)"lpr"; /* string to use for the print command */ 208unsigned char *start_at_line = NULL; /* move to this line at start of session*/ 209int in; /* input character */ 210 211FILE *temp_fp; /* temporary file pointer */ 212FILE *bit_bucket; /* file pointer to /dev/null */ 213 214char *table[] = { 215 "^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G", "^H", "\t", "^J", 216 "^K", "^L", "^M", "^N", "^O", "^P", "^Q", "^R", "^S", "^T", "^U", 217 "^V", "^W", "^X", "^Y", "^Z", "^[", "^\\", "^]", "^^", "^_" 218 }; 219 220WINDOW *com_win; 221WINDOW *text_win; 222WINDOW *help_win; 223WINDOW *info_win; 224 225#if defined(__STDC__) || defined(__cplusplus) 226#define P_(s) s 227#else 228#define P_(s) () 229#endif 230 231 232/* 233 | The following structure allows menu items to be flexibly declared. 234 | The first item is the string describing the selection, the second 235 | is the address of the procedure to call when the item is selected, 236 | and the third is the argument for the procedure. 237 | 238 | For those systems with i18n, the string should be accompanied by a 239 | catalog number. The 'int *' should be replaced with 'void *' on 240 | systems with that type. 241 | 242 | The first menu item will be the title of the menu, with NULL 243 | parameters for the procedure and argument, followed by the menu items. 244 | 245 | If the procedure value is NULL, the menu item is displayed, but no 246 | procedure is called when the item is selected. The number of the 247 | item will be returned. If the third (argument) parameter is -1, no 248 | argument is given to the procedure when it is called. 249 */ 250 251struct menu_entries { 252 char *item_string; 253 int (*procedure)P_((struct menu_entries *)); 254 struct menu_entries *ptr_argument; 255 int (*iprocedure)P_((int)); 256 void (*nprocedure)P_((void)); 257 int argument; 258 }; 259 260int main P_((int argc, char *argv[])); 261unsigned char *resiz_line P_((int factor, struct text *rline, int rpos)); 262void insert P_((int character)); 263void delete P_((int disp)); 264void scanline P_((unsigned char *pos)); 265int tabshift P_((int temp_int)); 266int out_char P_((WINDOW *window, int character, int column)); 267int len_char P_((int character, int column)); 268void draw_line P_((int vertical, int horiz, unsigned char *ptr, int t_pos, int length)); 269void insert_line P_((int disp)); 270struct text *txtalloc P_((void)); 271struct files *name_alloc P_((void)); 272unsigned char *next_word P_((unsigned char *string)); 273void prev_word P_((void)); 274void control P_((void)); 275void emacs_control P_((void)); 276void bottom P_((void)); 277void top P_((void)); 278void nextline P_((void)); 279void prevline P_((void)); 280void left P_((int disp)); 281void right P_((int disp)); 282void find_pos P_((void)); 283void up P_((void)); 284void down P_((void)); 285void function_key P_((void)); 286void print_buffer P_((void)); 287void command_prompt P_((void)); 288void command P_((char *cmd_str1)); 289int scan P_((char *line, int offset, int column)); 290char *get_string P_((char *prompt, int advance)); 291int compare P_((char *string1, char *string2, int sensitive)); 292void goto_line P_((char *cmd_str)); 293void midscreen P_((int line, unsigned char *pnt)); 294void get_options P_((int numargs, char *arguments[])); 295void check_fp P_((void)); 296void get_file P_((char *file_name)); 297void get_line P_((int length, unsigned char *in_string, int *append)); 298void draw_screen P_((void)); 299void finish P_((void)); 300int quit P_((int noverify)); 301void edit_abort P_((int arg)); 302void delete_text P_((void)); 303int write_file P_((char *file_name, int warn_if_exists)); 304int search P_((int display_message)); 305void search_prompt P_((void)); 306void del_char P_((void)); 307void undel_char P_((void)); 308void del_word P_((void)); 309void undel_word P_((void)); 310void del_line P_((void)); 311void undel_line P_((void)); 312void adv_word P_((void)); 313void move_rel P_((char *direction, int lines)); 314void eol P_((void)); 315void bol P_((void)); 316void adv_line P_((void)); 317void sh_command P_((char *string)); 318void set_up_term P_((void)); 319void resize_check P_((void)); 320int menu_op P_((struct menu_entries *)); 321void 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)); 322void help P_((void)); 323void paint_info_win P_((void)); 324void no_info_window P_((void)); 325void create_info_window P_((void)); 326int file_op P_((int arg)); 327void shell_op P_((void)); 328void leave_op P_((void)); 329void redraw P_((void)); 330int Blank_Line P_((struct text *test_line)); 331void Format P_((void)); 332void ee_init P_((void)); 333void dump_ee_conf P_((void)); 334void echo_string P_((char *string)); 335void spell_op P_((void)); 336void ispell_op P_((void)); 337int first_word_len P_((struct text *test_line)); 338void Auto_Format P_((void)); 339void modes_op P_((void)); 340char *is_in_string P_((char *string, char *substring)); 341char *resolve_name P_((char *name)); 342int restrict_mode P_((void)); 343int unique_test P_((char *string, char *list[])); 344void strings_init P_((void)); 345 346#undef P_ 347/* 348 | allocate space here for the strings that will be in the menu 349 */ 350 351struct menu_entries modes_menu[] = { 352 {"", NULL, NULL, NULL, NULL, 0}, /* title */ 353 {"", NULL, NULL, NULL, NULL, -1}, /* 1. tabs to spaces */ 354 {"", NULL, NULL, NULL, NULL, -1}, /* 2. case sensitive search*/ 355 {"", NULL, NULL, NULL, NULL, -1}, /* 3. margins observed */ 356 {"", NULL, NULL, NULL, NULL, -1}, /* 4. auto-paragraph */ 357 {"", NULL, NULL, NULL, NULL, -1}, /* 5. eightbit characters*/ 358 {"", NULL, NULL, NULL, NULL, -1}, /* 6. info window */ 359 {"", NULL, NULL, NULL, NULL, -1}, /* 7. emacs key bindings*/ 360 {"", NULL, NULL, NULL, NULL, -1}, /* 8. right margin */ 361 {"", NULL, NULL, NULL, NULL, -1}, /* 9. chinese text */ 362 {"", NULL, NULL, NULL, dump_ee_conf, -1}, /* 10. save editor config */ 363 {NULL, NULL, NULL, NULL, NULL, -1} /* terminator */ 364 }; 365 366char *mode_strings[11]; 367 368#define NUM_MODES_ITEMS 10 369 370struct menu_entries config_dump_menu[] = { 371 {"", NULL, NULL, NULL, NULL, 0}, 372 {"", NULL, NULL, NULL, NULL, -1}, 373 {"", NULL, NULL, NULL, NULL, -1}, 374 {NULL, NULL, NULL, NULL, NULL, -1} 375 }; 376 377struct menu_entries leave_menu[] = { 378 {"", NULL, NULL, NULL, NULL, -1}, 379 {"", NULL, NULL, NULL, finish, -1}, 380 {"", NULL, NULL, quit, NULL, TRUE}, 381 {NULL, NULL, NULL, NULL, NULL, -1} 382 }; 383 384#define READ_FILE 1 385#define WRITE_FILE 2 386#define SAVE_FILE 3 387 388struct menu_entries file_menu[] = { 389 {"", NULL, NULL, NULL, NULL, -1}, 390 {"", NULL, NULL, file_op, NULL, READ_FILE}, 391 {"", NULL, NULL, file_op, NULL, WRITE_FILE}, 392 {"", NULL, NULL, file_op, NULL, SAVE_FILE}, 393 {"", NULL, NULL, NULL, print_buffer, -1}, 394 {NULL, NULL, NULL, NULL, NULL, -1} 395 }; 396 397struct menu_entries search_menu[] = { 398 {"", NULL, NULL, NULL, NULL, 0}, 399 {"", NULL, NULL, NULL, search_prompt, -1}, 400 {"", NULL, NULL, search, NULL, TRUE}, 401 {NULL, NULL, NULL, NULL, NULL, -1} 402 }; 403 404struct menu_entries spell_menu[] = { 405 {"", NULL, NULL, NULL, NULL, -1}, 406 {"", NULL, NULL, NULL, spell_op, -1}, 407 {"", NULL, NULL, NULL, ispell_op, -1}, 408 {NULL, NULL, NULL, NULL, NULL, -1} 409 }; 410 411struct menu_entries misc_menu[] = { 412 {"", NULL, NULL, NULL, NULL, -1}, 413 {"", NULL, NULL, NULL, Format, -1}, 414 {"", NULL, NULL, NULL, shell_op, -1}, 415 {"", menu_op, spell_menu, NULL, NULL, -1}, 416 {NULL, NULL, NULL, NULL, NULL, -1} 417 }; 418 419struct menu_entries main_menu[] = { 420 {"", NULL, NULL, NULL, NULL, -1}, 421 {"", NULL, NULL, NULL, leave_op, -1}, 422 {"", NULL, NULL, NULL, help, -1}, 423 {"", menu_op, file_menu, NULL, NULL, -1}, 424 {"", NULL, NULL, NULL, redraw, -1}, 425 {"", NULL, NULL, NULL, modes_op, -1}, 426 {"", menu_op, search_menu, NULL, NULL, -1}, 427 {"", menu_op, misc_menu, NULL, NULL, -1}, 428 {NULL, NULL, NULL, NULL, NULL, -1} 429 }; 430 431char *help_text[23]; 432char *control_keys[5]; 433 434char *emacs_help_text[22]; 435char *emacs_control_keys[5]; 436 437char *command_strings[5]; 438char *commands[32]; 439char *init_strings[22]; 440 441#define MENU_WARN 1 442 443#define max_alpha_char 36 444 445/* 446 | Declarations for strings for localization 447 */ 448 449char *com_win_message; /* to be shown in com_win if no info window */ 450char *no_file_string; 451char *ascii_code_str; 452char *printer_msg_str; 453char *command_str; 454char *file_write_prompt_str; 455char *file_read_prompt_str; 456char *char_str; 457char *unkn_cmd_str; 458char *non_unique_cmd_msg; 459char *line_num_str; 460char *line_len_str; 461char *current_file_str; 462char *usage0; 463char *usage1; 464char *usage2; 465char *usage3; 466char *usage4; 467char *file_is_dir_msg; 468char *new_file_msg; 469char *cant_open_msg; 470char *open_file_msg; 471char *file_read_fin_msg; 472char *reading_file_msg; 473char *read_only_msg; 474char *file_read_lines_msg; 475char *save_file_name_prompt; 476char *file_not_saved_msg; 477char *changes_made_prompt; 478char *yes_char; 479char *file_exists_prompt; 480char *create_file_fail_msg; 481char *writing_file_msg; 482char *file_written_msg; 483char *searching_msg; 484char *str_not_found_msg; 485char *search_prompt_str; 486char *exec_err_msg; 487char *continue_msg; 488char *menu_cancel_msg; 489char *menu_size_err_msg; 490char *press_any_key_msg; 491char *shell_prompt; 492char *formatting_msg; 493char *shell_echo_msg; 494char *spell_in_prog_msg; 495char *margin_prompt; 496char *restricted_msg; 497char *ON; 498char *OFF; 499char *HELP; 500char *WRITE; 501char *READ; 502char *LINE; 503char *FILE_str; 504char *CHARACTER; 505char *REDRAW; 506char *RESEQUENCE; 507char *AUTHOR; 508char *VERSION; 509char *CASE; 510char *NOCASE; 511char *EXPAND; 512char *NOEXPAND; 513char *Exit_string; 514char *QUIT_string; 515char *INFO; 516char *NOINFO; 517char *MARGINS; 518char *NOMARGINS; 519char *AUTOFORMAT; 520char *NOAUTOFORMAT; 521char *Echo; 522char *PRINTCOMMAND; 523char *RIGHTMARGIN; 524char *HIGHLIGHT; 525char *NOHIGHLIGHT; 526char *EIGHTBIT; 527char *NOEIGHTBIT; 528char *EMACS_string; 529char *NOEMACS_string; 530char *conf_dump_err_msg; 531char *conf_dump_success_msg; 532char *conf_not_saved_msg; 533char *ree_no_file_msg; 534char *cancel_string; 535char *menu_too_lrg_msg; 536char *more_above_str, *more_below_str; 537char *separator = "==============================================================================="; 538 539char *chinese_cmd, *nochinese_cmd; 540 541#ifndef __STDC__ 542#ifndef HAS_STDLIB 543extern char *malloc(); 544extern char *realloc(); 545extern char *getenv(); 546FILE *fopen(); /* declaration for open function */ 547#endif /* HAS_STDLIB */ 548#endif /* __STDC__ */ 549 550int 551main(argc, argv) /* beginning of main program */ 552int argc; 553char *argv[]; 554{ 555 int counter; 556 557 for (counter = 1; counter < 24; counter++) 558 signal(counter, SIG_IGN); 559 560 signal(SIGCHLD, SIG_DFL); 561 signal(SIGSEGV, SIG_DFL); 562 signal(SIGINT, edit_abort); 563 d_char = malloc(3); /* provide a buffer for multi-byte chars */ 564 d_word = malloc(150); 565 *d_word = '\0'; 566 d_line = NULL; 567 dlt_line = txtalloc(); 568 dlt_line->line = d_line; 569 dlt_line->line_length = 0; 570 curr_line = first_line = txtalloc(); 571 curr_line->line = point = malloc(10); 572 curr_line->line_length = 1; 573 curr_line->max_length = 10; 574 curr_line->prev_line = NULL; 575 curr_line->next_line = NULL; 576 curr_line->line_number = 1; 577 srch_str = NULL; 578 u_srch_str = NULL; 579 position = 1; 580 scr_pos =0; 581 scr_vert = 0; 582 scr_horz = 0; 583 absolute_lin = 1; 584 bit_bucket = fopen("/dev/null", "w"); 585 edit = TRUE; 586 gold = case_sen = FALSE; 587 shell_fork = TRUE; 588 strings_init(); 589 ee_init(); 590 if (argc > 0 ) 591 get_options(argc, argv); 592 set_up_term(); 593 if (right_margin == 0) 594 right_margin = COLS - 1; 595 if (top_of_stack == NULL) 596 { 597 if (restrict_mode()) 598 { 599 wmove(com_win, 0, 0); 600 werase(com_win); 601 wprintw(com_win, ree_no_file_msg); 602 wrefresh(com_win); 603 edit_abort(0); 604 } 605 wprintw(com_win, no_file_string); 606 wrefresh(com_win); 607 } 608 else 609 check_fp(); 610 611 clear_com_win = TRUE; 612 613 counter = 0; 614 615 while(edit) 616 { 617 /* 618 | display line and column information 619 */ 620 if (info_window) 621 { 622 if (!nohighlight) 623 wstandout(info_win); 624 wmove(info_win, 5, 0); 625 wprintw(info_win, separator); 626 wmove(info_win, 5, 5); 627 wprintw(info_win, "line %d col %d lines from top %d ", 628 curr_line->line_number, scr_horz, absolute_lin); 629 wstandend(info_win); 630 wrefresh(info_win); 631 } 632 633 wrefresh(text_win); 634 in = wgetch(text_win); 635 if (in == -1) 636 exit(0); /* without this exit ee will go into an 637 infinite loop if the network 638 session detaches */ 639 640 resize_check(); 641 642 if (clear_com_win) 643 { 644 clear_com_win = FALSE; 645 wmove(com_win, 0, 0); 646 werase(com_win); 647 if (!info_window) 648 { 649 wprintw(com_win, "%s", com_win_message); 650 } 651 wrefresh(com_win); 652 } 653 654 if (in > 255) 655 function_key(); 656 else if ((in == '\10') || (in == 127)) 657 { 658 in = 8; /* make sure key is set to backspace */ 659 delete(TRUE); 660 } 661 else if ((in > 31) || (in == 9)) 662 insert(in); 663 else if ((in >= 0) && (in <= 31)) 664 { 665 if (emacs_keys_mode) 666 emacs_control(); 667 else 668 control(); 669 } 670 } 671 return(0); 672} 673 674unsigned char * 675resiz_line(factor, rline, rpos) /* resize the line to length + factor*/ 676int factor; /* resize factor */ 677struct text *rline; /* position in line */ 678int rpos; 679{ 680 unsigned char *rpoint; 681 int resiz_var; 682 683 rline->max_length += factor; 684 rpoint = rline->line = realloc(rline->line, rline->max_length ); 685 for (resiz_var = 1 ; (resiz_var < rpos) ; resiz_var++) 686 rpoint++; 687 return(rpoint); 688} 689 690void 691insert(character) /* insert character into line */ 692int character; /* new character */ 693{ 694 int counter; 695 int value; 696 unsigned char *temp; /* temporary pointer */ 697 unsigned char *temp2; /* temporary pointer */ 698 699 if ((character == '\011') && (expand_tabs)) 700 { 701 counter = len_char('\011', scr_horz); 702 for (; counter > 0; counter--) 703 insert(' '); 704 if (auto_format) 705 Auto_Format(); 706 return; 707 } 708 text_changes = TRUE; 709 if ((curr_line->max_length - curr_line->line_length) < 5) 710 point = resiz_line(10, curr_line, position); 711 curr_line->line_length++; 712 temp = point; 713 counter = position; 714 while (counter < curr_line->line_length) /* find end of line */ 715 { 716 counter++; 717 temp++; 718 } 719 temp++; /* increase length of line by one */ 720 while (point < temp) 721 { 722 temp2=temp - 1; 723 *temp= *temp2; /* shift characters over by one */ 724 temp--; 725 } 726 *point = character; /* insert new character */ 727 wclrtoeol(text_win); 728 if (!isprint((unsigned char)character)) /* check for TAB character*/ 729 { 730 scr_pos = scr_horz += out_char(text_win, character, scr_horz); 731 point++; 732 position++; 733 } 734 else 735 { 736 waddch(text_win, (unsigned char)character); 737 scr_pos = ++scr_horz; 738 point++; 739 position ++; 740 } 741 742 if ((observ_margins) && (right_margin < scr_pos)) 743 { 744 counter = position; 745 while (scr_pos > right_margin) 746 prev_word(); 747 if (scr_pos == 0) 748 { 749 while (position < counter) 750 right(TRUE); 751 } 752 else 753 { 754 counter -= position; 755 insert_line(TRUE); 756 for (value = 0; value < counter; value++) 757 right(TRUE); 758 } 759 } 760 761 if ((scr_horz - horiz_offset) > last_col) 762 { 763 horiz_offset += 8; 764 midscreen(scr_vert, point); 765 } 766 767 if ((auto_format) && (character == ' ') && (!formatted)) 768 Auto_Format(); 769 else if ((character != ' ') && (character != '\t')) 770 formatted = FALSE; 771 772 draw_line(scr_vert, scr_horz, point, position, curr_line->line_length); 773} 774 775void 776delete(disp) /* delete character */ 777int disp; 778{ 779 unsigned char *tp; 780 unsigned char *temp2; 781 struct text *temp_buff; 782 int temp_vert; 783 int temp_pos; 784 int del_width = 1; 785 786 if (point != curr_line->line) /* if not at beginning of line */ 787 { 788 text_changes = TRUE; 789 temp2 = tp = point; 790 if ((ee_chinese) && (position >= 2) && (*(point - 2) > 127)) 791 { 792 del_width = 2; 793 } 794 tp -= del_width; 795 point -= del_width; 796 position -= del_width; 797 temp_pos = position; 798 curr_line->line_length -= del_width; 799 if ((*tp < ' ') || (*tp >= 127)) /* check for TAB */ 800 scanline(tp); 801 else 802 scr_horz -= del_width; 803 scr_pos = scr_horz; 804 if (in == 8) 805 { 806 if (del_width == 1) 807 *d_char = *point; /* save deleted character */ 808 else 809 { 810 d_char[0] = *point; 811 d_char[1] = *(point + 1); 812 } 813 d_char[del_width] = '\0'; 814 } 815 while (temp_pos <= curr_line->line_length) 816 { 817 temp_pos++; 818 *tp = *temp2; 819 tp++; 820 temp2++; 821 } 822 if (scr_horz < horiz_offset) 823 { 824 horiz_offset -= 8; 825 midscreen(scr_vert, point); 826 } 827 } 828 else if (curr_line->prev_line != NULL) 829 { 830 absolute_lin--; 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 883void 884scanline(pos) /* find the proper horizontal position for the pointer */ 885unsigned 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 923int 924tabshift(temp_int) /* give the number of spaces to shift */ 925int 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 936int 937out_char(window, character, column) /* output non-printing character */ 938WINDOW *window; 939int character; 940int 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 985int 986len_char(character, column) /* return the length of the character */ 987int character; 988int 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 1008void 1009draw_line(vertical, horiz, ptr, t_pos, length) /* redraw line from current position */ 1010int vertical; /* current vertical position on screen */ 1011int horiz; /* current horizontal position on screen */ 1012unsigned char *ptr; /* pointer to line */ 1013int t_pos; /* current position (offset in bytes) from bol */ 1014int 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 1065void 1066insert_line(disp) /* insert new line */ 1067int 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 1142struct text *txtalloc() /* allocate space for line structure */ 1143{ 1144 return((struct text *) malloc(sizeof( struct text))); 1145} 1146 1147struct files *name_alloc() /* allocate space for file name list node */ 1148{ 1149 return((struct files *) malloc(sizeof( struct files))); 1150} 1151 1152unsigned char *next_word(string) /* move to next word in string */ 1153unsigned 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 1162void 1163prev_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 1183void 1184control() /* 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 1261void 1262emacs_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 1335void 1336bottom() /* 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 1351void 1352top() /* 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 1367void 1368nextline() /* 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 1386void 1387prevline() /* 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 1407void 1408left(disp) /* move left one character */ 1409int 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 1442void 1443right(disp) /* move right one character */ 1444int 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 1482void 1483find_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 1518void 1519up() /* 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 1529void 1530down() /* move down one line */ 1531{ 1532 if (curr_line->next_line != NULL) 1533 { 1534 nextline(); 1535 find_pos(); 1536 } 1537} 1538 1539void 1540function_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 1644void 1645print_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 1657void 1658command_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 1693void 1694command(cmd_str1) /* process commands from keyboard */ 1695char *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 1847int 1848scan(line, offset, column) /* determine horizontal position for get_string */ 1849char *line; 1850int offset; 1851int 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 1869char * 1870get_string(prompt, advance) /* read string from input on command line */ 1871char *prompt; /* string containing user prompt message */ 1872int 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 1950int 1951compare(string1, string2, sensitive) /* compare two strings */ 1952char *string1; 1953char *string2; 1954int 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(*strng1) != toupper(*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 1988void 1989goto_line(cmd_str) 1990char *cmd_str; 1991{ 1992 int number; 1993 int i; 1994 char *ptr; 1995 char *direction = NULL; 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 (!strcmp(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 2046void 2047midscreen(line, pnt) /* put current line in middle of screen */ 2048int line; 2049unsigned 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 2067void 2068get_options(numargs, arguments) /* get arguments from command line */ 2069int numargs; 2070char *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 fprintf(stderr, usage1); 2113 fprintf(stderr, usage2); 2114 fprintf(stderr, usage3); 2115 fprintf(stderr, usage4); 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 2159void 2160check_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 2241void 2242get_file(file_name) /* read specified file into current buffer */ 2243char *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 2309void 2310get_line(length, in_string, append) /* read string and split into lines */ 2311int length; /* length of string read by read */ 2312unsigned char *in_string; /* string read by read */ 2313int *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 2379void 2380draw_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 2400void 2401finish() /* 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 2437int 2438quit(noverify) /* exit editor */ 2439int 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(*ans) == toupper(*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 2474void 2475edit_abort(arg) 2476int arg; 2477{ 2478 wrefresh(com_win); 2479 resetty(); 2480 endwin(); 2481 putchar('\n'); 2482 exit(1); 2483} 2484 2485void 2486delete_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 2506int 2507write_file(file_name, warn_if_exists) 2508char *file_name; 2509int 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(*tmp_point) == toupper(*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 2582int 2583search(display_message) /* search for string in srch_str */ 2584int 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 2696void 2697search_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 2717void 2718del_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(FALSE); 2737 delete(FALSE); 2738 } 2739} 2740 2741void 2742undel_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 2758void 2759del_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 2812void 2813undel_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 2874void 2875del_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 2907void 2908undel_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 2935void 2936adv_word() /* advance to next word */ 2937{ 2938while ((position < curr_line->line_length) && ((*point != 32) && (*point != 9))) 2939 right(TRUE); 2940while ((position < curr_line->line_length) && ((*point == 32) || (*point == 9))) 2941 right(TRUE); 2942} 2943 2944void 2945move_rel(direction, lines) /* move relative to current line */ 2946char *direction; 2947int 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 3012void 3013eol() /* 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 3028void 3029bol() /* 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 3043void 3044adv_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 3059void 3060from_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 3073void 3074sh_command(string) /* execute shell command */ 3075char *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 printf(continue_msg); 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 3270void 3271set_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 3325void 3326resize_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 3341static char item_alpha[] = "abcdefghijklmnopqrstuvwxyz0123456789 "; 3342 3343int 3344menu_op(menu_list) 3345struct 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 (((tolower(input) >= 'a') && (tolower(input) <= 'z')) || 3441 ((input >= '0') && (input <= '9'))) 3442 { 3443 if ((tolower(input) >= 'a') && (tolower(input) <= 'z')) 3444 { 3445 temp = 1 + tolower(input) - 'a'; 3446 } 3447 else if ((input >= '0') && (input <= '9')) 3448 { 3449 temp = (2 + 'z' - 'a') + (input - '0'); 3450 } 3451 3452 if (temp <= list_size) 3453 { 3454 input = '\n'; 3455 counter = temp; 3456 } 3457 } 3458 else 3459 { 3460 switch (input) 3461 { 3462 case ' ': /* space */ 3463 case '\004': /* ^d, down */ 3464 case KEY_RIGHT: 3465 case KEY_DOWN: 3466 counter++; 3467 if (counter > list_size) 3468 counter = 1; 3469 break; 3470 case '\010': /* ^h, backspace*/ 3471 case '\025': /* ^u, up */ 3472 case 127: /* ^?, delete */ 3473 case KEY_BACKSPACE: 3474 case KEY_LEFT: 3475 case KEY_UP: 3476 counter--; 3477 if (counter == 0) 3478 counter = list_size; 3479 break; 3480 case '\033': /* escape key */ 3481 if (menu_list[0].argument != MENU_WARN) 3482 counter = 0; 3483 break; 3484 case '\014': /* ^l */ 3485 case '\022': /* ^r, redraw */ 3486 paint_menu(menu_list, max_width, max_height, 3487 list_size, top_offset, temp_win, 3488 off_start, vert_size); 3489 break; 3490 default: 3491 break; 3492 } 3493 } 3494 3495 if (((list_size - off_start) >= (vert_size - 1)) && 3496 (counter > (off_start + vert_size - 3)) && 3497 (off_start > 1)) 3498 { 3499 if (counter == list_size) 3500 off_start = (list_size - vert_size) + 2; 3501 else 3502 off_start++; 3503 3504 paint_menu(menu_list, max_width, max_height, 3505 list_size, top_offset, temp_win, off_start, 3506 vert_size); 3507 } 3508 else if ((list_size != vert_size) && 3509 (counter > (off_start + vert_size - 2))) 3510 { 3511 if (counter == list_size) 3512 off_start = 2 + (list_size - vert_size); 3513 else if (off_start == 1) 3514 off_start = 3; 3515 else 3516 off_start++; 3517 3518 paint_menu(menu_list, max_width, max_height, 3519 list_size, top_offset, temp_win, off_start, 3520 vert_size); 3521 } 3522 else if (counter < off_start) 3523 { 3524 if (counter <= 2) 3525 off_start = 1; 3526 else 3527 off_start = counter; 3528 3529 paint_menu(menu_list, max_width, max_height, 3530 list_size, top_offset, temp_win, off_start, 3531 vert_size); 3532 } 3533 } 3534 while ((input != '\r') && (input != '\n') && (counter != 0)); 3535 3536 werase(temp_win); 3537 wrefresh(temp_win); 3538 delwin(temp_win); 3539 3540 if ((menu_list[counter].procedure != NULL) || 3541 (menu_list[counter].iprocedure != NULL) || 3542 (menu_list[counter].nprocedure != NULL)) 3543 { 3544 if (menu_list[counter].argument != -1) 3545 (*menu_list[counter].iprocedure)(menu_list[counter].argument); 3546 else if (menu_list[counter].ptr_argument != NULL) 3547 (*menu_list[counter].procedure)(menu_list[counter].ptr_argument); 3548 else 3549 (*menu_list[counter].nprocedure)(); 3550 } 3551 3552 if (info_window) 3553 paint_info_win(); 3554 redraw(); 3555 3556 return(counter); 3557} 3558 3559void 3560paint_menu(menu_list, max_width, max_height, list_size, top_offset, menu_win, 3561 off_start, vert_size) 3562struct menu_entries menu_list[]; 3563int max_width, max_height, list_size, top_offset; 3564WINDOW *menu_win; 3565int off_start, vert_size; 3566{ 3567 int counter, temp_int; 3568 3569 werase(menu_win); 3570 3571 /* 3572 | output top and bottom portions of menu box only if window 3573 | large enough 3574 */ 3575 3576 if (max_height > vert_size) 3577 { 3578 wmove(menu_win, 1, 1); 3579 if (!nohighlight) 3580 wstandout(menu_win); 3581 waddch(menu_win, '+'); 3582 for (counter = 0; counter < (max_width - 4); counter++) 3583 waddch(menu_win, '-'); 3584 waddch(menu_win, '+'); 3585 3586 wmove(menu_win, (max_height - 2), 1); 3587 waddch(menu_win, '+'); 3588 for (counter = 0; counter < (max_width - 4); counter++) 3589 waddch(menu_win, '-'); 3590 waddch(menu_win, '+'); 3591 wstandend(menu_win); 3592 wmove(menu_win, 2, 3); 3593 waddstr(menu_win, menu_list[0].item_string); 3594 wmove(menu_win, (max_height - 3), 3); 3595 if (menu_list[0].argument != MENU_WARN) 3596 waddstr(menu_win, menu_cancel_msg); 3597 } 3598 if (!nohighlight) 3599 wstandout(menu_win); 3600 3601 for (counter = 0; counter < (vert_size + top_offset); counter++) 3602 { 3603 if (top_offset == 4) 3604 { 3605 temp_int = counter + 2; 3606 } 3607 else 3608 temp_int = counter; 3609 3610 wmove(menu_win, temp_int, 1); 3611 waddch(menu_win, '|'); 3612 wmove(menu_win, temp_int, (max_width - 2)); 3613 waddch(menu_win, '|'); 3614 } 3615 wstandend(menu_win); 3616 3617 if (list_size > vert_size) 3618 { 3619 if (off_start >= 3) 3620 { 3621 temp_int = 1; 3622 wmove(menu_win, top_offset, 3); 3623 waddstr(menu_win, more_above_str); 3624 } 3625 else 3626 temp_int = 0; 3627 3628 for (counter = off_start; 3629 ((temp_int + counter - off_start) < (vert_size - 1)); 3630 counter++) 3631 { 3632 wmove(menu_win, (top_offset + temp_int + 3633 (counter - off_start)), 3); 3634 if (list_size > 1) 3635 wprintw(menu_win, "%c) ", item_alpha[min((counter - 1), max_alpha_char)]); 3636 waddstr(menu_win, menu_list[counter].item_string); 3637 } 3638 3639 wmove(menu_win, (top_offset + (vert_size - 1)), 3); 3640 3641 if (counter == list_size) 3642 { 3643 if (list_size > 1) 3644 wprintw(menu_win, "%c) ", item_alpha[min((counter - 1), max_alpha_char)]); 3645 wprintw(menu_win, menu_list[counter].item_string); 3646 } 3647 else 3648 wprintw(menu_win, more_below_str); 3649 } 3650 else 3651 { 3652 for (counter = 1; counter <= list_size; counter++) 3653 { 3654 wmove(menu_win, (top_offset + counter - 1), 3); 3655 if (list_size > 1) 3656 wprintw(menu_win, "%c) ", item_alpha[min((counter - 1), max_alpha_char)]); 3657 waddstr(menu_win, menu_list[counter].item_string); 3658 } 3659 } 3660} 3661 3662void 3663help() 3664{ 3665 int counter; 3666 3667 werase(help_win); 3668 clearok(help_win, TRUE); 3669 for (counter = 0; counter < 22; counter++) 3670 { 3671 wmove(help_win, counter, 0); 3672 waddstr(help_win, (emacs_keys_mode) ? 3673 emacs_help_text[counter] : help_text[counter]); 3674 } 3675 wrefresh(help_win); 3676 werase(com_win); 3677 wmove(com_win, 0, 0); 3678 wprintw(com_win, press_any_key_msg); 3679 wrefresh(com_win); 3680 counter = wgetch(com_win); 3681 if (counter == -1) 3682 exit(0); 3683 werase(com_win); 3684 wmove(com_win, 0, 0); 3685 werase(help_win); 3686 wrefresh(help_win); 3687 wrefresh(com_win); 3688 redraw(); 3689} 3690 3691void 3692paint_info_win() 3693{ 3694 int counter; 3695 3696 if (!info_window) 3697 return; 3698 3699 werase(info_win); 3700 for (counter = 0; counter < 5; counter++) 3701 { 3702 wmove(info_win, counter, 0); 3703 wclrtoeol(info_win); 3704 if (info_type == CONTROL_KEYS) 3705 waddstr(info_win, (emacs_keys_mode) ? 3706 emacs_control_keys[counter] : control_keys[counter]); 3707 else if (info_type == COMMANDS) 3708 waddstr(info_win, command_strings[counter]); 3709 } 3710 wmove(info_win, 5, 0); 3711 if (!nohighlight) 3712 wstandout(info_win); 3713 waddstr(info_win, separator); 3714 wstandend(info_win); 3715 wrefresh(info_win); 3716} 3717 3718void 3719no_info_window() 3720{ 3721 if (!info_window) 3722 return; 3723 delwin(info_win); 3724 delwin(text_win); 3725 info_window = FALSE; 3726 last_line = LINES - 2; 3727 text_win = newwin((LINES - 1), COLS, 0, 0); 3728 keypad(text_win, TRUE); 3729 idlok(text_win, TRUE); 3730 clearok(text_win, TRUE); 3731 midscreen(scr_vert, point); 3732 wrefresh(text_win); 3733 clear_com_win = TRUE; 3734} 3735 3736void 3737create_info_window() 3738{ 3739 if (info_window) 3740 return; 3741 last_line = LINES - 8; 3742 delwin(text_win); 3743 text_win = newwin((LINES - 7), COLS, 6, 0); 3744 keypad(text_win, TRUE); 3745 idlok(text_win, TRUE); 3746 werase(text_win); 3747 info_window = TRUE; 3748 info_win = newwin(6, COLS, 0, 0); 3749 werase(info_win); 3750 info_type = CONTROL_KEYS; 3751 midscreen(min(scr_vert, last_line), point); 3752 clearok(info_win, TRUE); 3753 paint_info_win(); 3754 wrefresh(text_win); 3755 clear_com_win = TRUE; 3756} 3757 3758int 3759file_op(arg) 3760int arg; 3761{ 3762 char *string; 3763 int flag; 3764 3765 if (restrict_mode()) 3766 { 3767 return(0); 3768 } 3769 3770 if (arg == READ_FILE) 3771 { 3772 string = get_string(file_read_prompt_str, TRUE); 3773 recv_file = TRUE; 3774 tmp_file = resolve_name(string); 3775 check_fp(); 3776 if (tmp_file != string) 3777 free(tmp_file); 3778 free(string); 3779 } 3780 else if (arg == WRITE_FILE) 3781 { 3782 string = get_string(file_write_prompt_str, TRUE); 3783 tmp_file = resolve_name(string); 3784 write_file(tmp_file, 1); 3785 if (tmp_file != string) 3786 free(tmp_file); 3787 free(string); 3788 } 3789 else if (arg == SAVE_FILE) 3790 { 3791 /* 3792 | changes made here should be reflected in finish() 3793 */ 3794 3795 if (in_file_name) 3796 flag = TRUE; 3797 else 3798 flag = FALSE; 3799 3800 string = in_file_name; 3801 if ((string == NULL) || (*string == '\0')) 3802 string = get_string(save_file_name_prompt, TRUE); 3803 if ((string == NULL) || (*string == '\0')) 3804 { 3805 wmove(com_win, 0, 0); 3806 wprintw(com_win, file_not_saved_msg); 3807 wclrtoeol(com_win); 3808 wrefresh(com_win); 3809 clear_com_win = TRUE; 3810 return(0); 3811 } 3812 if (!flag) 3813 { 3814 tmp_file = resolve_name(string); 3815 if (tmp_file != string) 3816 { 3817 free(string); 3818 string = tmp_file; 3819 } 3820 } 3821 if (write_file(string, 1)) 3822 { 3823 in_file_name = string; 3824 text_changes = FALSE; 3825 } 3826 else if (!flag) 3827 free(string); 3828 } 3829 return(0); 3830} 3831 3832void 3833shell_op() 3834{ 3835 char *string; 3836 3837 if (((string = get_string(shell_prompt, TRUE)) != NULL) && 3838 (*string != '\0')) 3839 { 3840 sh_command(string); 3841 free(string); 3842 } 3843} 3844 3845void 3846leave_op() 3847{ 3848 if (text_changes) 3849 { 3850 menu_op(leave_menu); 3851 } 3852 else 3853 quit(TRUE); 3854} 3855 3856void 3857redraw() 3858{ 3859 if (info_window) 3860 { 3861 clearok(info_win, TRUE); 3862 paint_info_win(); 3863 } 3864 else 3865 clearok(text_win, TRUE); 3866 midscreen(scr_vert, point); 3867} 3868 3869/* 3870 | The following routines will "format" a paragraph (as defined by a 3871 | block of text with blank lines before and after the block). 3872 */ 3873 3874int 3875Blank_Line(test_line) /* test if line has any non-space characters */ 3876struct text *test_line; 3877{ 3878 unsigned char *line; 3879 int length; 3880 3881 if (test_line == NULL) 3882 return(TRUE); 3883 3884 length = 1; 3885 line = test_line->line; 3886 3887 /* 3888 | To handle troff/nroff documents, consider a line with a 3889 | period ('.') in the first column to be blank. To handle mail 3890 | messages with included text, consider a line with a '>' blank. 3891 */ 3892 3893 if ((*line == '.') || (*line == '>')) 3894 return(TRUE); 3895 3896 while (((*line == ' ') || (*line == '\t')) && (length < test_line->line_length)) 3897 { 3898 length++; 3899 line++; 3900 } 3901 if (length != test_line->line_length) 3902 return(FALSE); 3903 else 3904 return(TRUE); 3905} 3906 3907void 3908Format() /* format the paragraph according to set margins */ 3909{ 3910 int string_count; 3911 int offset; 3912 int temp_case; 3913 int status; 3914 int tmp_af; 3915 int counter; 3916 unsigned char *line; 3917 unsigned char *tmp_srchstr; 3918 unsigned char *temp1, *temp2; 3919 unsigned char *temp_dword; 3920 unsigned char temp_d_char[3]; 3921 3922 temp_d_char[0] = d_char[0]; 3923 temp_d_char[1] = d_char[1]; 3924 temp_d_char[2] = d_char[2]; 3925 3926/* 3927 | if observ_margins is not set, or the current line is blank, 3928 | do not format the current paragraph 3929 */ 3930 3931 if ((!observ_margins) || (Blank_Line(curr_line))) 3932 return; 3933 3934/* 3935 | save the currently set flags, and clear them 3936 */ 3937 3938 wmove(com_win, 0, 0); 3939 wclrtoeol(com_win); 3940 wprintw(com_win, formatting_msg); 3941 wrefresh(com_win); 3942 3943/* 3944 | get current position in paragraph, so after formatting, the cursor 3945 | will be in the same relative position 3946 */ 3947 3948 tmp_af = auto_format; 3949 auto_format = FALSE; 3950 offset = position; 3951 if (position != 1) 3952 prev_word(); 3953 temp_dword = d_word; 3954 d_word = NULL; 3955 temp_case = case_sen; 3956 case_sen = TRUE; 3957 tmp_srchstr = srch_str; 3958 temp2 = srch_str = (unsigned char *) malloc(1 + curr_line->line_length - position); 3959 if ((*point == ' ') || (*point == '\t')) 3960 adv_word(); 3961 offset -= position; 3962 counter = position; 3963 line = temp1 = point; 3964 while ((*temp1 != '\0') && (*temp1 != ' ') && (*temp1 != '\t') && (counter < curr_line->line_length)) 3965 { 3966 *temp2 = *temp1; 3967 temp2++; 3968 temp1++; 3969 counter++; 3970 } 3971 *temp2 = '\0'; 3972 if (position != 1) 3973 bol(); 3974 while (!Blank_Line(curr_line->prev_line)) 3975 bol(); 3976 string_count = 0; 3977 status = TRUE; 3978 while ((line != point) && (status)) 3979 { 3980 status = search(FALSE); 3981 string_count++; 3982 } 3983 3984 wmove(com_win, 0, 0); 3985 wclrtoeol(com_win); 3986 wprintw(com_win, formatting_msg); 3987 wrefresh(com_win); 3988 3989/* 3990 | now get back to the start of the paragraph to start formatting 3991 */ 3992 3993 if (position != 1) 3994 bol(); 3995 while (!Blank_Line(curr_line->prev_line)) 3996 bol(); 3997 3998 observ_margins = FALSE; 3999 4000/* 4001 | Start going through lines, putting spaces at end of lines if they do 4002 | not already exist. Append lines together to get one long line, and 4003 | eliminate spacing at begin of lines. 4004 */ 4005 4006 while (!Blank_Line(curr_line->next_line)) 4007 { 4008 eol(); 4009 left(TRUE); 4010 if (*point != ' ') 4011 { 4012 right(TRUE); 4013 insert(' '); 4014 } 4015 else 4016 right(TRUE); 4017 del_char(); 4018 if ((*point == ' ') || (*point == '\t')) 4019 del_word(); 4020 } 4021 4022/* 4023 | Now there is one long line. Eliminate extra spaces within the line 4024 | after the first word (so as not to blow away any indenting the user 4025 | may have put in). 4026 */ 4027 4028 bol(); 4029 adv_word(); 4030 while (position < curr_line->line_length) 4031 { 4032 if ((*point == ' ') && (*(point + 1) == ' ')) 4033 del_char(); 4034 else 4035 right(TRUE); 4036 } 4037 4038/* 4039 | Now make sure there are two spaces after a '.'. 4040 */ 4041 4042 bol(); 4043 while (position < curr_line->line_length) 4044 { 4045 if ((*point == '.') && (*(point + 1) == ' ')) 4046 { 4047 right(TRUE); 4048 insert(' '); 4049 insert(' '); 4050 while (*point == ' ') 4051 del_char(); 4052 } 4053 right(TRUE); 4054 } 4055 4056 observ_margins = TRUE; 4057 bol(); 4058 4059 wmove(com_win, 0, 0); 4060 wclrtoeol(com_win); 4061 wprintw(com_win, formatting_msg); 4062 wrefresh(com_win); 4063 4064/* 4065 | create lines between margins 4066 */ 4067 4068 while (position < curr_line->line_length) 4069 { 4070 while ((scr_pos < right_margin) && (position < curr_line->line_length)) 4071 right(TRUE); 4072 if (position < curr_line->line_length) 4073 { 4074 prev_word(); 4075 if (position == 1) 4076 adv_word(); 4077 insert_line(TRUE); 4078 } 4079 } 4080 4081/* 4082 | go back to begin of paragraph, put cursor back to original position 4083 */ 4084 4085 bol(); 4086 while (!Blank_Line(curr_line->prev_line)) 4087 bol(); 4088 4089/* 4090 | find word cursor was in 4091 */ 4092 4093 while ((status) && (string_count > 0)) 4094 { 4095 search(FALSE); 4096 string_count--; 4097 } 4098 4099/* 4100 | offset the cursor to where it was before from the start of the word 4101 */ 4102 4103 while (offset > 0) 4104 { 4105 offset--; 4106 right(TRUE); 4107 } 4108 4109/* 4110 | reset flags and strings to what they were before formatting 4111 */ 4112 4113 if (d_word != NULL) 4114 free(d_word); 4115 d_word = temp_dword; 4116 case_sen = temp_case; 4117 free(srch_str); 4118 srch_str = tmp_srchstr; 4119 d_char[0] = temp_d_char[0]; 4120 d_char[1] = temp_d_char[1]; 4121 d_char[2] = temp_d_char[2]; 4122 auto_format = tmp_af; 4123 4124 midscreen(scr_vert, point); 4125 werase(com_win); 4126 wrefresh(com_win); 4127} 4128 4129unsigned char *init_name[3] = { 4130 "/usr/share/misc/init.ee", 4131 NULL, 4132 ".init.ee" 4133 }; 4134 4135void 4136ee_init() /* check for init file and read it if it exists */ 4137{ 4138 FILE *init_file; 4139 unsigned char *string; 4140 unsigned char *str1; 4141 unsigned char *str2; 4142 char *home; 4143 int counter; 4144 int temp_int; 4145 4146 string = getenv("HOME"); 4147 if (string == NULL) 4148 string = "/tmp"; 4149 str1 = home = malloc(strlen(string)+10); 4150 strcpy(home, string); 4151 strcat(home, "/.init.ee"); 4152 init_name[1] = home; 4153 string = malloc(512); 4154 4155 for (counter = 0; counter < 3; counter++) 4156 { 4157 if (!(access(init_name[counter], 4))) 4158 { 4159 init_file = fopen(init_name[counter], "r"); 4160 while ((str2 = fgets(string, 512, init_file)) != NULL) 4161 { 4162 str1 = str2 = string; 4163 while (*str2 != '\n') 4164 str2++; 4165 *str2 = '\0'; 4166 4167 if (unique_test(string, init_strings) != 1) 4168 continue; 4169 4170 if (compare(str1, CASE, FALSE)) 4171 case_sen = TRUE; 4172 else if (compare(str1, NOCASE, FALSE)) 4173 case_sen = FALSE; 4174 else if (compare(str1, EXPAND, FALSE)) 4175 expand_tabs = TRUE; 4176 else if (compare(str1, NOEXPAND, FALSE)) 4177 expand_tabs = FALSE; 4178 else if (compare(str1, INFO, FALSE)) 4179 info_window = TRUE; 4180 else if (compare(str1, NOINFO, FALSE)) 4181 info_window = FALSE; 4182 else if (compare(str1, MARGINS, FALSE)) 4183 observ_margins = TRUE; 4184 else if (compare(str1, NOMARGINS, FALSE)) 4185 observ_margins = FALSE; 4186 else if (compare(str1, AUTOFORMAT, FALSE)) 4187 { 4188 auto_format = TRUE; 4189 observ_margins = TRUE; 4190 } 4191 else if (compare(str1, NOAUTOFORMAT, FALSE)) 4192 auto_format = FALSE; 4193 else if (compare(str1, Echo, FALSE)) 4194 { 4195 str1 = next_word(str1); 4196 if (*str1 != '\0') 4197 echo_string(str1); 4198 } 4199 else if (compare(str1, PRINTCOMMAND, FALSE)) 4200 { 4201 str1 = next_word(str1); 4202 print_command = malloc(strlen(str1)+1); 4203 strcpy(print_command, str1); 4204 } 4205 else if (compare(str1, RIGHTMARGIN, FALSE)) 4206 { 4207 str1 = next_word(str1); 4208 if ((*str1 >= '0') && (*str1 <= '9')) 4209 { 4210 temp_int = atoi(str1); 4211 if (temp_int > 0) 4212 right_margin = temp_int; 4213 } 4214 } 4215 else if (compare(str1, HIGHLIGHT, FALSE)) 4216 nohighlight = FALSE; 4217 else if (compare(str1, NOHIGHLIGHT, FALSE)) 4218 nohighlight = TRUE; 4219 else if (compare(str1, EIGHTBIT, FALSE)) 4220 eightbit = TRUE; 4221 else if (compare(str1, NOEIGHTBIT, FALSE)) 4222 { 4223 eightbit = FALSE; 4224 ee_chinese = FALSE; 4225 } 4226 else if (compare(str1, EMACS_string, FALSE)) 4227 emacs_keys_mode = TRUE; 4228 else if (compare(str1, NOEMACS_string, FALSE)) 4229 emacs_keys_mode = FALSE; 4230 else if (compare(str1, chinese_cmd, FALSE)) 4231 { 4232 ee_chinese = TRUE; 4233 eightbit = TRUE; 4234 } 4235 else if (compare(str1, nochinese_cmd, FALSE)) 4236 ee_chinese = FALSE; 4237 } 4238 fclose(init_file); 4239 } 4240 } 4241 free(string); 4242 free(home); 4243 4244 string = getenv("LANG"); 4245 if (string != NULL) 4246 { 4247 if (strcmp(string, "zh_TW.big5") == 0) 4248 { 4249 ee_chinese = TRUE; 4250 eightbit = TRUE; 4251 } 4252 } 4253} 4254 4255/* 4256 | Save current configuration to .init.ee file in the current directory. 4257 */ 4258 4259void 4260dump_ee_conf() 4261{ 4262 FILE *init_file; 4263 FILE *old_init_file = NULL; 4264 char *file_name = ".init.ee"; 4265 char *home_dir = "~/.init.ee"; 4266 char buffer[512]; 4267 struct stat buf; 4268 char *string; 4269 int length; 4270 int option = 0; 4271 4272 if (restrict_mode()) 4273 { 4274 return; 4275 } 4276 4277 option = menu_op(config_dump_menu); 4278 4279 werase(com_win); 4280 wmove(com_win, 0, 0); 4281 4282 if (option == 0) 4283 { 4284 wprintw(com_win, conf_not_saved_msg); 4285 wrefresh(com_win); 4286 return; 4287 } 4288 else if (option == 2) 4289 file_name = resolve_name(home_dir); 4290 4291 /* 4292 | If a .init.ee file exists, move it to .init.ee.old. 4293 */ 4294 4295 if (stat(file_name, &buf) != -1) 4296 { 4297 sprintf(buffer, "%s.old", file_name); 4298 unlink(buffer); 4299 link(file_name, buffer); 4300 unlink(file_name); 4301 old_init_file = fopen(buffer, "r"); 4302 } 4303 4304 init_file = fopen(file_name, "w"); 4305 if (init_file == NULL) 4306 { 4307 wprintw(com_win, conf_dump_err_msg); 4308 wrefresh(com_win); 4309 return; 4310 } 4311 4312 if (old_init_file != NULL) 4313 { 4314 /* 4315 | Copy non-configuration info into new .init.ee file. 4316 */ 4317 while ((string = fgets(buffer, 512, old_init_file)) != NULL) 4318 { 4319 length = strlen(string); 4320 string[length - 1] = '\0'; 4321 4322 if (unique_test(string, init_strings) == 1) 4323 { 4324 if (compare(string, Echo, FALSE)) 4325 { 4326 fprintf(init_file, "%s\n", string); 4327 } 4328 } 4329 else 4330 fprintf(init_file, "%s\n", string); 4331 } 4332 4333 fclose(old_init_file); 4334 } 4335 4336 fprintf(init_file, "%s\n", case_sen ? CASE : NOCASE); 4337 fprintf(init_file, "%s\n", expand_tabs ? EXPAND : NOEXPAND); 4338 fprintf(init_file, "%s\n", info_window ? INFO : NOINFO ); 4339 fprintf(init_file, "%s\n", observ_margins ? MARGINS : NOMARGINS ); 4340 fprintf(init_file, "%s\n", auto_format ? AUTOFORMAT : NOAUTOFORMAT ); 4341 fprintf(init_file, "%s %s\n", PRINTCOMMAND, print_command); 4342 fprintf(init_file, "%s %d\n", RIGHTMARGIN, right_margin); 4343 fprintf(init_file, "%s\n", nohighlight ? NOHIGHLIGHT : HIGHLIGHT ); 4344 fprintf(init_file, "%s\n", eightbit ? EIGHTBIT : NOEIGHTBIT ); 4345 fprintf(init_file, "%s\n", emacs_keys_mode ? EMACS_string : NOEMACS_string ); 4346 fprintf(init_file, "%s\n", ee_chinese ? chinese_cmd : nochinese_cmd ); 4347 4348 fclose(init_file); 4349 4350 wprintw(com_win, conf_dump_success_msg, file_name); 4351 wrefresh(com_win); 4352 4353 if ((option == 2) && (file_name != home_dir)) 4354 { 4355 free(file_name); 4356 } 4357} 4358 4359void 4360echo_string(string) /* echo the given string */ 4361char *string; 4362{ 4363 char *temp; 4364 int Counter; 4365 4366 temp = string; 4367 while (*temp != '\0') 4368 { 4369 if (*temp == '\\') 4370 { 4371 temp++; 4372 if (*temp == 'n') 4373 putchar('\n'); 4374 else if (*temp == 't') 4375 putchar('\t'); 4376 else if (*temp == 'b') 4377 putchar('\b'); 4378 else if (*temp == 'r') 4379 putchar('\r'); 4380 else if (*temp == 'f') 4381 putchar('\f'); 4382 else if ((*temp == 'e') || (*temp == 'E')) 4383 putchar('\033'); /* escape */ 4384 else if (*temp == '\\') 4385 putchar('\\'); 4386 else if (*temp == '\'') 4387 putchar('\''); 4388 else if ((*temp >= '0') && (*temp <= '9')) 4389 { 4390 Counter = 0; 4391 while ((*temp >= '0') && (*temp <= '9')) 4392 { 4393 Counter = (8 * Counter) + (*temp - '0'); 4394 temp++; 4395 } 4396 putchar(Counter); 4397 temp--; 4398 } 4399 temp++; 4400 } 4401 else 4402 { 4403 putchar(*temp); 4404 temp++; 4405 } 4406 } 4407 4408 fflush(stdout); 4409} 4410 4411void 4412spell_op() /* check spelling of words in the editor */ 4413{ 4414 if (restrict_mode()) 4415 { 4416 return; 4417 } 4418 top(); /* go to top of file */ 4419 insert_line(FALSE); /* create two blank lines */ 4420 insert_line(FALSE); 4421 top(); 4422 command(shell_echo_msg); 4423 adv_line(); 4424 wmove(com_win, 0, 0); 4425 wprintw(com_win, spell_in_prog_msg); 4426 wrefresh(com_win); 4427 command("<>!spell"); /* send contents of buffer to command 'spell' 4428 and read the results back into the editor */ 4429} 4430 4431void 4432ispell_op() 4433{ 4434 char template[128], *name; 4435 char string[256]; 4436 int fd; 4437 4438 if (restrict_mode()) 4439 { 4440 return; 4441 } 4442 (void)sprintf(template, "/tmp/ee.XXXXXXXX"); 4443 fd = mkstemp(template); 4444 if (fd < 0) { 4445 wmove(com_win, 0, 0); 4446 wprintw(com_win, create_file_fail_msg, name); 4447 wrefresh(com_win); 4448 return; 4449 } 4450 close(fd); 4451 if (write_file(name, 0)) 4452 { 4453 sprintf(string, "ispell %s", name); 4454 sh_command(string); 4455 delete_text(); 4456 tmp_file = name; 4457 recv_file = TRUE; 4458 check_fp(); 4459 unlink(name); 4460 } 4461} 4462 4463int 4464first_word_len(test_line) 4465struct text *test_line; 4466{ 4467 int counter; 4468 unsigned char *pnt; 4469 4470 if (test_line == NULL) 4471 return(0); 4472 4473 pnt = test_line->line; 4474 if ((pnt == NULL) || (*pnt == '\0') || 4475 (*pnt == '.') || (*pnt == '>')) 4476 return(0); 4477 4478 if ((*pnt == ' ') || (*pnt == '\t')) 4479 { 4480 pnt = next_word(pnt); 4481 } 4482 4483 if (*pnt == '\0') 4484 return(0); 4485 4486 counter = 0; 4487 while ((*pnt != '\0') && ((*pnt != ' ') && (*pnt != '\t'))) 4488 { 4489 pnt++; 4490 counter++; 4491 } 4492 while ((*pnt != '\0') && ((*pnt == ' ') || (*pnt == '\t'))) 4493 { 4494 pnt++; 4495 counter++; 4496 } 4497 return(counter); 4498} 4499 4500void 4501Auto_Format() /* format the paragraph according to set margins */ 4502{ 4503 int string_count; 4504 int offset; 4505 int temp_case; 4506 int word_len; 4507 int temp_dwl; 4508 int tmp_d_line_length; 4509 int leave_loop = FALSE; 4510 int status; 4511 int counter; 4512 char not_blank; 4513 unsigned char *line; 4514 unsigned char *tmp_srchstr; 4515 unsigned char *temp1, *temp2; 4516 unsigned char *temp_dword; 4517 unsigned char temp_d_char[3]; 4518 unsigned char *tmp_d_line; 4519 4520 4521 temp_d_char[0] = d_char[0]; 4522 temp_d_char[1] = d_char[1]; 4523 temp_d_char[2] = d_char[2]; 4524 4525/* 4526 | if observ_margins is not set, or the current line is blank, 4527 | do not format the current paragraph 4528 */ 4529 4530 if ((!observ_margins) || (Blank_Line(curr_line))) 4531 return; 4532 4533/* 4534 | get current position in paragraph, so after formatting, the cursor 4535 | will be in the same relative position 4536 */ 4537 4538 tmp_d_line = d_line; 4539 tmp_d_line_length = dlt_line->line_length; 4540 d_line = NULL; 4541 auto_format = FALSE; 4542 offset = position; 4543 if ((position != 1) && ((*point == ' ') || (*point == '\t') || (position == curr_line->line_length) || (*point == '\0'))) 4544 prev_word(); 4545 temp_dword = d_word; 4546 temp_dwl = d_wrd_len; 4547 d_wrd_len = 0; 4548 d_word = NULL; 4549 temp_case = case_sen; 4550 case_sen = TRUE; 4551 tmp_srchstr = srch_str; 4552 temp2 = srch_str = (unsigned char *) malloc(1 + curr_line->line_length - position); 4553 if ((*point == ' ') || (*point == '\t')) 4554 adv_word(); 4555 offset -= position; 4556 counter = position; 4557 line = temp1 = point; 4558 while ((*temp1 != '\0') && (*temp1 != ' ') && (*temp1 != '\t') && (counter < curr_line->line_length)) 4559 { 4560 *temp2 = *temp1; 4561 temp2++; 4562 temp1++; 4563 counter++; 4564 } 4565 *temp2 = '\0'; 4566 if (position != 1) 4567 bol(); 4568 while (!Blank_Line(curr_line->prev_line)) 4569 bol(); 4570 string_count = 0; 4571 status = TRUE; 4572 while ((line != point) && (status)) 4573 { 4574 status = search(FALSE); 4575 string_count++; 4576 } 4577 4578/* 4579 | now get back to the start of the paragraph to start checking 4580 */ 4581 4582 if (position != 1) 4583 bol(); 4584 while (!Blank_Line(curr_line->prev_line)) 4585 bol(); 4586 4587/* 4588 | Start going through lines, putting spaces at end of lines if they do 4589 | not already exist. Check line length, and move words to the next line 4590 | if they cross the margin. Then get words from the next line if they 4591 | will fit in before the margin. 4592 */ 4593 4594 counter = 0; 4595 4596 while (!leave_loop) 4597 { 4598 if (position != curr_line->line_length) 4599 eol(); 4600 left(TRUE); 4601 if (*point != ' ') 4602 { 4603 right(TRUE); 4604 insert(' '); 4605 } 4606 else 4607 right(TRUE); 4608 4609 not_blank = FALSE; 4610 4611 /* 4612 | fill line if first word on next line will fit 4613 | in the line without crossing the margin 4614 */ 4615 4616 while ((curr_line->next_line != NULL) && 4617 ((word_len = first_word_len(curr_line->next_line)) > 0) 4618 && ((scr_pos + word_len) < right_margin)) 4619 { 4620 adv_line(); 4621 if ((*point == ' ') || (*point == '\t')) 4622 adv_word(); 4623 del_word(); 4624 if (position != 1) 4625 bol(); 4626 4627 /* 4628 | We know this line was not blank before, so 4629 | make sure that it doesn't have one of the 4630 | leading characters that indicate the line 4631 | should not be modified. 4632 | 4633 | We also know that this character should not 4634 | be left as the first character of this line. 4635 */ 4636 4637 if ((Blank_Line(curr_line)) && 4638 (curr_line->line[0] != '.') && 4639 (curr_line->line[0] != '>')) 4640 { 4641 del_line(); 4642 not_blank = FALSE; 4643 } 4644 else 4645 not_blank = TRUE; 4646 4647 /* 4648 | go to end of previous line 4649 */ 4650 left(TRUE); 4651 undel_word(); 4652 eol(); 4653 /* 4654 | make sure there's a space at the end of the line 4655 */ 4656 left(TRUE); 4657 if (*point != ' ') 4658 { 4659 right(TRUE); 4660 insert(' '); 4661 } 4662 else 4663 right(TRUE); 4664 } 4665 4666 /* 4667 | make sure line does not cross right margin 4668 */ 4669 4670 while (right_margin <= scr_pos) 4671 { 4672 prev_word(); 4673 if (position != 1) 4674 { 4675 del_word(); 4676 if (Blank_Line(curr_line->next_line)) 4677 insert_line(TRUE); 4678 else 4679 adv_line(); 4680 if ((*point == ' ') || (*point == '\t')) 4681 adv_word(); 4682 undel_word(); 4683 not_blank = TRUE; 4684 if (position != 1) 4685 bol(); 4686 left(TRUE); 4687 } 4688 } 4689 4690 if ((!Blank_Line(curr_line->next_line)) || (not_blank)) 4691 { 4692 adv_line(); 4693 counter++; 4694 } 4695 else 4696 leave_loop = TRUE; 4697 } 4698 4699/* 4700 | go back to begin of paragraph, put cursor back to original position 4701 */ 4702 4703 if (position != 1) 4704 bol(); 4705 while ((counter-- > 0) || (!Blank_Line(curr_line->prev_line))) 4706 bol(); 4707 4708/* 4709 | find word cursor was in 4710 */ 4711 4712 status = TRUE; 4713 while ((status) && (string_count > 0)) 4714 { 4715 status = search(FALSE); 4716 string_count--; 4717 } 4718 4719/* 4720 | offset the cursor to where it was before from the start of the word 4721 */ 4722 4723 while (offset > 0) 4724 { 4725 offset--; 4726 right(TRUE); 4727 } 4728 4729 if ((string_count > 0) && (offset < 0)) 4730 { 4731 while (offset < 0) 4732 { 4733 offset++; 4734 left(TRUE); 4735 } 4736 } 4737 4738/* 4739 | reset flags and strings to what they were before formatting 4740 */ 4741 4742 if (d_word != NULL) 4743 free(d_word); 4744 d_word = temp_dword; 4745 d_wrd_len = temp_dwl; 4746 case_sen = temp_case; 4747 free(srch_str); 4748 srch_str = tmp_srchstr; 4749 d_char[0] = temp_d_char[0]; 4750 d_char[1] = temp_d_char[1]; 4751 d_char[2] = temp_d_char[2]; 4752 auto_format = TRUE; 4753 dlt_line->line_length = tmp_d_line_length; 4754 d_line = tmp_d_line; 4755 4756 formatted = TRUE; 4757 midscreen(scr_vert, point); 4758} 4759 4760void 4761modes_op() 4762{ 4763 int ret_value; 4764 int counter; 4765 char *string; 4766 4767 do 4768 { 4769 sprintf(modes_menu[1].item_string, "%s %s", mode_strings[1], 4770 (expand_tabs ? ON : OFF)); 4771 sprintf(modes_menu[2].item_string, "%s %s", mode_strings[2], 4772 (case_sen ? ON : OFF)); 4773 sprintf(modes_menu[3].item_string, "%s %s", mode_strings[3], 4774 (observ_margins ? ON : OFF)); 4775 sprintf(modes_menu[4].item_string, "%s %s", mode_strings[4], 4776 (auto_format ? ON : OFF)); 4777 sprintf(modes_menu[5].item_string, "%s %s", mode_strings[5], 4778 (eightbit ? ON : OFF)); 4779 sprintf(modes_menu[6].item_string, "%s %s", mode_strings[6], 4780 (info_window ? ON : OFF)); 4781 sprintf(modes_menu[7].item_string, "%s %s", mode_strings[7], 4782 (emacs_keys_mode ? ON : OFF)); 4783 sprintf(modes_menu[8].item_string, "%s %d", mode_strings[8], 4784 right_margin); 4785 sprintf(modes_menu[9].item_string, "%s %s", mode_strings[9], 4786 (ee_chinese ? ON : OFF)); 4787 4788 ret_value = menu_op(modes_menu); 4789 4790 switch (ret_value) 4791 { 4792 case 1: 4793 expand_tabs = !expand_tabs; 4794 break; 4795 case 2: 4796 case_sen = !case_sen; 4797 break; 4798 case 3: 4799 observ_margins = !observ_margins; 4800 break; 4801 case 4: 4802 auto_format = !auto_format; 4803 if (auto_format) 4804 observ_margins = TRUE; 4805 break; 4806 case 5: 4807 eightbit = !eightbit; 4808 if (!eightbit) 4809 ee_chinese = FALSE; 4810#ifdef NCURSE 4811 if (ee_chinese) 4812 nc_setattrib(A_NC_BIG5); 4813 else 4814 nc_clearattrib(A_NC_BIG5); 4815#endif /* NCURSE */ 4816 4817 redraw(); 4818 wnoutrefresh(text_win); 4819 break; 4820 case 6: 4821 if (info_window) 4822 no_info_window(); 4823 else 4824 create_info_window(); 4825 break; 4826 case 7: 4827 emacs_keys_mode = !emacs_keys_mode; 4828 if (info_window) 4829 paint_info_win(); 4830 break; 4831 case 8: 4832 string = get_string(margin_prompt, TRUE); 4833 if (string != NULL) 4834 { 4835 counter = atoi(string); 4836 if (counter > 0) 4837 right_margin = counter; 4838 free(string); 4839 } 4840 break; 4841 case 9: 4842 ee_chinese = !ee_chinese; 4843 if (ee_chinese != FALSE) 4844 eightbit = TRUE; 4845#ifdef NCURSE 4846 if (ee_chinese) 4847 nc_setattrib(A_NC_BIG5); 4848 else 4849 nc_clearattrib(A_NC_BIG5); 4850#endif /* NCURSE */ 4851 redraw(); 4852 break; 4853 default: 4854 break; 4855 } 4856 } 4857 while (ret_value != 0); 4858} 4859 4860char * 4861is_in_string(string, substring) /* a strchr() look-alike for systems without 4862 strchr() */ 4863char * string, *substring; 4864{ 4865 char *full, *sub; 4866 4867 for (sub = substring; (sub != NULL) && (*sub != '\0'); sub++) 4868 { 4869 for (full = string; (full != NULL) && (*full != '\0'); 4870 full++) 4871 { 4872 if (*sub == *full) 4873 return(full); 4874 } 4875 } 4876 return(NULL); 4877} 4878 4879/* 4880 | handle names of the form "~/file", "~user/file", 4881 | "$HOME/foo", "~/$FOO", etc. 4882 */ 4883 4884char * 4885resolve_name(name) 4886char *name; 4887{ 4888 char long_buffer[1024]; 4889 char short_buffer[128]; 4890 char *buffer; 4891 char *slash; 4892 char *tmp; 4893 char *start_of_var; 4894 int offset; 4895 int index; 4896 int counter; 4897 struct passwd *user; 4898 4899 if (name[0] == '~') 4900 { 4901 if (name[1] == '/') 4902 { 4903 index = getuid(); 4904 user = (struct passwd *) getpwuid(index); 4905 slash = name + 1; 4906 } 4907 else 4908 { 4909 slash = strchr(name, '/'); 4910 if (slash == NULL) 4911 return(name); 4912 *slash = '\0'; 4913 user = (struct passwd *) getpwnam((name + 1)); 4914 *slash = '/'; 4915 } 4916 if (user == NULL) 4917 { 4918 return(name); 4919 } 4920 buffer = malloc(strlen(user->pw_dir) + strlen(slash) + 1); 4921 strcpy(buffer, user->pw_dir); 4922 strcat(buffer, slash); 4923 } 4924 else 4925 buffer = name; 4926 4927 if (is_in_string(buffer, "$")) 4928 { 4929 tmp = buffer; 4930 index = 0; 4931 4932 while ((*tmp != '\0') && (index < 1024)) 4933 { 4934 4935 while ((*tmp != '\0') && (*tmp != '$') && 4936 (index < 1024)) 4937 { 4938 long_buffer[index] = *tmp; 4939 tmp++; 4940 index++; 4941 } 4942 4943 if ((*tmp == '$') && (index < 1024)) 4944 { 4945 counter = 0; 4946 start_of_var = tmp; 4947 tmp++; 4948 if (*tmp == '{') /* } */ /* bracketed variable name */ 4949 { 4950 tmp++; /* { */ 4951 while ((*tmp != '\0') && 4952 (*tmp != '}') && 4953 (counter < 128)) 4954 { 4955 short_buffer[counter] = *tmp; 4956 counter++; 4957 tmp++; 4958 } /* { */ 4959 if (*tmp == '}') 4960 tmp++; 4961 } 4962 else 4963 { 4964 while ((*tmp != '\0') && 4965 (*tmp != '/') && 4966 (*tmp != '$') && 4967 (counter < 128)) 4968 { 4969 short_buffer[counter] = *tmp; 4970 counter++; 4971 tmp++; 4972 } 4973 } 4974 short_buffer[counter] = '\0'; 4975 if ((slash = getenv(short_buffer)) != NULL) 4976 { 4977 offset = strlen(slash); 4978 if ((offset + index) < 1024) 4979 strcpy(&long_buffer[index], slash); 4980 index += offset; 4981 } 4982 else 4983 { 4984 while ((start_of_var != tmp) && (index < 1024)) 4985 { 4986 long_buffer[index] = *start_of_var; 4987 start_of_var++; 4988 index++; 4989 } 4990 } 4991 } 4992 } 4993 4994 if (index == 1024) 4995 return(buffer); 4996 else 4997 long_buffer[index] = '\0'; 4998 4999 if (name != buffer) 5000 free(buffer); 5001 buffer = malloc(index + 1); 5002 strcpy(buffer, long_buffer); 5003 } 5004 5005 return(buffer); 5006} 5007 5008int 5009restrict_mode() 5010{ 5011 if (!restricted) 5012 return(FALSE); 5013 5014 wmove(com_win, 0, 0); 5015 wprintw(com_win, restricted_msg); 5016 wclrtoeol(com_win); 5017 wrefresh(com_win); 5018 clear_com_win = TRUE; 5019 return(TRUE); 5020} 5021 5022/* 5023 | The following routine tests the input string against the list of 5024 | strings, to determine if the string is a unique match with one of the 5025 | valid values. 5026 */ 5027 5028int 5029unique_test(string, list) 5030char *string; 5031char *list[]; 5032{ 5033 int counter; 5034 int num_match; 5035 int result; 5036 5037 num_match = 0; 5038 counter = 0; 5039 while (list[counter] != NULL) 5040 { 5041 result = compare(string, list[counter], FALSE); 5042 if (result) 5043 num_match++; 5044 counter++; 5045 } 5046 return(num_match); 5047} 5048 5049#ifndef NO_CATGETS 5050/* 5051 | Get the catalog entry, and if it got it from the catalog, 5052 | make a copy, since the buffer will be overwritten by the 5053 | next call to catgets(). 5054 */ 5055 5056char * 5057catgetlocal(number, string) 5058int number; 5059char *string; 5060{ 5061 char *temp1; 5062 char *temp2; 5063 5064 temp1 = catgets(catalog, 1, number, string); 5065 if (temp1 != string) 5066 { 5067 temp2 = malloc(strlen(temp1) + 1); 5068 strcpy(temp2, temp1); 5069 temp1 = temp2; 5070 } 5071 return(temp1); 5072} 5073#endif /* NO_CATGETS */ 5074 5075/* 5076 | The following is to allow for using message catalogs which allow 5077 | the software to be 'localized', that is, to use different languages 5078 | all with the same binary. For more information, see your system 5079 | documentation, or the X/Open Internationalization Guide. 5080 */ 5081 5082void 5083strings_init() 5084{ 5085 int counter; 5086 5087 setlocale(LC_ALL, ""); 5088#ifndef NO_CATGETS 5089 catalog = catopen("ee", NL_CAT_LOCALE); 5090#endif /* NO_CATGETS */ 5091 5092 modes_menu[0].item_string = catgetlocal( 1, "modes menu"); 5093 mode_strings[1] = catgetlocal( 2, "tabs to spaces "); 5094 mode_strings[2] = catgetlocal( 3, "case sensitive search"); 5095 mode_strings[3] = catgetlocal( 4, "margins observed "); 5096 mode_strings[4] = catgetlocal( 5, "auto-paragraph format"); 5097 mode_strings[5] = catgetlocal( 6, "eightbit characters "); 5098 mode_strings[6] = catgetlocal( 7, "info window "); 5099 mode_strings[8] = catgetlocal( 8, "right margin "); 5100 leave_menu[0].item_string = catgetlocal( 9, "leave menu"); 5101 leave_menu[1].item_string = catgetlocal( 10, "save changes"); 5102 leave_menu[2].item_string = catgetlocal( 11, "no save"); 5103 file_menu[0].item_string = catgetlocal( 12, "file menu"); 5104 file_menu[1].item_string = catgetlocal( 13, "read a file"); 5105 file_menu[2].item_string = catgetlocal( 14, "write a file"); 5106 file_menu[3].item_string = catgetlocal( 15, "save file"); 5107 file_menu[4].item_string = catgetlocal( 16, "print editor contents"); 5108 search_menu[0].item_string = catgetlocal( 17, "search menu"); 5109 search_menu[1].item_string = catgetlocal( 18, "search for ..."); 5110 search_menu[2].item_string = catgetlocal( 19, "search"); 5111 spell_menu[0].item_string = catgetlocal( 20, "spell menu"); 5112 spell_menu[1].item_string = catgetlocal( 21, "use 'spell'"); 5113 spell_menu[2].item_string = catgetlocal( 22, "use 'ispell'"); 5114 misc_menu[0].item_string = catgetlocal( 23, "miscellaneous menu"); 5115 misc_menu[1].item_string = catgetlocal( 24, "format paragraph"); 5116 misc_menu[2].item_string = catgetlocal( 25, "shell command"); 5117 misc_menu[3].item_string = catgetlocal( 26, "check spelling"); 5118 main_menu[0].item_string = catgetlocal( 27, "main menu"); 5119 main_menu[1].item_string = catgetlocal( 28, "leave editor"); 5120 main_menu[2].item_string = catgetlocal( 29, "help"); 5121 main_menu[3].item_string = catgetlocal( 30, "file operations"); 5122 main_menu[4].item_string = catgetlocal( 31, "redraw screen"); 5123 main_menu[5].item_string = catgetlocal( 32, "settings"); 5124 main_menu[6].item_string = catgetlocal( 33, "search"); 5125 main_menu[7].item_string = catgetlocal( 34, "miscellaneous"); 5126 help_text[0] = catgetlocal( 35, "Control keys: "); 5127 help_text[1] = catgetlocal( 36, "^a ascii code ^i tab ^r right "); 5128 help_text[2] = catgetlocal( 37, "^b bottom of text ^j newline ^t top of text "); 5129 help_text[3] = catgetlocal( 38, "^c command ^k delete char ^u up "); 5130 help_text[4] = catgetlocal( 39, "^d down ^l left ^v undelete word "); 5131 help_text[5] = catgetlocal( 40, "^e search prompt ^m newline ^w delete word "); 5132 help_text[6] = catgetlocal( 41, "^f undelete char ^n next page ^x search "); 5133 help_text[7] = catgetlocal( 42, "^g begin of line ^o end of line ^y delete line "); 5134 help_text[8] = catgetlocal( 43, "^h backspace ^p prev page ^z undelete line "); 5135 help_text[9] = catgetlocal( 44, "^[ (escape) menu ESC-Enter: exit ee "); 5136 help_text[10] = catgetlocal( 45, " "); 5137 help_text[11] = catgetlocal( 46, "Commands: "); 5138 help_text[12] = catgetlocal( 47, "help : get this info file : print file name "); 5139 help_text[13] = catgetlocal( 48, "read : read a file char : ascii code of char "); 5140 help_text[14] = catgetlocal( 49, "write : write a file case : case sensitive search "); 5141 help_text[15] = catgetlocal( 50, "exit : leave and save nocase : case insensitive search "); 5142 help_text[16] = catgetlocal( 51, "quit : leave, no save !cmd : execute \"cmd\" in shell "); 5143 help_text[17] = catgetlocal( 52, "line : display line # 0-9 : go to line \"#\" "); 5144 help_text[18] = catgetlocal( 53, "expand : expand tabs noexpand: do not expand tabs "); 5145 help_text[19] = catgetlocal( 54, " "); 5146 help_text[20] = catgetlocal( 55, " ee [+#] [-i] [-e] [-h] [file(s)] "); 5147 help_text[21] = catgetlocal( 56, "+# :go to line # -i :no info window -e : don't expand tabs -h :no highlight"); 5148 control_keys[0] = catgetlocal( 57, "^[ (escape) menu ^e search prompt ^y delete line ^u up ^p prev page "); 5149 control_keys[1] = catgetlocal( 58, "^a ascii code ^x search ^z undelete line ^d down ^n next page "); 5150 control_keys[2] = catgetlocal( 59, "^b bottom of text ^g begin of line ^w delete word ^l left "); 5151 control_keys[3] = catgetlocal( 60, "^t top of text ^o end of line ^v undelete word ^r right "); 5152 control_keys[4] = catgetlocal( 61, "^c command ^k delete char ^f undelete char ESC-Enter: exit ee "); 5153 command_strings[0] = catgetlocal( 62, "help : get help info |file : print file name |line : print line # "); 5154 command_strings[1] = catgetlocal( 63, "read : read a file |char : ascii code of char |0-9 : go to line \"#\""); 5155 command_strings[2] = catgetlocal( 64, "write: write a file |case : case sensitive search |exit : leave and save "); 5156 command_strings[3] = catgetlocal( 65, "!cmd : shell \"cmd\" |nocase: ignore case in search |quit : leave, no save"); 5157 command_strings[4] = catgetlocal( 66, "expand: expand tabs |noexpand: do not expand tabs "); 5158 com_win_message = catgetlocal( 67, " press Escape (^[) for menu"); 5159 no_file_string = catgetlocal( 68, "no file"); 5160 ascii_code_str = catgetlocal( 69, "ascii code: "); 5161 printer_msg_str = catgetlocal( 70, "sending contents of buffer to \"%s\" "); 5162 command_str = catgetlocal( 71, "command: "); 5163 file_write_prompt_str = catgetlocal( 72, "name of file to write: "); 5164 file_read_prompt_str = catgetlocal( 73, "name of file to read: "); 5165 char_str = catgetlocal( 74, "character = %d"); 5166 unkn_cmd_str = catgetlocal( 75, "unknown command \"%s\""); 5167 non_unique_cmd_msg = catgetlocal( 76, "entered command is not unique"); 5168 line_num_str = catgetlocal( 77, "line %d "); 5169 line_len_str = catgetlocal( 78, "length = %d"); 5170 current_file_str = catgetlocal( 79, "current file is \"%s\" "); 5171 usage0 = catgetlocal( 80, "usage: %s [-i] [-e] [-h] [+line_number] [file(s)]\n"); 5172 usage1 = catgetlocal( 81, " -i turn off info window\n"); 5173 usage2 = catgetlocal( 82, " -e do not convert tabs to spaces\n"); 5174 usage3 = catgetlocal( 83, " -h do not use highlighting\n"); 5175 file_is_dir_msg = catgetlocal( 84, "file \"%s\" is a directory"); 5176 new_file_msg = catgetlocal( 85, "new file \"%s\""); 5177 cant_open_msg = catgetlocal( 86, "can't open \"%s\""); 5178 open_file_msg = catgetlocal( 87, "file \"%s\", %d lines"); 5179 file_read_fin_msg = catgetlocal( 88, "finished reading file \"%s\""); 5180 reading_file_msg = catgetlocal( 89, "reading file \"%s\""); 5181 read_only_msg = catgetlocal( 90, ", read only"); 5182 file_read_lines_msg = catgetlocal( 91, "file \"%s\", %d lines"); 5183 save_file_name_prompt = catgetlocal( 92, "enter name of file: "); 5184 file_not_saved_msg = catgetlocal( 93, "no filename entered: file not saved"); 5185 changes_made_prompt = catgetlocal( 94, "changes have been made, are you sure? (y/n [n]) "); 5186 yes_char = catgetlocal( 95, "y"); 5187 file_exists_prompt = catgetlocal( 96, "file already exists, overwrite? (y/n) [n] "); 5188 create_file_fail_msg = catgetlocal( 97, "unable to create file \"%s\""); 5189 writing_file_msg = catgetlocal( 98, "writing file \"%s\""); 5190 file_written_msg = catgetlocal( 99, "\"%s\" %d lines, %d characters"); 5191 searching_msg = catgetlocal( 100, " ...searching"); 5192 str_not_found_msg = catgetlocal( 101, "string \"%s\" not found"); 5193 search_prompt_str = catgetlocal( 102, "search for: "); 5194 exec_err_msg = catgetlocal( 103, "could not exec %s\n"); 5195 continue_msg = catgetlocal( 104, "press return to continue "); 5196 menu_cancel_msg = catgetlocal( 105, "press Esc to cancel"); 5197 menu_size_err_msg = catgetlocal( 106, "menu too large for window"); 5198 press_any_key_msg = catgetlocal( 107, "press any key to continue "); 5199 shell_prompt = catgetlocal( 108, "shell command: "); 5200 formatting_msg = catgetlocal( 109, "...formatting paragraph..."); 5201 shell_echo_msg = catgetlocal( 110, "<!echo 'list of unrecognized words'; echo -=-=-=-=-=-"); 5202 spell_in_prog_msg = catgetlocal( 111, "sending contents of edit buffer to 'spell'"); 5203 margin_prompt = catgetlocal( 112, "right margin is: "); 5204 restricted_msg = catgetlocal( 113, "restricted mode: unable to perform requested operation"); 5205 ON = catgetlocal( 114, "ON"); 5206 OFF = catgetlocal( 115, "OFF"); 5207 HELP = catgetlocal( 116, "HELP"); 5208 WRITE = catgetlocal( 117, "WRITE"); 5209 READ = catgetlocal( 118, "READ"); 5210 LINE = catgetlocal( 119, "LINE"); 5211 FILE_str = catgetlocal( 120, "FILE"); 5212 CHARACTER = catgetlocal( 121, "CHARACTER"); 5213 REDRAW = catgetlocal( 122, "REDRAW"); 5214 RESEQUENCE = catgetlocal( 123, "RESEQUENCE"); 5215 AUTHOR = catgetlocal( 124, "AUTHOR"); 5216 VERSION = catgetlocal( 125, "VERSION"); 5217 CASE = catgetlocal( 126, "CASE"); 5218 NOCASE = catgetlocal( 127, "NOCASE"); 5219 EXPAND = catgetlocal( 128, "EXPAND"); 5220 NOEXPAND = catgetlocal( 129, "NOEXPAND"); 5221 Exit_string = catgetlocal( 130, "EXIT"); 5222 QUIT_string = catgetlocal( 131, "QUIT"); 5223 INFO = catgetlocal( 132, "INFO"); 5224 NOINFO = catgetlocal( 133, "NOINFO"); 5225 MARGINS = catgetlocal( 134, "MARGINS"); 5226 NOMARGINS = catgetlocal( 135, "NOMARGINS"); 5227 AUTOFORMAT = catgetlocal( 136, "AUTOFORMAT"); 5228 NOAUTOFORMAT = catgetlocal( 137, "NOAUTOFORMAT"); 5229 Echo = catgetlocal( 138, "ECHO"); 5230 PRINTCOMMAND = catgetlocal( 139, "PRINTCOMMAND"); 5231 RIGHTMARGIN = catgetlocal( 140, "RIGHTMARGIN"); 5232 HIGHLIGHT = catgetlocal( 141, "HIGHLIGHT"); 5233 NOHIGHLIGHT = catgetlocal( 142, "NOHIGHLIGHT"); 5234 EIGHTBIT = catgetlocal( 143, "EIGHTBIT"); 5235 NOEIGHTBIT = catgetlocal( 144, "NOEIGHTBIT"); 5236 /* 5237 | additions 5238 */ 5239 mode_strings[7] = catgetlocal( 145, "emacs key bindings "); 5240 emacs_help_text[0] = help_text[0]; 5241 emacs_help_text[1] = catgetlocal( 146, "^a beginning of line ^i tab ^r restore word "); 5242 emacs_help_text[2] = catgetlocal( 147, "^b back 1 char ^j undel char ^t top of text "); 5243 emacs_help_text[3] = catgetlocal( 148, "^c command ^k delete line ^u bottom of text "); 5244 emacs_help_text[4] = catgetlocal( 149, "^d delete char ^l undelete line ^v next page "); 5245 emacs_help_text[5] = catgetlocal( 150, "^e end of line ^m newline ^w delete word "); 5246 emacs_help_text[6] = catgetlocal( 151, "^f forward 1 char ^n next line ^x search "); 5247 emacs_help_text[7] = catgetlocal( 152, "^g go back 1 page ^o ascii char insert ^y search prompt "); 5248 emacs_help_text[8] = catgetlocal( 153, "^h backspace ^p prev line ^z next word "); 5249 emacs_help_text[9] = help_text[9]; 5250 emacs_help_text[10] = help_text[10]; 5251 emacs_help_text[11] = help_text[11]; 5252 emacs_help_text[12] = help_text[12]; 5253 emacs_help_text[13] = help_text[13]; 5254 emacs_help_text[14] = help_text[14]; 5255 emacs_help_text[15] = help_text[15]; 5256 emacs_help_text[16] = help_text[16]; 5257 emacs_help_text[17] = help_text[17]; 5258 emacs_help_text[18] = help_text[18]; 5259 emacs_help_text[19] = help_text[19]; 5260 emacs_help_text[20] = help_text[20]; 5261 emacs_help_text[21] = help_text[21]; 5262 emacs_control_keys[0] = catgetlocal( 154, "^[ (escape) menu ^y search prompt ^k delete line ^p prev li ^g prev page"); 5263 emacs_control_keys[1] = catgetlocal( 155, "^o ascii code ^x search ^l undelete line ^n next li ^v next page"); 5264 emacs_control_keys[2] = catgetlocal( 156, "^u end of file ^a begin of line ^w delete word ^b back 1 char ^z next word"); 5265 emacs_control_keys[3] = catgetlocal( 157, "^t top of text ^e end of line ^r restore word ^f forward char "); 5266 emacs_control_keys[4] = catgetlocal( 158, "^c command ^d delete char ^j undelete char ESC-Enter: exit"); 5267 EMACS_string = catgetlocal( 159, "EMACS"); 5268 NOEMACS_string = catgetlocal( 160, "NOEMACS"); 5269 usage4 = catgetlocal( 161, " +# put cursor at line #\n"); 5270 conf_dump_err_msg = catgetlocal( 162, "unable to open .init.ee for writing, no configuration saved!"); 5271 conf_dump_success_msg = catgetlocal( 163, "ee configuration saved in file %s"); 5272 modes_menu[10].item_string = catgetlocal( 164, "save editor configuration"); 5273 config_dump_menu[0].item_string = catgetlocal( 165, "save ee configuration"); 5274 config_dump_menu[1].item_string = catgetlocal( 166, "save in current directory"); 5275 config_dump_menu[2].item_string = catgetlocal( 167, "save in home directory"); 5276 conf_not_saved_msg = catgetlocal( 168, "ee configuration not saved"); 5277 ree_no_file_msg = catgetlocal( 169, "must specify a file when invoking ree"); 5278 menu_too_lrg_msg = catgetlocal( 180, "menu too large for window"); 5279 more_above_str = catgetlocal( 181, "^^more^^"); 5280 more_below_str = catgetlocal( 182, "VVmoreVV"); 5281 mode_strings[9] = catgetlocal( 183, "16 bit characters "); 5282 chinese_cmd = catgetlocal( 184, "16BIT"); 5283 nochinese_cmd = catgetlocal( 185, "NO16BIT"); 5284 5285 commands[0] = HELP; 5286 commands[1] = WRITE; 5287 commands[2] = READ; 5288 commands[3] = LINE; 5289 commands[4] = FILE_str; 5290 commands[5] = REDRAW; 5291 commands[6] = RESEQUENCE; 5292 commands[7] = AUTHOR; 5293 commands[8] = VERSION; 5294 commands[9] = CASE; 5295 commands[10] = NOCASE; 5296 commands[11] = EXPAND; 5297 commands[12] = NOEXPAND; 5298 commands[13] = Exit_string; 5299 commands[14] = QUIT_string; 5300 commands[15] = "<"; 5301 commands[16] = ">"; 5302 commands[17] = "!"; 5303 commands[18] = "0"; 5304 commands[19] = "1"; 5305 commands[20] = "2"; 5306 commands[21] = "3"; 5307 commands[22] = "4"; 5308 commands[23] = "5"; 5309 commands[24] = "6"; 5310 commands[25] = "7"; 5311 commands[26] = "8"; 5312 commands[27] = "9"; 5313 commands[28] = CHARACTER; 5314 commands[29] = chinese_cmd; 5315 commands[30] = nochinese_cmd; 5316 commands[31] = NULL; 5317 init_strings[0] = CASE; 5318 init_strings[1] = NOCASE; 5319 init_strings[2] = EXPAND; 5320 init_strings[3] = NOEXPAND; 5321 init_strings[4] = INFO; 5322 init_strings[5] = NOINFO; 5323 init_strings[6] = MARGINS; 5324 init_strings[7] = NOMARGINS; 5325 init_strings[8] = AUTOFORMAT; 5326 init_strings[9] = NOAUTOFORMAT; 5327 init_strings[10] = Echo; 5328 init_strings[11] = PRINTCOMMAND; 5329 init_strings[12] = RIGHTMARGIN; 5330 init_strings[13] = HIGHLIGHT; 5331 init_strings[14] = NOHIGHLIGHT; 5332 init_strings[15] = EIGHTBIT; 5333 init_strings[16] = NOEIGHTBIT; 5334 init_strings[17] = EMACS_string; 5335 init_strings[18] = NOEMACS_string; 5336 init_strings[19] = chinese_cmd; 5337 init_strings[20] = nochinese_cmd; 5338 init_strings[21] = NULL; 5339 5340 /* 5341 | allocate space for strings here for settings menu 5342 */ 5343 5344 for (counter = 1; counter < NUM_MODES_ITEMS; counter++) 5345 { 5346 modes_menu[counter].item_string = malloc(80); 5347 } 5348 5349#ifndef NO_CATGETS 5350 catclose(catalog); 5351#endif /* NO_CATGETS */ 5352} 5353 5354