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