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