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