Annotation of dgamelaunch-openbsd/ee.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: | ee (easy editor)
3: |
4: | An easy to use, simple screen oriented editor.
5: |
6: | written by Hugh Mahon
7: |
8: | THIS MATERIAL IS PROVIDED "AS IS". THERE ARE
9: | NO WARRANTIES OF ANY KIND WITH REGARD TO THIS
10: | MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE
11: | IMPLIED WARRANTIES OF MERCHANTABILITY AND
12: | FITNESS FOR A PARTICULAR PURPOSE. Neither
13: | Hewlett-Packard nor Hugh Mahon shall be liable
14: | for errors contained herein, nor for
15: | incidental or consequential damages in
16: | connection with the furnishing, performance or
17: | use of this material. Neither Hewlett-Packard
18: | nor Hugh Mahon assumes any responsibility for
19: | the use or reliability of this software or
20: | documentation. This software and
21: | documentation is totally UNSUPPORTED. There
22: | is no support contract available. Hewlett-
23: | Packard has done NO Quality Assurance on ANY
24: | of the program or documentation. You may find
25: | the quality of the materials inferior to
26: | supported materials.
27: |
28: | This software is not a product of Hewlett-Packard, Co., or any
29: | other company. No support is implied or offered with this software.
30: | You've got the source, and you're on your own.
31: |
32: | This software may be distributed under the terms of Larry Wall's
33: | Artistic license, a copy of which is included in this distribution.
34: |
35: | This notice must be included with this software and any derivatives.
36: |
37: | This editor was purposely developed to be simple, both in
38: | interface and implementation. This editor was developed to
39: | address a specific audience: the user who is new to computers
40: | (especially UNIX).
41: |
42: | ee is not aimed at technical users; for that reason more
43: | complex features were intentionally left out. In addition,
44: | ee is intended to be compiled by people with little computer
45: | experience, which means that it needs to be small, relatively
46: | simple in implementation, and portable.
47: |
48: | This software and documentation contains
49: | proprietary information which is protected by
50: | copyright. All rights are reserved.
51: |
52: | $Header: /var/cvs/dgamelaunch/ee.c,v 1.10 2004/01/26 16:54:02 joshk Exp $
53: |
54: */
55:
56: #include <wchar.h>
57: wchar_t *ee_copyright_message =
58: L"Copyright (c) 1986, 1990, 1991, 1992, 1993, 1994, 1995, 1996 Hugh Mahon ";
59:
60: wchar_t *ee_long_notice[] = {
61: L"This software and documentation contains",
62: L"proprietary information which is protected by",
63: L"copyright. All rights are reserved."
64: };
65:
66: wchar_t *version = L"@(#) ee, version 1.4.1 $Revision: 1.10 $";
67:
68: #include <locale.h>
69: #include <curses.h>
70: #include <signal.h>
71: #include <fcntl.h>
72: #include <sys/types.h>
73: #include <sys/stat.h>
74: #include <errno.h>
75: #include <string.h>
76: #include <pwd.h>
77:
78: #include <sys/wait.h>
79: #include <stdlib.h>
80: #include <stdarg.h>
81: #include <unistd.h>
82: #include <ctype.h>
83:
84: #ifndef SIGCHLD
85: #define SIGCHLD SIGCLD
86: #endif
87:
88: #define MAX_FILE 1048576
89:
90: #define TAB 9
91: #define max(a, b) (a > b ? a : b)
92: #define min(a, b) (a < b ? a : b)
93:
94: /*
95: | defines for type of data to show in info window
96: */
97:
98: #define CONTROL_KEYS 1
99: #define COMMANDS 2
100:
101: struct text {
102: wchar_t *line; /* line of characters */
103: int line_number; /* line number */
104: int line_length; /* actual number of characters in the line */
105: int max_length; /* maximum number of characters the line handles */
106: struct text *next_line; /* next line of text */
107: struct text *prev_line; /* previous line of text */
108: };
109:
110: struct text *first_line; /* first line of current buffer */
111: struct text *dlt_line; /* structure for info on deleted line */
112: struct text *curr_line; /* current line cursor is on */
113: struct text *tmp_line; /* temporary line pointer */
114: struct text *srch_line; /* temporary pointer for search routine */
115:
116: int d_wrd_len; /* length of deleted word */
117: int position; /* offset in bytes from begin of line */
118: int scr_pos; /* horizontal position */
119: int scr_vert; /* vertical position on screen */
120: int scr_horz; /* horizontal position on screen */
121: int tmp_vert, tmp_horz;
122: int input_file; /* indicate to read input file */
123: int recv_file; /* indicate reading a file */
124: int edit; /* continue executing while true */
125: int gold; /* 'gold' function key pressed */
126: int fildes; /* file descriptor */
127: int case_sen; /* case sensitive search flag */
128: int last_line; /* last line for text display */
129: int last_col; /* last column for text display */
130: int horiz_offset = 0; /* offset from left edge of text */
131: int clear_com_win; /* flag to indicate com_win needs clearing */
132: int text_changes = FALSE; /* indicate changes have been made to text */
133: int get_fd; /* file descriptor for reading a file */
134: int info_window = TRUE; /* flag to indicate if help window visible */
135: int info_type = CONTROL_KEYS; /* flag to indicate type of info to display */
136: int expand_tabs = TRUE; /* flag for expanding tabs */
137: int right_margin = 0; /* the right margin */
138: int observ_margins = TRUE; /* flag for whether margins are observed */
139: int out_pipe; /* flag that info is piped out */
140: int in_pipe; /* flag that info is piped in */
141: int formatted = FALSE; /* flag indicating paragraph formatted */
142: int nohighlight = FALSE; /* turns off highlighting */
143: int eightbit = TRUE; /* eight bit character flag */
144: int local_LINES = 0; /* copy of LINES, to detect when win resizes */
145: int local_COLS = 0; /* copy of COLS, to detect when win resizes */
146: int curses_initialized = FALSE; /* flag indicating if curses has been started*/
147: int emacs_keys_mode = TRUE; /* mode for if emacs key binings are used */
148:
149: wchar_t *point; /* points to current position in line */
150: wchar_t *srch_str; /* pointer for search string */
151: wchar_t *u_srch_str; /* pointer to non-case sensitive search */
152: wchar_t *srch_1; /* pointer to start of suspect string */
153: wchar_t *srch_2; /* pointer to next character of string */
154: wchar_t *srch_3;
155: char *in_file_name = NULL; /* name of input file */
156: char *tmp_file; /* temporary file name */
157: wchar_t *d_char; /* deleted character */
158: wchar_t *d_word; /* deleted word */
159: wchar_t *d_line; /* deleted line */
160: wchar_t *start_at_line = NULL; /* move to this line at start of session*/
161: int in; /* input character */
162:
163: FILE *temp_fp; /* temporary file pointer */
164:
165: wchar_t *table[] = {
166: L"^@", L"^A", L"^B", L"^C", L"^D", L"^E", L"^F", L"^G", L"^H", L"\t", L"^J",
167: L"^K", L"^L", L"^M", L"^N", L"^O", L"^P", L"^Q", L"^R", L"^S", L"^T", L"^U",
168: L"^V", L"^W", L"^X", L"^Y", L"^Z", L"^[", L"^\\", L"^]", L"^^", L"^_"
169: };
170:
171: WINDOW *com_win;
172: WINDOW *text_win;
173: WINDOW *help_win;
174: WINDOW *info_win;
175:
176: #if defined(__STDC__) || defined(__cplusplus)
177: #define P_(s) s
178: #else
179: #define P_(s) ()
180: #endif
181:
182:
183: /*
184: | The following structure allows menu items to be flexibly declared.
185: | The first item is the string describing the selection, the second
186: | is the address of the procedure to call when the item is selected,
187: | and the third is the argument for the procedure.
188: |
189: | For those systems with i18n, the string should be accompanied by a
190: | catalog number. The 'int *' should be replaced with 'void *' on
191: | systems with that type.
192: |
193: | The first menu item will be the title of the menu, with NULL
194: | parameters for the procedure and argument, followed by the menu items.
195: |
196: | If the procedure value is NULL, the menu item is displayed, but no
197: | procedure is called when the item is selected. The number of the
198: | item will be returned. If the third (argument) parameter is -1, no
199: | argument is given to the procedure when it is called.
200: */
201:
202: struct menu_entries
203: {
204: wchar_t *item_string;
205: int (*procedure)P_((struct menu_entries *));
206: struct menu_entries *ptr_argument;
207: int (*iprocedure)P_((int));
208: void (*nprocedure)P_((void));
209: int argument;
210: };
211:
212: int main(int argc, char *argv[]);
213: wchar_t *resiz_line(int factor, struct text *rline, int rpos);
214: void insert(int character);
215: void delete(int disp);
216: void scanline(wchar_t *pos);
217: int tabshift(int temp_int);
218: int out_char(WINDOW *window, int character, int column);
219: int len_char(wchar_t character, int column);
220: void draw_line(int vertical, int horiz, wchar_t *ptr, int t_pos, int length);
221: void insert_line(int disp);
222: struct text *txtalloc(void);
223: wchar_t *next_word(wchar_t *string);
224: void prev_word(void);
225: void control(void);
226: void emacs_control(void);
227: void bottom(void);
228: void top(void);
229: void nextline(void);
230: void prevline(void);
231: void left(int disp);
232: void right(int disp);
233: void find_pos(void);
234: void up(void);
235: void down(void);
236: void function_key(void);
237: void command_prompt(void);
238: void command(wchar_t *cmd_str1);
239: int scan(wchar_t *line, int offset, int column);
240: wchar_t *get_string(wchar_t *prompt, int advance);
241: int compare(wchar_t *string1, wchar_t *string2, int sensitive);
242: void goto_line(wchar_t *cmd_str);
243: void midscreen(int line, wchar_t *pnt);
244: void check_fp(void);
245: void get_file(char *file_name);
246: void get_line(int length, char *in_string, int *append);
247: void draw_screen(void);
248: void ee_finish(void);
249: int quit(int noverify);
250: void edit_abort(int arg);
251: void delete_text(void);
252: int write_file(char *file_name, int fd);
253: int search(int display_message);
254: void search_prompt(void);
255: void del_char(void);
256: void undel_char(void);
257: void del_word(void);
258: void undel_word(void);
259: void del_line(void);
260: void undel_line(void);
261: void adv_word(void);
262: void move_rel(char direction, int lines);
263: void eol(void);
264: void bol(void);
265: void adv_line(void);
266: void set_up_term(void);
267: void resize_check(void);
268: int menu_op(struct menu_entries menu_list[]);
269: 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);
270: void help(void);
271: void paint_info_win(void);
272: void no_info_window(void);
273: void create_info_window(void);
274: int file_op(int arg);
275: void leave_op(void);
276: void redraw(void);
277: int Blank_Line(struct text *test_line);
278: void echo_string(wchar_t *string);
279: int first_word_len(struct text *test_line);
280: wchar_t *is_in_string(wchar_t *string, wchar_t *substring);
281: int unique_test(wchar_t *string, wchar_t *list[]);
282: void strings_init(void);
283:
284: #undef P_
285: /*
286: | allocate space here for the strings that will be in the menu
287: */
288:
289: struct menu_entries leave_menu[] = {
290: {L"", NULL, NULL, NULL, NULL, -1},
291: {L"", NULL, NULL, NULL, ee_finish, -1},
292: {L"", NULL, NULL, quit, NULL, TRUE},
293: {NULL, NULL, NULL, NULL, NULL, -1}
294: };
295:
296: #define READ_FILE 1
297: #define WRITE_FILE 2
298: #define SAVE_FILE 3
299:
300: struct menu_entries search_menu[] = {
301: {L"", NULL, NULL, NULL, NULL, 0},
302: {L"", NULL, NULL, NULL, search_prompt, -1},
303: {L"", NULL, NULL, search, NULL, TRUE},
304: {NULL, NULL, NULL, NULL, NULL, -1}
305: };
306:
307: struct menu_entries main_menu[] = {
308: {L"", NULL, NULL, NULL, NULL, -1},
309: {L"", NULL, NULL, NULL, leave_op, -1},
310: {L"", NULL, NULL, NULL, help, -1},
311: {L"", NULL, NULL, file_op, NULL, SAVE_FILE},
312: {L"", NULL, NULL, NULL, redraw, -1},
313: {L"", menu_op, search_menu, NULL, NULL, -1},
314: {NULL, NULL, NULL, NULL, NULL, -1}
315: };
316:
317: wchar_t *help_text[23];
318: wchar_t *control_keys[5];
319:
320: wchar_t *emacs_help_text[22];
321: wchar_t *emacs_control_keys[5];
322:
323: wchar_t *command_strings[5];
324: wchar_t *commands[32];
325:
326: #define MENU_WARN 1
327:
328: #define max_alpha_char 36
329:
330: /*
331: | Declarations for strings for localization
332: */
333:
334: wchar_t *com_win_message; /* to be shown in com_win if no info window */
335: char *no_file_string;
336: wchar_t *ascii_code_str;
337: wchar_t *command_str;
338: char *char_str;
339: char *unkn_cmd_str;
340: wchar_t *non_unique_cmd_msg;
341: char *line_num_str;
342: char *line_len_str;
343: char *current_file_str;
344: wchar_t *usage0;
345: wchar_t *usage1;
346: wchar_t *usage2;
347: wchar_t *usage3;
348: wchar_t *usage4;
349: char *file_is_dir_msg;
350: char *new_file_msg;
351: char *cant_open_msg;
352: wchar_t *open_file_msg;
353: char *file_read_fin_msg;
354: char *reading_file_msg;
355: char *read_only_msg;
356: char *file_read_lines_msg;
357: wchar_t *save_file_name_prompt;
358: char *file_not_saved_msg;
359: wchar_t *changes_made_prompt;
360: wchar_t *yes_char;
361: wchar_t *file_exists_prompt;
362: char *create_file_fail_msg;
363: char *writing_file_msg;
364: char *file_written_msg;
365: char *searching_msg;
366: char *str_not_found_msg;
367: wchar_t *search_prompt_str;
368: wchar_t *continue_msg;
369: wchar_t *menu_cancel_msg;
370: wchar_t *menu_size_err_msg;
371: wchar_t *press_any_key_msg;
372: wchar_t *ON;
373: wchar_t *OFF;
374: wchar_t *HELP;
375: wchar_t *SAVE;
376: wchar_t *READ;
377: wchar_t *LINE;
378: wchar_t *FILE_str;
379: wchar_t *CHARACTER;
380: wchar_t *REDRAW;
381: wchar_t *RESEQUENCE;
382: wchar_t *AUTHOR;
383: wchar_t *ee_VERSION;
384: wchar_t *CASE;
385: wchar_t *NOCASE;
386: wchar_t *EXPAND;
387: wchar_t *NOEXPAND;
388: wchar_t *Exit_string;
389: wchar_t *QUIT_string;
390: wchar_t *INFO;
391: wchar_t *NOINFO;
392: wchar_t *MARGINS;
393: wchar_t *NOMARGINS;
394: wchar_t *AUTOFORMAT;
395: wchar_t *NOAUTOFORMAT;
396: wchar_t *Echo;
397: wchar_t *PRINTCOMMAND;
398: wchar_t *RIGHTMARGIN;
399: wchar_t *HIGHLIGHT;
400: wchar_t *NOHIGHLIGHT;
401: wchar_t *EIGHTBIT;
402: wchar_t *NOEIGHTBIT;
403: wchar_t *EMACS_string;
404: wchar_t *NOEMACS_string;
405: wchar_t *cancel_string;
406: char *menu_too_lrg_msg;
407: wchar_t *more_above_str, *more_below_str;
408:
409: #ifndef __STDC__
410: #ifndef HAS_STDLIB
411: extern char *malloc();
412: extern char *realloc();
413: extern char *getenv();
414: FILE *fopen(); /* declaration for open function */
415: #endif /* HAS_STDLIB */
416: #endif /* __STDC__ */
417:
418: int
419: main(argc, argv) /* beginning of main program */
420: int argc;
421: char *argv[];
422: {
423: int counter;
424:
425: setlocale(LC_ALL, "");
426: for (counter = 1; counter < 24; counter++)
427: {
428: if (!(counter == SIGKILL || counter == SIGSTOP))
429: signal(counter, SIG_IGN);
430: }
431:
432: signal(SIGCHLD, SIG_DFL);
433: signal(SIGSEGV, SIG_DFL);
434: signal(SIGINT, edit_abort);
435: d_char = malloc(3 * sizeof(wchar_t)); /* provide a buffer for multi-byte chars */
436: d_word = malloc(150 * sizeof(wchar_t));
437: *d_word = '\0';
438: d_line = NULL;
439: dlt_line = txtalloc();
440: dlt_line->line = d_line;
441: dlt_line->line_length = 0;
442: curr_line = first_line = txtalloc();
443: curr_line->line = point = malloc(10 * sizeof(wchar_t));
444: curr_line->line_length = 1;
445: curr_line->max_length = 10;
446: curr_line->prev_line = NULL;
447: curr_line->next_line = NULL;
448: curr_line->line_number = 1;
449: srch_str = NULL;
450: u_srch_str = NULL;
451: position = 1;
452: scr_pos =0;
453: scr_vert = 0;
454: scr_horz = 0;
455: edit = TRUE;
456: gold = case_sen = FALSE;
457: strings_init();
458:
459: if (argc != 2)
460: {
461: puts("need a filename! bailing out.");
462: return 1;
463: }
464: else
465: {
466: tmp_file = strdup(argv[1]);
467: input_file = recv_file = TRUE;
468: }
469:
470: set_up_term();
471: if (right_margin == 0)
472: right_margin = COLS - 1;
473:
474: if (!tmp_file)
475: {
476: wprintw(com_win, no_file_string);
477: wrefresh(com_win);
478: }
479: else
480: check_fp();
481:
482: clear_com_win = TRUE;
483:
484: while(edit)
485: {
486: int keyt;
487: wrefresh(text_win);
488: keyt = wget_wch(text_win, &in);
489: if (keyt == ERR)
490: exit(0);
491:
492: resize_check();
493:
494: if (clear_com_win)
495: {
496: clear_com_win = FALSE;
497: wmove(com_win, 0, 0);
498: werase(com_win);
499: if (!info_window)
500: {
501: wprintw(com_win, "%S", com_win_message);
502: }
503: wrefresh(com_win);
504: }
505:
506: if (keyt == KEY_CODE_YES)
507: function_key();
508: else if ((in == '\10') || (in == 127))
509: {
510: in = 8; /* make sure key is set to backspace */
511: delete(TRUE);
512: }
513: else if ((in > 31) || (in == 9))
514: insert(in);
515: else if ((in >= 0) && (in <= 31))
516: {
517: if (emacs_keys_mode)
518: emacs_control();
519: else
520: control();
521: }
522: }
523: return(0);
524: }
525:
526: wchar_t *
527: resiz_line(factor, rline, rpos) /* resize the line to length + factor*/
528: int factor; /* resize factor */
529: struct text *rline; /* position in line */
530: int rpos;
531: {
532: wchar_t *rpoint;
533: int resiz_var;
534:
535: rline->max_length += factor;
536: rpoint = rline->line = realloc(rline->line, rline->max_length * sizeof(wchar_t));
537: for (resiz_var = 1 ; (resiz_var < rpos) ; resiz_var++)
538: rpoint++;
539: return(rpoint);
540: }
541:
542: void
543: insert(character) /* insert character into line */
544: int character; /* new character */
545: {
546: int counter;
547: int value;
548: wchar_t *temp; /* temporary pointer */
549: wchar_t *temp2; /* temporary pointer */
550:
551: if ((character == '\011') && (expand_tabs))
552: {
553: counter = len_char('\011', scr_horz);
554: for (; counter > 0; counter--)
555: insert(' ');
556: return;
557: }
558: text_changes = TRUE;
559: if ((curr_line->max_length - curr_line->line_length) < 5)
560: point = resiz_line(10, curr_line, position);
561: curr_line->line_length++;
562: temp = point;
563: counter = position;
564: while (counter < curr_line->line_length) /* find end of line */
565: {
566: counter++;
567: temp++;
568: }
569: temp++; /* increase length of line by one */
570: while (point < temp)
571: {
572: temp2=temp - 1;
573: *temp= *temp2; /* shift characters over by one */
574: temp--;
575: }
576: *point = character; /* insert new character */
577: wclrtoeol(text_win);
578: if ((character >= 0) && (character < ' ')) /* check for TAB character*/
579: {
580: scr_pos = scr_horz += out_char(text_win, character, scr_horz);
581: point++;
582: position++;
583: }
584: else
585: {
586: waddnwstr(text_win, &character, 1);
587: scr_pos = ++scr_horz;
588: point++;
589: position ++;
590: }
591:
592: if ((observ_margins) && (right_margin < scr_pos))
593: {
594: counter = position;
595: while (scr_pos > right_margin)
596: prev_word();
597: if (scr_pos == 0)
598: {
599: while (position < counter)
600: right(TRUE);
601: }
602: else
603: {
604: counter -= position;
605: insert_line(TRUE);
606: for (value = 0; value < counter; value++)
607: right(TRUE);
608: }
609: }
610:
611: if ((scr_horz - horiz_offset) > last_col)
612: {
613: horiz_offset += 8;
614: midscreen(scr_vert, point);
615: }
616:
617: else if ((character != ' ') && (character != '\t'))
618: formatted = FALSE;
619:
620: draw_line(scr_vert, scr_horz, point, position, curr_line->line_length);
621: }
622:
623: void
624: delete(disp) /* delete character */
625: int disp;
626: {
627: wchar_t *tp;
628: wchar_t *temp2;
629: struct text *temp_buff;
630: int temp_vert;
631: int temp_pos;
632: int del_width = 1;
633:
634: if (point != curr_line->line) /* if not at beginning of line */
635: {
636: text_changes = TRUE;
637: temp2 = tp = point;
638: tp -= del_width;
639: point -= del_width;
640: position -= del_width;
641: temp_pos = position;
642: curr_line->line_length -= del_width;
643: if ((*tp < ' ') || (*tp >= 127)) /* check for TAB */
644: scanline(tp);
645: else
646: scr_horz -= del_width;
647: scr_pos = scr_horz;
648: if (in == 8)
649: {
650: if (del_width == 1)
651: *d_char = *point; /* save deleted character */
652: else
653: {
654: d_char[0] = *point;
655: d_char[1] = *(point + 1);
656: }
657: d_char[del_width] = '\0';
658: }
659: while (temp_pos <= curr_line->line_length)
660: {
661: temp_pos++;
662: *tp = *temp2;
663: tp++;
664: temp2++;
665: }
666: if (scr_horz < horiz_offset)
667: {
668: horiz_offset -= 8;
669: midscreen(scr_vert, point);
670: }
671: }
672: else if (curr_line->prev_line != NULL)
673: {
674: text_changes = TRUE;
675: left(disp); /* go to previous line */
676: temp_buff = curr_line->next_line;
677: point = resiz_line(temp_buff->line_length, curr_line, position);
678: if (temp_buff->next_line != NULL)
679: temp_buff->next_line->prev_line = curr_line;
680: curr_line->next_line = temp_buff->next_line;
681: temp2 = temp_buff->line;
682: if (in == 8)
683: {
684: d_char[0] = '\n';
685: d_char[1] = '\0';
686: }
687: tp = point;
688: temp_pos = 1;
689: while (temp_pos < temp_buff->line_length)
690: {
691: curr_line->line_length++;
692: temp_pos++;
693: *tp = *temp2;
694: tp++;
695: temp2++;
696: }
697: *tp = '\0';
698: free(temp_buff->line);
699: free(temp_buff);
700: temp_buff = curr_line;
701: temp_vert = scr_vert;
702: scr_pos = scr_horz;
703: if (scr_vert < last_line)
704: {
705: wmove(text_win, scr_vert + 1, 0);
706: wdeleteln(text_win);
707: }
708: while ((temp_buff != NULL) && (temp_vert < last_line))
709: {
710: temp_buff = temp_buff->next_line;
711: temp_vert++;
712: }
713: if ((temp_vert == last_line) && (temp_buff != NULL))
714: {
715: tp = temp_buff->line;
716: wmove(text_win, last_line,0);
717: wclrtobot(text_win);
718: draw_line(last_line, 0, tp, 1, temp_buff->line_length);
719: wmove(text_win, scr_vert, (scr_horz - horiz_offset));
720: }
721: }
722: draw_line(scr_vert, scr_horz, point, position, curr_line->line_length);
723: formatted = FALSE;
724: }
725:
726: void
727: scanline(pos) /* find the proper horizontal position for the pointer */
728: wchar_t *pos;
729: {
730: int temp;
731: wchar_t *ptr;
732:
733: ptr = curr_line->line;
734: temp = 0;
735: while (ptr < pos)
736: {
737: if (*ptr <= 8)
738: temp += 2;
739: else if (*ptr == 9)
740: temp += tabshift(temp);
741: else if ((*ptr >= 10) && (*ptr <= 31))
742: temp += 2;
743: else if ((*ptr >= 32) && (*ptr < 127))
744: temp++;
745: else if (*ptr == 127)
746: temp += 2;
747: else if (!eightbit)
748: temp += 5;
749: else
750: temp++;
751: ptr++;
752: }
753: scr_horz = temp;
754: if ((scr_horz - horiz_offset) > last_col)
755: {
756: horiz_offset = (scr_horz - (scr_horz % 8)) - (COLS - 8);
757: midscreen(scr_vert, point);
758: }
759: else if (scr_horz < horiz_offset)
760: {
761: horiz_offset = max(0, (scr_horz - (scr_horz % 8)));
762: midscreen(scr_vert, point);
763: }
764: }
765:
766: int
767: tabshift(temp_int) /* give the number of spaces to shift */
768: int temp_int;
769: {
770: int leftover;
771:
772: leftover = ((temp_int + 1) % 8);
773: if (leftover == 0)
774: return (1);
775: else
776: return (9 - leftover);
777: }
778:
779: int
780: out_char(window, character, column) /* output non-printing character */
781: WINDOW *window;
782: int character;
783: int column;
784: {
785: int i1, i2;
786: wchar_t *string;
787:
788: if (character == TAB)
789: {
790: i1 = tabshift(column);
791: for (i2 = 0;
792: (i2 < i1) && (((column+i2+1)-horiz_offset) < last_col); i2++)
793: {
794: waddch(window, ' ');
795: }
796: return(i1);
797: }
798: else if ((character >= '\0') && (character < ' '))
799: {
800: string = table[(int) character];
801: }
802: else
803: {
804: waddnwstr(window, &character, 1);
805: return(1);
806: }
807: for (i2 = 0; (string[i2] != '\0') && (((column+i2+1)-horiz_offset) < last_col); i2++)
808: waddch(window, string[i2]);
809: return(wcslen(string));
810: }
811:
812: int
813: len_char(character, column) /* return the length of the character */
814: wchar_t character;
815: int column; /* the column must be known to provide spacing for tabs */
816: {
817: int length;
818:
819: if (character == '\t')
820: length = tabshift(column);
821: else if ((character >= 0) && (character < 32))
822: length = 2;
823: else if ((character >= 32) && (character <= 126))
824: length = 1;
825: else if (character == 127)
826: length = 2;
827: else if (((character > 126) || (character < 0)) && (!eightbit))
828: length = 5;
829: else
830: length = 1;
831:
832: return(length);
833: }
834:
835: void
836: draw_line(vertical, horiz, ptr, t_pos, length) /* redraw line from current position */
837: int vertical; /* current vertical position on screen */
838: int horiz; /* current horizontal position on screen */
839: wchar_t *ptr; /* pointer to line */
840: int t_pos; /* current position (offset in bytes) from bol */
841: int length; /* length (in bytes) of line */
842: {
843: int d; /* partial length of special or tab char to display */
844: wchar_t *temp; /* temporary pointer to position in line */
845: int abs_column; /* offset in screen units from begin of line */
846: int column; /* horizontal position on screen */
847: int row; /* vertical position on screen */
848: int posit; /* temporary position indicator within line */
849:
850: abs_column = horiz;
851: column = horiz - horiz_offset;
852: row = vertical;
853: temp = ptr;
854: d = 0;
855: posit = t_pos;
856: if (column < 0)
857: {
858: wmove(text_win, row, 0);
859: wclrtoeol(text_win);
860: }
861: while (column < 0)
862: {
863: d = len_char(*temp, abs_column);
864: abs_column += d;
865: column += d;
866: posit++;
867: temp++;
868: }
869: wmove(text_win, row, column);
870: wclrtoeol(text_win);
871: while ((posit < length) && (column <= last_col))
872: {
873: if (*temp < 32)
874: {
875: column += len_char(*temp, abs_column);
876: abs_column += out_char(text_win, *temp, abs_column);
877: }
878: else
879: {
880: abs_column++;
881: column++;
882: waddnwstr(text_win, temp, 1);
883: }
884: posit++;
885: temp++;
886: }
887: if (column < last_col)
888: wclrtoeol(text_win);
889: wmove(text_win, vertical, (horiz - horiz_offset));
890: }
891:
892: void
893: insert_line(disp) /* insert new line */
894: int disp;
895: {
896: int temp_pos;
897: int temp_pos2;
898: wchar_t *temp;
899: wchar_t *extra;
900: struct text *temp_nod;
901:
902: text_changes = TRUE;
903: wmove(text_win, scr_vert, (scr_horz - horiz_offset));
904: wclrtoeol(text_win);
905: temp_nod= txtalloc();
906: temp_nod->line = extra= malloc(10 * sizeof(wchar_t));
907: temp_nod->line_length = 1;
908: temp_nod->max_length = 10;
909: temp_nod->line_number = curr_line->line_number + 1;
910: temp_nod->next_line = curr_line->next_line;
911: if (temp_nod->next_line != NULL)
912: temp_nod->next_line->prev_line = temp_nod;
913: temp_nod->prev_line = curr_line;
914: curr_line->next_line = temp_nod;
915: temp_pos2 = position;
916: temp = point;
917: if (temp_pos2 < curr_line->line_length)
918: {
919: temp_pos = 1;
920: while (temp_pos2 < curr_line->line_length)
921: {
922: if ((temp_nod->max_length - temp_nod->line_length)< 5)
923: extra = resiz_line(10, temp_nod, temp_pos);
924: temp_nod->line_length++;
925: temp_pos++;
926: temp_pos2++;
927: *extra= *temp;
928: extra++;
929: temp++;
930: }
931: temp=point;
932: *temp = '\0';
933: temp = resiz_line((1 - temp_nod->line_length), curr_line, position);
934: curr_line->line_length = 1 + temp - curr_line->line;
935: }
936: curr_line->line_length = position;
937: curr_line = temp_nod;
938: *extra = '\0';
939: position = 1;
940: point= curr_line->line;
941: if (disp)
942: {
943: if (scr_vert < last_line)
944: {
945: scr_vert++;
946: wclrtoeol(text_win);
947: wmove(text_win, scr_vert, 0);
948: winsertln(text_win);
949: }
950: else
951: {
952: wmove(text_win, 0,0);
953: wdeleteln(text_win);
954: wmove(text_win, last_line,0);
955: wclrtobot(text_win);
956: }
957: scr_pos = scr_horz = 0;
958: if (horiz_offset)
959: {
960: horiz_offset = 0;
961: midscreen(scr_vert, point);
962: }
963: draw_line(scr_vert, scr_horz, point, position,
964: curr_line->line_length);
965: }
966: }
967:
968: struct text *txtalloc() /* allocate space for line structure */
969: {
970: return((struct text *) malloc(sizeof( struct text)));
971: }
972:
973: wchar_t *next_word(string) /* move to next word in string */
974: wchar_t *string;
975: {
976: while ((*string != '\0') && ((*string != 32) && (*string != 9)))
977: string++;
978: while ((*string != '\0') && ((*string == 32) || (*string == 9)))
979: string++;
980: return(string);
981: }
982:
983: int watoi(wchar_t *s)
984: {
985: int x = 0;
986: while (*s >= '0' && *s <= '9')
987: x = x * 10 + *s++ - '0';
988: return x;
989: }
990:
991: void
992: prev_word() /* move to start of previous word in text */
993: {
994: if (position != 1)
995: {
996: if ((position != 1) && ((point[-1] == ' ') || (point[-1] == '\t')))
997: { /* if at the start of a word */
998: while ((position != 1) && ((*point != ' ') && (*point != '\t')))
999: left(TRUE);
1000: }
1001: while ((position != 1) && ((*point == ' ') || (*point == '\t')))
1002: left(TRUE);
1003: while ((position != 1) && ((*point != ' ') && (*point != '\t')))
1004: left(TRUE);
1005: if ((position != 1) && ((*point == ' ') || (*point == '\t')))
1006: right(TRUE);
1007: }
1008: else
1009: left(TRUE);
1010: }
1011:
1012: void
1013: control() /* use control for commands */
1014: {
1015: wchar_t *string;
1016:
1017: if (in == 1) /* control a */
1018: {
1019: string = get_string(ascii_code_str, TRUE);
1020: if (*string != '\0')
1021: {
1022: in = watoi(string);
1023: wmove(text_win, scr_vert, (scr_horz - horiz_offset));
1024: insert(in);
1025: }
1026: free(string);
1027: }
1028: else if (in == 2) /* control b */
1029: bottom();
1030: else if (in == 3) /* control c */
1031: {
1032: command_prompt();
1033: }
1034: else if (in == 4) /* control d */
1035: down();
1036: else if (in == 5) /* control e */
1037: search_prompt();
1038: else if (in == 6) /* control f */
1039: undel_char();
1040: else if (in == 7) /* control g */
1041: bol();
1042: else if (in == 8) /* control h */
1043: delete(TRUE);
1044: else if (in == 9) /* control i */
1045: ;
1046: else if (in == 10) /* control j */
1047: insert_line(TRUE);
1048: else if (in == 11) /* control k */
1049: del_char();
1050: else if (in == 12) /* control l */
1051: left(TRUE);
1052: else if (in == 13) /* control m */
1053: insert_line(TRUE);
1054: else if (in == 14) /* control n */
1055: move_rel('d', max(5, (last_line - 5)));
1056: else if (in == 15) /* control o */
1057: eol();
1058: else if (in == 16) /* control p */
1059: move_rel('u', max(5, (last_line - 5)));
1060: else if (in == 17) /* control q */
1061: ;
1062: else if (in == 18) /* control r */
1063: right(TRUE);
1064: else if (in == 19) /* control s */
1065: ;
1066: else if (in == 20) /* control t */
1067: top();
1068: else if (in == 21) /* control u */
1069: up();
1070: else if (in == 22) /* control v */
1071: undel_word();
1072: else if (in == 23) /* control w */
1073: del_word();
1074: else if (in == 24) /* control x */
1075: search(TRUE);
1076: else if (in == 25) /* control y */
1077: del_line();
1078: else if (in == 26) /* control z */
1079: undel_line();
1080: else if (in == 27) /* control [ (escape) */
1081: {
1082: menu_op(main_menu);
1083: }
1084: }
1085:
1086: /*
1087: | Emacs control-key bindings
1088: */
1089:
1090: void
1091: emacs_control()
1092: {
1093: wchar_t *string;
1094:
1095: if (in == 1) /* control a */
1096: bol();
1097: else if (in == 2) /* control b */
1098: left(TRUE);
1099: else if (in == 3) /* control c */
1100: {
1101: command_prompt();
1102: }
1103: else if (in == 4) /* control d */
1104: del_char();
1105: else if (in == 5) /* control e */
1106: eol();
1107: else if (in == 6) /* control f */
1108: right(TRUE);
1109: else if (in == 7) /* control g */
1110: move_rel('u', max(5, (last_line - 5)));
1111: else if (in == 8) /* control h */
1112: delete(TRUE);
1113: else if (in == 9) /* control i */
1114: ;
1115: else if (in == 10) /* control j */
1116: undel_char();
1117: else if (in == 11) /* control k */
1118: del_line();
1119: else if (in == 12) /* control l */
1120: undel_line();
1121: else if (in == 13) /* control m */
1122: insert_line(TRUE);
1123: else if (in == 14) /* control n */
1124: down();
1125: else if (in == 15) /* control o */
1126: {
1127: string = get_string(ascii_code_str, TRUE);
1128: if (*string != '\0')
1129: {
1130: in = watoi(string);
1131: wmove(text_win, scr_vert, (scr_horz - horiz_offset));
1132: insert(in);
1133: }
1134: free(string);
1135: }
1136: else if (in == 16) /* control p */
1137: up();
1138: else if (in == 17) /* control q */
1139: ;
1140: else if (in == 18) /* control r */
1141: undel_word();
1142: else if (in == 19) /* control s */
1143: ;
1144: else if (in == 20) /* control t */
1145: top();
1146: else if (in == 21) /* control u */
1147: bottom();
1148: else if (in == 22) /* control v */
1149: move_rel('d', max(5, (last_line - 5)));
1150: else if (in == 23) /* control w */
1151: del_word();
1152: else if (in == 24) /* control x */
1153: search(TRUE);
1154: else if (in == 25) /* control y */
1155: search_prompt();
1156: else if (in == 26) /* control z */
1157: adv_word();
1158: else if (in == 27) /* control [ (escape) */
1159: {
1160: menu_op(main_menu);
1161: }
1162: }
1163:
1164: void
1165: bottom() /* go to bottom of file */
1166: {
1167: while (curr_line->next_line != NULL)
1168: curr_line = curr_line->next_line;
1169: point = curr_line->line;
1170: if (horiz_offset)
1171: horiz_offset = 0;
1172: position = 1;
1173: midscreen(last_line, point);
1174: scr_pos = scr_horz;
1175: }
1176:
1177: void
1178: top() /* go to top of file */
1179: {
1180: while (curr_line->prev_line != NULL)
1181: curr_line = curr_line->prev_line;
1182: point = curr_line->line;
1183: if (horiz_offset)
1184: horiz_offset = 0;
1185: position = 1;
1186: midscreen(0, point);
1187: scr_pos = scr_horz;
1188: }
1189:
1190: void
1191: nextline() /* move pointers to start of next line */
1192: {
1193: curr_line = curr_line->next_line;
1194: point = curr_line->line;
1195: position = 1;
1196: if (scr_vert == last_line)
1197: {
1198: wmove(text_win, 0,0);
1199: wdeleteln(text_win);
1200: wmove(text_win, last_line,0);
1201: wclrtobot(text_win);
1202: draw_line(last_line,0,point,1,curr_line->line_length);
1203: }
1204: else
1205: scr_vert++;
1206: }
1207:
1208: void
1209: prevline() /* move pointers to start of previous line*/
1210: {
1211: curr_line = curr_line->prev_line;
1212: point = curr_line->line;
1213: position = 1;
1214: if (scr_vert == 0)
1215: {
1216: winsertln(text_win);
1217: draw_line(0,0,point,1,curr_line->line_length);
1218: }
1219: else
1220: scr_vert--;
1221: while (position < curr_line->line_length)
1222: {
1223: position++;
1224: point++;
1225: }
1226: }
1227:
1228: void
1229: left(disp) /* move left one character */
1230: int disp;
1231: {
1232: if (point != curr_line->line) /* if not at begin of line */
1233: {
1234: point--;
1235: position--;
1236: scanline(point);
1237: wmove(text_win, scr_vert, (scr_horz - horiz_offset));
1238: scr_pos = scr_horz;
1239: }
1240: else if (curr_line->prev_line != NULL)
1241: {
1242: if (!disp)
1243: {
1244: curr_line = curr_line->prev_line;
1245: point = curr_line->line + curr_line->line_length;
1246: position = curr_line->line_length;
1247: return;
1248: }
1249: position = 1;
1250: prevline();
1251: scanline(point);
1252: scr_pos = scr_horz;
1253: wmove(text_win, scr_vert, (scr_horz - horiz_offset));
1254: }
1255: }
1256:
1257: void
1258: right(disp) /* move right one character */
1259: int disp;
1260: {
1261: if (position < curr_line->line_length)
1262: {
1263: point++;
1264: position++;
1265: scanline(point);
1266: wmove(text_win, scr_vert, (scr_horz - horiz_offset));
1267: scr_pos = scr_horz;
1268: }
1269: else if (curr_line->next_line != NULL)
1270: {
1271: if (!disp)
1272: {
1273: curr_line = curr_line->next_line;
1274: point = curr_line->line;
1275: position = 1;
1276: return;
1277: }
1278: nextline();
1279: scr_pos = scr_horz = 0;
1280: if (horiz_offset)
1281: {
1282: horiz_offset = 0;
1283: midscreen(scr_vert, point);
1284: }
1285: wmove(text_win, scr_vert, (scr_horz - horiz_offset));
1286: position = 1;
1287: }
1288: }
1289:
1290: void
1291: find_pos() /* move to the same column as on other line */
1292: {
1293: scr_horz = 0;
1294: position = 1;
1295: while ((scr_horz < scr_pos) && (position < curr_line->line_length))
1296: {
1297: if (*point == 9)
1298: scr_horz += tabshift(scr_horz);
1299: else if (*point < ' ')
1300: scr_horz += 2;
1301: else if ((*point > 127) && ((curr_line->line_length - position) >= 2))
1302: {
1303: scr_horz += 2;
1304: point++;
1305: position++;
1306: }
1307: else
1308: scr_horz++;
1309: position++;
1310: point++;
1311: }
1312: if ((scr_horz - horiz_offset) > last_col)
1313: {
1314: horiz_offset = (scr_horz - (scr_horz % 8)) - (COLS - 8);
1315: midscreen(scr_vert, point);
1316: }
1317: else if (scr_horz < horiz_offset)
1318: {
1319: horiz_offset = max(0, (scr_horz - (scr_horz % 8)));
1320: midscreen(scr_vert, point);
1321: }
1322: wmove(text_win, scr_vert, (scr_horz - horiz_offset));
1323: }
1324:
1325: void
1326: up() /* move up one line */
1327: {
1328: if (curr_line->prev_line != NULL)
1329: {
1330: prevline();
1331: point = curr_line->line;
1332: find_pos();
1333: }
1334: }
1335:
1336: void
1337: down() /* move down one line */
1338: {
1339: if (curr_line->next_line != NULL)
1340: {
1341: nextline();
1342: find_pos();
1343: }
1344: }
1345:
1346: void
1347: function_key() /* process function key */
1348: {
1349: if (in == KEY_LEFT)
1350: left(TRUE);
1351: else if (in == KEY_RIGHT)
1352: right(TRUE);
1353: else if ( in == KEY_HOME)
1354: top();
1355: else if ( in == KEY_UP)
1356: up();
1357: else if (in == KEY_DOWN)
1358: down();
1359: else if (in == KEY_NPAGE)
1360: move_rel('d', max( 5, (last_line - 5)));
1361: else if (in == KEY_PPAGE)
1362: move_rel('u', max(5, (last_line - 5)));
1363: else if (in == KEY_DL)
1364: del_line();
1365: else if (in == KEY_DC)
1366: del_char();
1367: else if (in == KEY_BACKSPACE)
1368: delete(TRUE);
1369: else if (in == KEY_IL)
1370: { /* insert a line before current line */
1371: insert_line(TRUE);
1372: left(TRUE);
1373: }
1374: else if (in == KEY_F(1))
1375: gold = !gold;
1376: else if (in == KEY_F(2))
1377: {
1378: if (gold)
1379: {
1380: gold = FALSE;
1381: undel_line();
1382: }
1383: else
1384: undel_char();
1385: }
1386: else if (in == KEY_F(3))
1387: {
1388: if (gold)
1389: {
1390: gold = FALSE;
1391: undel_word();
1392: }
1393: else
1394: del_word();
1395: }
1396: else if (in == KEY_F(4))
1397: {
1398: if (gold)
1399: {
1400: gold = FALSE;
1401: paint_info_win();
1402: midscreen(scr_vert, point);
1403: }
1404: else
1405: adv_word();
1406: }
1407: else if (in == KEY_F(5))
1408: {
1409: if (gold)
1410: {
1411: gold = FALSE;
1412: search_prompt();
1413: }
1414: else
1415: search(TRUE);
1416: }
1417: else if (in == KEY_F(6))
1418: {
1419: if (gold)
1420: {
1421: gold = FALSE;
1422: bottom();
1423: }
1424: else
1425: top();
1426: }
1427: else if (in == KEY_F(7))
1428: {
1429: if (gold)
1430: {
1431: gold = FALSE;
1432: eol();
1433: }
1434: else
1435: bol();
1436: }
1437: else if (in == KEY_F(8))
1438: {
1439: if (gold)
1440: {
1441: gold = FALSE;
1442: command_prompt();
1443: }
1444: else
1445: adv_line();
1446: }
1447: }
1448:
1449: void
1450: command_prompt()
1451: {
1452: wchar_t *cmd_str;
1453: int result;
1454:
1455: info_type = COMMANDS;
1456: paint_info_win();
1457: cmd_str = get_string(command_str, TRUE);
1458: if ((result = unique_test(cmd_str, commands)) != 1)
1459: {
1460: werase(com_win);
1461: wmove(com_win, 0, 0);
1462: if (result == 0)
1463: wprintw(com_win, unkn_cmd_str, cmd_str);
1464: else
1465: wprintw(com_win, "%S", non_unique_cmd_msg);
1466:
1467: wrefresh(com_win);
1468:
1469: info_type = CONTROL_KEYS;
1470: paint_info_win();
1471:
1472: if (cmd_str != NULL)
1473: free(cmd_str);
1474: return;
1475: }
1476: command(cmd_str);
1477: wrefresh(com_win);
1478: wmove(text_win, scr_vert, (scr_horz - horiz_offset));
1479: info_type = CONTROL_KEYS;
1480: paint_info_win();
1481: if (cmd_str != NULL)
1482: free(cmd_str);
1483: }
1484:
1485: void command(wchar_t *cmd_str1) /* process commands from keyboard */
1486: {
1487: wchar_t *cmd_str2 = NULL;
1488: wchar_t *cmd_str = cmd_str1;
1489:
1490: clear_com_win = TRUE;
1491: if (compare(cmd_str, HELP, FALSE))
1492: help();
1493: else if (compare(cmd_str, LINE, FALSE))
1494: {
1495: wmove(com_win, 0, 0);
1496: wclrtoeol(com_win);
1497: wprintw(com_win, line_num_str, curr_line->line_number);
1498: wprintw(com_win, line_len_str, curr_line->line_length);
1499: }
1500: else if (compare(cmd_str, FILE_str, FALSE))
1501: {
1502: wmove(com_win, 0, 0);
1503: wclrtoeol(com_win);
1504: if (in_file_name == NULL)
1505: wprintw(com_win, no_file_string);
1506: else
1507: wprintw(com_win, current_file_str, in_file_name);
1508: }
1509: else if ((*cmd_str >= '0') && (*cmd_str <= '9'))
1510: goto_line(cmd_str);
1511: else if (compare(cmd_str, CHARACTER, FALSE))
1512: {
1513: wmove(com_win, 0, 0);
1514: wclrtoeol(com_win);
1515: wprintw(com_win, char_str, *point);
1516: }
1517: else if (compare(cmd_str, REDRAW, FALSE))
1518: redraw();
1519: else if (compare(cmd_str, RESEQUENCE, FALSE))
1520: {
1521: tmp_line = first_line->next_line;
1522: while (tmp_line != NULL)
1523: {
1524: tmp_line->line_number = tmp_line->prev_line->line_number + 1;
1525: tmp_line = tmp_line->next_line;
1526: }
1527: }
1528: else if (compare(cmd_str, SAVE, FALSE))
1529: write_file(tmp_file, -1);
1530: else if (compare(cmd_str, AUTHOR, FALSE))
1531: {
1532: wmove(com_win, 0, 0);
1533: wclrtoeol(com_win);
1534: wprintw(com_win, "written by Hugh Mahon");
1535: }
1536: else if (compare(cmd_str, ee_VERSION, FALSE))
1537: {
1538: wmove(com_win, 0, 0);
1539: wclrtoeol(com_win);
1540: wprintw(com_win, "%s", version);
1541: }
1542: else if (compare(cmd_str, CASE, FALSE))
1543: case_sen = TRUE;
1544: else if (compare(cmd_str, NOCASE, FALSE))
1545: case_sen = FALSE;
1546: else if (compare(cmd_str, EXPAND, FALSE))
1547: expand_tabs = TRUE;
1548: else if (compare(cmd_str, NOEXPAND, FALSE))
1549: expand_tabs = FALSE;
1550: else if (compare(cmd_str, Exit_string, FALSE))
1551: ee_finish();
1552: else if (compare(cmd_str, QUIT_string, FALSE))
1553: quit(0);
1554: else if ((*cmd_str == '<') && (!in_pipe))
1555: {
1556: in_pipe = TRUE;
1557: cmd_str++;
1558: if ((*cmd_str == ' ') || (*cmd_str == '\t'))
1559: cmd_str = next_word((wchar_t*)cmd_str);
1560: command(cmd_str);
1561: in_pipe = FALSE;
1562: }
1563: else if ((*cmd_str == '>') && (!out_pipe))
1564: {
1565: out_pipe = TRUE;
1566: cmd_str++;
1567: if ((*cmd_str == ' ') || (*cmd_str == '\t'))
1568: cmd_str = next_word((wchar_t*)cmd_str);
1569: command(cmd_str);
1570: out_pipe = FALSE;
1571: }
1572: else
1573: {
1574: wmove(com_win, 0, 0);
1575: wclrtoeol(com_win);
1576: wprintw(com_win, unkn_cmd_str, cmd_str);
1577: }
1578: if (cmd_str2 != NULL)
1579: free(cmd_str2);
1580: }
1581:
1582: int
1583: scan(line, offset, column) /* determine horizontal position for get_string */
1584: wchar_t *line;
1585: int offset;
1586: int column;
1587: {
1588: wchar_t *stemp;
1589: int i;
1590: int j;
1591:
1592: stemp = line;
1593: i = 0;
1594: j = column;
1595: while (i < offset)
1596: {
1597: i++;
1598: j += len_char(*stemp, j);
1599: stemp++;
1600: }
1601: return(j);
1602: }
1603:
1604: wchar_t *
1605: get_string(prompt, advance) /* read string from input on command line */
1606: wchar_t *prompt; /* string containing user prompt message */
1607: int advance; /* if true, skip leading spaces and tabs */
1608: {
1609: wchar_t *string;
1610: wchar_t *tmp_string;
1611: wchar_t *nam_str;
1612: wchar_t *g_point;
1613: int tmp_int;
1614: int g_horz, g_position, g_pos;
1615: int esc_flag;
1616:
1617: g_point = tmp_string = malloc(512 * sizeof(wchar_t));
1618: wmove(com_win,0,0);
1619: wclrtoeol(com_win);
1620: waddwstr(com_win, prompt);
1621: wrefresh(com_win);
1622: nam_str = tmp_string;
1623: clear_com_win = TRUE;
1624: g_horz = g_position = scan(prompt, wcslen(prompt), 0);
1625: g_pos = 0;
1626: do
1627: {
1628: int keyt;
1629: esc_flag = FALSE;
1630: keyt = wget_wch(com_win, &in);
1631: if (keyt == ERR)
1632: exit(0);
1633: if (keyt == KEY_CODE_YES)
1634: {
1635: if (in == KEY_BACKSPACE)
1636: in = 8;
1637: else
1638: continue;
1639: }
1640: if (((in == 8) || (in == 127)) && (g_pos > 0))
1641: {
1642: tmp_int = g_horz;
1643: g_pos--;
1644: g_horz = scan(g_point, g_pos, g_position);
1645: tmp_int = tmp_int - g_horz;
1646: for (; 0 < tmp_int; tmp_int--)
1647: {
1648: if ((g_horz+tmp_int) < (last_col - 1))
1649: {
1650: waddch(com_win, '\010');
1651: waddch(com_win, ' ');
1652: waddch(com_win, '\010');
1653: }
1654: }
1655: nam_str--;
1656: }
1657: else if ((in != 8) && (in != 127) && (in != '\n') && (in != '\r'))
1658: {
1659: if (in == '\026') /* control-v, accept next character verbatim */
1660: { /* allows entry of ^m, ^j, and ^h */
1661: int keyt;
1662: esc_flag = TRUE;
1663: do
1664: {
1665: keyt = wget_wch(com_win, &in);
1666:
1667: if (keyt == ERR)
1668: exit(0);
1669: } while (keyt != OK);
1670: }
1671: *nam_str = in;
1672: g_pos++;
1673: if (in < ' ')
1674: g_horz += out_char(com_win, in, g_horz);
1675: else
1676: {
1677: g_horz++;
1678: if (g_horz < (last_col - 1))
1679: waddnwstr(com_win, &in, 1);
1680: }
1681: nam_str++;
1682: }
1683: wrefresh(com_win);
1684: if (esc_flag)
1685: in = '\0';
1686: } while ((in != '\n') && (in != '\r'));
1687: *nam_str = '\0';
1688: nam_str = tmp_string;
1689: if (((*nam_str == ' ') || (*nam_str == 9)) && (advance))
1690: nam_str = next_word(nam_str);
1691: string = malloc((wcslen(nam_str) + 1) * sizeof(wchar_t));
1692: wcscpy(string, nam_str);
1693: free(tmp_string);
1694: wrefresh(com_win);
1695: return(string);
1696: }
1697:
1698: int
1699: compare(string1, string2, sensitive) /* compare two strings */
1700: wchar_t *string1;
1701: wchar_t *string2;
1702: int sensitive;
1703: {
1704: wchar_t *strng1;
1705: wchar_t *strng2;
1706: int tmp;
1707: int equal;
1708:
1709: strng1 = string1;
1710: strng2 = string2;
1711: tmp = 0;
1712: if ((strng1 == NULL) || (strng2 == NULL) || (*strng1 == '\0') || (*strng2 == '\0'))
1713: return(FALSE);
1714: equal = TRUE;
1715: while (equal)
1716: {
1717: if (sensitive)
1718: {
1719: if (*strng1 != *strng2)
1720: equal = FALSE;
1721: }
1722: else
1723: {
1724: if (toupper(*strng1) != toupper(*strng2))
1725: equal = FALSE;
1726: }
1727: strng1++;
1728: strng2++;
1729: if ((*strng1 == '\0') || (*strng2 == '\0') || (*strng1 == ' ') || (*strng2 == ' '))
1730: break;
1731: tmp++;
1732: }
1733: return(equal);
1734: }
1735:
1736: void goto_line(wchar_t *cmd_str)
1737: {
1738: int number;
1739: int i;
1740: wchar_t *ptr;
1741: char direction = 0;
1742: struct text *t_line;
1743:
1744: ptr = cmd_str;
1745: i= 0;
1746: while ((*ptr >='0') && (*ptr <= '9'))
1747: {
1748: i= i * 10 + (*ptr - '0');
1749: ptr++;
1750: }
1751: number = i;
1752: i = 0;
1753: t_line = curr_line;
1754: while ((t_line->line_number > number) && (t_line->prev_line != NULL))
1755: {
1756: i++;
1757: t_line = t_line->prev_line;
1758: direction = 'u';
1759: }
1760: while ((t_line->line_number < number) && (t_line->next_line != NULL))
1761: {
1762: i++;
1763: direction = 'd';
1764: t_line = t_line->next_line;
1765: }
1766: if ((i < 30) && (i > 0))
1767: {
1768: move_rel(direction, i);
1769: }
1770: else
1771: {
1772: curr_line = t_line;
1773: point = curr_line->line;
1774: position = 1;
1775: midscreen((last_line / 2), point);
1776: scr_pos = scr_horz;
1777: }
1778: wmove(com_win, 0, 0);
1779: wclrtoeol(com_win);
1780: wprintw(com_win, line_num_str, curr_line->line_number);
1781: wmove(text_win, scr_vert, (scr_horz - horiz_offset));
1782: }
1783:
1784: void
1785: midscreen(line, pnt) /* put current line in middle of screen */
1786: int line;
1787: wchar_t *pnt;
1788: {
1789: struct text *mid_line;
1790: int i;
1791:
1792: line = min(line, last_line);
1793: mid_line = curr_line;
1794: for (i = 0; ((i < line) && (curr_line->prev_line != NULL)); i++)
1795: curr_line = curr_line->prev_line;
1796: scr_vert = scr_horz = 0;
1797: wmove(text_win, 0, 0);
1798: draw_screen();
1799: scr_vert = i;
1800: curr_line = mid_line;
1801: scanline(pnt);
1802: wmove(text_win, scr_vert, (scr_horz - horiz_offset));
1803: }
1804:
1805: void
1806: check_fp() /* open or close files according to flags */
1807: {
1808: int line_num;
1809: int temp;
1810: struct stat buf;
1811:
1812: clear_com_win = TRUE;
1813: tmp_vert = scr_vert;
1814: tmp_horz = scr_horz;
1815: tmp_line = curr_line;
1816: if (input_file)
1817: in_file_name = tmp_file;
1818:
1819: temp = stat(tmp_file, &buf);
1820: buf.st_mode &= ~07777;
1821: if ((temp != -1) && (buf.st_mode != 0100000) && (buf.st_mode != 0))
1822: {
1823: wprintw(com_win, file_is_dir_msg, tmp_file);
1824: wrefresh(com_win);
1825: if (input_file)
1826: {
1827: quit(0);
1828: return;
1829: }
1830: else
1831: return;
1832: }
1833: if ((get_fd = open(tmp_file, O_RDONLY)) == -1)
1834: {
1835: wmove(com_win, 0, 0);
1836: wclrtoeol(com_win);
1837: if (input_file)
1838: wprintw(com_win, new_file_msg, tmp_file);
1839: else
1840: wprintw(com_win, cant_open_msg, tmp_file);
1841: wrefresh(com_win);
1842: wmove(text_win, scr_vert, (scr_horz - horiz_offset));
1843: wrefresh(text_win);
1844: recv_file = FALSE;
1845: input_file = FALSE;
1846: return;
1847: }
1848: else
1849: get_file(tmp_file);
1850:
1851: recv_file = FALSE;
1852: line_num = curr_line->line_number;
1853: scr_vert = tmp_vert;
1854: scr_horz = tmp_horz;
1855: if (input_file)
1856: curr_line= first_line;
1857: else
1858: curr_line = tmp_line;
1859: point = curr_line->line;
1860: draw_screen();
1861: if (input_file)
1862: {
1863: input_file = FALSE;
1864: if (start_at_line != NULL)
1865: {
1866: line_num = watoi(start_at_line) - 1;
1867: move_rel('d', line_num);
1868: line_num = 0;
1869: start_at_line = NULL;
1870: }
1871: }
1872: else
1873: {
1874: wmove(com_win, 0, 0);
1875: wclrtoeol(com_win);
1876: text_changes = TRUE;
1877: if ((tmp_file != NULL) && (*tmp_file != '\0'))
1878: wprintw(com_win, file_read_fin_msg, tmp_file);
1879: }
1880: wrefresh(com_win);
1881: wmove(text_win, scr_vert, (scr_horz - horiz_offset));
1882: wrefresh(text_win);
1883: }
1884:
1885: void
1886: get_file(file_name) /* read specified file into current buffer */
1887: char *file_name;
1888: {
1889: int can_read; /* file has at least one character */
1890: int length; /* length of line read by read */
1891: int append; /* should text be appended to current line */
1892: struct text *temp_line;
1893: char ro_flag = FALSE;
1894: char in_string[MAX_FILE+1];
1895:
1896: if (recv_file) /* if reading a file */
1897: {
1898: wmove(com_win, 0, 0);
1899: wclrtoeol(com_win);
1900: wprintw(com_win, reading_file_msg, file_name);
1901: if (access(file_name, 2)) /* check permission to write */
1902: {
1903: if ((errno == ENOTDIR) || (errno == EACCES) || (errno == EROFS) || (errno == ETXTBSY) || (errno == EFAULT))
1904: {
1905: wprintw(com_win, read_only_msg);
1906: ro_flag = TRUE;
1907: }
1908: }
1909: wrefresh(com_win);
1910: }
1911: if (curr_line->line_length > 1) /* if current line is not blank */
1912: {
1913: insert_line(FALSE);
1914: left(FALSE);
1915: append = FALSE;
1916: }
1917: else
1918: append = TRUE;
1919: can_read = FALSE; /* test if file has any characters */
1920: length = read(get_fd, in_string, sizeof(in_string) - 1);
1921: // in DGL, config files are better capped
1922: if (length != -1)
1923: {
1924: can_read = TRUE; /* if set file has at least 1 character */
1925: in_string[length] = 0;
1926: get_line(length, in_string, &append);
1927: }
1928: if ((can_read) && (curr_line->line_length == 1) && (curr_line->prev_line))
1929: {
1930: temp_line = curr_line->prev_line;
1931: temp_line->next_line = curr_line->next_line;
1932: if (temp_line->next_line != NULL)
1933: temp_line->next_line->prev_line = temp_line;
1934: if (curr_line->line != NULL)
1935: free(curr_line->line);
1936: free(curr_line);
1937: curr_line = temp_line;
1938: }
1939: if (input_file) /* if this is the file to be edited display number of lines */
1940: {
1941: wmove(com_win, 0, 0);
1942: wclrtoeol(com_win);
1943: wprintw(com_win, file_read_lines_msg, in_file_name, curr_line->line_number);
1944: if (ro_flag)
1945: wprintw(com_win, read_only_msg);
1946: wrefresh(com_win);
1947: }
1948: else if (can_read) /* not input_file and file is non-zero size */
1949: text_changes = TRUE;
1950:
1951: if (recv_file) /* if reading a file */
1952: {
1953: in = EOF;
1954: }
1955: }
1956:
1957: void
1958: get_line(length, in_str, append) /* read string and split into lines */
1959: int length; /* length of string read by read */
1960: char *in_str; /* string read by read */
1961: int *append; /* TRUE if must append more text to end of current line */
1962: {
1963: wchar_t *str1;
1964: wchar_t *str2;
1965: int num; /* offset from start of string */
1966: int char_count; /* length of new line (or added portion */
1967: int temp_counter; /* temporary counter value */
1968: struct text *tline; /* temporary pointer to new line */
1969: int first_time; /* if TRUE, the first time through the loop */
1970: wchar_t in_string[MAX_FILE];
1971: length = mbstowcs(in_string, in_str, sizeof(in_string)/sizeof(wchar_t));
1972:
1973: if (length == -1) {
1974: wmove(com_win, 0, 0);
1975: wprintw(com_win, "ERROR: Encountered a strange character. --more--");
1976: wclrtoeol(com_win);
1977: wrefresh(com_win);
1978: (void) wget_wch(com_win, &in);
1979: resetty();
1980: endwin();
1981: exit(0);
1982: }
1983:
1984: str2 = in_string;
1985: num = 0;
1986: first_time = TRUE;
1987: while (num < length)
1988: {
1989: if (!first_time)
1990: {
1991: if (num < length)
1992: {
1993: str2++;
1994: num++;
1995: }
1996: }
1997: else
1998: first_time = FALSE;
1999: str1 = str2;
2000: char_count = 1;
2001: /* find end of line */
2002: while ((*str2 != '\n') && (num < length))
2003: {
2004: str2++;
2005: num++;
2006: char_count++;
2007: }
2008: if (!(*append)) /* if not append to current line, insert new one */
2009: {
2010: tline = txtalloc(); /* allocate data structure for next line */
2011: tline->line_number = curr_line->line_number + 1;
2012: tline->next_line = curr_line->next_line;
2013: tline->prev_line = curr_line;
2014: curr_line->next_line = tline;
2015: if (tline->next_line != NULL)
2016: tline->next_line->prev_line = tline;
2017: curr_line = tline;
2018: curr_line->line = point = (wchar_t *) malloc(char_count * sizeof(wchar_t));
2019: curr_line->line_length = char_count;
2020: curr_line->max_length = char_count;
2021: }
2022: else
2023: {
2024: point = resiz_line(char_count, curr_line, curr_line->line_length);
2025: curr_line->line_length += (char_count - 1);
2026: }
2027: for (temp_counter = 1; temp_counter < char_count; temp_counter++)
2028: {
2029: *point = *str1;
2030: point++;
2031: str1++;
2032: }
2033: *point = '\0';
2034: *append = FALSE;
2035: if ((num == length) && (*str2 != '\n'))
2036: *append = TRUE;
2037: }
2038: }
2039:
2040: void
2041: draw_screen() /* redraw the screen from current postion */
2042: {
2043: struct text *temp_line;
2044: wchar_t *line_out;
2045: int temp_vert;
2046:
2047: temp_line = curr_line;
2048: temp_vert = scr_vert;
2049: wclrtobot(text_win);
2050: while ((temp_line != NULL) && (temp_vert <= last_line))
2051: {
2052: line_out = temp_line->line;
2053: draw_line(temp_vert, 0, line_out, 1, temp_line->line_length);
2054: temp_vert++;
2055: temp_line = temp_line->next_line;
2056: }
2057: wmove(text_win, temp_vert, 0);
2058: wmove(text_win, scr_vert, (scr_horz - horiz_offset));
2059: }
2060:
2061: void
2062: ee_finish() /* prepare to exit edit session */
2063: {
2064: char *file_name = in_file_name;
2065:
2066: /*
2067: | changes made here should be reflected in the 'save'
2068: | portion of file_op()
2069: */
2070:
2071: // if ((file_name == NULL) || (*file_name == '\0'))
2072: // file_name = get_string(save_file_name_prompt, TRUE);
2073:
2074: if ((file_name == NULL) || (*file_name == '\0'))
2075: {
2076: wmove(com_win, 0, 0);
2077: wprintw(com_win, file_not_saved_msg);
2078: wclrtoeol(com_win);
2079: wrefresh(com_win);
2080: clear_com_win = TRUE;
2081: return;
2082: }
2083:
2084: if (write_file(file_name, -1))
2085: {
2086: text_changes = FALSE;
2087: quit(0);
2088: }
2089: }
2090:
2091: int
2092: quit(noverify) /* exit editor */
2093: int noverify;
2094: {
2095: wchar_t *ans;
2096:
2097: touchwin(text_win);
2098: wrefresh(text_win);
2099: if ((text_changes) && (!noverify))
2100: {
2101: ans = get_string(changes_made_prompt, TRUE);
2102: if (toupper(*ans) == toupper(*yes_char))
2103: text_changes = FALSE;
2104: else
2105: return(0);
2106: free(ans);
2107: }
2108:
2109: if (info_window)
2110: wrefresh(info_win);
2111: wrefresh(com_win);
2112: resetty();
2113: endwin();
2114: putchar('\n');
2115: exit(0);
2116: }
2117:
2118: void
2119: edit_abort(arg)
2120: int arg;
2121: {
2122: wrefresh(com_win);
2123: resetty();
2124: endwin();
2125: putchar('\n');
2126: exit(1);
2127: }
2128:
2129: void
2130: delete_text()
2131: {
2132: while (curr_line->next_line != NULL)
2133: curr_line = curr_line->next_line;
2134: while (curr_line != first_line)
2135: {
2136: free(curr_line->line);
2137: curr_line = curr_line->prev_line;
2138: free(curr_line->next_line);
2139: }
2140: curr_line->next_line = NULL;
2141: *curr_line->line = '\0';
2142: curr_line->line_length = 1;
2143: curr_line->line_number = 1;
2144: point = curr_line->line;
2145: scr_pos = scr_vert = scr_horz = 0;
2146: position = 1;
2147: }
2148:
2149: /* If fd >= 0, then use the previously opened file. This is a
2150: hack to get safe tempfile handling in ispell.*/
2151: int write_file(char *file_name, int fd)
2152: {
2153: wchar_t cr;
2154: wchar_t *tmp_point;
2155: struct text *out_line;
2156: int lines, charac;
2157: int temp_pos;
2158: int write_flag = TRUE;
2159:
2160: charac = lines = 0;
2161: if ((fd < 0) &&
2162: ((in_file_name == NULL) || strcmp(in_file_name, file_name)))
2163: {
2164: if ((temp_fp = fopen(file_name, "r")))
2165: {
2166: tmp_point = get_string(file_exists_prompt, TRUE);
2167: if (toupper(*tmp_point) == toupper(*yes_char))
2168: write_flag = TRUE;
2169: else
2170: write_flag = FALSE;
2171: fclose(temp_fp);
2172: free(tmp_point);
2173: }
2174: }
2175:
2176: clear_com_win = TRUE;
2177:
2178: if (write_flag)
2179: {
2180: if (fd < 0)
2181: {
2182: temp_fp = fopen(file_name, "w");
2183: }
2184: else
2185: {
2186: temp_fp = fdopen(fd, "w");
2187: }
2188:
2189: if (temp_fp == NULL)
2190: {
2191: clear_com_win = TRUE;
2192: wmove(com_win,0,0);
2193: wclrtoeol(com_win);
2194: wprintw(com_win, create_file_fail_msg, file_name);
2195: wrefresh(com_win);
2196: return(FALSE);
2197: }
2198: else
2199: {
2200: wmove(com_win,0,0);
2201: wclrtoeol(com_win);
2202: wprintw(com_win, writing_file_msg, file_name);
2203: wrefresh(com_win);
2204: cr = '\n';
2205: out_line = first_line;
2206: while (out_line != NULL)
2207: {
2208: temp_pos = 1;
2209: tmp_point= out_line->line;
2210: while (temp_pos < out_line->line_length)
2211: {
2212: fputwc(*tmp_point, temp_fp);
2213: tmp_point++;
2214: temp_pos++;
2215: }
2216: charac += out_line->line_length;
2217: out_line = out_line->next_line;
2218: fputwc(cr, temp_fp);
2219: lines++;
2220: }
2221: fclose(temp_fp);
2222: wmove(com_win,0,0);
2223: wclrtoeol(com_win);
2224: wprintw(com_win, file_written_msg, file_name, lines, charac);
2225: wrefresh(com_win);
2226: return(TRUE);
2227: }
2228: }
2229: else
2230: return(FALSE);
2231: }
2232:
2233: int
2234: search(display_message) /* search for string in srch_str */
2235: int display_message;
2236: {
2237: int lines_moved;
2238: int iter;
2239: int found;
2240:
2241: if ((srch_str == NULL) || (*srch_str == '\0'))
2242: return(FALSE);
2243: if (display_message)
2244: {
2245: wmove(com_win, 0, 0);
2246: wclrtoeol(com_win);
2247: wprintw(com_win, searching_msg);
2248: wrefresh(com_win);
2249: clear_com_win = TRUE;
2250: }
2251: lines_moved = 0;
2252: found = FALSE;
2253: srch_line = curr_line;
2254: srch_1 = point;
2255: if (position < curr_line->line_length)
2256: srch_1++;
2257: iter = position + 1;
2258: while ((!found) && (srch_line != NULL))
2259: {
2260: while ((iter < srch_line->line_length) && (!found))
2261: {
2262: srch_2 = srch_1;
2263: if (case_sen) /* if case sensitive */
2264: {
2265: srch_3 = srch_str;
2266: while ((*srch_2 == *srch_3) && (*srch_3 != '\0'))
2267: {
2268: found = TRUE;
2269: srch_2++;
2270: srch_3++;
2271: } /* end while */
2272: }
2273: else /* if not case sensitive */
2274: {
2275: srch_3 = u_srch_str;
2276: while ((toupper(*srch_2) == *srch_3) && (*srch_3 != '\0'))
2277: {
2278: found = TRUE;
2279: srch_2++;
2280: srch_3++;
2281: }
2282: } /* end else */
2283: if (!((*srch_3 == '\0') && (found)))
2284: {
2285: found = FALSE;
2286: if (iter < srch_line->line_length)
2287: srch_1++;
2288: iter++;
2289: }
2290: }
2291: if (!found)
2292: {
2293: srch_line = srch_line->next_line;
2294: if (srch_line != NULL)
2295: srch_1 = srch_line->line;
2296: iter = 1;
2297: lines_moved++;
2298: }
2299: }
2300: if (found)
2301: {
2302: if (display_message)
2303: {
2304: wmove(com_win, 0, 0);
2305: wclrtoeol(com_win);
2306: wrefresh(com_win);
2307: }
2308: if (lines_moved == 0)
2309: {
2310: while (position < iter)
2311: right(TRUE);
2312: }
2313: else
2314: {
2315: if (lines_moved < 30)
2316: {
2317: move_rel('d', lines_moved);
2318: while (position < iter)
2319: right(TRUE);
2320: }
2321: else
2322: {
2323: curr_line = srch_line;
2324: point = srch_1;
2325: position = iter;
2326: scanline(point);
2327: scr_pos = scr_horz;
2328: midscreen((last_line / 2), point);
2329: }
2330: }
2331: }
2332: else
2333: {
2334: if (display_message)
2335: {
2336: wmove(com_win, 0, 0);
2337: wclrtoeol(com_win);
2338: wprintw(com_win, str_not_found_msg, srch_str);
2339: wrefresh(com_win);
2340: }
2341: wmove(text_win, scr_vert,(scr_horz - horiz_offset));
2342: }
2343: return(found);
2344: }
2345:
2346: void
2347: search_prompt() /* prompt and read search string (srch_str) */
2348: {
2349: if (srch_str != NULL)
2350: free(srch_str);
2351: if ((u_srch_str != NULL) && (*u_srch_str != '\0'))
2352: free(u_srch_str);
2353: srch_str = get_string(search_prompt_str, FALSE);
2354: gold = FALSE;
2355: srch_3 = srch_str;
2356: srch_1 = u_srch_str = (wchar_t*)malloc((wcslen(srch_str) + 1) * sizeof(wchar_t));
2357: while (*srch_3 != '\0')
2358: {
2359: *srch_1 = toupper(*srch_3);
2360: srch_1++;
2361: srch_3++;
2362: }
2363: *srch_1 = '\0';
2364: search(TRUE);
2365: }
2366:
2367: void
2368: del_char() /* delete current character */
2369: {
2370: in = 8; /* backspace */
2371: if (position < curr_line->line_length) /* if not end of line */
2372: {
2373: if ((*point > 127) && ((curr_line->line_length - position) >= 2))
2374: {
2375: point++;
2376: position++;
2377: }
2378: position++;
2379: point++;
2380: scanline(point);
2381: delete(TRUE);
2382: }
2383: else
2384: {
2385: right(FALSE);
2386: delete(FALSE);
2387: }
2388: }
2389:
2390: void
2391: undel_char() /* undelete last deleted character */
2392: {
2393: if (d_char[0] == '\n') /* insert line if last del_char deleted eol */
2394: insert_line(TRUE);
2395: else
2396: {
2397: in = d_char[0];
2398: insert(in);
2399: if (d_char[1] != '\0')
2400: {
2401: in = d_char[1];
2402: insert(in);
2403: }
2404: }
2405: }
2406:
2407: void
2408: del_word() /* delete word in front of cursor */
2409: {
2410: int tposit;
2411: int difference;
2412: wchar_t *d_word2;
2413: wchar_t *d_word3;
2414: wchar_t tmp_char[3];
2415:
2416: if (d_word != NULL)
2417: free(d_word);
2418: d_word = (wchar_t*)malloc(curr_line->line_length * sizeof(wchar_t));
2419: tmp_char[0] = d_char[0];
2420: tmp_char[1] = d_char[1];
2421: tmp_char[2] = d_char[2];
2422: d_word3 = point;
2423: d_word2 = d_word;
2424: tposit = position;
2425: while ((tposit < curr_line->line_length) &&
2426: ((*d_word3 != ' ') && (*d_word3 != '\t')))
2427: {
2428: tposit++;
2429: *d_word2 = *d_word3;
2430: d_word2++;
2431: d_word3++;
2432: }
2433: while ((tposit < curr_line->line_length) &&
2434: ((*d_word3 == ' ') || (*d_word3 == '\t')))
2435: {
2436: tposit++;
2437: *d_word2 = *d_word3;
2438: d_word2++;
2439: d_word3++;
2440: }
2441: *d_word2 = '\0';
2442: d_wrd_len = difference = d_word2 - d_word;
2443: d_word2 = point;
2444: while (tposit < curr_line->line_length)
2445: {
2446: tposit++;
2447: *d_word2 = *d_word3;
2448: d_word2++;
2449: d_word3++;
2450: }
2451: curr_line->line_length -= difference;
2452: *d_word2 = '\0';
2453: draw_line(scr_vert, scr_horz,point,position,curr_line->line_length);
2454: d_char[0] = tmp_char[0];
2455: d_char[1] = tmp_char[1];
2456: d_char[2] = tmp_char[2];
2457: text_changes = TRUE;
2458: formatted = FALSE;
2459: }
2460:
2461: void
2462: undel_word() /* undelete last deleted word */
2463: {
2464: int temp;
2465: int tposit;
2466: wchar_t *tmp_old_ptr;
2467: wchar_t *tmp_space;
2468: wchar_t *tmp_ptr;
2469: wchar_t *d_word_ptr;
2470:
2471: /*
2472: | resize line to handle undeleted word
2473: */
2474: if ((curr_line->max_length - (curr_line->line_length + d_wrd_len)) < 5)
2475: point = resiz_line(d_wrd_len, curr_line, position);
2476: tmp_ptr = tmp_space = (wchar_t*)malloc((curr_line->line_length + d_wrd_len) * sizeof(wchar_t));
2477: d_word_ptr = d_word;
2478: temp = 1;
2479: /*
2480: | copy d_word contents into temp space
2481: */
2482: while (temp <= d_wrd_len)
2483: {
2484: temp++;
2485: *tmp_ptr = *d_word_ptr;
2486: tmp_ptr++;
2487: d_word_ptr++;
2488: }
2489: tmp_old_ptr = point;
2490: tposit = position;
2491: /*
2492: | copy contents of line from curent position to eol into
2493: | temp space
2494: */
2495: while (tposit < curr_line->line_length)
2496: {
2497: temp++;
2498: tposit++;
2499: *tmp_ptr = *tmp_old_ptr;
2500: tmp_ptr++;
2501: tmp_old_ptr++;
2502: }
2503: curr_line->line_length += d_wrd_len;
2504: tmp_old_ptr = point;
2505: *tmp_ptr = '\0';
2506: tmp_ptr = tmp_space;
2507: tposit = 1;
2508: /*
2509: | now copy contents from temp space back to original line
2510: */
2511: while (tposit < temp)
2512: {
2513: tposit++;
2514: *tmp_old_ptr = *tmp_ptr;
2515: tmp_ptr++;
2516: tmp_old_ptr++;
2517: }
2518: *tmp_old_ptr = '\0';
2519: free(tmp_space);
2520: draw_line(scr_vert, scr_horz, point, position, curr_line->line_length);
2521: }
2522:
2523: void
2524: del_line() /* delete from cursor to end of line */
2525: {
2526: wchar_t *dl1;
2527: wchar_t *dl2;
2528: int tposit;
2529:
2530: if (d_line != NULL)
2531: free(d_line);
2532: d_line = (wchar_t*)malloc(curr_line->line_length * sizeof(wchar_t));
2533: dl1 = d_line;
2534: dl2 = point;
2535: tposit = position;
2536: while (tposit < curr_line->line_length)
2537: {
2538: *dl1 = *dl2;
2539: dl1++;
2540: dl2++;
2541: tposit++;
2542: }
2543: dlt_line->line_length = 1 + tposit - position;
2544: *dl1 = *point = '\0';
2545: curr_line->line_length = position;
2546: wclrtoeol(text_win);
2547: if (curr_line->next_line != NULL)
2548: {
2549: right(FALSE);
2550: delete(FALSE);
2551: }
2552: text_changes = TRUE;
2553: }
2554:
2555: void
2556: undel_line() /* undelete last deleted line */
2557: {
2558: wchar_t *ud1;
2559: wchar_t *ud2;
2560: int tposit;
2561:
2562: if (dlt_line->line_length == 0)
2563: return;
2564:
2565: insert_line(TRUE);
2566: left(TRUE);
2567: point = resiz_line(dlt_line->line_length, curr_line, position);
2568: curr_line->line_length += dlt_line->line_length - 1;
2569: ud1 = point;
2570: ud2 = d_line;
2571: tposit = 1;
2572: while (tposit < dlt_line->line_length)
2573: {
2574: tposit++;
2575: *ud1 = *ud2;
2576: ud1++;
2577: ud2++;
2578: }
2579: *ud1 = '\0';
2580: draw_line(scr_vert, scr_horz,point,position,curr_line->line_length);
2581: }
2582:
2583: void
2584: adv_word() /* advance to next word */
2585: {
2586: while ((position < curr_line->line_length) && ((*point != 32) && (*point != 9)))
2587: right(TRUE);
2588: while ((position < curr_line->line_length) && ((*point == 32) || (*point == 9)))
2589: right(TRUE);
2590: }
2591:
2592: void move_rel(char direction, int lines) /* move relative to current line */
2593: {
2594: int i;
2595: wchar_t *tmp;
2596:
2597: if (direction == 'u')
2598: {
2599: scr_pos = 0;
2600: while (position > 1)
2601: left(TRUE);
2602: for (i = 0; i < lines; i++)
2603: {
2604: up();
2605: }
2606: if ((last_line > 5) && ( scr_vert < 4))
2607: {
2608: tmp = point;
2609: tmp_line = curr_line;
2610: for (i= 0;(i<5)&&(curr_line->prev_line != NULL); i++)
2611: {
2612: up();
2613: }
2614: scr_vert = scr_vert + i;
2615: curr_line = tmp_line;
2616: point = tmp;
2617: scanline(point);
2618: }
2619: }
2620: else
2621: {
2622: if ((position != 1) && (curr_line->next_line != NULL))
2623: {
2624: nextline();
2625: scr_pos = scr_horz = 0;
2626: if (horiz_offset)
2627: {
2628: horiz_offset = 0;
2629: midscreen(scr_vert, point);
2630: }
2631: }
2632: else
2633: adv_line();
2634: for (i = 1; i < lines; i++)
2635: {
2636: down();
2637: }
2638: if ((last_line > 10) && (scr_vert > (last_line - 5)))
2639: {
2640: tmp = point;
2641: tmp_line = curr_line;
2642: for (i=0; (i<5) && (curr_line->next_line != NULL); i++)
2643: {
2644: down();
2645: }
2646: scr_vert = scr_vert - i;
2647: curr_line = tmp_line;
2648: point = tmp;
2649: scanline(point);
2650: }
2651: }
2652: wmove(text_win, scr_vert, (scr_horz - horiz_offset));
2653: }
2654:
2655: void
2656: eol() /* go to end of line */
2657: {
2658: if (position < curr_line->line_length)
2659: {
2660: while (position < curr_line->line_length)
2661: right(TRUE);
2662: }
2663: else if (curr_line->next_line != NULL)
2664: {
2665: right(TRUE);
2666: while (position < curr_line->line_length)
2667: right(TRUE);
2668: }
2669: }
2670:
2671: void
2672: bol() /* move to beginning of line */
2673: {
2674: if (point != curr_line->line)
2675: {
2676: while (point != curr_line->line)
2677: left(TRUE);
2678: }
2679: else if (curr_line->prev_line != NULL)
2680: {
2681: scr_pos = 0;
2682: up();
2683: }
2684: }
2685:
2686: void
2687: adv_line() /* advance to beginning of next line */
2688: {
2689: if ((point != curr_line->line) || (scr_pos > 0))
2690: {
2691: while (position < curr_line->line_length)
2692: right(TRUE);
2693: right(TRUE);
2694: }
2695: else if (curr_line->next_line != NULL)
2696: {
2697: scr_pos = 0;
2698: down();
2699: }
2700: }
2701:
2702: void
2703: set_up_term() /* set up the terminal for operating with ae */
2704: {
2705: if (!curses_initialized)
2706: {
2707: initscr();
2708: savetty();
2709: noecho();
2710: raw();
2711: nonl();
2712: curses_initialized = TRUE;
2713: }
2714:
2715: if (((LINES > 15) && (COLS >= 80)) && info_window)
2716: last_line = LINES - 8;
2717: else
2718: {
2719: info_window = FALSE;
2720: last_line = LINES - 2;
2721: }
2722:
2723: idlok(stdscr, TRUE);
2724: com_win = newwin(1, COLS, (LINES - 1), 0);
2725: keypad(com_win, TRUE);
2726: idlok(com_win, TRUE);
2727: wrefresh(com_win);
2728: if (!info_window)
2729: text_win = newwin((LINES - 1), COLS, 0, 0);
2730: else
2731: text_win = newwin((LINES - 7), COLS, 6, 0);
2732: keypad(text_win, TRUE);
2733: idlok(text_win, TRUE);
2734: wrefresh(text_win);
2735: help_win = newwin((LINES - 1), COLS, 0, 0);
2736: keypad(help_win, TRUE);
2737: idlok(help_win, TRUE);
2738: if (info_window)
2739: {
2740: info_type = CONTROL_KEYS;
2741: info_win = newwin(6, COLS, 0, 0);
2742: werase(info_win);
2743: paint_info_win();
2744: }
2745:
2746: last_col = COLS - 1;
2747: local_LINES = LINES;
2748: local_COLS = COLS;
2749: }
2750:
2751: void
2752: resize_check()
2753: {
2754: if ((LINES == local_LINES) && (COLS == local_COLS))
2755: return;
2756:
2757: if (info_window)
2758: delwin(info_win);
2759: delwin(text_win);
2760: delwin(com_win);
2761: delwin(help_win);
2762: set_up_term();
2763: redraw();
2764: wrefresh(text_win);
2765: }
2766:
2767: static char item_alpha[] = "abcdefghijklmnopqrstuvwxyz0123456789 ";
2768:
2769: int menu_op(struct menu_entries menu_list[])
2770: {
2771: WINDOW *temp_win;
2772: int max_width, max_height;
2773: int x_off, y_off;
2774: int counter;
2775: int length;
2776: int input;
2777: int temp = 0;
2778: int list_size;
2779: int top_offset; /* offset from top where menu items start */
2780: int vert_size; /* vertical size for menu list item display */
2781: int off_start = 1; /* offset from start of menu items to start display */
2782:
2783:
2784: /*
2785: | determine number and width of menu items
2786: */
2787:
2788: list_size = 1;
2789: while (menu_list[list_size + 1].item_string != NULL)
2790: list_size++;
2791: max_width = 0;
2792: for (counter = 0; counter <= list_size; counter++)
2793: {
2794: if ((length = wcslen(menu_list[counter].item_string)) > max_width)
2795: max_width = length;
2796: }
2797: max_width += 3;
2798: max_width = max(max_width, wcslen(menu_cancel_msg));
2799: max_width = max(max_width, max(wcslen(more_above_str), wcslen(more_below_str)));
2800: max_width += 6;
2801:
2802: /*
2803: | make sure that window is large enough to handle menu
2804: | if not, print error message and return to calling function
2805: */
2806:
2807: if (max_width > COLS)
2808: {
2809: wmove(com_win, 0, 0);
2810: werase(com_win);
2811: wprintw(com_win, menu_too_lrg_msg);
2812: wrefresh(com_win);
2813: clear_com_win = TRUE;
2814: return(0);
2815: }
2816:
2817: top_offset = 0;
2818:
2819: if (list_size > LINES)
2820: {
2821: max_height = LINES;
2822: if (max_height > 11)
2823: vert_size = max_height - 8;
2824: else
2825: vert_size = max_height;
2826: }
2827: else
2828: {
2829: vert_size = list_size;
2830: max_height = list_size;
2831: }
2832:
2833: if (LINES >= (vert_size + 8))
2834: {
2835: if (menu_list[0].argument != MENU_WARN)
2836: max_height = vert_size + 8;
2837: else
2838: max_height = vert_size + 7;
2839: top_offset = 4;
2840: }
2841: x_off = (COLS - max_width) / 2;
2842: y_off = (LINES - max_height - 1) / 2;
2843: temp_win = newwin(max_height, max_width, y_off, x_off);
2844: keypad(temp_win, TRUE);
2845:
2846: paint_menu(menu_list, max_width, max_height, list_size, top_offset, temp_win, off_start, vert_size);
2847:
2848: counter = 1;
2849: do
2850: {
2851: int keyt;
2852: if (off_start > 2)
2853: wmove(temp_win, (1 + counter + top_offset - off_start), 3);
2854: else
2855: wmove(temp_win, (counter + top_offset - off_start), 3);
2856:
2857: wrefresh(temp_win);
2858: keyt = wget_wch(temp_win, &in);
2859: input = in;
2860: if (keyt == ERR)
2861: exit(0);
2862:
2863: if (keyt == OK && isalnum(tolower(input)))
2864: {
2865: if (isalpha(tolower(input)))
2866: {
2867: temp = 1 + tolower(input) - 'a';
2868: }
2869: else if (isdigit(input))
2870: {
2871: temp = (2 + 'z' - 'a') + (input - '0');
2872: }
2873:
2874: if (temp <= list_size)
2875: {
2876: input = '\n';
2877: counter = temp;
2878: }
2879: }
2880: else if (keyt == OK)
2881: {
2882: switch (input)
2883: {
2884: case ' ': /* space */
2885: case '\004': /* ^d, down */
2886: counter++;
2887: if (counter > list_size)
2888: counter = 1;
2889: break;
2890: case '\010': /* ^h, backspace*/
2891: case '\025': /* ^u, up */
2892: case 127: /* ^?, delete */
2893: counter--;
2894: if (counter == 0)
2895: counter = list_size;
2896: break;
2897: case '\033': /* escape key */
2898: if (menu_list[0].argument != MENU_WARN)
2899: counter = 0;
2900: break;
2901: case '\014': /* ^l */
2902: case '\022': /* ^r, redraw */
2903: paint_menu(menu_list, max_width, max_height,
2904: list_size, top_offset, temp_win,
2905: off_start, vert_size);
2906: break;
2907: default:
2908: break;
2909: }
2910: }
2911: else
2912: {
2913: switch (input)
2914: {
2915: case KEY_RIGHT:
2916: case KEY_DOWN:
2917: counter++;
2918: if (counter > list_size)
2919: counter = 1;
2920: break;
2921: case 127: /* ^?, delete */
2922: case KEY_BACKSPACE:
2923: case KEY_LEFT:
2924: case KEY_UP:
2925: counter--;
2926: if (counter == 0)
2927: counter = list_size;
2928: break;
2929: case '\033': /* escape key */
2930: if (menu_list[0].argument != MENU_WARN)
2931: counter = 0;
2932: break;
2933: case '\014': /* ^l */
2934: case '\022': /* ^r, redraw */
2935: paint_menu(menu_list, max_width, max_height,
2936: list_size, top_offset, temp_win,
2937: off_start, vert_size);
2938: break;
2939: default:
2940: break;
2941: }
2942: }
2943:
2944: if (((list_size - off_start) >= (vert_size - 1)) &&
2945: (counter > (off_start + vert_size - 3)) &&
2946: (off_start > 1))
2947: {
2948: if (counter == list_size)
2949: off_start = (list_size - vert_size) + 2;
2950: else
2951: off_start++;
2952:
2953: paint_menu(menu_list, max_width, max_height,
2954: list_size, top_offset, temp_win, off_start,
2955: vert_size);
2956: }
2957: else if ((list_size != vert_size) &&
2958: (counter > (off_start + vert_size - 2)))
2959: {
2960: if (counter == list_size)
2961: off_start = 2 + (list_size - vert_size);
2962: else if (off_start == 1)
2963: off_start = 3;
2964: else
2965: off_start++;
2966:
2967: paint_menu(menu_list, max_width, max_height,
2968: list_size, top_offset, temp_win, off_start,
2969: vert_size);
2970: }
2971: else if (counter < off_start)
2972: {
2973: if (counter <= 2)
2974: off_start = 1;
2975: else
2976: off_start = counter;
2977:
2978: paint_menu(menu_list, max_width, max_height,
2979: list_size, top_offset, temp_win, off_start,
2980: vert_size);
2981: }
2982: }
2983: while ((input != '\r') && (input != '\n') && (counter != 0));
2984:
2985: werase(temp_win);
2986: wrefresh(temp_win);
2987: delwin(temp_win);
2988:
2989: if ((menu_list[counter].procedure != NULL) ||
2990: (menu_list[counter].iprocedure != NULL) ||
2991: (menu_list[counter].nprocedure != NULL))
2992: {
2993: if (menu_list[counter].argument != -1)
2994: (*menu_list[counter].iprocedure)(menu_list[counter].argument);
2995: else if (menu_list[counter].ptr_argument != NULL)
2996: (*menu_list[counter].procedure)(menu_list[counter].ptr_argument);
2997: else
2998: (*menu_list[counter].nprocedure)();
2999: }
3000:
3001: if (info_window)
3002: paint_info_win();
3003: redraw();
3004:
3005: return(counter);
3006: }
3007:
3008: void
3009: paint_menu(menu_list, max_width, max_height, list_size, top_offset, menu_win,
3010: off_start, vert_size)
3011: struct menu_entries menu_list[];
3012: int max_width, max_height, list_size, top_offset;
3013: WINDOW *menu_win;
3014: int off_start, vert_size;
3015: {
3016: int counter, temp_int;
3017:
3018: werase(menu_win);
3019:
3020: /*
3021: | output top and bottom portions of menu box only if window
3022: | large enough
3023: */
3024:
3025: if (max_height > vert_size)
3026: {
3027: wmove(menu_win, 1, 1);
3028: if (!nohighlight)
3029: wstandout(menu_win);
3030: waddch(menu_win, '+');
3031: for (counter = 0; counter < (max_width - 4); counter++)
3032: waddch(menu_win, '-');
3033: waddch(menu_win, '+');
3034:
3035: wmove(menu_win, (max_height - 2), 1);
3036: waddch(menu_win, '+');
3037: for (counter = 0; counter < (max_width - 4); counter++)
3038: waddch(menu_win, '-');
3039: waddch(menu_win, '+');
3040: wstandend(menu_win);
3041: wmove(menu_win, 2, 3);
3042: waddwstr(menu_win, menu_list[0].item_string);
3043: wmove(menu_win, (max_height - 3), 3);
3044: if (menu_list[0].argument != MENU_WARN)
3045: waddwstr(menu_win, menu_cancel_msg);
3046: }
3047: if (!nohighlight)
3048: wstandout(menu_win);
3049:
3050: for (counter = 0; counter < (vert_size + top_offset); counter++)
3051: {
3052: if (top_offset == 4)
3053: {
3054: temp_int = counter + 2;
3055: }
3056: else
3057: temp_int = counter;
3058:
3059: wmove(menu_win, temp_int, 1);
3060: waddch(menu_win, '|');
3061: wmove(menu_win, temp_int, (max_width - 2));
3062: waddch(menu_win, '|');
3063: }
3064: wstandend(menu_win);
3065:
3066: if (list_size > vert_size)
3067: {
3068: if (off_start >= 3)
3069: {
3070: temp_int = 1;
3071: wmove(menu_win, top_offset, 3);
3072: waddwstr(menu_win, more_above_str);
3073: }
3074: else
3075: temp_int = 0;
3076:
3077: for (counter = off_start;
3078: ((temp_int + counter - off_start) < (vert_size - 1));
3079: counter++)
3080: {
3081: wmove(menu_win, (top_offset + temp_int +
3082: (counter - off_start)), 3);
3083: if (list_size > 1)
3084: wprintw(menu_win, "%c) ", item_alpha[min((counter - 1), max_alpha_char)]);
3085: waddwstr(menu_win, menu_list[counter].item_string);
3086: }
3087:
3088: wmove(menu_win, (top_offset + (vert_size - 1)), 3);
3089:
3090: if (counter == list_size)
3091: {
3092: if (list_size > 1)
3093: wprintw(menu_win, "%c) ", item_alpha[min((counter - 1), max_alpha_char)]);
3094: waddwstr(menu_win, menu_list[counter].item_string);
3095: }
3096: else
3097: waddwstr(menu_win, more_below_str);
3098: }
3099: else
3100: {
3101: for (counter = 1; counter <= list_size; counter++)
3102: {
3103: wmove(menu_win, (top_offset + counter - 1), 3);
3104: if (list_size > 1)
3105: wprintw(menu_win, "%c) ", item_alpha[min((counter - 1), max_alpha_char)]);
3106: waddwstr(menu_win, menu_list[counter].item_string);
3107: }
3108: }
3109: }
3110:
3111: void
3112: help()
3113: {
3114: int counter, dummy;
3115:
3116: werase(help_win);
3117: clearok(help_win, TRUE);
3118: for (counter = 0; counter < 22; counter++)
3119: {
3120: wmove(help_win, counter, 0);
3121: waddwstr(help_win, (emacs_keys_mode) ?
3122: emacs_help_text[counter] : help_text[counter]);
3123: }
3124: wrefresh(help_win);
3125: werase(com_win);
3126: wmove(com_win, 0, 0);
3127: waddwstr(com_win, press_any_key_msg);
3128: wrefresh(com_win);
3129: counter = wget_wch(com_win, &dummy);
3130: if (counter == ERR)
3131: exit(0);
3132: werase(com_win);
3133: wmove(com_win, 0, 0);
3134: werase(help_win);
3135: wrefresh(help_win);
3136: wrefresh(com_win);
3137: redraw();
3138: }
3139:
3140: void
3141: paint_info_win()
3142: {
3143: int counter;
3144:
3145: if (!info_window)
3146: return;
3147:
3148: werase(info_win);
3149: for (counter = 0; counter < 5; counter++)
3150: {
3151: wmove(info_win, counter, 0);
3152: wclrtoeol(info_win);
3153: if (info_type == CONTROL_KEYS)
3154: waddwstr(info_win, (emacs_keys_mode) ?
3155: emacs_control_keys[counter] : control_keys[counter]);
3156: else if (info_type == COMMANDS)
3157: waddwstr(info_win, command_strings[counter]);
3158: }
3159: wmove(info_win, 5, 0);
3160: if (!nohighlight)
3161: wstandout(info_win);
3162: waddstr(info_win, "===============================================================================");
3163: wstandend(info_win);
3164: wrefresh(info_win);
3165: }
3166:
3167: void
3168: no_info_window()
3169: {
3170: if (!info_window)
3171: return;
3172: delwin(info_win);
3173: delwin(text_win);
3174: info_window = FALSE;
3175: last_line = LINES - 2;
3176: text_win = newwin((LINES - 1), COLS, 0, 0);
3177: keypad(text_win, TRUE);
3178: idlok(text_win, TRUE);
3179: clearok(text_win, TRUE);
3180: midscreen(scr_vert, point);
3181: wrefresh(text_win);
3182: clear_com_win = TRUE;
3183: }
3184:
3185: void
3186: create_info_window()
3187: {
3188: if (info_window)
3189: return;
3190: last_line = LINES - 8;
3191: delwin(text_win);
3192: text_win = newwin((LINES - 7), COLS, 6, 0);
3193: keypad(text_win, TRUE);
3194: idlok(text_win, TRUE);
3195: werase(text_win);
3196: info_window = TRUE;
3197: info_win = newwin(6, COLS, 0, 0);
3198: werase(info_win);
3199: info_type = CONTROL_KEYS;
3200: midscreen(min(scr_vert, last_line), point);
3201: clearok(info_win, TRUE);
3202: paint_info_win();
3203: wrefresh(text_win);
3204: clear_com_win = TRUE;
3205: }
3206:
3207: int
3208: file_op(arg)
3209: int arg;
3210: {
3211: char *string;
3212: int flag;
3213:
3214: if (arg == SAVE_FILE)
3215: {
3216: /*
3217: | changes made here should be reflected in ee_finish()
3218: */
3219:
3220: if (in_file_name)
3221: flag = TRUE;
3222: else
3223: flag = FALSE;
3224:
3225: string = in_file_name;
3226: // if ((string == NULL) || (*string == '\0'))
3227: // string = get_string(save_file_name_prompt, TRUE);
3228: if ((string == NULL) || (*string == '\0'))
3229: {
3230: wmove(com_win, 0, 0);
3231: wprintw(com_win, file_not_saved_msg);
3232: wclrtoeol(com_win);
3233: wrefresh(com_win);
3234: clear_com_win = TRUE;
3235: return(0);
3236: }
3237: if (write_file(string, -1))
3238: {
3239: in_file_name = string;
3240: text_changes = FALSE;
3241: }
3242: else if (!flag)
3243: free(string);
3244: }
3245: return(0);
3246: }
3247:
3248: void
3249: leave_op()
3250: {
3251: if (text_changes)
3252: {
3253: menu_op(leave_menu);
3254: }
3255: else
3256: quit(TRUE);
3257: }
3258:
3259: void
3260: redraw()
3261: {
3262: if (info_window)
3263: {
3264: clearok(info_win, TRUE);
3265: paint_info_win();
3266: }
3267: else
3268: clearok(text_win, TRUE);
3269: midscreen(scr_vert, point);
3270: }
3271:
3272: /*
3273: | The following routines will "format" a paragraph (as defined by a
3274: | block of text with blank lines before and after the block).
3275: */
3276:
3277: int
3278: Blank_Line(test_line) /* test if line has any non-space characters */
3279: struct text *test_line;
3280: {
3281: wchar_t *line;
3282: int length;
3283:
3284: if (test_line == NULL)
3285: return(TRUE);
3286:
3287: length = 1;
3288: line = test_line->line;
3289:
3290: /*
3291: | To handle troff/nroff documents, consider a line with a
3292: | period ('.') in the first column to be blank. To handle mail
3293: | messages with included text, consider a line with a '>' blank.
3294: */
3295:
3296: if ((*line == '.') || (*line == '>'))
3297: return(TRUE);
3298:
3299: while (((*line == ' ') || (*line == '\t')) && (length < test_line->line_length))
3300: {
3301: length++;
3302: line++;
3303: }
3304: if (length != test_line->line_length)
3305: return(FALSE);
3306: else
3307: return(TRUE);
3308: }
3309:
3310: void
3311: echo_string(string) /* echo the given string */
3312: wchar_t *string;
3313: {
3314: wchar_t *temp;
3315: int Counter;
3316:
3317: temp = string;
3318: while (*temp != '\0')
3319: {
3320: if (*temp == '\\')
3321: {
3322: temp++;
3323: if (*temp == 'n')
3324: putchar('\n');
3325: else if (*temp == 't')
3326: putchar('\t');
3327: else if (*temp == 'b')
3328: putchar('\b');
3329: else if (*temp == 'r')
3330: putchar('\r');
3331: else if (*temp == 'f')
3332: putchar('\f');
3333: else if ((*temp == 'e') || (*temp == 'E'))
3334: putchar('\033'); /* escape */
3335: else if (*temp == '\\')
3336: putchar('\\');
3337: else if (*temp == '\'')
3338: putchar('\'');
3339: else if ((*temp >= '0') && (*temp <= '9'))
3340: {
3341: Counter = 0;
3342: while ((*temp >= '0') && (*temp <= '9'))
3343: {
3344: Counter = (8 * Counter) + (*temp - '0');
3345: temp++;
3346: }
3347: putchar(Counter);
3348: temp--;
3349: }
3350: temp++;
3351: }
3352: else
3353: {
3354: putchar(*temp);
3355: temp++;
3356: }
3357: }
3358:
3359: fflush(stdout);
3360: }
3361:
3362: int
3363: first_word_len(test_line)
3364: struct text *test_line;
3365: {
3366: int counter;
3367: wchar_t *pnt;
3368:
3369: if (test_line == NULL)
3370: return(0);
3371:
3372: pnt = test_line->line;
3373: if ((pnt == NULL) || (*pnt == '\0') ||
3374: (*pnt == '.') || (*pnt == '>'))
3375: return(0);
3376:
3377: if ((*pnt == ' ') || (*pnt == '\t'))
3378: {
3379: pnt = next_word(pnt);
3380: }
3381:
3382: if (*pnt == '\0')
3383: return(0);
3384:
3385: counter = 0;
3386: while ((*pnt != '\0') && ((*pnt != ' ') && (*pnt != '\t')))
3387: {
3388: pnt++;
3389: counter++;
3390: }
3391: while ((*pnt != '\0') && ((*pnt == ' ') || (*pnt == '\t')))
3392: {
3393: pnt++;
3394: counter++;
3395: }
3396: return(counter);
3397: }
3398:
3399: wchar_t *
3400: is_in_string(string, substring) /* a strchr() look-alike for systems without
3401: strchr() */
3402: wchar_t * string, *substring;
3403: {
3404: wchar_t *full, *sub;
3405:
3406: for (sub = substring; (sub != NULL) && (*sub != '\0'); sub++)
3407: {
3408: for (full = string; (full != NULL) && (*full != '\0');
3409: full++)
3410: {
3411: if (*sub == *full)
3412: return(full);
3413: }
3414: }
3415: return(NULL);
3416: }
3417:
3418: /*
3419: | The following routine tests the input string against the list of
3420: | strings, to determine if the string is a unique match with one of the
3421: | valid values.
3422: */
3423:
3424: int
3425: unique_test(string, list)
3426: wchar_t *string;
3427: wchar_t *list[];
3428: {
3429: int counter;
3430: int num_match;
3431: int result;
3432:
3433: num_match = 0;
3434: counter = 0;
3435: while (list[counter] != NULL)
3436: {
3437: result = compare(string, list[counter], FALSE);
3438: if (result)
3439: num_match++;
3440: counter++;
3441: }
3442: return(num_match);
3443: }
3444:
3445: /*
3446: | The following is to allow for using message catalogs which allow
3447: | the software to be 'localized', that is, to use different languages
3448: | all with the same binary. For more information, see your system
3449: | documentation, or the X/Open Internationalization Guide.
3450: */
3451:
3452: void
3453: strings_init()
3454: {
3455: leave_menu[0].item_string = L"leave menu";
3456: leave_menu[1].item_string = L"save changes";
3457: leave_menu[2].item_string = L"no save";
3458: search_menu[0].item_string = L"search menu";
3459: search_menu[1].item_string = L"search for ...";
3460: search_menu[2].item_string = L"search";
3461: main_menu[0].item_string = L"main menu";
3462: main_menu[1].item_string = L"leave editor";
3463: main_menu[2].item_string = L"help";
3464: main_menu[3].item_string = L"save file";
3465: main_menu[4].item_string = L"redraw screen";
3466: main_menu[5].item_string = L"search";
3467: help_text[0] = L"Control keys: ";
3468: help_text[1] = L"^a ascii code ^i tab ^r right ";
3469: help_text[2] = L"^b bottom of text ^j newline ^t top of text ";
3470: help_text[3] = L"^c command ^k delete char ^u up ";
3471: help_text[4] = L"^d down ^l left ^v undelete word ";
3472: help_text[5] = L"^e search prompt ^m newline ^w delete word ";
3473: help_text[6] = L"^f undelete char ^n next page ^x search ";
3474: help_text[7] = L"^g begin of line ^o end of line ^y delete line ";
3475: help_text[8] = L"^h backspace ^p prev page ^z undelete line ";
3476: help_text[9] = L"^[ (escape) menu ";
3477: help_text[10] = L" ";
3478: help_text[11] = L"Commands: ";
3479: help_text[12] = L"help : get this info file : print file name ";
3480: help_text[13] = L"read : (disabled) char : ascii code of char ";
3481: help_text[14] = L"write : (disabled) case : case sensitive search ";
3482: help_text[15] = L"exit : leave and save nocase : case insensitive search ";
3483: help_text[16] = L"quit : leave, no save !cmd : (disabled) ";
3484: help_text[17] = L"line : display line # 0-9 : go to line \"#\" ";
3485: help_text[18] = L"expand : expand tabs noexpand: do not expand tabs ";
3486: help_text[19] = L" ";
3487: help_text[20] = L" ee [+#] [-i] [-e] [-h] [file(s)] ";
3488: help_text[21] = L"+# :go to line # -i :no info window -e : don't expand tabs -h :no highlight";
3489: control_keys[0] = L"^[ (escape) menu ^e search prompt ^y delete line ^u up ^p prev page ";
3490: control_keys[1] = L"^a ascii code ^x search ^z undelete line ^d down ^n next page ";
3491: control_keys[2] = L"^b bottom of text ^g begin of line ^w delete word ^l left ";
3492: control_keys[3] = L"^t top of text ^o end of line ^v undelete word ^r right ";
3493: control_keys[4] = L"^c command ^k delete char ^f undelete char ";
3494: command_strings[0] = L"help : get help info |file : print file name |line : print line # ";
3495: command_strings[1] = L"read : (disabled) |char : ascii code of char |0-9 : go to line \"#\"";
3496: command_strings[2] = L"save: save changes |case : case sensitive search |exit : leave and save ";
3497: command_strings[3] = L"!cmd : (disabled) |nocase: ignore case in search |quit : leave, no save";
3498: command_strings[4] = L"expand: expand tabs |noexpand: do not expand tabs ";
3499: com_win_message = L" press Escape (^[) for menu";
3500: no_file_string = "no file";
3501: ascii_code_str = L"ascii code: ";
3502: command_str = L"command: ";
3503: char_str = "character = %d";
3504: unkn_cmd_str = "unknown command \"%S\"";
3505: non_unique_cmd_msg = L"entered command is not unique";
3506: line_num_str = "line %d ";
3507: line_len_str = "length = %d";
3508: current_file_str = "current file is \"%S\" ";
3509: usage0 = L"usage: %s [-i] [-e] [-h] [+line_number] [file(s)]\n";
3510: usage1 = L" -i turn off info window\n";
3511: usage2 = L" -e do not convert tabs to spaces\n";
3512: usage3 = L" -h do not use highlighting\n";
3513: file_is_dir_msg = "file \"%s\" is a directory";
3514: new_file_msg = "new file \"%s\"";
3515: cant_open_msg = "can't open \"%s\"";
3516: open_file_msg = L"file \"%s\", %d lines";
3517: file_read_fin_msg = "finished reading file \"%s\"";
3518: reading_file_msg = "reading file \"%s\"";
3519: read_only_msg = ", read only";
3520: file_read_lines_msg = "file \"%s\", %d lines";
3521: save_file_name_prompt = L"enter name of file: ";
3522: file_not_saved_msg = "no filename entered: file not saved";
3523: changes_made_prompt = L"changes have been made, are you sure? (y/n [n]) ";
3524: yes_char = L"y";
3525: file_exists_prompt = L"file already exists, overwrite? (y/n) [n] ";
3526: create_file_fail_msg = "unable to create file \"%s\"";
3527: writing_file_msg = "writing file \"%s\"";
3528: file_written_msg = "\"%s\" %d lines, %d characters";
3529: searching_msg = " ...searching";
3530: str_not_found_msg = "string \"%S\" not found";
3531: search_prompt_str = L"search for: ";
3532: continue_msg = L"press return to continue ";
3533: menu_cancel_msg = L"press Esc to cancel";
3534: menu_size_err_msg = L"menu too large for window";
3535: press_any_key_msg = L"press any key to continue ";
3536: ON = L"ON";
3537: OFF = L"OFF";
3538: HELP = L"HELP";
3539: SAVE = L"SAVE";
3540: READ = L"READ";
3541: LINE = L"LINE";
3542: FILE_str = L"FILE";
3543: CHARACTER = L"CHARACTER";
3544: REDRAW = L"REDRAW";
3545: RESEQUENCE = L"RESEQUENCE";
3546: AUTHOR = L"AUTHOR";
3547: ee_VERSION = L"VERSION";
3548: CASE = L"CASE";
3549: NOCASE = L"NOCASE";
3550: EXPAND = L"EXPAND";
3551: NOEXPAND = L"NOEXPAND";
3552: Exit_string = L"EXIT";
3553: QUIT_string = L"QUIT";
3554: INFO = L"INFO";
3555: NOINFO = L"NOINFO";
3556: MARGINS = L"MARGINS";
3557: NOMARGINS = L"NOMARGINS";
3558: AUTOFORMAT = L"AUTOFORMAT";
3559: NOAUTOFORMAT = L"NOAUTOFORMAT";
3560: Echo = L"ECHO";
3561: PRINTCOMMAND = L"PRINTCOMMAND";
3562: RIGHTMARGIN = L"RIGHTMARGIN";
3563: HIGHLIGHT = L"HIGHLIGHT";
3564: NOHIGHLIGHT = L"NOHIGHLIGHT";
3565: EIGHTBIT = L"EIGHTBIT";
3566: NOEIGHTBIT = L"NOEIGHTBIT";
3567: /*
3568: | additions
3569: */
3570: emacs_help_text[0] = help_text[0];
3571: emacs_help_text[1] = L"^a beginning of line ^i tab ^r restore word ";
3572: emacs_help_text[2] = L"^b back 1 char ^j undel char ^t top of text ";
3573: emacs_help_text[3] = L"^c command ^k delete line ^u bottom of text ";
3574: emacs_help_text[4] = L"^d delete char ^l undelete line ^v next page ";
3575: emacs_help_text[5] = L"^e end of line ^m newline ^w delete word ";
3576: emacs_help_text[6] = L"^f forward 1 char ^n next line ^x search ";
3577: emacs_help_text[7] = L"^g go back 1 page ^o ascii char insert ^y search prompt ";
3578: emacs_help_text[8] = L"^h backspace ^p prev line ^z next word ";
3579: emacs_help_text[9] = help_text[9];
3580: emacs_help_text[10] = help_text[10];
3581: emacs_help_text[11] = help_text[11];
3582: emacs_help_text[12] = help_text[12];
3583: emacs_help_text[13] = help_text[13];
3584: emacs_help_text[14] = help_text[14];
3585: emacs_help_text[15] = help_text[15];
3586: emacs_help_text[16] = help_text[16];
3587: emacs_help_text[17] = help_text[17];
3588: emacs_help_text[18] = help_text[18];
3589: emacs_help_text[19] = help_text[19];
3590: emacs_help_text[20] = help_text[20];
3591: emacs_help_text[21] = help_text[21];
3592: emacs_control_keys[0] = L"^[ (escape) menu ^y search prompt ^k delete line ^p prev li ^g prev page";
3593: emacs_control_keys[1] = L"^o ascii code ^x search ^l undelete line ^n next li ^v next page";
3594: emacs_control_keys[2] = L"^u end of file ^a begin of line ^w delete word ^b back 1 char ";
3595: emacs_control_keys[3] = L"^t top of text ^e end of line ^r restore word ^f forward 1 char ";
3596: emacs_control_keys[4] = L"^c command ^d delete char ^j undelete char ^z next word ";
3597: EMACS_string = L"EMACS";
3598: NOEMACS_string = L"NOEMACS";
3599: usage4 = L" +# put cursor at line #\n";
3600: menu_too_lrg_msg = "menu too large for window";
3601: more_above_str = L"^^more^^";
3602: more_below_str = L"VVmoreVV";
3603:
3604:
3605: commands[0] = HELP;
3606: commands[1] = SAVE;
3607: commands[2] = READ;
3608: commands[3] = LINE;
3609: commands[4] = FILE_str;
3610: commands[5] = REDRAW;
3611: commands[6] = RESEQUENCE;
3612: commands[7] = AUTHOR;
3613: commands[8] = ee_VERSION;
3614: commands[9] = CASE;
3615: commands[10] = NOCASE;
3616: commands[11] = EXPAND;
3617: commands[12] = NOEXPAND;
3618: commands[13] = Exit_string;
3619: commands[14] = QUIT_string;
3620: commands[15] = L"<";
3621: commands[16] = L">";
3622: commands[17] = L"!";
3623: commands[18] = L"0";
3624: commands[19] = L"1";
3625: commands[20] = L"2";
3626: commands[21] = L"3";
3627: commands[22] = L"4";
3628: commands[23] = L"5";
3629: commands[24] = L"6";
3630: commands[25] = L"7";
3631: commands[26] = L"8";
3632: commands[27] = L"9";
3633: commands[28] = CHARACTER;
3634: commands[29] = NULL;
3635: }
3636:
CVSweb