diff options
author | ed <ed@FreeBSD.org> | 2009-05-26 20:13:17 +0000 |
---|---|---|
committer | ed <ed@FreeBSD.org> | 2009-05-26 20:13:17 +0000 |
commit | fbad22d013baa1ed80ce29fd090be19e99ed314c (patch) | |
tree | 802aed2d76270bc9fee21713d1e79973febde177 /contrib/ee/ee.c | |
parent | 6cf142b7b439d69ca0ee2ce20e9551f628a65110 (diff) | |
parent | cd2cd8f376f2d165e207cc5b80154f80bffbac4d (diff) | |
download | FreeBSD-src-fbad22d013baa1ed80ce29fd090be19e99ed314c.zip FreeBSD-src-fbad22d013baa1ed80ce29fd090be19e99ed314c.tar.gz |
Copy ee 1.4.2 into the contrib directory.
This allows me to merge our custom changes to ee(1) back on top of
original sources, with correct mergeinfo.
Diffstat (limited to 'contrib/ee/ee.c')
-rwxr-xr-x | contrib/ee/ee.c | 5268 |
1 files changed, 5268 insertions, 0 deletions
diff --git a/contrib/ee/ee.c b/contrib/ee/ee.c new file mode 100755 index 0000000..9a08dc4 --- /dev/null +++ b/contrib/ee/ee.c @@ -0,0 +1,5268 @@ +/* + | ee (easy editor) + | + | An easy to use, simple screen oriented editor. + | + | written by Hugh Mahon + | + | THIS MATERIAL IS PROVIDED "AS IS". THERE ARE + | NO WARRANTIES OF ANY KIND WITH REGARD TO THIS + | MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE + | IMPLIED WARRANTIES OF MERCHANTABILITY AND + | FITNESS FOR A PARTICULAR PURPOSE. Neither + | Hewlett-Packard nor Hugh Mahon shall be liable + | for errors contained herein, nor for + | incidental or consequential damages in + | connection with the furnishing, performance or + | use of this material. Neither Hewlett-Packard + | nor Hugh Mahon assumes any responsibility for + | the use or reliability of this software or + | documentation. This software and + | documentation is totally UNSUPPORTED. There + | is no support contract available. Hewlett- + | Packard has done NO Quality Assurance on ANY + | of the program or documentation. You may find + | the quality of the materials inferior to + | supported materials. + | + | This software is not a product of Hewlett-Packard, Co., or any + | other company. No support is implied or offered with this software. + | You've got the source, and you're on your own. + | + | This software may be distributed under the terms of Larry Wall's + | Artistic license, a copy of which is included in this distribution. + | + | This notice must be included with this software and any derivatives. + | + | This editor was purposely developed to be simple, both in + | interface and implementation. This editor was developed to + | address a specific audience: the user who is new to computers + | (especially UNIX). + | + | ee is not aimed at technical users; for that reason more + | complex features were intentionally left out. In addition, + | ee is intended to be compiled by people with little computer + | experience, which means that it needs to be small, relatively + | simple in implementation, and portable. + | + | This software and documentation contains + | proprietary information which is protected by + | copyright. All rights are reserved. + | + | $Header: /home/hugh/sources/old_ae/RCS/ee.c,v 1.96 1998/07/14 05:02:30 hugh Exp $ + | + */ + +char *ee_copyright_message = +"Copyright (c) 1986, 1990, 1991, 1992, 1993, 1994, 1995, 1996 Hugh Mahon "; + +char *ee_long_notice[] = { + "This software and documentation contains", + "proprietary information which is protected by", + "copyright. All rights are reserved." + }; + +char *version = "@(#) ee, version 1.4.1 $Revision: 1.96 $"; + +#ifdef NCURSE +#include "new_curse.h" +#else +#include <curses.h> +#endif + +#include <signal.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <string.h> +#include <pwd.h> + +#ifdef HAS_SYS_WAIT +#include <sys/wait.h> +#endif + +#ifdef HAS_STDLIB +#include <stdlib.h> +#endif + +#ifdef HAS_STDARG +#include <stdarg.h> +#endif + +#ifdef HAS_UNISTD +#include <unistd.h> +#endif + +#ifdef HAS_CTYPE +#include <ctype.h> +#endif + + +#ifndef NO_CATGETS +#include <locale.h> +#include <nl_types.h> + +nl_catd catalog; +#else +#define catgetlocal(a, b) (b) +#endif /* NO_CATGETS */ + +#ifndef SIGCHLD +#define SIGCHLD SIGCLD +#endif + +#define TAB 9 +#define max(a, b) (a > b ? a : b) +#define min(a, b) (a < b ? a : b) + +/* + | defines for type of data to show in info window + */ + +#define CONTROL_KEYS 1 +#define COMMANDS 2 + +struct text { + unsigned char *line; /* line of characters */ + int line_number; /* line number */ + int line_length; /* actual number of characters in the line */ + int max_length; /* maximum number of characters the line handles */ + struct text *next_line; /* next line of text */ + struct text *prev_line; /* previous line of text */ + }; + +struct text *first_line; /* first line of current buffer */ +struct text *dlt_line; /* structure for info on deleted line */ +struct text *curr_line; /* current line cursor is on */ +struct text *tmp_line; /* temporary line pointer */ +struct text *srch_line; /* temporary pointer for search routine */ + +struct files { /* structure to store names of files to be edited*/ + unsigned char *name; /* name of file */ + struct files *next_name; + }; + +struct files *top_of_stack = NULL; + +int d_wrd_len; /* length of deleted word */ +int position; /* offset in bytes from begin of line */ +int scr_pos; /* horizontal position */ +int scr_vert; /* vertical position on screen */ +int scr_horz; /* horizontal position on screen */ +int tmp_vert, tmp_horz; +int input_file; /* indicate to read input file */ +int recv_file; /* indicate reading a file */ +int edit; /* continue executing while true */ +int gold; /* 'gold' function key pressed */ +int fildes; /* file descriptor */ +int case_sen; /* case sensitive search flag */ +int last_line; /* last line for text display */ +int last_col; /* last column for text display */ +int horiz_offset = 0; /* offset from left edge of text */ +int clear_com_win; /* flag to indicate com_win needs clearing */ +int text_changes = FALSE; /* indicate changes have been made to text */ +int get_fd; /* file descriptor for reading a file */ +int info_window = TRUE; /* flag to indicate if help window visible */ +int info_type = CONTROL_KEYS; /* flag to indicate type of info to display */ +int expand_tabs = TRUE; /* flag for expanding tabs */ +int right_margin = 0; /* the right margin */ +int observ_margins = TRUE; /* flag for whether margins are observed */ +int shell_fork; +int temp_stdin; /* temporary storage for stdin */ +int temp_stdout; /* temp storage for stdout descriptor */ +int temp_stderr; /* temp storage for stderr descriptor */ +int pipe_out[2]; /* pipe file desc for output */ +int pipe_in[2]; /* pipe file descriptors for input */ +int out_pipe; /* flag that info is piped out */ +int in_pipe; /* flag that info is piped in */ +int formatted = FALSE; /* flag indicating paragraph formatted */ +int auto_format = FALSE; /* flag for auto_format mode */ +int restricted = FALSE; /* flag to indicate restricted mode */ +int nohighlight = FALSE; /* turns off highlighting */ +int eightbit = TRUE; /* eight bit character flag */ +int local_LINES = 0; /* copy of LINES, to detect when win resizes */ +int local_COLS = 0; /* copy of COLS, to detect when win resizes */ +int curses_initialized = FALSE; /* flag indicating if curses has been started*/ +int emacs_keys_mode = FALSE; /* mode for if emacs key binings are used */ +int ee_chinese = FALSE; /* allows handling of multi-byte characters */ + /* by checking for high bit in a byte the */ + /* code recognizes a two-byte character */ + /* sequence */ + +unsigned char *point; /* points to current position in line */ +unsigned char *srch_str; /* pointer for search string */ +unsigned char *u_srch_str; /* pointer to non-case sensitive search */ +unsigned char *srch_1; /* pointer to start of suspect string */ +unsigned char *srch_2; /* pointer to next character of string */ +unsigned char *srch_3; +unsigned char *in_file_name = NULL; /* name of input file */ +char *tmp_file; /* temporary file name */ +unsigned char *d_char; /* deleted character */ +unsigned char *d_word; /* deleted word */ +unsigned char *d_line; /* deleted line */ +char in_string[513]; /* buffer for reading a file */ +unsigned char *print_command = "lp"; /* string to use for the print command */ +unsigned char *start_at_line = NULL; /* move to this line at start of session*/ +int in; /* input character */ + +FILE *temp_fp; /* temporary file pointer */ +FILE *bit_bucket; /* file pointer to /dev/null */ + +char *table[] = { + "^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G", "^H", "\t", "^J", + "^K", "^L", "^M", "^N", "^O", "^P", "^Q", "^R", "^S", "^T", "^U", + "^V", "^W", "^X", "^Y", "^Z", "^[", "^\\", "^]", "^^", "^_" + }; + +WINDOW *com_win; +WINDOW *text_win; +WINDOW *help_win; +WINDOW *info_win; + +#if defined(__STDC__) || defined(__cplusplus) +#define P_(s) s +#else +#define P_(s) () +#endif + + +/* + | The following structure allows menu items to be flexibly declared. + | The first item is the string describing the selection, the second + | is the address of the procedure to call when the item is selected, + | and the third is the argument for the procedure. + | + | For those systems with i18n, the string should be accompanied by a + | catalog number. The 'int *' should be replaced with 'void *' on + | systems with that type. + | + | The first menu item will be the title of the menu, with NULL + | parameters for the procedure and argument, followed by the menu items. + | + | If the procedure value is NULL, the menu item is displayed, but no + | procedure is called when the item is selected. The number of the + | item will be returned. If the third (argument) parameter is -1, no + | argument is given to the procedure when it is called. + */ + +struct menu_entries { + char *item_string; + int (*procedure)P_((struct menu_entries *)); + struct menu_entries *ptr_argument; + int (*iprocedure)P_((int)); + void (*nprocedure)P_((void)); + int argument; + }; + +int main P_((int argc, char *argv[])); +unsigned char *resiz_line P_((int factor, struct text *rline, int rpos)); +void insert P_((int character)); +void delete P_((int disp)); +void scanline P_((unsigned char *pos)); +int tabshift P_((int temp_int)); +int out_char P_((WINDOW *window, int character, int column)); +int len_char P_((int character, int column)); +void draw_line P_((int vertical, int horiz, unsigned char *ptr, int t_pos, int length)); +void insert_line P_((int disp)); +struct text *txtalloc P_((void)); +struct files *name_alloc P_((void)); +unsigned char *next_word P_((unsigned char *string)); +void prev_word P_((void)); +void control P_((void)); +void emacs_control P_((void)); +void bottom P_((void)); +void top P_((void)); +void nextline P_((void)); +void prevline P_((void)); +void left P_((int disp)); +void right P_((int disp)); +void find_pos P_((void)); +void up P_((void)); +void down P_((void)); +void function_key P_((void)); +void print_buffer P_((void)); +void command_prompt P_((void)); +void command P_((char *cmd_str1)); +int scan P_((char *line, int offset, int column)); +char *get_string P_((char *prompt, int advance)); +int compare P_((char *string1, char *string2, int sensitive)); +void goto_line P_((char *cmd_str)); +void midscreen P_((int line, unsigned char *pnt)); +void get_options P_((int numargs, char *arguments[])); +void check_fp P_((void)); +void get_file P_((char *file_name)); +void get_line P_((int length, unsigned char *in_string, int *append)); +void draw_screen P_((void)); +void finish P_((void)); +int quit P_((int noverify)); +void edit_abort P_((int arg)); +void delete_text P_((void)); +int write_file P_((char *file_name)); +int search P_((int display_message)); +void search_prompt P_((void)); +void del_char P_((void)); +void undel_char P_((void)); +void del_word P_((void)); +void undel_word P_((void)); +void del_line P_((void)); +void undel_line P_((void)); +void adv_word P_((void)); +void move_rel P_((char *direction, int lines)); +void eol P_((void)); +void bol P_((void)); +void adv_line P_((void)); +void sh_command P_((char *string)); +void set_up_term P_((void)); +void resize_check P_((void)); +int menu_op P_((struct menu_entries *)); +void paint_menu P_((struct menu_entries menu_list[], int max_width, int max_height, int list_size, int top_offset, WINDOW *menu_win, int off_start, int vert_size)); +void help P_((void)); +void paint_info_win P_((void)); +void no_info_window P_((void)); +void create_info_window P_((void)); +int file_op P_((int arg)); +void shell_op P_((void)); +void leave_op P_((void)); +void redraw P_((void)); +int Blank_Line P_((struct text *test_line)); +void Format P_((void)); +void ee_init P_((void)); +void dump_ee_conf P_((void)); +void echo_string P_((char *string)); +void spell_op P_((void)); +void ispell_op P_((void)); +int first_word_len P_((struct text *test_line)); +void Auto_Format P_((void)); +void modes_op P_((void)); +char *is_in_string P_((char *string, char *substring)); +char *resolve_name P_((char *name)); +int restrict_mode P_((void)); +int unique_test P_((char *string, char *list[])); +void strings_init P_((void)); + +#undef P_ +/* + | allocate space here for the strings that will be in the menu + */ + +struct menu_entries modes_menu[] = { + {"", NULL, NULL, NULL, NULL, 0}, /* title */ + {"", NULL, NULL, NULL, NULL, -1}, /* 1. tabs to spaces */ + {"", NULL, NULL, NULL, NULL, -1}, /* 2. case sensitive search*/ + {"", NULL, NULL, NULL, NULL, -1}, /* 3. margins observed */ + {"", NULL, NULL, NULL, NULL, -1}, /* 4. auto-paragraph */ + {"", NULL, NULL, NULL, NULL, -1}, /* 5. eightbit characters*/ + {"", NULL, NULL, NULL, NULL, -1}, /* 6. info window */ + {"", NULL, NULL, NULL, NULL, -1}, /* 7. emacs key bindings*/ + {"", NULL, NULL, NULL, NULL, -1}, /* 8. right margin */ + {"", NULL, NULL, NULL, NULL, -1}, /* 9. chinese text */ + {"", NULL, NULL, NULL, dump_ee_conf, -1}, /* 10. save editor config */ + {NULL, NULL, NULL, NULL, NULL, -1} /* terminator */ + }; + +char *mode_strings[11]; + +#define NUM_MODES_ITEMS 10 + +struct menu_entries config_dump_menu[] = { + {"", NULL, NULL, NULL, NULL, 0}, + {"", NULL, NULL, NULL, NULL, -1}, + {"", NULL, NULL, NULL, NULL, -1}, + {NULL, NULL, NULL, NULL, NULL, -1} + }; + +struct menu_entries leave_menu[] = { + {"", NULL, NULL, NULL, NULL, -1}, + {"", NULL, NULL, NULL, finish, -1}, + {"", NULL, NULL, quit, NULL, TRUE}, + {NULL, NULL, NULL, NULL, NULL, -1} + }; + +#define READ_FILE 1 +#define WRITE_FILE 2 +#define SAVE_FILE 3 + +struct menu_entries file_menu[] = { + {"", NULL, NULL, NULL, NULL, -1}, + {"", NULL, NULL, file_op, NULL, READ_FILE}, + {"", NULL, NULL, file_op, NULL, WRITE_FILE}, + {"", NULL, NULL, file_op, NULL, SAVE_FILE}, + {"", NULL, NULL, NULL, print_buffer, -1}, + {NULL, NULL, NULL, NULL, NULL, -1} + }; + +struct menu_entries search_menu[] = { + {"", NULL, NULL, NULL, NULL, 0}, + {"", NULL, NULL, NULL, search_prompt, -1}, + {"", NULL, NULL, search, NULL, TRUE}, + {NULL, NULL, NULL, NULL, NULL, -1} + }; + +struct menu_entries spell_menu[] = { + {"", NULL, NULL, NULL, NULL, -1}, + {"", NULL, NULL, NULL, spell_op, -1}, + {"", NULL, NULL, NULL, ispell_op, -1}, + {NULL, NULL, NULL, NULL, NULL, -1} + }; + +struct menu_entries misc_menu[] = { + {"", NULL, NULL, NULL, NULL, -1}, + {"", NULL, NULL, NULL, Format, -1}, + {"", NULL, NULL, NULL, shell_op, -1}, + {"", menu_op, spell_menu, NULL, NULL, -1}, + {NULL, NULL, NULL, NULL, NULL, -1} + }; + +struct menu_entries main_menu[] = { + {"", NULL, NULL, NULL, NULL, -1}, + {"", NULL, NULL, NULL, leave_op, -1}, + {"", NULL, NULL, NULL, help, -1}, + {"", menu_op, file_menu, NULL, NULL, -1}, + {"", NULL, NULL, NULL, redraw, -1}, + {"", NULL, NULL, NULL, modes_op, -1}, + {"", menu_op, search_menu, NULL, NULL, -1}, + {"", menu_op, misc_menu, NULL, NULL, -1}, + {NULL, NULL, NULL, NULL, NULL, -1} + }; + +char *help_text[23]; +char *control_keys[5]; + +char *emacs_help_text[22]; +char *emacs_control_keys[5]; + +char *command_strings[5]; +char *commands[32]; +char *init_strings[22]; + +#define MENU_WARN 1 + +#define max_alpha_char 36 + +/* + | Declarations for strings for localization + */ + +char *com_win_message; /* to be shown in com_win if no info window */ +char *no_file_string; +char *ascii_code_str; +char *printer_msg_str; +char *command_str; +char *file_write_prompt_str; +char *file_read_prompt_str; +char *char_str; +char *unkn_cmd_str; +char *non_unique_cmd_msg; +char *line_num_str; +char *line_len_str; +char *current_file_str; +char *usage0; +char *usage1; +char *usage2; +char *usage3; +char *usage4; +char *file_is_dir_msg; +char *new_file_msg; +char *cant_open_msg; +char *open_file_msg; +char *file_read_fin_msg; +char *reading_file_msg; +char *read_only_msg; +char *file_read_lines_msg; +char *save_file_name_prompt; +char *file_not_saved_msg; +char *changes_made_prompt; +char *yes_char; +char *file_exists_prompt; +char *create_file_fail_msg; +char *writing_file_msg; +char *file_written_msg; +char *searching_msg; +char *str_not_found_msg; +char *search_prompt_str; +char *exec_err_msg; +char *continue_msg; +char *menu_cancel_msg; +char *menu_size_err_msg; +char *press_any_key_msg; +char *shell_prompt; +char *formatting_msg; +char *shell_echo_msg; +char *spell_in_prog_msg; +char *margin_prompt; +char *restricted_msg; +char *ON; +char *OFF; +char *HELP; +char *WRITE; +char *READ; +char *LINE; +char *FILE_str; +char *CHARACTER; +char *REDRAW; +char *RESEQUENCE; +char *AUTHOR; +char *VERSION; +char *CASE; +char *NOCASE; +char *EXPAND; +char *NOEXPAND; +char *Exit_string; +char *QUIT_string; +char *INFO; +char *NOINFO; +char *MARGINS; +char *NOMARGINS; +char *AUTOFORMAT; +char *NOAUTOFORMAT; +char *Echo; +char *PRINTCOMMAND; +char *RIGHTMARGIN; +char *HIGHLIGHT; +char *NOHIGHLIGHT; +char *EIGHTBIT; +char *NOEIGHTBIT; +char *EMACS_string; +char *NOEMACS_string; +char *conf_dump_err_msg; +char *conf_dump_success_msg; +char *conf_not_saved_msg; +char *ree_no_file_msg; +char *cancel_string; +char *menu_too_lrg_msg; +char *more_above_str, *more_below_str; + +char *chinese_cmd, *nochinese_cmd; + +#ifndef __STDC__ +#ifndef HAS_STDLIB +extern char *malloc(); +extern char *realloc(); +extern char *getenv(); +FILE *fopen(); /* declaration for open function */ +#endif /* HAS_STDLIB */ +#endif /* __STDC__ */ + +int +main(argc, argv) /* beginning of main program */ +int argc; +char *argv[]; +{ + int counter; + + for (counter = 1; counter < 24; counter++) + signal(counter, SIG_IGN); + + signal(SIGCHLD, SIG_DFL); + signal(SIGSEGV, SIG_DFL); + signal(SIGINT, edit_abort); + d_char = malloc(3); /* provide a buffer for multi-byte chars */ + d_word = malloc(150); + *d_word = (char) NULL; + d_line = NULL; + dlt_line = txtalloc(); + dlt_line->line = d_line; + dlt_line->line_length = 0; + curr_line = first_line = txtalloc(); + curr_line->line = point = malloc(10); + curr_line->line_length = 1; + curr_line->max_length = 10; + curr_line->prev_line = NULL; + curr_line->next_line = NULL; + curr_line->line_number = 1; + srch_str = NULL; + u_srch_str = NULL; + position = 1; + scr_pos =0; + scr_vert = 0; + scr_horz = 0; + bit_bucket = fopen("/dev/null", "w"); + edit = TRUE; + gold = case_sen = FALSE; + shell_fork = TRUE; + strings_init(); + ee_init(); + if (argc > 0 ) + get_options(argc, argv); + set_up_term(); + if (right_margin == 0) + right_margin = COLS - 1; + if (top_of_stack == NULL) + { + if (restrict_mode()) + { + wmove(com_win, 0, 0); + werase(com_win); + wprintw(com_win, ree_no_file_msg); + wrefresh(com_win); + edit_abort(0); + } + wprintw(com_win, no_file_string); + wrefresh(com_win); + } + else + check_fp(); + + clear_com_win = TRUE; + + while(edit) + { + wrefresh(text_win); + in = wgetch(text_win); + if (in == -1) + exit(0); + + resize_check(); + + if (clear_com_win) + { + clear_com_win = FALSE; + wmove(com_win, 0, 0); + werase(com_win); + if (!info_window) + { + wprintw(com_win, "%s", com_win_message); + } + wrefresh(com_win); + } + + if (in > 255) + function_key(); + else if ((in == '\10') || (in == 127)) + { + in = 8; /* make sure key is set to backspace */ + delete(TRUE); + } + else if ((in > 31) || (in == 9)) + insert(in); + else if ((in >= 0) && (in <= 31)) + { + if (emacs_keys_mode) + emacs_control(); + else + control(); + } + } + return(0); +} + +unsigned char * +resiz_line(factor, rline, rpos) /* resize the line to length + factor*/ +int factor; /* resize factor */ +struct text *rline; /* position in line */ +int rpos; +{ + unsigned char *rpoint; + int resiz_var; + + rline->max_length += factor; + rpoint = rline->line = realloc(rline->line, rline->max_length ); + for (resiz_var = 1 ; (resiz_var < rpos) ; resiz_var++) + rpoint++; + return(rpoint); +} + +void +insert(character) /* insert character into line */ +int character; /* new character */ +{ + int counter; + int value; + unsigned char *temp; /* temporary pointer */ + unsigned char *temp2; /* temporary pointer */ + + if ((character == '\011') && (expand_tabs)) + { + counter = len_char('\011', scr_horz); + for (; counter > 0; counter--) + insert(' '); + if (auto_format) + Auto_Format(); + return; + } + text_changes = TRUE; + if ((curr_line->max_length - curr_line->line_length) < 5) + point = resiz_line(10, curr_line, position); + curr_line->line_length++; + temp = point; + counter = position; + while (counter < curr_line->line_length) /* find end of line */ + { + counter++; + temp++; + } + temp++; /* increase length of line by one */ + while (point < temp) + { + temp2=temp - 1; + *temp= *temp2; /* shift characters over by one */ + temp--; + } + *point = character; /* insert new character */ + wclrtoeol(text_win); + if (((character >= 0) && (character < ' ')) || (character >= 127)) /* check for TAB character*/ + { + scr_pos = scr_horz += out_char(text_win, character, scr_horz); + point++; + position++; + } + else + { + waddch(text_win, character); + scr_pos = ++scr_horz; + point++; + position ++; + } + + if ((observ_margins) && (right_margin < scr_pos)) + { + counter = position; + while (scr_pos > right_margin) + prev_word(); + if (scr_pos == 0) + { + while (position < counter) + right(TRUE); + } + else + { + counter -= position; + insert_line(TRUE); + for (value = 0; value < counter; value++) + right(TRUE); + } + } + + if ((scr_horz - horiz_offset) > last_col) + { + horiz_offset += 8; + midscreen(scr_vert, point); + } + + if ((auto_format) && (character == ' ') && (!formatted)) + Auto_Format(); + else if ((character != ' ') && (character != '\t')) + formatted = FALSE; + + draw_line(scr_vert, scr_horz, point, position, curr_line->line_length); +} + +void +delete(disp) /* delete character */ +int disp; +{ + unsigned char *tp; + unsigned char *temp2; + struct text *temp_buff; + int temp_vert; + int temp_pos; + int del_width = 1; + + if (point != curr_line->line) /* if not at beginning of line */ + { + text_changes = TRUE; + temp2 = tp = point; + if ((ee_chinese) && (position >= 2) && (*(point - 2) > 127)) + { + del_width = 2; + } + tp -= del_width; + point -= del_width; + position -= del_width; + temp_pos = position; + curr_line->line_length -= del_width; + if ((*tp < ' ') || (*tp >= 127)) /* check for TAB */ + scanline(tp); + else + scr_horz -= del_width; + scr_pos = scr_horz; + if (in == 8) + { + if (del_width == 1) + *d_char = *point; /* save deleted character */ + else + { + d_char[0] = *point; + d_char[1] = *(point + 1); + } + d_char[del_width] = (unsigned char) NULL; + } + while (temp_pos <= curr_line->line_length) + { + temp_pos++; + *tp = *temp2; + tp++; + temp2++; + } + if (scr_horz < horiz_offset) + { + horiz_offset -= 8; + midscreen(scr_vert, point); + } + } + else if (curr_line->prev_line != NULL) + { + text_changes = TRUE; + left(disp); /* go to previous line */ + temp_buff = curr_line->next_line; + point = resiz_line(temp_buff->line_length, curr_line, position); + if (temp_buff->next_line != NULL) + temp_buff->next_line->prev_line = curr_line; + curr_line->next_line = temp_buff->next_line; + temp2 = temp_buff->line; + if (in == 8) + { + d_char[0] = '\n'; + d_char[1] = (unsigned char) NULL; + } + tp = point; + temp_pos = 1; + while (temp_pos < temp_buff->line_length) + { + curr_line->line_length++; + temp_pos++; + *tp = *temp2; + tp++; + temp2++; + } + *tp = (char) NULL; + free(temp_buff->line); + free(temp_buff); + temp_buff = curr_line; + temp_vert = scr_vert; + scr_pos = scr_horz; + if (scr_vert < last_line) + { + wmove(text_win, scr_vert + 1, 0); + wdeleteln(text_win); + } + while ((temp_buff != NULL) && (temp_vert < last_line)) + { + temp_buff = temp_buff->next_line; + temp_vert++; + } + if ((temp_vert == last_line) && (temp_buff != NULL)) + { + tp = temp_buff->line; + wmove(text_win, last_line,0); + wclrtobot(text_win); + draw_line(last_line, 0, tp, 1, temp_buff->line_length); + wmove(text_win, scr_vert, (scr_horz - horiz_offset)); + } + } + draw_line(scr_vert, scr_horz, point, position, curr_line->line_length); + formatted = FALSE; +} + +void +scanline(pos) /* find the proper horizontal position for the pointer */ +unsigned char *pos; +{ + int temp; + unsigned char *ptr; + + ptr = curr_line->line; + temp = 0; + while (ptr < pos) + { + if (*ptr <= 8) + temp += 2; + else if (*ptr == 9) + temp += tabshift(temp); + else if ((*ptr >= 10) && (*ptr <= 31)) + temp += 2; + else if ((*ptr >= 32) && (*ptr < 127)) + temp++; + else if (*ptr == 127) + temp += 2; + else if (!eightbit) + temp += 5; + else + temp++; + ptr++; + } + scr_horz = temp; + if ((scr_horz - horiz_offset) > last_col) + { + horiz_offset = (scr_horz - (scr_horz % 8)) - (COLS - 8); + midscreen(scr_vert, point); + } + else if (scr_horz < horiz_offset) + { + horiz_offset = max(0, (scr_horz - (scr_horz % 8))); + midscreen(scr_vert, point); + } +} + +int +tabshift(temp_int) /* give the number of spaces to shift */ +int temp_int; +{ + int leftover; + + leftover = ((temp_int + 1) % 8); + if (leftover == 0) + return (1); + else + return (9 - leftover); +} + +int +out_char(window, character, column) /* output non-printing character */ +WINDOW *window; +char character; +int column; +{ + int i1, i2; + unsigned char *string; + char string2[8]; + + if (character == TAB) + { + i1 = tabshift(column); + for (i2 = 0; + (i2 < i1) && (((column+i2+1)-horiz_offset) < last_col); i2++) + { + waddch(window, ' '); + } + return(i1); + } + else if ((character >= '\0') && (character < ' ')) + { + string = table[(int) character]; + } + else if ((character < 0) || (character >= 127)) + { + if (character == 127) + string = "^?"; + else if (!eightbit) + { + sprintf(string2, "<%d>", (character < 0) ? (character + 256) : character); + string = string2; + } + else + { + waddch(window, (char)character ); + return(1); + } + } + else + { + waddch(window, (char)character); + return(1); + } + for (i2 = 0; (string[i2] != (char) NULL) && (((column+i2+1)-horiz_offset) < last_col); i2++) + waddch(window, string[i2]); + return(strlen(string)); +} + +int +len_char(character, column) /* return the length of the character */ +char character; +int column; /* the column must be known to provide spacing for tabs */ +{ + int length; + + if (character == '\t') + length = tabshift(column); + else if ((character >= 0) && (character < 32)) + length = 2; + else if ((character >= 32) && (character <= 126)) + length = 1; + else if (character == 127) + length = 2; + else if (((character > 126) || (character < 0)) && (!eightbit)) + length = 5; + else + length = 1; + + return(length); +} + +void +draw_line(vertical, horiz, ptr, t_pos, length) /* redraw line from current position */ +int vertical; /* current vertical position on screen */ +int horiz; /* current horizontal position on screen */ +unsigned char *ptr; /* pointer to line */ +int t_pos; /* current position (offset in bytes) from bol */ +int length; /* length (in bytes) of line */ +{ + int d; /* partial length of special or tab char to display */ + unsigned char *temp; /* temporary pointer to position in line */ + int abs_column; /* offset in screen units from begin of line */ + int column; /* horizontal position on screen */ + int row; /* vertical position on screen */ + int posit; /* temporary position indicator within line */ + + abs_column = horiz; + column = horiz - horiz_offset; + row = vertical; + temp = ptr; + d = 0; + posit = t_pos; + if (column < 0) + { + wmove(text_win, row, 0); + wclrtoeol(text_win); + } + while (column < 0) + { + d = len_char(*temp, abs_column); + abs_column += d; + column += d; + posit++; + temp++; + } + wmove(text_win, row, column); + wclrtoeol(text_win); + while ((posit < length) && (column <= last_col)) + { + if ((*temp < 32) || (*temp >= 127)) + { + column += len_char(*temp, abs_column); + abs_column += out_char(text_win, *temp, abs_column); + } + else + { + abs_column++; + column++; + waddch(text_win, *temp); + } + posit++; + temp++; + } + if (column < last_col) + wclrtoeol(text_win); + wmove(text_win, vertical, (horiz - horiz_offset)); +} + +void +insert_line(disp) /* insert new line */ +int disp; +{ + int temp_pos; + int temp_pos2; + unsigned char *temp; + unsigned char *extra; + struct text *temp_nod; + + text_changes = TRUE; + wmove(text_win, scr_vert, (scr_horz - horiz_offset)); + wclrtoeol(text_win); + temp_nod= txtalloc(); + temp_nod->line = extra= malloc(10); + temp_nod->line_length = 1; + temp_nod->max_length = 10; + temp_nod->line_number = curr_line->line_number + 1; + temp_nod->next_line = curr_line->next_line; + if (temp_nod->next_line != NULL) + temp_nod->next_line->prev_line = temp_nod; + temp_nod->prev_line = curr_line; + curr_line->next_line = temp_nod; + temp_pos2 = position; + temp = point; + if (temp_pos2 < curr_line->line_length) + { + temp_pos = 1; + while (temp_pos2 < curr_line->line_length) + { + if ((temp_nod->max_length - temp_nod->line_length)< 5) + extra = resiz_line(10, temp_nod, temp_pos); + temp_nod->line_length++; + temp_pos++; + temp_pos2++; + *extra= *temp; + extra++; + temp++; + } + temp=point; + *temp = (char) NULL; + temp = resiz_line((1 - temp_nod->line_length), curr_line, position); + curr_line->line_length = 1 + temp - curr_line->line; + } + curr_line->line_length = position; + curr_line = temp_nod; + *extra = (char) NULL; + position = 1; + point= curr_line->line; + if (disp) + { + if (scr_vert < last_line) + { + scr_vert++; + wclrtoeol(text_win); + wmove(text_win, scr_vert, 0); + winsertln(text_win); + } + else + { + wmove(text_win, 0,0); + wdeleteln(text_win); + wmove(text_win, last_line,0); + wclrtobot(text_win); + } + scr_pos = scr_horz = 0; + if (horiz_offset) + { + horiz_offset = 0; + midscreen(scr_vert, point); + } + draw_line(scr_vert, scr_horz, point, position, + curr_line->line_length); + } +} + +struct text *txtalloc() /* allocate space for line structure */ +{ + return((struct text *) malloc(sizeof( struct text))); +} + +struct files *name_alloc() /* allocate space for file name list node */ +{ + return((struct files *) malloc(sizeof( struct files))); +} + +unsigned char *next_word(string) /* move to next word in string */ +unsigned char *string; +{ + while ((*string != (char) NULL) && ((*string != 32) && (*string != 9))) + string++; + while ((*string != (char) NULL) && ((*string == 32) || (*string == 9))) + string++; + return(string); +} + +void +prev_word() /* move to start of previous word in text */ +{ + if (position != 1) + { + if ((position != 1) && ((point[-1] == ' ') || (point[-1] == '\t'))) + { /* if at the start of a word */ + while ((position != 1) && ((*point != ' ') && (*point != '\t'))) + left(TRUE); + } + while ((position != 1) && ((*point == ' ') || (*point == '\t'))) + left(TRUE); + while ((position != 1) && ((*point != ' ') && (*point != '\t'))) + left(TRUE); + if ((position != 1) && ((*point == ' ') || (*point == '\t'))) + right(TRUE); + } + else + left(TRUE); +} + +void +control() /* use control for commands */ +{ + char *string; + + if (in == 1) /* control a */ + { + string = get_string(ascii_code_str, TRUE); + if (*string != (char) NULL) + { + in = atoi(string); + wmove(text_win, scr_vert, (scr_horz - horiz_offset)); + insert(in); + } + free(string); + } + else if (in == 2) /* control b */ + bottom(); + else if (in == 3) /* control c */ + { + command_prompt(); + } + else if (in == 4) /* control d */ + down(); + else if (in == 5) /* control e */ + search_prompt(); + else if (in == 6) /* control f */ + undel_char(); + else if (in == 7) /* control g */ + bol(); + else if (in == 8) /* control h */ + delete(TRUE); + else if (in == 9) /* control i */ + ; + else if (in == 10) /* control j */ + insert_line(TRUE); + else if (in == 11) /* control k */ + del_char(); + else if (in == 12) /* control l */ + left(TRUE); + else if (in == 13) /* control m */ + insert_line(TRUE); + else if (in == 14) /* control n */ + move_rel("d", max(5, (last_line - 5))); + else if (in == 15) /* control o */ + eol(); + else if (in == 16) /* control p */ + move_rel("u", max(5, (last_line - 5))); + else if (in == 17) /* control q */ + ; + else if (in == 18) /* control r */ + right(TRUE); + else if (in == 19) /* control s */ + ; + else if (in == 20) /* control t */ + top(); + else if (in == 21) /* control u */ + up(); + else if (in == 22) /* control v */ + undel_word(); + else if (in == 23) /* control w */ + del_word(); + else if (in == 24) /* control x */ + search(TRUE); + else if (in == 25) /* control y */ + del_line(); + else if (in == 26) /* control z */ + undel_line(); + else if (in == 27) /* control [ (escape) */ + { + menu_op(main_menu); + } +} + +/* + | Emacs control-key bindings + */ + +void +emacs_control() +{ + char *string; + + if (in == 1) /* control a */ + bol(); + else if (in == 2) /* control b */ + left(TRUE); + else if (in == 3) /* control c */ + { + command_prompt(); + } + else if (in == 4) /* control d */ + del_char(); + else if (in == 5) /* control e */ + eol(); + else if (in == 6) /* control f */ + right(TRUE); + else if (in == 7) /* control g */ + move_rel("u", max(5, (last_line - 5))); + else if (in == 8) /* control h */ + delete(TRUE); + else if (in == 9) /* control i */ + ; + else if (in == 10) /* control j */ + undel_char(); + else if (in == 11) /* control k */ + del_line(); + else if (in == 12) /* control l */ + undel_line(); + else if (in == 13) /* control m */ + insert_line(TRUE); + else if (in == 14) /* control n */ + down(); + else if (in == 15) /* control o */ + { + string = get_string(ascii_code_str, TRUE); + if (*string != (char) NULL) + { + in = atoi(string); + wmove(text_win, scr_vert, (scr_horz - horiz_offset)); + insert(in); + } + free(string); + } + else if (in == 16) /* control p */ + up(); + else if (in == 17) /* control q */ + ; + else if (in == 18) /* control r */ + undel_word(); + else if (in == 19) /* control s */ + ; + else if (in == 20) /* control t */ + top(); + else if (in == 21) /* control u */ + bottom(); + else if (in == 22) /* control v */ + move_rel("d", max(5, (last_line - 5))); + else if (in == 23) /* control w */ + del_word(); + else if (in == 24) /* control x */ + search(TRUE); + else if (in == 25) /* control y */ + search_prompt(); + else if (in == 26) /* control z */ + adv_word(); + else if (in == 27) /* control [ (escape) */ + { + menu_op(main_menu); + } +} + +void +bottom() /* go to bottom of file */ +{ + while (curr_line->next_line != NULL) + curr_line = curr_line->next_line; + point = curr_line->line; + if (horiz_offset) + horiz_offset = 0; + position = 1; + midscreen(last_line, point); + scr_pos = scr_horz; +} + +void +top() /* go to top of file */ +{ + while (curr_line->prev_line != NULL) + curr_line = curr_line->prev_line; + point = curr_line->line; + if (horiz_offset) + horiz_offset = 0; + position = 1; + midscreen(0, point); + scr_pos = scr_horz; +} + +void +nextline() /* move pointers to start of next line */ +{ + curr_line = curr_line->next_line; + point = curr_line->line; + position = 1; + if (scr_vert == last_line) + { + wmove(text_win, 0,0); + wdeleteln(text_win); + wmove(text_win, last_line,0); + wclrtobot(text_win); + draw_line(last_line,0,point,1,curr_line->line_length); + } + else + scr_vert++; +} + +void +prevline() /* move pointers to start of previous line*/ +{ + curr_line = curr_line->prev_line; + point = curr_line->line; + position = 1; + if (scr_vert == 0) + { + winsertln(text_win); + draw_line(0,0,point,1,curr_line->line_length); + } + else + scr_vert--; + while (position < curr_line->line_length) + { + position++; + point++; + } +} + +void +left(disp) /* move left one character */ +int disp; +{ + if (point != curr_line->line) /* if not at begin of line */ + { + if ((ee_chinese) && (position >= 2) && (*(point - 2) > 127)) + { + point--; + position--; + } + point--; + position--; + scanline(point); + wmove(text_win, scr_vert, (scr_horz - horiz_offset)); + scr_pos = scr_horz; + } + else if (curr_line->prev_line != NULL) + { + if (!disp) + { + curr_line = curr_line->prev_line; + point = curr_line->line + curr_line->line_length; + position = curr_line->line_length; + return; + } + position = 1; + prevline(); + scanline(point); + scr_pos = scr_horz; + wmove(text_win, scr_vert, (scr_horz - horiz_offset)); + } +} + +void +right(disp) /* move right one character */ +int disp; +{ + if (position < curr_line->line_length) + { + if ((ee_chinese) && (*point > 127) && + ((curr_line->line_length - position) >= 2)) + { + point++; + position++; + } + point++; + position++; + scanline(point); + wmove(text_win, scr_vert, (scr_horz - horiz_offset)); + scr_pos = scr_horz; + } + else if (curr_line->next_line != NULL) + { + if (!disp) + { + curr_line = curr_line->next_line; + point = curr_line->line; + position = 1; + return; + } + nextline(); + scr_pos = scr_horz = 0; + if (horiz_offset) + { + horiz_offset = 0; + midscreen(scr_vert, point); + } + wmove(text_win, scr_vert, (scr_horz - horiz_offset)); + position = 1; + } +} + +void +find_pos() /* move to the same column as on other line */ +{ + scr_horz = 0; + position = 1; + while ((scr_horz < scr_pos) && (position < curr_line->line_length)) + { + if (*point == 9) + scr_horz += tabshift(scr_horz); + else if (*point < ' ') + scr_horz += 2; + else if ((ee_chinese) && (*point > 127) && + ((curr_line->line_length - position) >= 2)) + { + scr_horz += 2; + point++; + position++; + } + else + scr_horz++; + position++; + point++; + } + if ((scr_horz - horiz_offset) > last_col) + { + horiz_offset = (scr_horz - (scr_horz % 8)) - (COLS - 8); + midscreen(scr_vert, point); + } + else if (scr_horz < horiz_offset) + { + horiz_offset = max(0, (scr_horz - (scr_horz % 8))); + midscreen(scr_vert, point); + } + wmove(text_win, scr_vert, (scr_horz - horiz_offset)); +} + +void +up() /* move up one line */ +{ + if (curr_line->prev_line != NULL) + { + prevline(); + point = curr_line->line; + find_pos(); + } +} + +void +down() /* move down one line */ +{ + if (curr_line->next_line != NULL) + { + nextline(); + find_pos(); + } +} + +void +function_key() /* process function key */ +{ + if (in == KEY_LEFT) + left(TRUE); + else if (in == KEY_RIGHT) + right(TRUE); + else if ( in == KEY_HOME) + top(); + else if ( in == KEY_UP) + up(); + else if (in == KEY_DOWN) + down(); + else if (in == KEY_NPAGE) + move_rel("d", max( 5, (last_line - 5))); + else if (in == KEY_PPAGE) + move_rel("u", max(5, (last_line - 5))); + else if (in == KEY_DL) + del_line(); + else if (in == KEY_DC) + del_char(); + else if (in == KEY_BACKSPACE) + delete(TRUE); + else if (in == KEY_IL) + { /* insert a line before current line */ + insert_line(TRUE); + left(TRUE); + } + else if (in == KEY_F(1)) + gold = !gold; + else if (in == KEY_F(2)) + { + if (gold) + { + gold = FALSE; + undel_line(); + } + else + undel_char(); + } + else if (in == KEY_F(3)) + { + if (gold) + { + gold = FALSE; + undel_word(); + } + else + del_word(); + } + else if (in == KEY_F(4)) + { + if (gold) + { + gold = FALSE; + paint_info_win(); + midscreen(scr_vert, point); + } + else + adv_word(); + } + else if (in == KEY_F(5)) + { + if (gold) + { + gold = FALSE; + search_prompt(); + } + else + search(TRUE); + } + else if (in == KEY_F(6)) + { + if (gold) + { + gold = FALSE; + bottom(); + } + else + top(); + } + else if (in == KEY_F(7)) + { + if (gold) + { + gold = FALSE; + eol(); + } + else + bol(); + } + else if (in == KEY_F(8)) + { + if (gold) + { + gold = FALSE; + command_prompt(); + } + else + adv_line(); + } +} + +void +print_buffer() +{ + char buffer[256]; + + sprintf(buffer, ">!%s", print_command); + wmove(com_win, 0, 0); + wclrtoeol(com_win); + wprintw(com_win, printer_msg_str, print_command); + wrefresh(com_win); + command(buffer); +} + +void +command_prompt() +{ + char *cmd_str; + int result; + + info_type = COMMANDS; + paint_info_win(); + cmd_str = get_string(command_str, TRUE); + if ((result = unique_test(cmd_str, commands)) != 1) + { + werase(com_win); + wmove(com_win, 0, 0); + if (result == 0) + wprintw(com_win, unkn_cmd_str, cmd_str); + else + wprintw(com_win, non_unique_cmd_msg); + + wrefresh(com_win); + + info_type = CONTROL_KEYS; + paint_info_win(); + + if (cmd_str != NULL) + free(cmd_str); + return; + } + command(cmd_str); + wrefresh(com_win); + wmove(text_win, scr_vert, (scr_horz - horiz_offset)); + info_type = CONTROL_KEYS; + paint_info_win(); + if (cmd_str != NULL) + free(cmd_str); +} + +void +command(cmd_str1) /* process commands from keyboard */ +char *cmd_str1; +{ + char *cmd_str2 = NULL; + char *cmd_str = cmd_str1; + + clear_com_win = TRUE; + if (compare(cmd_str, HELP, FALSE)) + help(); + else if (compare(cmd_str, WRITE, FALSE)) + { + if (restrict_mode()) + { + return; + } + cmd_str = next_word(cmd_str); + if (*cmd_str == (char) NULL) + { + cmd_str = cmd_str2 = get_string(file_write_prompt_str, TRUE); + } + tmp_file = resolve_name(cmd_str); + write_file(tmp_file); + if (tmp_file != cmd_str) + free(tmp_file); + } + else if (compare(cmd_str, READ, FALSE)) + { + if (restrict_mode()) + { + return; + } + cmd_str = next_word(cmd_str); + if (*cmd_str == (char) NULL) + { + cmd_str = cmd_str2 = get_string(file_read_prompt_str, TRUE); + } + tmp_file = cmd_str; + recv_file = TRUE; + tmp_file = resolve_name(cmd_str); + check_fp(); + if (tmp_file != cmd_str) + free(tmp_file); + } + else if (compare(cmd_str, LINE, FALSE)) + { + wmove(com_win, 0, 0); + wclrtoeol(com_win); + wprintw(com_win, line_num_str, curr_line->line_number); + wprintw(com_win, line_len_str, curr_line->line_length); + } + else if (compare(cmd_str, FILE_str, FALSE)) + { + wmove(com_win, 0, 0); + wclrtoeol(com_win); + if (in_file_name == NULL) + wprintw(com_win, no_file_string); + else + wprintw(com_win, current_file_str, in_file_name); + } + else if ((*cmd_str >= '0') && (*cmd_str <= '9')) + goto_line(cmd_str); + else if (compare(cmd_str, CHARACTER, FALSE)) + { + wmove(com_win, 0, 0); + wclrtoeol(com_win); + wprintw(com_win, char_str, *point); + } + else if (compare(cmd_str, REDRAW, FALSE)) + redraw(); + else if (compare(cmd_str, RESEQUENCE, FALSE)) + { + tmp_line = first_line->next_line; + while (tmp_line != NULL) + { + tmp_line->line_number = tmp_line->prev_line->line_number + 1; + tmp_line = tmp_line->next_line; + } + } + else if (compare(cmd_str, AUTHOR, FALSE)) + { + wmove(com_win, 0, 0); + wclrtoeol(com_win); + wprintw(com_win, "written by Hugh Mahon"); + } + else if (compare(cmd_str, VERSION, FALSE)) + { + wmove(com_win, 0, 0); + wclrtoeol(com_win); + wprintw(com_win, "%s", version); + } + else if (compare(cmd_str, CASE, FALSE)) + case_sen = TRUE; + else if (compare(cmd_str, NOCASE, FALSE)) + case_sen = FALSE; + else if (compare(cmd_str, EXPAND, FALSE)) + expand_tabs = TRUE; + else if (compare(cmd_str, NOEXPAND, FALSE)) + expand_tabs = FALSE; + else if (compare(cmd_str, Exit_string, FALSE)) + finish(); + else if (compare(cmd_str, chinese_cmd, FALSE)) + { + ee_chinese = TRUE; +#ifdef NCURSE + nc_setattrib(A_NC_BIG5); +#endif /* NCURSE */ + } + else if (compare(cmd_str, nochinese_cmd, FALSE)) + { + ee_chinese = FALSE; +#ifdef NCURSE + nc_clearattrib(A_NC_BIG5); +#endif /* NCURSE */ + } + else if (compare(cmd_str, QUIT_string, FALSE)) + quit(0); + else if (*cmd_str == '!') + { + cmd_str++; + if ((*cmd_str == ' ') || (*cmd_str == 9)) + cmd_str = next_word(cmd_str); + sh_command(cmd_str); + } + else if ((*cmd_str == '<') && (!in_pipe)) + { + in_pipe = TRUE; + shell_fork = FALSE; + cmd_str++; + if ((*cmd_str == ' ') || (*cmd_str == '\t')) + cmd_str = next_word(cmd_str); + command(cmd_str); + in_pipe = FALSE; + shell_fork = TRUE; + } + else if ((*cmd_str == '>') && (!out_pipe)) + { + out_pipe = TRUE; + cmd_str++; + if ((*cmd_str == ' ') || (*cmd_str == '\t')) + cmd_str = next_word(cmd_str); + command(cmd_str); + out_pipe = FALSE; + } + else + { + wmove(com_win, 0, 0); + wclrtoeol(com_win); + wprintw(com_win, unkn_cmd_str, cmd_str); + } + if (cmd_str2 != NULL) + free(cmd_str2); +} + +int +scan(line, offset, column) /* determine horizontal position for get_string */ +char *line; +int offset; +int column; +{ + char *stemp; + int i; + int j; + + stemp = line; + i = 0; + j = column; + while (i < offset) + { + i++; + j += len_char(*stemp, j); + stemp++; + } + return(j); +} + +char * +get_string(prompt, advance) /* read string from input on command line */ +char *prompt; /* string containing user prompt message */ +int advance; /* if true, skip leading spaces and tabs */ +{ + char *string; + char *tmp_string; + char *nam_str; + char *g_point; + int tmp_int; + int g_horz, g_position, g_pos; + int esc_flag; + + g_point = tmp_string = malloc(512); + wmove(com_win,0,0); + wclrtoeol(com_win); + waddstr(com_win, prompt); + wrefresh(com_win); + nam_str = tmp_string; + clear_com_win = TRUE; + g_horz = g_position = scan(prompt, strlen(prompt), 0); + g_pos = 0; + do + { + esc_flag = FALSE; + in = wgetch(com_win); + if (in == -1) + exit(0); + if (((in == 8) || (in == 127) || (in == KEY_BACKSPACE)) && (g_pos > 0)) + { + tmp_int = g_horz; + g_pos--; + g_horz = scan(g_point, g_pos, g_position); + tmp_int = tmp_int - g_horz; + for (; 0 < tmp_int; tmp_int--) + { + if ((g_horz+tmp_int) < (last_col - 1)) + { + waddch(com_win, '\010'); + waddch(com_win, ' '); + waddch(com_win, '\010'); + } + } + nam_str--; + } + else if ((in != 8) && (in != 127) && (in != '\n') && (in != '\r') && (in < 256)) + { + if (in == '\026') /* control-v, accept next character verbatim */ + { /* allows entry of ^m, ^j, and ^h */ + esc_flag = TRUE; + in = wgetch(com_win); + if (in == -1) + exit(0); + } + *nam_str = in; + g_pos++; + if (((in < ' ') || (in > 126)) && (g_horz < (last_col - 1))) + g_horz += out_char(com_win, in, g_horz); + else + { + g_horz++; + if (g_horz < (last_col - 1)) + waddch(com_win, in); + } + nam_str++; + } + wrefresh(com_win); + if (esc_flag) + in = (char) NULL; + } while ((in != '\n') && (in != '\r')); + *nam_str = (char) NULL; + nam_str = tmp_string; + if (((*nam_str == ' ') || (*nam_str == 9)) && (advance)) + nam_str = next_word(nam_str); + string = malloc(strlen(nam_str) + 1); + strcpy(string, nam_str); + free(tmp_string); + wrefresh(com_win); + return(string); +} + +int +compare(string1, string2, sensitive) /* compare two strings */ +char *string1; +char *string2; +int sensitive; +{ + char *strng1; + char *strng2; + int tmp; + int equal; + + strng1 = string1; + strng2 = string2; + tmp = 0; + if ((strng1 == NULL) || (strng2 == NULL) || (*strng1 == (char) NULL) || (*strng2 == (char) NULL)) + return(FALSE); + equal = TRUE; + while (equal) + { + if (sensitive) + { + if (*strng1 != *strng2) + equal = FALSE; + } + else + { + if (toupper(*strng1) != toupper(*strng2)) + equal = FALSE; + } + strng1++; + strng2++; + if ((*strng1 == (char) NULL) || (*strng2 == (char) NULL) || (*strng1 == ' ') || (*strng2 == ' ')) + break; + tmp++; + } + return(equal); +} + +void +goto_line(cmd_str) +char *cmd_str; +{ + int number; + int i; + char *ptr; + char *direction; + struct text *t_line; + + ptr = cmd_str; + i= 0; + while ((*ptr >='0') && (*ptr <= '9')) + { + i= i * 10 + (*ptr - '0'); + ptr++; + } + number = i; + i = 0; + t_line = curr_line; + while ((t_line->line_number > number) && (t_line->prev_line != NULL)) + { + i++; + t_line = t_line->prev_line; + direction = "u"; + } + while ((t_line->line_number < number) && (t_line->next_line != NULL)) + { + i++; + direction = "d"; + t_line = t_line->next_line; + } + if ((i < 30) && (i > 0)) + { + move_rel(direction, i); + } + else + { + curr_line = t_line; + point = curr_line->line; + position = 1; + midscreen((last_line / 2), point); + scr_pos = scr_horz; + } + wmove(com_win, 0, 0); + wclrtoeol(com_win); + wprintw(com_win, line_num_str, curr_line->line_number); + wmove(text_win, scr_vert, (scr_horz - horiz_offset)); +} + +void +midscreen(line, pnt) /* put current line in middle of screen */ +int line; +unsigned char *pnt; +{ + struct text *mid_line; + int i; + + line = min(line, last_line); + mid_line = curr_line; + for (i = 0; ((i < line) && (curr_line->prev_line != NULL)); i++) + curr_line = curr_line->prev_line; + scr_vert = scr_horz = 0; + wmove(text_win, 0, 0); + draw_screen(); + scr_vert = i; + curr_line = mid_line; + scanline(pnt); + wmove(text_win, scr_vert, (scr_horz - horiz_offset)); +} + +void +get_options(numargs, arguments) /* get arguments from command line */ +int numargs; +char *arguments[]; +{ + char *buff; + int count; + struct files *temp_names; + char *name; + char *ptr; + + /* + | see if editor was invoked as 'ree' (restricted mode) + */ + + if (!(name = strrchr(arguments[0], '/'))) + name = arguments[0]; + else + name++; + if (!strcmp(name, "ree")) + restricted = TRUE; + + top_of_stack = NULL; + input_file = FALSE; + recv_file = FALSE; + count = 1; + while (count < numargs) + { + buff = arguments[count]; + if (!strcmp("-i", buff)) + { + info_window = FALSE; + } + else if (!strcmp("-e", buff)) + { + expand_tabs = FALSE; + } + else if (!strcmp("-h", buff)) + { + nohighlight = TRUE; + } + else if (!strcmp("-?", buff)) + { + fprintf(stderr, usage0, arguments[0]); + fprintf(stderr, usage1); + fprintf(stderr, usage2); + fprintf(stderr, usage3); + fprintf(stderr, usage4); + exit(1); + } + else if (*buff == '+') + { + buff++; + start_at_line = buff; + } + + else + { + if (top_of_stack == NULL) + { + temp_names = top_of_stack = name_alloc(); + } + else + { + temp_names->next_name = name_alloc(); + temp_names = temp_names->next_name; + } + ptr = temp_names->name = malloc(strlen(buff) + 1); + while (*buff != (char) NULL) + { + *ptr = *buff; + buff++; + ptr++; + } + *ptr = (char) NULL; + temp_names->next_name = NULL; + input_file = TRUE; + recv_file = TRUE; + } + count++; + } +} + +void +check_fp() /* open or close files according to flags */ +{ + int line_num; + int temp; + struct stat buf; + + clear_com_win = TRUE; + tmp_vert = scr_vert; + tmp_horz = scr_horz; + tmp_line = curr_line; + if (input_file) + { + in_file_name = tmp_file = top_of_stack->name; + top_of_stack = top_of_stack->next_name; + } + temp = stat(tmp_file, &buf); + buf.st_mode &= ~07777; + if ((temp != -1) && (buf.st_mode != 0100000) && (buf.st_mode != 0)) + { + wprintw(com_win, file_is_dir_msg, tmp_file); + wrefresh(com_win); + if (input_file) + { + quit(0); + return; + } + else + return; + } + if ((get_fd = open(tmp_file, O_RDONLY)) == -1) + { + wmove(com_win, 0, 0); + wclrtoeol(com_win); + if (input_file) + wprintw(com_win, new_file_msg, tmp_file); + else + wprintw(com_win, cant_open_msg, tmp_file); + wrefresh(com_win); + wmove(text_win, scr_vert, (scr_horz - horiz_offset)); + wrefresh(text_win); + recv_file = FALSE; + input_file = FALSE; + return; + } + else + get_file(tmp_file); + + recv_file = FALSE; + line_num = curr_line->line_number; + scr_vert = tmp_vert; + scr_horz = tmp_horz; + if (input_file) + curr_line= first_line; + else + curr_line = tmp_line; + point = curr_line->line; + draw_screen(); + if (input_file) + { + input_file = FALSE; + if (start_at_line != NULL) + { + line_num = atoi(start_at_line) - 1; + move_rel("d", line_num); + line_num = 0; + start_at_line = NULL; + } + } + else + { + wmove(com_win, 0, 0); + wclrtoeol(com_win); + text_changes = TRUE; + if ((tmp_file != NULL) && (*tmp_file != (char) NULL)) + wprintw(com_win, file_read_fin_msg, tmp_file); + } + wrefresh(com_win); + wmove(text_win, scr_vert, (scr_horz - horiz_offset)); + wrefresh(text_win); +} + +void +get_file(file_name) /* read specified file into current buffer */ +char *file_name; +{ + int can_read; /* file has at least one character */ + int length; /* length of line read by read */ + int append; /* should text be appended to current line */ + struct text *temp_line; + char ro_flag = FALSE; + + if (recv_file) /* if reading a file */ + { + wmove(com_win, 0, 0); + wclrtoeol(com_win); + wprintw(com_win, reading_file_msg, file_name); + if (access(file_name, 2)) /* check permission to write */ + { + if ((errno == ENOTDIR) || (errno == EACCES) || (errno == EROFS) || (errno == ETXTBSY) || (errno == EFAULT)) + { + wprintw(com_win, read_only_msg); + ro_flag = TRUE; + } + } + wrefresh(com_win); + } + if (curr_line->line_length > 1) /* if current line is not blank */ + { + insert_line(FALSE); + left(FALSE); + append = FALSE; + } + else + append = TRUE; + can_read = FALSE; /* test if file has any characters */ + while (((length = read(get_fd, in_string, 512)) != 0) && (length != -1)) + { + can_read = TRUE; /* if set file has at least 1 character */ + get_line(length, in_string, &append); + } + if ((can_read) && (curr_line->line_length == 1)) + { + temp_line = curr_line->prev_line; + temp_line->next_line = curr_line->next_line; + if (temp_line->next_line != NULL) + temp_line->next_line->prev_line = temp_line; + if (curr_line->line != NULL) + free(curr_line->line); + free(curr_line); + curr_line = temp_line; + } + if (input_file) /* if this is the file to be edited display number of lines */ + { + wmove(com_win, 0, 0); + wclrtoeol(com_win); + wprintw(com_win, file_read_lines_msg, in_file_name, curr_line->line_number); + if (ro_flag) + wprintw(com_win, read_only_msg); + wrefresh(com_win); + } + else if (can_read) /* not input_file and file is non-zero size */ + text_changes = TRUE; + + if (recv_file) /* if reading a file */ + { + in = EOF; + } +} + +void +get_line(length, in_string, append) /* read string and split into lines */ +int length; /* length of string read by read */ +unsigned char *in_string; /* string read by read */ +int *append; /* TRUE if must append more text to end of current line */ +{ + unsigned char *str1; + unsigned char *str2; + int num; /* offset from start of string */ + int char_count; /* length of new line (or added portion */ + int temp_counter; /* temporary counter value */ + struct text *tline; /* temporary pointer to new line */ + int first_time; /* if TRUE, the first time through the loop */ + + str2 = in_string; + num = 0; + first_time = TRUE; + while (num < length) + { + if (!first_time) + { + if (num < length) + { + str2++; + num++; + } + } + else + first_time = FALSE; + str1 = str2; + char_count = 1; + /* find end of line */ + while ((*str2 != '\n') && (num < length)) + { + str2++; + num++; + char_count++; + } + if (!(*append)) /* if not append to current line, insert new one */ + { + tline = txtalloc(); /* allocate data structure for next line */ + tline->line_number = curr_line->line_number + 1; + tline->next_line = curr_line->next_line; + tline->prev_line = curr_line; + curr_line->next_line = tline; + if (tline->next_line != NULL) + tline->next_line->prev_line = tline; + curr_line = tline; + curr_line->line = point = (unsigned char *) malloc(char_count); + curr_line->line_length = char_count; + curr_line->max_length = char_count; + } + else + { + point = resiz_line(char_count, curr_line, curr_line->line_length); + curr_line->line_length += (char_count - 1); + } + for (temp_counter = 1; temp_counter < char_count; temp_counter++) + { + *point = *str1; + point++; + str1++; + } + *point = (char) NULL; + *append = FALSE; + if ((num == length) && (*str2 != '\n')) + *append = TRUE; + } +} + +void +draw_screen() /* redraw the screen from current postion */ +{ + struct text *temp_line; + unsigned char *line_out; + int temp_vert; + + temp_line = curr_line; + temp_vert = scr_vert; + wclrtobot(text_win); + while ((temp_line != NULL) && (temp_vert <= last_line)) + { + line_out = temp_line->line; + draw_line(temp_vert, 0, line_out, 1, temp_line->line_length); + temp_vert++; + temp_line = temp_line->next_line; + } + wmove(text_win, temp_vert, 0); + wmove(text_win, scr_vert, (scr_horz - horiz_offset)); +} + +void +finish() /* prepare to exit edit session */ +{ + char *file_name = in_file_name; + + /* + | changes made here should be reflected in the 'save' + | portion of file_op() + */ + + if ((file_name == NULL) || (*file_name == (char) NULL)) + file_name = get_string(save_file_name_prompt, TRUE); + + if ((file_name == NULL) || (*file_name == (char) NULL)) + { + wmove(com_win, 0, 0); + wprintw(com_win, file_not_saved_msg); + wclrtoeol(com_win); + wrefresh(com_win); + clear_com_win = TRUE; + return; + } + + tmp_file = resolve_name(file_name); + if (tmp_file != file_name) + { + free(file_name); + file_name = tmp_file; + } + + if (write_file(file_name)) + { + text_changes = FALSE; + quit(0); + } +} + +int +quit(noverify) /* exit editor */ +int noverify; +{ + char *ans; + + touchwin(text_win); + wrefresh(text_win); + if ((text_changes) && (!noverify)) + { + ans = get_string(changes_made_prompt, TRUE); + if (toupper(*ans) == toupper(*yes_char)) + text_changes = FALSE; + else + return(0); + free(ans); + } + if (top_of_stack == NULL) + { + if (info_window) + wrefresh(info_win); + wrefresh(com_win); + resetty(); + endwin(); + putchar('\n'); + exit(0); + } + else + { + delete_text(); + recv_file = TRUE; + input_file = TRUE; + check_fp(); + } + return(0); +} + +void +edit_abort(arg) +int arg; +{ + wrefresh(com_win); + resetty(); + endwin(); + putchar('\n'); + exit(1); +} + +void +delete_text() +{ + while (curr_line->next_line != NULL) + curr_line = curr_line->next_line; + while (curr_line != first_line) + { + free(curr_line->line); + curr_line = curr_line->prev_line; + free(curr_line->next_line); + } + curr_line->next_line = NULL; + *curr_line->line = (char) NULL; + curr_line->line_length = 1; + curr_line->line_number = 1; + point = curr_line->line; + scr_pos = scr_vert = scr_horz = 0; + position = 1; +} + +int +write_file(file_name) +char *file_name; +{ + char cr; + char *tmp_point; + struct text *out_line; + int lines, charac; + int temp_pos; + int write_flag = TRUE; + + charac = lines = 0; + if ((in_file_name == NULL) || strcmp(in_file_name, file_name)) + { + if ((temp_fp = fopen(file_name, "r"))) + { + tmp_point = get_string(file_exists_prompt, TRUE); + if (toupper(*tmp_point) == toupper(*yes_char)) + write_flag = TRUE; + else + write_flag = FALSE; + fclose(temp_fp); + free(tmp_point); + } + } + + clear_com_win = TRUE; + + if (write_flag) + { + if ((temp_fp = fopen(file_name, "w")) == NULL) + { + clear_com_win = TRUE; + wmove(com_win,0,0); + wclrtoeol(com_win); + wprintw(com_win, create_file_fail_msg, file_name); + wrefresh(com_win); + return(FALSE); + } + else + { + wmove(com_win,0,0); + wclrtoeol(com_win); + wprintw(com_win, writing_file_msg, file_name); + wrefresh(com_win); + cr = '\n'; + out_line = first_line; + while (out_line != NULL) + { + temp_pos = 1; + tmp_point= out_line->line; + while (temp_pos < out_line->line_length) + { + putc(*tmp_point, temp_fp); + tmp_point++; + temp_pos++; + } + charac += out_line->line_length; + out_line = out_line->next_line; + putc(cr, temp_fp); + lines++; + } + fclose(temp_fp); + wmove(com_win,0,0); + wclrtoeol(com_win); + wprintw(com_win, file_written_msg, file_name, lines, charac); + wrefresh(com_win); + return(TRUE); + } + } + else + return(FALSE); +} + +int +search(display_message) /* search for string in srch_str */ +int display_message; +{ + int lines_moved; + int iter; + int found; + + if ((srch_str == NULL) || (*srch_str == (char) NULL)) + return(FALSE); + if (display_message) + { + wmove(com_win, 0, 0); + wclrtoeol(com_win); + wprintw(com_win, searching_msg); + wrefresh(com_win); + clear_com_win = TRUE; + } + lines_moved = 0; + found = FALSE; + srch_line = curr_line; + srch_1 = point; + if (position < curr_line->line_length) + srch_1++; + iter = position + 1; + while ((!found) && (srch_line != NULL)) + { + while ((iter < srch_line->line_length) && (!found)) + { + srch_2 = srch_1; + if (case_sen) /* if case sensitive */ + { + srch_3 = srch_str; + while ((*srch_2 == *srch_3) && (*srch_3 != (char) NULL)) + { + found = TRUE; + srch_2++; + srch_3++; + } /* end while */ + } + else /* if not case sensitive */ + { + srch_3 = u_srch_str; + while ((toupper(*srch_2) == *srch_3) && (*srch_3 != (char) NULL)) + { + found = TRUE; + srch_2++; + srch_3++; + } + } /* end else */ + if (!((*srch_3 == (char) NULL) && (found))) + { + found = FALSE; + if (iter < srch_line->line_length) + srch_1++; + iter++; + } + } + if (!found) + { + srch_line = srch_line->next_line; + if (srch_line != NULL) + srch_1 = srch_line->line; + iter = 1; + lines_moved++; + } + } + if (found) + { + if (display_message) + { + wmove(com_win, 0, 0); + wclrtoeol(com_win); + wrefresh(com_win); + } + if (lines_moved == 0) + { + while (position < iter) + right(TRUE); + } + else + { + if (lines_moved < 30) + { + move_rel("d", lines_moved); + while (position < iter) + right(TRUE); + } + else + { + curr_line = srch_line; + point = srch_1; + position = iter; + scanline(point); + scr_pos = scr_horz; + midscreen((last_line / 2), point); + } + } + } + else + { + if (display_message) + { + wmove(com_win, 0, 0); + wclrtoeol(com_win); + wprintw(com_win, str_not_found_msg, srch_str); + wrefresh(com_win); + } + wmove(text_win, scr_vert,(scr_horz - horiz_offset)); + } + return(found); +} + +void +search_prompt() /* prompt and read search string (srch_str) */ +{ + if (srch_str != NULL) + free(srch_str); + if ((u_srch_str != NULL) && (*u_srch_str != (char) NULL)) + free(u_srch_str); + srch_str = get_string(search_prompt_str, FALSE); + gold = FALSE; + srch_3 = srch_str; + srch_1 = u_srch_str = malloc(strlen(srch_str) + 1); + while (*srch_3 != (char) NULL) + { + *srch_1 = toupper(*srch_3); + srch_1++; + srch_3++; + } + *srch_1 = (char) NULL; + search(TRUE); +} + +void +del_char() /* delete current character */ +{ + in = 8; /* backspace */ + if (position < curr_line->line_length) /* if not end of line */ + { + if ((ee_chinese) && (*point > 127) && + ((curr_line->line_length - position) >= 2)) + { + point++; + position++; + } + position++; + point++; + scanline(point); + delete(TRUE); + } + else + { + right(FALSE); + delete(FALSE); + } +} + +void +undel_char() /* undelete last deleted character */ +{ + if (d_char[0] == '\n') /* insert line if last del_char deleted eol */ + insert_line(TRUE); + else + { + in = d_char[0]; + insert(in); + if (d_char[1] != (unsigned char) NULL) + { + in = d_char[1]; + insert(in); + } + } +} + +void +del_word() /* delete word in front of cursor */ +{ + int tposit; + int difference; + unsigned char *d_word2; + unsigned char *d_word3; + unsigned char tmp_char[3]; + + if (d_word != NULL) + free(d_word); + d_word = malloc(curr_line->line_length); + tmp_char[0] = d_char[0]; + tmp_char[1] = d_char[1]; + tmp_char[2] = d_char[2]; + d_word3 = point; + d_word2 = d_word; + tposit = position; + while ((tposit < curr_line->line_length) && + ((*d_word3 != ' ') && (*d_word3 != '\t'))) + { + tposit++; + *d_word2 = *d_word3; + d_word2++; + d_word3++; + } + while ((tposit < curr_line->line_length) && + ((*d_word3 == ' ') || (*d_word3 == '\t'))) + { + tposit++; + *d_word2 = *d_word3; + d_word2++; + d_word3++; + } + *d_word2 = (char) NULL; + d_wrd_len = difference = d_word2 - d_word; + d_word2 = point; + while (tposit < curr_line->line_length) + { + tposit++; + *d_word2 = *d_word3; + d_word2++; + d_word3++; + } + curr_line->line_length -= difference; + *d_word2 = (char) NULL; + draw_line(scr_vert, scr_horz,point,position,curr_line->line_length); + d_char[0] = tmp_char[0]; + d_char[1] = tmp_char[1]; + d_char[2] = tmp_char[2]; + text_changes = TRUE; + formatted = FALSE; +} + +void +undel_word() /* undelete last deleted word */ +{ + int temp; + int tposit; + unsigned char *tmp_old_ptr; + unsigned char *tmp_space; + unsigned char *tmp_ptr; + unsigned char *d_word_ptr; + + /* + | resize line to handle undeleted word + */ + if ((curr_line->max_length - (curr_line->line_length + d_wrd_len)) < 5) + point = resiz_line(d_wrd_len, curr_line, position); + tmp_ptr = tmp_space = malloc(curr_line->line_length + d_wrd_len); + d_word_ptr = d_word; + temp = 1; + /* + | copy d_word contents into temp space + */ + while (temp <= d_wrd_len) + { + temp++; + *tmp_ptr = *d_word_ptr; + tmp_ptr++; + d_word_ptr++; + } + tmp_old_ptr = point; + tposit = position; + /* + | copy contents of line from curent position to eol into + | temp space + */ + while (tposit < curr_line->line_length) + { + temp++; + tposit++; + *tmp_ptr = *tmp_old_ptr; + tmp_ptr++; + tmp_old_ptr++; + } + curr_line->line_length += d_wrd_len; + tmp_old_ptr = point; + *tmp_ptr = (char) NULL; + tmp_ptr = tmp_space; + tposit = 1; + /* + | now copy contents from temp space back to original line + */ + while (tposit < temp) + { + tposit++; + *tmp_old_ptr = *tmp_ptr; + tmp_ptr++; + tmp_old_ptr++; + } + *tmp_old_ptr = (char) NULL; + free(tmp_space); + draw_line(scr_vert, scr_horz, point, position, curr_line->line_length); +} + +void +del_line() /* delete from cursor to end of line */ +{ + unsigned char *dl1; + unsigned char *dl2; + int tposit; + + if (d_line != NULL) + free(d_line); + d_line = malloc(curr_line->line_length); + dl1 = d_line; + dl2 = point; + tposit = position; + while (tposit < curr_line->line_length) + { + *dl1 = *dl2; + dl1++; + dl2++; + tposit++; + } + dlt_line->line_length = 1 + tposit - position; + *dl1 = (char) NULL; + *point = (char) NULL; + curr_line->line_length = position; + wclrtoeol(text_win); + if (curr_line->next_line != NULL) + { + right(FALSE); + delete(FALSE); + } + text_changes = TRUE; +} + +void +undel_line() /* undelete last deleted line */ +{ + unsigned char *ud1; + unsigned char *ud2; + int tposit; + + if (dlt_line->line_length == 0) + return; + + insert_line(TRUE); + left(TRUE); + point = resiz_line(dlt_line->line_length, curr_line, position); + curr_line->line_length += dlt_line->line_length - 1; + ud1 = point; + ud2 = d_line; + tposit = 1; + while (tposit < dlt_line->line_length) + { + tposit++; + *ud1 = *ud2; + ud1++; + ud2++; + } + *ud1 = (char) NULL; + draw_line(scr_vert, scr_horz,point,position,curr_line->line_length); +} + +void +adv_word() /* advance to next word */ +{ +while ((position < curr_line->line_length) && ((*point != 32) && (*point != 9))) + right(TRUE); +while ((position < curr_line->line_length) && ((*point == 32) || (*point == 9))) + right(TRUE); +} + +void +move_rel(direction, lines) /* move relative to current line */ +char *direction; +int lines; +{ + int i; + char *tmp; + + if (*direction == 'u') + { + scr_pos = 0; + while (position > 1) + left(TRUE); + for (i = 0; i < lines; i++) + { + up(); + } + if ((last_line > 5) && ( scr_vert < 4)) + { + tmp = point; + tmp_line = curr_line; + for (i= 0;(i<5)&&(curr_line->prev_line != NULL); i++) + { + up(); + } + scr_vert = scr_vert + i; + curr_line = tmp_line; + point = tmp; + scanline(point); + } + } + else + { + if ((position != 1) && (curr_line->next_line != NULL)) + { + nextline(); + scr_pos = scr_horz = 0; + if (horiz_offset) + { + horiz_offset = 0; + midscreen(scr_vert, point); + } + } + else + adv_line(); + for (i = 1; i < lines; i++) + { + down(); + } + if ((last_line > 10) && (scr_vert > (last_line - 5))) + { + tmp = point; + tmp_line = curr_line; + for (i=0; (i<5) && (curr_line->next_line != NULL); i++) + { + down(); + } + scr_vert = scr_vert - i; + curr_line = tmp_line; + point = tmp; + scanline(point); + } + } + wmove(text_win, scr_vert, (scr_horz - horiz_offset)); +} + +void +eol() /* go to end of line */ +{ + if (position < curr_line->line_length) + { + while (position < curr_line->line_length) + right(TRUE); + } + else if (curr_line->next_line != NULL) + { + right(TRUE); + while (position < curr_line->line_length) + right(TRUE); + } +} + +void +bol() /* move to beginning of line */ +{ + if (point != curr_line->line) + { + while (point != curr_line->line) + left(TRUE); + } + else if (curr_line->prev_line != NULL) + { + scr_pos = 0; + up(); + } +} + +void +adv_line() /* advance to beginning of next line */ +{ + if ((point != curr_line->line) || (scr_pos > 0)) + { + while (position < curr_line->line_length) + right(TRUE); + right(TRUE); + } + else if (curr_line->next_line != NULL) + { + scr_pos = 0; + down(); + } +} + +void +sh_command(string) /* execute shell command */ +char *string; /* string containing user command */ +{ + char *temp_point; + char *last_slash; + char *path; /* directory path to executable */ + int parent; /* zero if child, child's pid if parent */ + int value; + int return_val; + struct text *line_holder; + + if (restrict_mode()) + { + return; + } + + if (!(path = getenv("SHELL"))) + path = "/bin/sh"; + last_slash = temp_point = path; + while (*temp_point != (char) NULL) + { + if (*temp_point == '/') + last_slash = ++temp_point; + else + temp_point++; + } + + /* + | if in_pipe is true, then output of the shell operation will be + | read by the editor, and curses doesn't need to be turned off + */ + + if (!in_pipe) + { + keypad(com_win, FALSE); + keypad(text_win, FALSE); + echo(); + nl(); + noraw(); + resetty(); + +#ifndef NCURSE + endwin(); +#endif + } + + if (in_pipe) + { + pipe(pipe_in); /* create a pipe */ + parent = fork(); + if (!parent) /* if the child */ + { +/* + | child process which will fork and exec shell command (if shell output is + | to be read by editor) + */ + in_pipe = FALSE; +/* + | redirect stdout to pipe + */ + temp_stdout = dup(1); + close(1); + dup(pipe_in[1]); +/* + | redirect stderr to pipe + */ + temp_stderr = dup(2); + close(2); + dup(pipe_in[1]); + close(pipe_in[1]); + /* + | child will now continue down 'if (!in_pipe)' + | path below + */ + } + else /* if the parent */ + { +/* + | prepare editor to read from the pipe + */ + signal(SIGCHLD, SIG_IGN); + line_holder = curr_line; + tmp_vert = scr_vert; + close(pipe_in[1]); + get_fd = pipe_in[0]; + get_file(""); + close(pipe_in[0]); + scr_vert = tmp_vert; + scr_horz = scr_pos = 0; + position = 1; + curr_line = line_holder; + point = curr_line->line; + out_pipe = FALSE; + signal(SIGCHLD, SIG_DFL); +/* + | since flag "in_pipe" is still TRUE, the path which waits for the child + | process to die will be avoided. + | (the pipe is closed, no more output can be expected) + */ + } + } + if (!in_pipe) + { + signal(SIGINT, SIG_IGN); + if (out_pipe) + { + pipe(pipe_out); + } +/* + | fork process which will exec command + */ + parent = fork(); + if (!parent) /* if the child */ + { + if (shell_fork) + putchar('\n'); + if (out_pipe) + { +/* + | prepare the child process (soon to exec a shell command) to read from the + | pipe (which will be output from the editor's buffer) + */ + close(0); + dup(pipe_out[0]); + close(pipe_out[0]); + close(pipe_out[1]); + } + for (value = 1; value < 24; value++) + signal(value, SIG_DFL); + execl(path, last_slash, "-c", string, NULL); + printf(exec_err_msg, path); + exit(-1); + } + else /* if the parent */ + { + if (out_pipe) + { +/* + | output the contents of the buffer to the pipe (to be read by the + | process forked and exec'd above as stdin) + */ + close(pipe_out[0]); + line_holder = first_line; + while (line_holder != NULL) + { + write(pipe_out[1], line_holder->line, (line_holder->line_length-1)); + write(pipe_out[1], "\n", 1); + line_holder = line_holder->next_line; + } + close(pipe_out[1]); + out_pipe = FALSE; + } + do + { + return_val = wait((int *) 0); + } + while ((return_val != parent) && (return_val != -1)); +/* + | if this process is actually the child of the editor, exit. Here's how it + | works: + | The editor forks a process. If output must be sent to the command to be + | exec'd another process is forked, and that process (the child's child) + | will exec the command. In this case, "shell_fork" will be FALSE. If no + | output is to be performed to the shell command, "shell_fork" will be TRUE. + | If this is the editor process, shell_fork will be true, otherwise this is + | the child of the edit process. + */ + if (!shell_fork) + exit(0); + } + signal(SIGINT, edit_abort); + } + if (shell_fork) + { + printf(continue_msg); + fflush(stdout); + while ((in = getchar()) != '\n') + ; + } + + if (!in_pipe) + { + fixterm(); + noecho(); + nonl(); + raw(); + keypad(text_win, TRUE); + keypad(com_win, TRUE); + if (info_window) + clearok(info_win, TRUE); + } + + redraw(); +} + +void +set_up_term() /* set up the terminal for operating with ae */ +{ + if (!curses_initialized) + { + initscr(); + savetty(); + noecho(); + raw(); + nonl(); + curses_initialized = TRUE; + } + + if (((LINES > 15) && (COLS >= 80)) && info_window) + last_line = LINES - 8; + else + { + info_window = FALSE; + last_line = LINES - 2; + } + + idlok(stdscr, TRUE); + com_win = newwin(1, COLS, (LINES - 1), 0); + keypad(com_win, TRUE); + idlok(com_win, TRUE); + wrefresh(com_win); + if (!info_window) + text_win = newwin((LINES - 1), COLS, 0, 0); + else + text_win = newwin((LINES - 7), COLS, 6, 0); + keypad(text_win, TRUE); + idlok(text_win, TRUE); + wrefresh(text_win); + help_win = newwin((LINES - 1), COLS, 0, 0); + keypad(help_win, TRUE); + idlok(help_win, TRUE); + if (info_window) + { + info_type = CONTROL_KEYS; + info_win = newwin(6, COLS, 0, 0); + werase(info_win); + paint_info_win(); + } + + last_col = COLS - 1; + local_LINES = LINES; + local_COLS = COLS; + +#ifdef NCURSE + if (ee_chinese) + nc_setattrib(A_NC_BIG5); +#endif /* NCURSE */ + +} + +void +resize_check() +{ + if ((LINES == local_LINES) && (COLS == local_COLS)) + return; + + if (info_window) + delwin(info_win); + delwin(text_win); + delwin(com_win); + delwin(help_win); + set_up_term(); + redraw(); + wrefresh(text_win); +} + +static char item_alpha[] = "abcdefghijklmnopqrstuvwxyz0123456789 "; + +int +menu_op(menu_list) +struct menu_entries menu_list[]; +{ + WINDOW *temp_win; + int max_width, max_height; + int x_off, y_off; + int counter; + int length; + int input; + int temp; + int list_size; + int top_offset; /* offset from top where menu items start */ + int vert_pos; /* vertical position */ + int vert_size; /* vertical size for menu list item display */ + int off_start = 1; /* offset from start of menu items to start display */ + + + /* + | determine number and width of menu items + */ + + list_size = 1; + while (menu_list[list_size + 1].item_string != NULL) + list_size++; + max_width = 0; + for (counter = 0; counter <= list_size; counter++) + { + if ((length = strlen(menu_list[counter].item_string)) > max_width) + max_width = length; + } + max_width += 3; + max_width = max(max_width, strlen(menu_cancel_msg)); + max_width = max(max_width, max(strlen(more_above_str), strlen(more_below_str))); + max_width += 6; + + /* + | make sure that window is large enough to handle menu + | if not, print error message and return to calling function + */ + + if (max_width > COLS) + { + wmove(com_win, 0, 0); + werase(com_win); + wprintw(com_win, menu_too_lrg_msg); + wrefresh(com_win); + clear_com_win = TRUE; + return(0); + } + + top_offset = 0; + + if (list_size > LINES) + { + max_height = LINES; + if (max_height > 11) + vert_size = max_height - 8; + else + vert_size = max_height; + } + else + { + vert_size = list_size; + max_height = list_size; + } + + if (LINES >= (vert_size + 8)) + { + if (menu_list[0].argument != MENU_WARN) + max_height = vert_size + 8; + else + max_height = vert_size + 7; + top_offset = 4; + } + x_off = (COLS - max_width) / 2; + y_off = (LINES - max_height - 1) / 2; + temp_win = newwin(max_height, max_width, y_off, x_off); + keypad(temp_win, TRUE); + + paint_menu(menu_list, max_width, max_height, list_size, top_offset, temp_win, off_start, vert_size); + + counter = 1; + vert_pos = 0; + do + { + if (off_start > 2) + wmove(temp_win, (1 + counter + top_offset - off_start), 3); + else + wmove(temp_win, (counter + top_offset - off_start), 3); + + wrefresh(temp_win); + in = wgetch(temp_win); + input = in; + if (input == -1) + exit(0); + + if (((tolower(input) >= 'a') && (tolower(input) <= 'z')) || + ((input >= '0') && (input <= '9'))) + { + if ((tolower(input) >= 'a') && (tolower(input) <= 'z')) + { + temp = 1 + tolower(input) - 'a'; + } + else if ((input >= '0') && (input <= '9')) + { + temp = (2 + 'z' - 'a') + (input - '0'); + } + + if (temp <= list_size) + { + input = '\n'; + counter = temp; + } + } + else + { + switch (input) + { + case ' ': /* space */ + case '\004': /* ^d, down */ + case KEY_RIGHT: + case KEY_DOWN: + counter++; + if (counter > list_size) + counter = 1; + break; + case '\010': /* ^h, backspace*/ + case '\025': /* ^u, up */ + case 127: /* ^?, delete */ + case KEY_BACKSPACE: + case KEY_LEFT: + case KEY_UP: + counter--; + if (counter == 0) + counter = list_size; + break; + case '\033': /* escape key */ + if (menu_list[0].argument != MENU_WARN) + counter = 0; + break; + case '\014': /* ^l */ + case '\022': /* ^r, redraw */ + paint_menu(menu_list, max_width, max_height, + list_size, top_offset, temp_win, + off_start, vert_size); + break; + default: + break; + } + } + + if (((list_size - off_start) >= (vert_size - 1)) && + (counter > (off_start + vert_size - 3)) && + (off_start > 1)) + { + if (counter == list_size) + off_start = (list_size - vert_size) + 2; + else + off_start++; + + paint_menu(menu_list, max_width, max_height, + list_size, top_offset, temp_win, off_start, + vert_size); + } + else if ((list_size != vert_size) && + (counter > (off_start + vert_size - 2))) + { + if (counter == list_size) + off_start = 2 + (list_size - vert_size); + else if (off_start == 1) + off_start = 3; + else + off_start++; + + paint_menu(menu_list, max_width, max_height, + list_size, top_offset, temp_win, off_start, + vert_size); + } + else if (counter < off_start) + { + if (counter <= 2) + off_start = 1; + else + off_start = counter; + + paint_menu(menu_list, max_width, max_height, + list_size, top_offset, temp_win, off_start, + vert_size); + } + } + while ((input != '\r') && (input != '\n') && (counter != 0)); + + werase(temp_win); + wrefresh(temp_win); + delwin(temp_win); + + if ((menu_list[counter].procedure != NULL) || + (menu_list[counter].iprocedure != NULL) || + (menu_list[counter].nprocedure != NULL)) + { + if (menu_list[counter].argument != -1) + (*menu_list[counter].iprocedure)(menu_list[counter].argument); + else if (menu_list[counter].ptr_argument != NULL) + (*menu_list[counter].procedure)(menu_list[counter].ptr_argument); + else + (*menu_list[counter].nprocedure)(); + } + + if (info_window) + paint_info_win(); + redraw(); + + return(counter); +} + +void +paint_menu(menu_list, max_width, max_height, list_size, top_offset, menu_win, + off_start, vert_size) +struct menu_entries menu_list[]; +int max_width, max_height, list_size, top_offset; +WINDOW *menu_win; +int off_start, vert_size; +{ + int counter, temp_int; + + werase(menu_win); + + /* + | output top and bottom portions of menu box only if window + | large enough + */ + + if (max_height > vert_size) + { + wmove(menu_win, 1, 1); + if (!nohighlight) + wstandout(menu_win); + waddch(menu_win, '+'); + for (counter = 0; counter < (max_width - 4); counter++) + waddch(menu_win, '-'); + waddch(menu_win, '+'); + + wmove(menu_win, (max_height - 2), 1); + waddch(menu_win, '+'); + for (counter = 0; counter < (max_width - 4); counter++) + waddch(menu_win, '-'); + waddch(menu_win, '+'); + wstandend(menu_win); + wmove(menu_win, 2, 3); + waddstr(menu_win, menu_list[0].item_string); + wmove(menu_win, (max_height - 3), 3); + if (menu_list[0].argument != MENU_WARN) + waddstr(menu_win, menu_cancel_msg); + } + if (!nohighlight) + wstandout(menu_win); + + for (counter = 0; counter < (vert_size + top_offset); counter++) + { + if (top_offset == 4) + { + temp_int = counter + 2; + } + else + temp_int = counter; + + wmove(menu_win, temp_int, 1); + waddch(menu_win, '|'); + wmove(menu_win, temp_int, (max_width - 2)); + waddch(menu_win, '|'); + } + wstandend(menu_win); + + if (list_size > vert_size) + { + if (off_start >= 3) + { + temp_int = 1; + wmove(menu_win, top_offset, 3); + waddstr(menu_win, more_above_str); + } + else + temp_int = 0; + + for (counter = off_start; + ((temp_int + counter - off_start) < (vert_size - 1)); + counter++) + { + wmove(menu_win, (top_offset + temp_int + + (counter - off_start)), 3); + if (list_size > 1) + wprintw(menu_win, "%c) ", item_alpha[min((counter - 1), max_alpha_char)]); + waddstr(menu_win, menu_list[counter].item_string); + } + + wmove(menu_win, (top_offset + (vert_size - 1)), 3); + + if (counter == list_size) + { + if (list_size > 1) + wprintw(menu_win, "%c) ", item_alpha[min((counter - 1), max_alpha_char)]); + wprintw(menu_win, menu_list[counter].item_string); + } + else + wprintw(menu_win, more_below_str); + } + else + { + for (counter = 1; counter <= list_size; counter++) + { + wmove(menu_win, (top_offset + counter - 1), 3); + if (list_size > 1) + wprintw(menu_win, "%c) ", item_alpha[min((counter - 1), max_alpha_char)]); + waddstr(menu_win, menu_list[counter].item_string); + } + } +} + +void +help() +{ + int counter; + + werase(help_win); + clearok(help_win, TRUE); + for (counter = 0; counter < 22; counter++) + { + wmove(help_win, counter, 0); + waddstr(help_win, (emacs_keys_mode) ? + emacs_help_text[counter] : help_text[counter]); + } + wrefresh(help_win); + werase(com_win); + wmove(com_win, 0, 0); + wprintw(com_win, press_any_key_msg); + wrefresh(com_win); + counter = wgetch(com_win); + if (counter == -1) + exit(0); + werase(com_win); + wmove(com_win, 0, 0); + werase(help_win); + wrefresh(help_win); + wrefresh(com_win); + redraw(); +} + +void +paint_info_win() +{ + int counter; + + if (!info_window) + return; + + werase(info_win); + for (counter = 0; counter < 5; counter++) + { + wmove(info_win, counter, 0); + wclrtoeol(info_win); + if (info_type == CONTROL_KEYS) + waddstr(info_win, (emacs_keys_mode) ? + emacs_control_keys[counter] : control_keys[counter]); + else if (info_type == COMMANDS) + waddstr(info_win, command_strings[counter]); + } + wmove(info_win, 5, 0); + if (!nohighlight) + wstandout(info_win); + waddstr(info_win, "==============================================================================="); + wstandend(info_win); + wrefresh(info_win); +} + +void +no_info_window() +{ + if (!info_window) + return; + delwin(info_win); + delwin(text_win); + info_window = FALSE; + last_line = LINES - 2; + text_win = newwin((LINES - 1), COLS, 0, 0); + keypad(text_win, TRUE); + idlok(text_win, TRUE); + clearok(text_win, TRUE); + midscreen(scr_vert, point); + wrefresh(text_win); + clear_com_win = TRUE; +} + +void +create_info_window() +{ + if (info_window) + return; + last_line = LINES - 8; + delwin(text_win); + text_win = newwin((LINES - 7), COLS, 6, 0); + keypad(text_win, TRUE); + idlok(text_win, TRUE); + werase(text_win); + info_window = TRUE; + info_win = newwin(6, COLS, 0, 0); + werase(info_win); + info_type = CONTROL_KEYS; + midscreen(min(scr_vert, last_line), point); + clearok(info_win, TRUE); + paint_info_win(); + wrefresh(text_win); + clear_com_win = TRUE; +} + +int +file_op(arg) +int arg; +{ + char *string; + int flag; + + if (restrict_mode()) + { + return(0); + } + + if (arg == READ_FILE) + { + string = get_string(file_read_prompt_str, TRUE); + recv_file = TRUE; + tmp_file = resolve_name(string); + check_fp(); + if (tmp_file != string) + free(tmp_file); + free(string); + } + else if (arg == WRITE_FILE) + { + string = get_string(file_write_prompt_str, TRUE); + tmp_file = resolve_name(string); + write_file(tmp_file); + if (tmp_file != string) + free(tmp_file); + free(string); + } + else if (arg == SAVE_FILE) + { + /* + | changes made here should be reflected in finish() + */ + + if (in_file_name) + flag = TRUE; + else + flag = FALSE; + + string = in_file_name; + if ((string == NULL) || (*string == (char) NULL)) + string = get_string(save_file_name_prompt, TRUE); + if ((string == NULL) || (*string == (char) NULL)) + { + wmove(com_win, 0, 0); + wprintw(com_win, file_not_saved_msg); + wclrtoeol(com_win); + wrefresh(com_win); + clear_com_win = TRUE; + return(0); + } + if (!flag) + { + tmp_file = resolve_name(string); + if (tmp_file != string) + { + free(string); + string = tmp_file; + } + } + if (write_file(string)) + { + in_file_name = string; + text_changes = FALSE; + } + else if (!flag) + free(string); + } + return(0); +} + +void +shell_op() +{ + char *string; + + if (((string = get_string(shell_prompt, TRUE)) != NULL) && + (*string != (char) NULL)) + { + sh_command(string); + free(string); + } +} + +void +leave_op() +{ + if (text_changes) + { + menu_op(leave_menu); + } + else + quit(TRUE); +} + +void +redraw() +{ + if (info_window) + { + clearok(info_win, TRUE); + paint_info_win(); + } + else + clearok(text_win, TRUE); + midscreen(scr_vert, point); +} + +/* + | The following routines will "format" a paragraph (as defined by a + | block of text with blank lines before and after the block). + */ + +int +Blank_Line(test_line) /* test if line has any non-space characters */ +struct text *test_line; +{ + unsigned char *line; + int length; + + if (test_line == NULL) + return(TRUE); + + length = 1; + line = test_line->line; + + /* + | To handle troff/nroff documents, consider a line with a + | period ('.') in the first column to be blank. To handle mail + | messages with included text, consider a line with a '>' blank. + */ + + if ((*line == '.') || (*line == '>')) + return(TRUE); + + while (((*line == ' ') || (*line == '\t')) && (length < test_line->line_length)) + { + length++; + line++; + } + if (length != test_line->line_length) + return(FALSE); + else + return(TRUE); +} + +void +Format() /* format the paragraph according to set margins */ +{ + int string_count; + int offset; + int temp_case; + int status; + int tmp_af; + int counter; + unsigned char *line; + unsigned char *tmp_srchstr; + unsigned char *temp1, *temp2; + unsigned char *temp_dword; + unsigned char temp_d_char[3]; + + temp_d_char[0] = d_char[0]; + temp_d_char[1] = d_char[1]; + temp_d_char[2] = d_char[2]; + +/* + | if observ_margins is not set, or the current line is blank, + | do not format the current paragraph + */ + + if ((!observ_margins) || (Blank_Line(curr_line))) + return; + +/* + | save the currently set flags, and clear them + */ + + wmove(com_win, 0, 0); + wclrtoeol(com_win); + wprintw(com_win, formatting_msg); + wrefresh(com_win); + +/* + | get current position in paragraph, so after formatting, the cursor + | will be in the same relative position + */ + + tmp_af = auto_format; + auto_format = FALSE; + offset = position; + if (position != 1) + prev_word(); + temp_dword = d_word; + d_word = NULL; + temp_case = case_sen; + case_sen = TRUE; + tmp_srchstr = srch_str; + temp2 = srch_str = (unsigned char *) malloc(1 + curr_line->line_length - position); + if ((*point == ' ') || (*point == '\t')) + adv_word(); + offset -= position; + counter = position; + line = temp1 = point; + while ((*temp1 != (char) NULL) && (*temp1 != ' ') && (*temp1 != '\t') && (counter < curr_line->line_length)) + { + *temp2 = *temp1; + temp2++; + temp1++; + counter++; + } + *temp2 = (char) NULL; + if (position != 1) + bol(); + while (!Blank_Line(curr_line->prev_line)) + bol(); + string_count = 0; + status = TRUE; + while ((line != point) && (status)) + { + status = search(FALSE); + string_count++; + } + + wmove(com_win, 0, 0); + wclrtoeol(com_win); + wprintw(com_win, formatting_msg); + wrefresh(com_win); + +/* + | now get back to the start of the paragraph to start formatting + */ + + if (position != 1) + bol(); + while (!Blank_Line(curr_line->prev_line)) + bol(); + + observ_margins = FALSE; + +/* + | Start going through lines, putting spaces at end of lines if they do + | not already exist. Append lines together to get one long line, and + | eliminate spacing at begin of lines. + */ + + while (!Blank_Line(curr_line->next_line)) + { + eol(); + left(TRUE); + if (*point != ' ') + { + right(TRUE); + insert(' '); + } + else + right(TRUE); + del_char(); + if ((*point == ' ') || (*point == '\t')) + del_word(); + } + +/* + | Now there is one long line. Eliminate extra spaces within the line + | after the first word (so as not to blow away any indenting the user + | may have put in). + */ + + bol(); + adv_word(); + while (position < curr_line->line_length) + { + if ((*point == ' ') && (*(point + 1) == ' ')) + del_char(); + else + right(TRUE); + } + +/* + | Now make sure there are two spaces after a '.'. + */ + + bol(); + while (position < curr_line->line_length) + { + if ((*point == '.') && (*(point + 1) == ' ')) + { + right(TRUE); + insert(' '); + insert(' '); + while (*point == ' ') + del_char(); + } + right(TRUE); + } + + observ_margins = TRUE; + bol(); + + wmove(com_win, 0, 0); + wclrtoeol(com_win); + wprintw(com_win, formatting_msg); + wrefresh(com_win); + +/* + | create lines between margins + */ + + while (position < curr_line->line_length) + { + while ((scr_pos < right_margin) && (position < curr_line->line_length)) + right(TRUE); + if (position < curr_line->line_length) + { + prev_word(); + if (position == 1) + adv_word(); + insert_line(TRUE); + } + } + +/* + | go back to begin of paragraph, put cursor back to original position + */ + + bol(); + while (!Blank_Line(curr_line->prev_line)) + bol(); + +/* + | find word cursor was in + */ + + while ((status) && (string_count > 0)) + { + search(FALSE); + string_count--; + } + +/* + | offset the cursor to where it was before from the start of the word + */ + + while (offset > 0) + { + offset--; + right(TRUE); + } + +/* + | reset flags and strings to what they were before formatting + */ + + if (d_word != NULL) + free(d_word); + d_word = temp_dword; + case_sen = temp_case; + free(srch_str); + srch_str = tmp_srchstr; + d_char[0] = temp_d_char[0]; + d_char[1] = temp_d_char[1]; + d_char[2] = temp_d_char[2]; + auto_format = tmp_af; + + midscreen(scr_vert, point); + werase(com_win); + wrefresh(com_win); +} + +unsigned char *init_name[3] = { + "/usr/local/lib/init.ee", + NULL, + ".init.ee" + }; + +void +ee_init() /* check for init file and read it if it exists */ +{ + FILE *init_file; + unsigned char *string; + unsigned char *str1; + unsigned char *str2; + char *home; + int counter; + int temp_int; + + string = getenv("HOME"); + str1 = home = malloc(strlen(string)+10); + strcpy(home, string); + strcat(home, "/.init.ee"); + init_name[1] = home; + string = malloc(512); + + for (counter = 0; counter < 3; counter++) + { + if (!(access(init_name[counter], 4))) + { + init_file = fopen(init_name[counter], "r"); + while ((str2 = fgets(string, 512, init_file)) != NULL) + { + str1 = str2 = string; + while (*str2 != '\n') + str2++; + *str2 = (char) NULL; + + if (unique_test(string, init_strings) != 1) + continue; + + if (compare(str1, CASE, FALSE)) + case_sen = TRUE; + else if (compare(str1, NOCASE, FALSE)) + case_sen = FALSE; + else if (compare(str1, EXPAND, FALSE)) + expand_tabs = TRUE; + else if (compare(str1, NOEXPAND, FALSE)) + expand_tabs = FALSE; + else if (compare(str1, INFO, FALSE)) + info_window = TRUE; + else if (compare(str1, NOINFO, FALSE)) + info_window = FALSE; + else if (compare(str1, MARGINS, FALSE)) + observ_margins = TRUE; + else if (compare(str1, NOMARGINS, FALSE)) + observ_margins = FALSE; + else if (compare(str1, AUTOFORMAT, FALSE)) + { + auto_format = TRUE; + observ_margins = TRUE; + } + else if (compare(str1, NOAUTOFORMAT, FALSE)) + auto_format = FALSE; + else if (compare(str1, Echo, FALSE)) + { + str1 = next_word(str1); + if (*str1 != (char) NULL) + echo_string(str1); + } + else if (compare(str1, PRINTCOMMAND, FALSE)) + { + str1 = next_word(str1); + print_command = malloc(strlen(str1)+1); + strcpy(print_command, str1); + } + else if (compare(str1, RIGHTMARGIN, FALSE)) + { + str1 = next_word(str1); + if ((*str1 >= '0') && (*str1 <= '9')) + { + temp_int = atoi(str1); + if (temp_int > 0) + right_margin = temp_int; + } + } + else if (compare(str1, HIGHLIGHT, FALSE)) + nohighlight = FALSE; + else if (compare(str1, NOHIGHLIGHT, FALSE)) + nohighlight = TRUE; + else if (compare(str1, EIGHTBIT, FALSE)) + eightbit = TRUE; + else if (compare(str1, NOEIGHTBIT, FALSE)) + { + eightbit = FALSE; + ee_chinese = FALSE; + } + else if (compare(str1, EMACS_string, FALSE)) + emacs_keys_mode = TRUE; + else if (compare(str1, NOEMACS_string, FALSE)) + emacs_keys_mode = FALSE; + else if (compare(str1, chinese_cmd, FALSE)) + { + ee_chinese = TRUE; + eightbit = TRUE; + } + else if (compare(str1, nochinese_cmd, FALSE)) + ee_chinese = FALSE; + } + fclose(init_file); + } + } + free(string); + free(home); + + string = getenv("LANG"); + if (string != NULL) + { + if (strcmp(string, "zh_TW.big5") == 0) + { + ee_chinese = TRUE; + eightbit = TRUE; + } + } +} + +/* + | Save current configuration to .init.ee file in the current directory. + */ + +void +dump_ee_conf() +{ + FILE *init_file; + FILE *old_init_file = NULL; + char *file_name = ".init.ee"; + char *home_dir = "~/.init.ee"; + char buffer[512]; + struct stat buf; + char *string; + int length; + int option = 0; + + if (restrict_mode()) + { + return; + } + + option = menu_op(config_dump_menu); + + werase(com_win); + wmove(com_win, 0, 0); + + if (option == 0) + { + wprintw(com_win, conf_not_saved_msg); + wrefresh(com_win); + return; + } + else if (option == 2) + file_name = resolve_name(home_dir); + + /* + | If a .init.ee file exists, move it to .init.ee.old. + */ + + if (stat(file_name, &buf) != -1) + { + sprintf(buffer, "%s.old", file_name); + unlink(buffer); + link(file_name, buffer); + unlink(file_name); + old_init_file = fopen(buffer, "r"); + } + + init_file = fopen(file_name, "w"); + if (init_file == NULL) + { + wprintw(com_win, conf_dump_err_msg); + wrefresh(com_win); + return; + } + + if (old_init_file != NULL) + { + /* + | Copy non-configuration info into new .init.ee file. + */ + while ((string = fgets(buffer, 512, old_init_file)) != NULL) + { + length = strlen(string); + string[length - 1] = (char) NULL; + + if (unique_test(string, init_strings) == 1) + { + if (compare(string, Echo, FALSE)) + { + fprintf(init_file, "%s\n", string); + } + } + else + fprintf(init_file, "%s\n", string); + } + + fclose(old_init_file); + } + + fprintf(init_file, "%s\n", case_sen ? CASE : NOCASE); + fprintf(init_file, "%s\n", expand_tabs ? EXPAND : NOEXPAND); + fprintf(init_file, "%s\n", info_window ? INFO : NOINFO ); + fprintf(init_file, "%s\n", observ_margins ? MARGINS : NOMARGINS ); + fprintf(init_file, "%s\n", auto_format ? AUTOFORMAT : NOAUTOFORMAT ); + fprintf(init_file, "%s %s\n", PRINTCOMMAND, print_command); + fprintf(init_file, "%s %d\n", RIGHTMARGIN, right_margin); + fprintf(init_file, "%s\n", nohighlight ? NOHIGHLIGHT : HIGHLIGHT ); + fprintf(init_file, "%s\n", eightbit ? EIGHTBIT : NOEIGHTBIT ); + fprintf(init_file, "%s\n", emacs_keys_mode ? EMACS_string : NOEMACS_string ); + fprintf(init_file, "%s\n", ee_chinese ? chinese_cmd : nochinese_cmd ); + + fclose(init_file); + + wprintw(com_win, conf_dump_success_msg, file_name); + wrefresh(com_win); + + if ((option == 2) && (file_name != home_dir)) + { + free(file_name); + } +} + +void +echo_string(string) /* echo the given string */ +char *string; +{ + char *temp; + int Counter; + + temp = string; + while (*temp != (char) NULL) + { + if (*temp == '\\') + { + temp++; + if (*temp == 'n') + putchar('\n'); + else if (*temp == 't') + putchar('\t'); + else if (*temp == 'b') + putchar('\b'); + else if (*temp == 'r') + putchar('\r'); + else if (*temp == 'f') + putchar('\f'); + else if ((*temp == 'e') || (*temp == 'E')) + putchar('\033'); /* escape */ + else if (*temp == '\\') + putchar('\\'); + else if (*temp == '\'') + putchar('\''); + else if ((*temp >= '0') && (*temp <= '9')) + { + Counter = 0; + while ((*temp >= '0') && (*temp <= '9')) + { + Counter = (8 * Counter) + (*temp - '0'); + temp++; + } + putchar(Counter); + temp--; + } + temp++; + } + else + { + putchar(*temp); + temp++; + } + } + + fflush(stdout); +} + +void +spell_op() /* check spelling of words in the editor */ +{ + if (restrict_mode()) + { + return; + } + top(); /* go to top of file */ + insert_line(FALSE); /* create two blank lines */ + insert_line(FALSE); + top(); + command(shell_echo_msg); + adv_line(); + wmove(com_win, 0, 0); + wprintw(com_win, spell_in_prog_msg); + wrefresh(com_win); + command("<>!spell"); /* send contents of buffer to command 'spell' + and read the results back into the editor */ +} + +void +ispell_op() +{ + char name[128]; + char string[256]; + int pid; + + if (restrict_mode()) + { + return; + } + pid = getpid(); + sprintf(name, "/tmp/ee.%d", pid); + if (write_file(name)) + { + sprintf(string, "ispell %s", name); + sh_command(string); + delete_text(); + tmp_file = name; + recv_file = TRUE; + check_fp(); + unlink(name); + } +} + +int +first_word_len(test_line) +struct text *test_line; +{ + int counter; + unsigned char *pnt; + + if (test_line == NULL) + return(0); + + pnt = test_line->line; + if ((pnt == NULL) || (*pnt == (char) NULL) || + (*pnt == '.') || (*pnt == '>')) + return(0); + + if ((*pnt == ' ') || (*pnt == '\t')) + { + pnt = next_word(pnt); + } + + if (*pnt == (char) NULL) + return(0); + + counter = 0; + while ((*pnt != (char) NULL) && ((*pnt != ' ') && (*pnt != '\t'))) + { + pnt++; + counter++; + } + while ((*pnt != (char) NULL) && ((*pnt == ' ') || (*pnt == '\t'))) + { + pnt++; + counter++; + } + return(counter); +} + +void +Auto_Format() /* format the paragraph according to set margins */ +{ + int string_count; + int offset; + int temp_case; + int word_len; + int temp_dwl; + int tmp_d_line_length; + int leave_loop = FALSE; + int status; + int counter; + char not_blank; + unsigned char *line; + unsigned char *tmp_srchstr; + unsigned char *temp1, *temp2; + unsigned char *temp_dword; + unsigned char temp_d_char[3]; + unsigned char *tmp_d_line; + + + temp_d_char[0] = d_char[0]; + temp_d_char[1] = d_char[1]; + temp_d_char[2] = d_char[2]; + +/* + | if observ_margins is not set, or the current line is blank, + | do not format the current paragraph + */ + + if ((!observ_margins) || (Blank_Line(curr_line))) + return; + +/* + | get current position in paragraph, so after formatting, the cursor + | will be in the same relative position + */ + + tmp_d_line = d_line; + tmp_d_line_length = dlt_line->line_length; + d_line = NULL; + auto_format = FALSE; + offset = position; + if ((position != 1) && ((*point == ' ') || (*point == '\t') || (position == curr_line->line_length) || (*point == (char) NULL))) + prev_word(); + temp_dword = d_word; + temp_dwl = d_wrd_len; + d_wrd_len = 0; + d_word = NULL; + temp_case = case_sen; + case_sen = TRUE; + tmp_srchstr = srch_str; + temp2 = srch_str = (unsigned char *) malloc(1 + curr_line->line_length - position); + if ((*point == ' ') || (*point == '\t')) + adv_word(); + offset -= position; + counter = position; + line = temp1 = point; + while ((*temp1 != (char) NULL) && (*temp1 != ' ') && (*temp1 != '\t') && (counter < curr_line->line_length)) + { + *temp2 = *temp1; + temp2++; + temp1++; + counter++; + } + *temp2 = (char) NULL; + if (position != 1) + bol(); + while (!Blank_Line(curr_line->prev_line)) + bol(); + string_count = 0; + status = TRUE; + while ((line != point) && (status)) + { + status = search(FALSE); + string_count++; + } + +/* + | now get back to the start of the paragraph to start checking + */ + + if (position != 1) + bol(); + while (!Blank_Line(curr_line->prev_line)) + bol(); + +/* + | Start going through lines, putting spaces at end of lines if they do + | not already exist. Check line length, and move words to the next line + | if they cross the margin. Then get words from the next line if they + | will fit in before the margin. + */ + + counter = 0; + + while (!leave_loop) + { + if (position != curr_line->line_length) + eol(); + left(TRUE); + if (*point != ' ') + { + right(TRUE); + insert(' '); + } + else + right(TRUE); + + not_blank = FALSE; + + /* + | fill line if first word on next line will fit + | in the line without crossing the margin + */ + + while ((curr_line->next_line != NULL) && + ((word_len = first_word_len(curr_line->next_line)) > 0) + && ((scr_pos + word_len) < right_margin)) + { + adv_line(); + if ((*point == ' ') || (*point == '\t')) + adv_word(); + del_word(); + if (position != 1) + bol(); + + /* + | We know this line was not blank before, so + | make sure that it doesn't have one of the + | leading characters that indicate the line + | should not be modified. + | + | We also know that this character should not + | be left as the first character of this line. + */ + + if ((Blank_Line(curr_line)) && + (curr_line->line[0] != '.') && + (curr_line->line[0] != '>')) + { + del_line(); + not_blank = FALSE; + } + else + not_blank = TRUE; + + /* + | go to end of previous line + */ + left(TRUE); + undel_word(); + eol(); + /* + | make sure there's a space at the end of the line + */ + left(TRUE); + if (*point != ' ') + { + right(TRUE); + insert(' '); + } + else + right(TRUE); + } + + /* + | make sure line does not cross right margin + */ + + while (right_margin <= scr_pos) + { + prev_word(); + if (position != 1) + { + del_word(); + if (Blank_Line(curr_line->next_line)) + insert_line(TRUE); + else + adv_line(); + if ((*point == ' ') || (*point == '\t')) + adv_word(); + undel_word(); + not_blank = TRUE; + if (position != 1) + bol(); + left(TRUE); + } + } + + if ((!Blank_Line(curr_line->next_line)) || (not_blank)) + { + adv_line(); + counter++; + } + else + leave_loop = TRUE; + } + +/* + | go back to begin of paragraph, put cursor back to original position + */ + + if (position != 1) + bol(); + while ((counter-- > 0) || (!Blank_Line(curr_line->prev_line))) + bol(); + +/* + | find word cursor was in + */ + + status = TRUE; + while ((status) && (string_count > 0)) + { + status = search(FALSE); + string_count--; + } + +/* + | offset the cursor to where it was before from the start of the word + */ + + while (offset > 0) + { + offset--; + right(TRUE); + } + + if ((string_count > 0) && (offset < 0)) + { + while (offset < 0) + { + offset++; + left(TRUE); + } + } + +/* + | reset flags and strings to what they were before formatting + */ + + if (d_word != NULL) + free(d_word); + d_word = temp_dword; + d_wrd_len = temp_dwl; + case_sen = temp_case; + free(srch_str); + srch_str = tmp_srchstr; + d_char[0] = temp_d_char[0]; + d_char[1] = temp_d_char[1]; + d_char[2] = temp_d_char[2]; + auto_format = TRUE; + dlt_line->line_length = tmp_d_line_length; + d_line = tmp_d_line; + + formatted = TRUE; + midscreen(scr_vert, point); +} + +void +modes_op() +{ + int ret_value; + int counter; + char *string; + + do + { + sprintf(modes_menu[1].item_string, "%s %s", mode_strings[1], + (expand_tabs ? ON : OFF)); + sprintf(modes_menu[2].item_string, "%s %s", mode_strings[2], + (case_sen ? ON : OFF)); + sprintf(modes_menu[3].item_string, "%s %s", mode_strings[3], + (observ_margins ? ON : OFF)); + sprintf(modes_menu[4].item_string, "%s %s", mode_strings[4], + (auto_format ? ON : OFF)); + sprintf(modes_menu[5].item_string, "%s %s", mode_strings[5], + (eightbit ? ON : OFF)); + sprintf(modes_menu[6].item_string, "%s %s", mode_strings[6], + (info_window ? ON : OFF)); + sprintf(modes_menu[7].item_string, "%s %s", mode_strings[7], + (emacs_keys_mode ? ON : OFF)); + sprintf(modes_menu[8].item_string, "%s %d", mode_strings[8], + right_margin); + sprintf(modes_menu[9].item_string, "%s %s", mode_strings[9], + (ee_chinese ? ON : OFF)); + + ret_value = menu_op(modes_menu); + + switch (ret_value) + { + case 1: + expand_tabs = !expand_tabs; + break; + case 2: + case_sen = !case_sen; + break; + case 3: + observ_margins = !observ_margins; + break; + case 4: + auto_format = !auto_format; + if (auto_format) + observ_margins = TRUE; + break; + case 5: + eightbit = !eightbit; + if (!eightbit) + ee_chinese = FALSE; +#ifdef NCURSE + if (ee_chinese) + nc_setattrib(A_NC_BIG5); + else + nc_clearattrib(A_NC_BIG5); +#endif /* NCURSE */ + + redraw(); + wnoutrefresh(text_win); + break; + case 6: + if (info_window) + no_info_window(); + else + create_info_window(); + break; + case 7: + emacs_keys_mode = !emacs_keys_mode; + if (info_window) + paint_info_win(); + break; + case 8: + string = get_string(margin_prompt, TRUE); + if (string != NULL) + { + counter = atoi(string); + if (counter > 0) + right_margin = counter; + free(string); + } + break; + case 9: + ee_chinese = !ee_chinese; + if (ee_chinese != FALSE) + eightbit = TRUE; +#ifdef NCURSE + if (ee_chinese) + nc_setattrib(A_NC_BIG5); + else + nc_clearattrib(A_NC_BIG5); +#endif /* NCURSE */ + redraw(); + break; + default: + break; + } + } + while (ret_value != 0); +} + +char * +is_in_string(string, substring) /* a strchr() look-alike for systems without + strchr() */ +char * string, *substring; +{ + char *full, *sub; + + for (sub = substring; (sub != NULL) && (*sub != (char)NULL); sub++) + { + for (full = string; (full != NULL) && (*full != (char)NULL); + full++) + { + if (*sub == *full) + return(full); + } + } + return(NULL); +} + +/* + | handle names of the form "~/file", "~user/file", + | "$HOME/foo", "~/$FOO", etc. + */ + +char * +resolve_name(name) +char *name; +{ + char long_buffer[1024]; + char short_buffer[128]; + char *buffer; + char *slash; + char *tmp; + char *start_of_var; + int offset; + int index; + int counter; + struct passwd *user; + + if (name[0] == '~') + { + if (name[1] == '/') + { + index = getuid(); + user = (struct passwd *) getpwuid(index); + slash = name + 1; + } + else + { + slash = strchr(name, '/'); + if (slash == NULL) + return(name); + *slash = (char) NULL; + user = (struct passwd *) getpwnam((name + 1)); + *slash = '/'; + } + if (user == NULL) + { + return(name); + } + buffer = malloc(strlen(user->pw_dir) + strlen(slash) + 1); + strcpy(buffer, user->pw_dir); + strcat(buffer, slash); + } + else + buffer = name; + + if (is_in_string(buffer, "$")) + { + tmp = buffer; + index = 0; + + while ((*tmp != (char) NULL) && (index < 1024)) + { + + while ((*tmp != (char) NULL) && (*tmp != '$') && + (index < 1024)) + { + long_buffer[index] = *tmp; + tmp++; + index++; + } + + if ((*tmp == '$') && (index < 1024)) + { + counter = 0; + start_of_var = tmp; + tmp++; + if (*tmp == '{') /* } */ /* bracketed variable name */ + { + tmp++; /* { */ + while ((*tmp != (char) NULL) && + (*tmp != '}') && + (counter < 128)) + { + short_buffer[counter] = *tmp; + counter++; + tmp++; + } /* { */ + if (*tmp == '}') + tmp++; + } + else + { + while ((*tmp != (char) NULL) && + (*tmp != '/') && + (*tmp != '$') && + (counter < 128)) + { + short_buffer[counter] = *tmp; + counter++; + tmp++; + } + } + short_buffer[counter] = (char) NULL; + if ((slash = getenv(short_buffer)) != NULL) + { + offset = strlen(slash); + if ((offset + index) < 1024) + strcpy(&long_buffer[index], slash); + index += offset; + } + else + { + while ((start_of_var != tmp) && (index < 1024)) + { + long_buffer[index] = *start_of_var; + start_of_var++; + index++; + } + } + } + } + + if (index == 1024) + return(buffer); + else + long_buffer[index] = (char) NULL; + + if (name != buffer) + free(buffer); + buffer = malloc(index + 1); + strcpy(buffer, long_buffer); + } + + return(buffer); +} + +int +restrict_mode() +{ + if (!restricted) + return(FALSE); + + wmove(com_win, 0, 0); + wprintw(com_win, restricted_msg); + wclrtoeol(com_win); + wrefresh(com_win); + clear_com_win = TRUE; + return(TRUE); +} + +/* + | The following routine tests the input string against the list of + | strings, to determine if the string is a unique match with one of the + | valid values. + */ + +int +unique_test(string, list) +char *string; +char *list[]; +{ + int counter; + int num_match; + int result; + + num_match = 0; + counter = 0; + while (list[counter] != NULL) + { + result = compare(string, list[counter], FALSE); + if (result) + num_match++; + counter++; + } + return(num_match); +} + +#ifndef NO_CATGETS +/* + | Get the catalog entry, and if it got it from the catalog, + | make a copy, since the buffer will be overwritten by the + | next call to catgets(). + */ + +char * +catgetlocal(number, string) +int number; +char *string; +{ + char *temp1; + char *temp2; + + temp1 = catgets(catalog, 1, number, string); + if (temp1 != string) + { + temp2 = malloc(strlen(temp1) + 1); + strcpy(temp2, temp1); + temp1 = temp2; + } + return(temp1); +} +#endif /* NO_CATGETS */ + +/* + | The following is to allow for using message catalogs which allow + | the software to be 'localized', that is, to use different languages + | all with the same binary. For more information, see your system + | documentation, or the X/Open Internationalization Guide. + */ + +void +strings_init() +{ + int counter; + +#ifndef NO_CATGETS + setlocale(LC_ALL, ""); + catalog = catopen("ee", 0); +#endif /* NO_CATGETS */ + + modes_menu[0].item_string = catgetlocal( 1, "modes menu"); + mode_strings[1] = catgetlocal( 2, "tabs to spaces "); + mode_strings[2] = catgetlocal( 3, "case sensitive search"); + mode_strings[3] = catgetlocal( 4, "margins observed "); + mode_strings[4] = catgetlocal( 5, "auto-paragraph format"); + mode_strings[5] = catgetlocal( 6, "eightbit characters "); + mode_strings[6] = catgetlocal( 7, "info window "); + mode_strings[8] = catgetlocal( 8, "right margin "); + leave_menu[0].item_string = catgetlocal( 9, "leave menu"); + leave_menu[1].item_string = catgetlocal( 10, "save changes"); + leave_menu[2].item_string = catgetlocal( 11, "no save"); + file_menu[0].item_string = catgetlocal( 12, "file menu"); + file_menu[1].item_string = catgetlocal( 13, "read a file"); + file_menu[2].item_string = catgetlocal( 14, "write a file"); + file_menu[3].item_string = catgetlocal( 15, "save file"); + file_menu[4].item_string = catgetlocal( 16, "print editor contents"); + search_menu[0].item_string = catgetlocal( 17, "search menu"); + search_menu[1].item_string = catgetlocal( 18, "search for ..."); + search_menu[2].item_string = catgetlocal( 19, "search"); + spell_menu[0].item_string = catgetlocal( 20, "spell menu"); + spell_menu[1].item_string = catgetlocal( 21, "use 'spell'"); + spell_menu[2].item_string = catgetlocal( 22, "use 'ispell'"); + misc_menu[0].item_string = catgetlocal( 23, "miscellaneous menu"); + misc_menu[1].item_string = catgetlocal( 24, "format paragraph"); + misc_menu[2].item_string = catgetlocal( 25, "shell command"); + misc_menu[3].item_string = catgetlocal( 26, "check spelling"); + main_menu[0].item_string = catgetlocal( 27, "main menu"); + main_menu[1].item_string = catgetlocal( 28, "leave editor"); + main_menu[2].item_string = catgetlocal( 29, "help"); + main_menu[3].item_string = catgetlocal( 30, "file operations"); + main_menu[4].item_string = catgetlocal( 31, "redraw screen"); + main_menu[5].item_string = catgetlocal( 32, "settings"); + main_menu[6].item_string = catgetlocal( 33, "search"); + main_menu[7].item_string = catgetlocal( 34, "miscellaneous"); + help_text[0] = catgetlocal( 35, "Control keys: "); + help_text[1] = catgetlocal( 36, "^a ascii code ^i tab ^r right "); + help_text[2] = catgetlocal( 37, "^b bottom of text ^j newline ^t top of text "); + help_text[3] = catgetlocal( 38, "^c command ^k delete char ^u up "); + help_text[4] = catgetlocal( 39, "^d down ^l left ^v undelete word "); + help_text[5] = catgetlocal( 40, "^e search prompt ^m newline ^w delete word "); + help_text[6] = catgetlocal( 41, "^f undelete char ^n next page ^x search "); + help_text[7] = catgetlocal( 42, "^g begin of line ^o end of line ^y delete line "); + help_text[8] = catgetlocal( 43, "^h backspace ^p prev page ^z undelete line "); + help_text[9] = catgetlocal( 44, "^[ (escape) menu "); + help_text[10] = catgetlocal( 45, " "); + help_text[11] = catgetlocal( 46, "Commands: "); + help_text[12] = catgetlocal( 47, "help : get this info file : print file name "); + help_text[13] = catgetlocal( 48, "read : read a file char : ascii code of char "); + help_text[14] = catgetlocal( 49, "write : write a file case : case sensitive search "); + help_text[15] = catgetlocal( 50, "exit : leave and save nocase : case insensitive search "); + help_text[16] = catgetlocal( 51, "quit : leave, no save !cmd : execute \"cmd\" in shell "); + help_text[17] = catgetlocal( 52, "line : display line # 0-9 : go to line \"#\" "); + help_text[18] = catgetlocal( 53, "expand : expand tabs noexpand: do not expand tabs "); + help_text[19] = catgetlocal( 54, " "); + help_text[20] = catgetlocal( 55, " ee [+#] [-i] [-e] [-h] [file(s)] "); + help_text[21] = catgetlocal( 56, "+# :go to line # -i :no info window -e : don't expand tabs -h :no highlight"); + control_keys[0] = catgetlocal( 57, "^[ (escape) menu ^e search prompt ^y delete line ^u up ^p prev page "); + control_keys[1] = catgetlocal( 58, "^a ascii code ^x search ^z undelete line ^d down ^n next page "); + control_keys[2] = catgetlocal( 59, "^b bottom of text ^g begin of line ^w delete word ^l left "); + control_keys[3] = catgetlocal( 60, "^t top of text ^o end of line ^v undelete word ^r right "); + control_keys[4] = catgetlocal( 61, "^c command ^k delete char ^f undelete char "); + command_strings[0] = catgetlocal( 62, "help : get help info |file : print file name |line : print line # "); + command_strings[1] = catgetlocal( 63, "read : read a file |char : ascii code of char |0-9 : go to line \"#\""); + command_strings[2] = catgetlocal( 64, "write: write a file |case : case sensitive search |exit : leave and save "); + command_strings[3] = catgetlocal( 65, "!cmd : shell \"cmd\" |nocase: ignore case in search |quit : leave, no save"); + command_strings[4] = catgetlocal( 66, "expand: expand tabs |noexpand: do not expand tabs "); + com_win_message = catgetlocal( 67, " press Escape (^[) for menu"); + no_file_string = catgetlocal( 68, "no file"); + ascii_code_str = catgetlocal( 69, "ascii code: "); + printer_msg_str = catgetlocal( 70, "sending contents of buffer to \"%s\" "); + command_str = catgetlocal( 71, "command: "); + file_write_prompt_str = catgetlocal( 72, "name of file to write: "); + file_read_prompt_str = catgetlocal( 73, "name of file to read: "); + char_str = catgetlocal( 74, "character = %d"); + unkn_cmd_str = catgetlocal( 75, "unknown command \"%s\""); + non_unique_cmd_msg = catgetlocal( 76, "entered command is not unique"); + line_num_str = catgetlocal( 77, "line %d "); + line_len_str = catgetlocal( 78, "length = %d"); + current_file_str = catgetlocal( 79, "current file is \"%s\" "); + usage0 = catgetlocal( 80, "usage: %s [-i] [-e] [-h] [+line_number] [file(s)]\n"); + usage1 = catgetlocal( 81, " -i turn off info window\n"); + usage2 = catgetlocal( 82, " -e do not convert tabs to spaces\n"); + usage3 = catgetlocal( 83, " -h do not use highlighting\n"); + file_is_dir_msg = catgetlocal( 84, "file \"%s\" is a directory"); + new_file_msg = catgetlocal( 85, "new file \"%s\""); + cant_open_msg = catgetlocal( 86, "can't open \"%s\""); + open_file_msg = catgetlocal( 87, "file \"%s\", %d lines"); + file_read_fin_msg = catgetlocal( 88, "finished reading file \"%s\""); + reading_file_msg = catgetlocal( 89, "reading file \"%s\""); + read_only_msg = catgetlocal( 90, ", read only"); + file_read_lines_msg = catgetlocal( 91, "file \"%s\", %d lines"); + save_file_name_prompt = catgetlocal( 92, "enter name of file: "); + file_not_saved_msg = catgetlocal( 93, "no filename entered: file not saved"); + changes_made_prompt = catgetlocal( 94, "changes have been made, are you sure? (y/n [n]) "); + yes_char = catgetlocal( 95, "y"); + file_exists_prompt = catgetlocal( 96, "file already exists, overwrite? (y/n) [n] "); + create_file_fail_msg = catgetlocal( 97, "unable to create file \"%s\""); + writing_file_msg = catgetlocal( 98, "writing file \"%s\""); + file_written_msg = catgetlocal( 99, "\"%s\" %d lines, %d characters"); + searching_msg = catgetlocal( 100, " ...searching"); + str_not_found_msg = catgetlocal( 101, "string \"%s\" not found"); + search_prompt_str = catgetlocal( 102, "search for: "); + exec_err_msg = catgetlocal( 103, "could not exec %s\n"); + continue_msg = catgetlocal( 104, "press return to continue "); + menu_cancel_msg = catgetlocal( 105, "press Esc to cancel"); + menu_size_err_msg = catgetlocal( 106, "menu too large for window"); + press_any_key_msg = catgetlocal( 107, "press any key to continue "); + shell_prompt = catgetlocal( 108, "shell command: "); + formatting_msg = catgetlocal( 109, "...formatting paragraph..."); + shell_echo_msg = catgetlocal( 110, "<!echo 'list of unrecognized words'; echo -=-=-=-=-=-"); + spell_in_prog_msg = catgetlocal( 111, "sending contents of edit buffer to 'spell'"); + margin_prompt = catgetlocal( 112, "right margin is: "); + restricted_msg = catgetlocal( 113, "restricted mode: unable to perform requested operation"); + ON = catgetlocal( 114, "ON"); + OFF = catgetlocal( 115, "OFF"); + HELP = catgetlocal( 116, "HELP"); + WRITE = catgetlocal( 117, "WRITE"); + READ = catgetlocal( 118, "READ"); + LINE = catgetlocal( 119, "LINE"); + FILE_str = catgetlocal( 120, "FILE"); + CHARACTER = catgetlocal( 121, "CHARACTER"); + REDRAW = catgetlocal( 122, "REDRAW"); + RESEQUENCE = catgetlocal( 123, "RESEQUENCE"); + AUTHOR = catgetlocal( 124, "AUTHOR"); + VERSION = catgetlocal( 125, "VERSION"); + CASE = catgetlocal( 126, "CASE"); + NOCASE = catgetlocal( 127, "NOCASE"); + EXPAND = catgetlocal( 128, "EXPAND"); + NOEXPAND = catgetlocal( 129, "NOEXPAND"); + Exit_string = catgetlocal( 130, "EXIT"); + QUIT_string = catgetlocal( 131, "QUIT"); + INFO = catgetlocal( 132, "INFO"); + NOINFO = catgetlocal( 133, "NOINFO"); + MARGINS = catgetlocal( 134, "MARGINS"); + NOMARGINS = catgetlocal( 135, "NOMARGINS"); + AUTOFORMAT = catgetlocal( 136, "AUTOFORMAT"); + NOAUTOFORMAT = catgetlocal( 137, "NOAUTOFORMAT"); + Echo = catgetlocal( 138, "ECHO"); + PRINTCOMMAND = catgetlocal( 139, "PRINTCOMMAND"); + RIGHTMARGIN = catgetlocal( 140, "RIGHTMARGIN"); + HIGHLIGHT = catgetlocal( 141, "HIGHLIGHT"); + NOHIGHLIGHT = catgetlocal( 142, "NOHIGHLIGHT"); + EIGHTBIT = catgetlocal( 143, "EIGHTBIT"); + NOEIGHTBIT = catgetlocal( 144, "NOEIGHTBIT"); + /* + | additions + */ + mode_strings[7] = catgetlocal( 145, "emacs key bindings "); + emacs_help_text[0] = help_text[0]; + emacs_help_text[1] = catgetlocal( 146, "^a beginning of line ^i tab ^r restore word "); + emacs_help_text[2] = catgetlocal( 147, "^b back 1 char ^j undel char ^t top of text "); + emacs_help_text[3] = catgetlocal( 148, "^c command ^k delete line ^u bottom of text "); + emacs_help_text[4] = catgetlocal( 149, "^d delete char ^l undelete line ^v next page "); + emacs_help_text[5] = catgetlocal( 150, "^e end of line ^m newline ^w delete word "); + emacs_help_text[6] = catgetlocal( 151, "^f forward 1 char ^n next line ^x search "); + emacs_help_text[7] = catgetlocal( 152, "^g go back 1 page ^o ascii char insert ^y search prompt "); + emacs_help_text[8] = catgetlocal( 153, "^h backspace ^p prev line ^z next word "); + emacs_help_text[9] = help_text[9]; + emacs_help_text[10] = help_text[10]; + emacs_help_text[11] = help_text[11]; + emacs_help_text[12] = help_text[12]; + emacs_help_text[13] = help_text[13]; + emacs_help_text[14] = help_text[14]; + emacs_help_text[15] = help_text[15]; + emacs_help_text[16] = help_text[16]; + emacs_help_text[17] = help_text[17]; + emacs_help_text[18] = help_text[18]; + emacs_help_text[19] = help_text[19]; + emacs_help_text[20] = help_text[20]; + emacs_help_text[21] = help_text[21]; + emacs_control_keys[0] = catgetlocal( 154, "^[ (escape) menu ^y search prompt ^k delete line ^p prev li ^g prev page"); + emacs_control_keys[1] = catgetlocal( 155, "^o ascii code ^x search ^l undelete line ^n next li ^v next page"); + emacs_control_keys[2] = catgetlocal( 156, "^u end of file ^a begin of line ^w delete word ^b back 1 char "); + emacs_control_keys[3] = catgetlocal( 157, "^t top of text ^e end of line ^r restore word ^f forward 1 char "); + emacs_control_keys[4] = catgetlocal( 158, "^c command ^d delete char ^j undelete char ^z next word "); + EMACS_string = catgetlocal( 159, "EMACS"); + NOEMACS_string = catgetlocal( 160, "NOEMACS"); + usage4 = catgetlocal( 161, " +# put cursor at line #\n"); + conf_dump_err_msg = catgetlocal( 162, "unable to open .init.ee for writing, no configuration saved!"); + conf_dump_success_msg = catgetlocal( 163, "ee configuration saved in file %s"); + modes_menu[10].item_string = catgetlocal( 164, "save editor configuration"); + config_dump_menu[0].item_string = catgetlocal( 165, "save ee configuration"); + config_dump_menu[1].item_string = catgetlocal( 166, "save in current directory"); + config_dump_menu[2].item_string = catgetlocal( 167, "save in home directory"); + conf_not_saved_msg = catgetlocal( 168, "ee configuration not saved"); + ree_no_file_msg = catgetlocal( 169, "must specify a file when invoking ree"); + menu_too_lrg_msg = catgetlocal( 180, "menu too large for window"); + more_above_str = catgetlocal( 181, "^^more^^"); + more_below_str = catgetlocal( 182, "VVmoreVV"); + mode_strings[9] = catgetlocal( 183, "16 bit characters "); + chinese_cmd = catgetlocal( 184, "16BIT"); + nochinese_cmd = catgetlocal( 185, "NO16BIT"); + + commands[0] = HELP; + commands[1] = WRITE; + commands[2] = READ; + commands[3] = LINE; + commands[4] = FILE_str; + commands[5] = REDRAW; + commands[6] = RESEQUENCE; + commands[7] = AUTHOR; + commands[8] = VERSION; + commands[9] = CASE; + commands[10] = NOCASE; + commands[11] = EXPAND; + commands[12] = NOEXPAND; + commands[13] = Exit_string; + commands[14] = QUIT_string; + commands[15] = "<"; + commands[16] = ">"; + commands[17] = "!"; + commands[18] = "0"; + commands[19] = "1"; + commands[20] = "2"; + commands[21] = "3"; + commands[22] = "4"; + commands[23] = "5"; + commands[24] = "6"; + commands[25] = "7"; + commands[26] = "8"; + commands[27] = "9"; + commands[28] = CHARACTER; + commands[29] = chinese_cmd; + commands[30] = nochinese_cmd; + commands[31] = NULL; + init_strings[0] = CASE; + init_strings[1] = NOCASE; + init_strings[2] = EXPAND; + init_strings[3] = NOEXPAND; + init_strings[4] = INFO; + init_strings[5] = NOINFO; + init_strings[6] = MARGINS; + init_strings[7] = NOMARGINS; + init_strings[8] = AUTOFORMAT; + init_strings[9] = NOAUTOFORMAT; + init_strings[10] = Echo; + init_strings[11] = PRINTCOMMAND; + init_strings[12] = RIGHTMARGIN; + init_strings[13] = HIGHLIGHT; + init_strings[14] = NOHIGHLIGHT; + init_strings[15] = EIGHTBIT; + init_strings[16] = NOEIGHTBIT; + init_strings[17] = EMACS_string; + init_strings[18] = NOEMACS_string; + init_strings[19] = chinese_cmd; + init_strings[20] = nochinese_cmd; + init_strings[21] = NULL; + + /* + | allocate space for strings here for settings menu + */ + + for (counter = 1; counter < NUM_MODES_ITEMS; counter++) + { + modes_menu[counter].item_string = malloc(80); + } + +#ifndef NO_CATGETS + catclose(catalog); +#endif /* NO_CATGETS */ +} + |