Logo Search packages:      
Sourcecode: aee version File versions  Download package

aee.c

/*
      +---------------------------------------------------------------+
      |                                               |
      |     Hugh F. Mahon                                   |
      |     begun Nov. 22, 1985                             |
      |                                               |
      |     ae (another editor)                             |
      +---------------------------------------------------------------+

      $Header: /home/hugh/sources/aee/RCS/aee.c,v 1.78 2002/07/06 05:03:00 hugh Exp $

*/

/*
 |    An easy to use, simple screen oriented editor.
 |
 |    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 software and documentation contains
 |    proprietary information which is protected by
 |    copyright.  All rights are reserved.
 |
 */
char *copyright_notice = "Copyright (c) 1986 - 1988, 1991 - 2002 Hugh Mahon.";

char *long_notice[] = {
      "This software and documentation contains", 
      "proprietary information which is protected by", 
      "copyright.  All rights are reserved."
      };

#include "aee_version.h"

char *version_string = "@(#) aee (another easy editor) version "  AEE_VERSION  " " DATE_STRING " $Revision: 1.78 $";

#include "aee.h"

int eightbit;                 /* eight bit character flag         */

struct stat buf;

#ifndef NO_CATGETS
nl_catd catalog;
#endif /* NO_CATGETS */

extern int errno;

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 *fpste_line;      /* first line of select buffer            */
struct text *cpste_line;      /* current paste/select line        */
struct text *paste_buff;      /* first line of paste buffer       */
struct text *pste_tmp;        /* temporary paste pointer          */
struct text *tmp_line;        /* temporary line pointer           */
struct text *srch_line;       /* temporary pointer for search routine */

struct files *top_of_stack;

struct bufr *first_buff;      /* first buffer in list             */
struct bufr *curr_buff;       /* pointer to current buffer        */
struct bufr *t_buff;          /* temporary pointer for buffers    */

struct tab_stops *tabs;

struct del_buffs *undel_first;
struct del_buffs *undel_current;

WINDOW *com_win;        /* command window             */
WINDOW *help_win;       /* window for help facility         */
int windows;                  /* flag for windows or no windows   */
WINDOW *info_win;

int lines_moved;        /* number of lines moved in search  */
int d_wrd_len;                /* length of deleted word           */
int value;              /* temporary integer value          */
int tmp_pos;                  /* temporary position               */
int tmp_vert;                 /* temporary vertical position            */
int tmp_horz;                 /* temporary horizontal position    */
int repl_length;        /* length of string to replace            */
int pst_pos;                  /* position in cpste_line->line           */
int gold_count;               /* number of times to execute pressed key */
int fildes;             /* file descriptor                  */
int get_fd;             /* get file descriptor              */
int write_fd;                 /* write file descriptor            */
int num_of_bufs;        /* the number of buffers that exist */
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 line_wrap;                /* should line extend forever?            */
int right_margin;       /* right margin   (if observ_margins = TRUE) */
int left_margin;        /* left margin                      */
int info_type;
int info_win_height = INFO_WIN_HEIGHT_DEF;
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 bit_bucket;               /* file descriptor to /dev/null           */
int tab_spacing = 8;          /* spacing for tabs                 */

/*
 |    boolean flags
 */

char mark_text;               /* flag to indicate if MARK is active     */
char journ_on;                /* flag for journaling              */
char input_file;        /* indicate to read input file            */
char recv_file;               /* indicate reading a file          */
char edit;              /* continue executing while true    */
char gold;              /* 'gold' function key pressed            */
char recover;                 /* set true if recover operation to occur */
char case_sen;                /* case sensitive search flag       */
char change;                  /* indicate changes have been made to file*/
char go_on;             /* loop control for help function   */
char clr_cmd_line;            /* flag set to clear command line   */
char literal;           /* is search string to be interpreted literally? */
char forward;     /* if TRUE, search after cursor, else search before cursor */
char echo_flag;               /* allow/disallow echo in init file */
char status_line;       /* place status info in the bottom line   */
char overstrike;        /* overstrike / insert mode flag    */
char indent;                  /* auto-indent mode flag            */
char expand;                  /* expand tabs flag                 */
char shell_fork;
char out_pipe = FALSE;        /* flag that info is piped out            */
char in_pipe = FALSE;         /* flag that info is piped in       */
char observ_margins = FALSE;  /* should margins be observed       */
char right_justify = FALSE;   /* justify right margin when formatting */
char free_d_line = FALSE;     /* free d_line (already freed from del list) */
char free_d_word = FALSE;     /* free d_word (already freed from del list) */
char info_window = TRUE;      /* is info window displayed?        */
char auto_format = FALSE;     /* automatically format paragraph   */
char formatted = FALSE;       /* has paragraph been formatted?    */
char window_resize = FALSE;   /* flag to indicate a resize has occurred */
char change_dir_allowed = TRUE;     /* flag to indicate if chdir is allowed */
char restricted = FALSE;      /* flag to indicate restricted mode */
char com_win_initialized = FALSE;
char text_only = TRUE;        /* editor is to treat file being read as 
                           text only (not a binary file)    */
char ee_mode_menu = FALSE;    /* make main menu look more like ee's     */

long mask;              /* mask for sigblock                */
#ifdef XAE
int win_width;                /* width and height of edit session window */
int win_height;
extern char *xsrch_string;
extern char *xold_string;
extern char *xnew_string;
extern Window testwin;
#endif

char in_string[513];          /* input buffer string              */
char *pst_line;               /* start of paste line              */
char *pst_pnt;                /* current position within paste line     */
char *pste1;                  /* temporary pointers for cut/paste ops */
char *pste2;
char *pste3;
char *old_string;       /* old string to be replaced        */
char *u_old_string;           /* upper case verson of old_string  */
char *new_string;       /* new string to insert instead of old    */
char *srch_str;               /* pointer for search string        */
char *u_srch_str;       /* pointer to non-case sensitive search */
char *in_file_name;           /* name of input file and path            */
char *short_file_name;        /* name of input file only          */
char *journ;                  /* name of journal file             */
char *journal_dir = "";       /* name of journal directory        */
char *out_file;               /* name of output file if not input file*/
char *tmp_file;               /* temporary file name              */
char d_char;                  /* deleted character                */
char *d_word;                 /* deleted word                     */
char *d_line;                 /* deleted line                     */
char *term_type;        /* type of terminal being used            */
char *help_line;              /* input line for help facility           */
char *sline;                  /* temporary line pointer for help fac    */
char *subject;                /* subject user wants to learn about      */
char *start_of_string;        /* start of search string           */
char match_char;        /* character found by search for match    */
char in_buff_name[128];       /* input buffer name                */
char out_buff_name[128];      /* output buffer name               */
char *start_at_line;          /* move to this line at start of session*/
char *print_command = "lp";   /* string to hold command for printing file */
char nohighlight = FALSE;

char *ctr[32];                /* control key strings              */
char ctr_changed[32];         /* control key strings changed flags      */
char *g_ctr[32];        /* gold control key strings         */
char g_ctr_changed[32]; /* gold control key strings changed       */
char *f[64];                  /* function key strings             */
char f_changed[64];           /* function key strings             */
char *g_f[64];                /* gold function key strings        */
char g_f_changed[64];         /* gold function key strings        */
char *ctrl_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", "^[", "^\\", "^]", 
      "^^", "^_", "^?"
      };
char *keypads[5];       /* keypad keys from terminfo        */
char *g_keypads[5];           /* keypad keys from terminfo        */

int in;                       /* input character                  */

FILE *fp;               /* file pointer for input           */
FILE *outp;             /* pointer for output file          */
FILE *temp_fp;                /* temporary file pointer           */
FILE *get_fp;                 /* read file pointer                */
FILE *write_fp;               /* write file pointer               */

char info_data[MAX_HELP_LINES][MAX_HELP_COLS];

struct edit_keys assignment[] = {
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 }, 
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 },
{ "", "",  0, 0, 0, 0 }
};


/*
 |    allocate space here for the strings that will be in the menu
 */

struct menu_entries modes_menu[] = {
      {"", NULL, NULL, NULL, NULL, 0},    /* 0 title        */
      {"", NULL, NULL, NULL, NULL, -1},   /* 1              */
      {"", NULL, NULL, NULL, NULL, -1},   /* 2              */
      {"", NULL, NULL, NULL, NULL, -1},   /* 3              */
      {"", NULL, NULL, NULL, NULL, -1},   /* 4              */
      {"", NULL, NULL, NULL, NULL, -1},   /* 5              */
      {"", NULL, NULL, NULL, NULL, -1},   /* 6              */
      {"", NULL, NULL, NULL, NULL, -1},   /* 7              */
      {"", NULL, NULL, NULL, NULL, -1},   /* 8              */
      {"", NULL, NULL, NULL, NULL, -1},   /* 9              */
      {"", NULL, NULL, NULL, NULL, -1},   /* 10             */
      {"", NULL, NULL, NULL, NULL, -1},   /* 11             */
      {"", NULL, NULL, NULL, NULL, -1},   /* 12             */
      {"", NULL, NULL, NULL, NULL, -1},   /* 13             */
      {"", NULL, NULL, NULL, NULL, -1},   /* 14             */
      {"", NULL, NULL, NULL, NULL, -1},   /* 15 text/binary mode  */
      {"", NULL, NULL, NULL, NULL, -1},   /* 16 dos/ux text file  */
      {"", NULL, NULL, NULL, NULL, -1},   /* 17 save configuration */
      {NULL, NULL, NULL, NULL, NULL, -1}
      };

int modes_initialized = FALSE;

char *mode_strings[NUM_MODES_ITEMS];

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, 0}, 
      {"", NULL, NULL, NULL, NULL, -1}, 
      {"", NULL, NULL, NULL, NULL, -1}, 
      {NULL, NULL, NULL, NULL, NULL, -1}
      };

struct menu_entries leave_menu_2[] = {
      {"", NULL, NULL, NULL, NULL, 0}, 
      {"", NULL, NULL, NULL, NULL, -1}, 
      {"", NULL, NULL, NULL, NULL, -1}, 
      {NULL, NULL, NULL, NULL, NULL, -1}
      };

struct menu_entries file_menu[] = {
      {"", NULL, NULL, NULL, NULL, 0},
      {"", 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, recover_op, -1},
      {NULL, NULL, NULL, NULL, NULL, -1}
      };

struct menu_entries search_menu[] = {
      {"", NULL, NULL, NULL, NULL, 0}, 
      {"", NULL, NULL, search_prompt, NULL, TRUE},
      {"", NULL, NULL, NULL, search_op, -1},
      {"", NULL, NULL, repl_prompt, NULL, TRUE},
      {"", NULL, NULL, NULL, replace, -1},
      {NULL, NULL, NULL, NULL, NULL, -1}
      };

struct menu_entries spell_menu[] = {
      {"", NULL, NULL, NULL, NULL, 0}, 
      {"", 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, 0}, 
      {"", 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 edit_menu[] = {
      {"", NULL, NULL, NULL, NULL, 0}, 
      {"", NULL, NULL, slct, NULL, Mark}, 
      {"", NULL, NULL, NULL, copy, -1}, 
      {"", NULL, NULL, NULL, cut, -1}, 
      {"", NULL, NULL, NULL, paste, -1}, 
      {NULL, NULL, NULL, NULL, NULL, -1}
      };

char *main_menu_strings[10];
char *ee_mode_main_menu_strings[10];

struct menu_entries main_menu[] = {
      {"", NULL, NULL, NULL, NULL, 0}, 
      {"", NULL, NULL, NULL, leave_op, -1}, 
      {"", NULL, NULL, NULL, help, -1}, 
      {"", menu_op, edit_menu, NULL, NULL, -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}
      };

struct menu_entries del_buff_menu[] = {
      {"", NULL, NULL, NULL, NULL, MENU_WARN}, 
      {"", NULL, NULL, file_op, NULL, SAVE_FILE}, 
      {"", NULL, NULL, NULL, NULL, -1}, 
      {"", NULL, NULL, NULL, NULL, -1}, 
      {NULL, NULL, NULL, NULL, NULL, -1}
      };

struct menu_entries rae_err_menu[] = {
      {"", NULL, NULL, NULL, NULL, MENU_WARN}, 
      {"", NULL, NULL, NULL, NULL, -1}, 
      {NULL, NULL, NULL, NULL, NULL, -1}
      };


char *commands[71];
char *init_strings[41];

/*
 |    memory debugging macros
 */

#ifdef DEBUG
FILE *error_fp;
#endif /* DEBUG */

/*
 |    declaration for localizable strings
 */

char *ae_help_file, *SL_line_str, *SL_col_str, *SL_lit_str, *SL_nolit_str;
char *SL_fwd_str, *SL_rev_str, *SL_over_str, *SL_insrt_str, *SL_indent_str;
char *SL_noindnt_str, *SL_marg_str, *SL_nomarg_str, *SL_mark_str, *ascii_code_str;
char *left_err_msg, *right_err_msg, *help_err_msg, *prompt_for_more, *topic_prompt;
char *topic_err_msg, *continue_prompt, *printing_msg, *EXPAND_str, *NOEXPAND_str;
char *NOJUSTIFY_str, *JUSTIFY_str, *EXIT_str, *QUIT_str, *AUTOFORMAT_str;
char *NOAUTOFORMAT_str, *INFO_str, *NOINFO_str, *TABS_str, *UNTABS_str;
char *WRITE_str, *READ_str, *SAVE_str, *LITERAL_str, *NOLITERAL_str;
char *STATUS_str, *NOSTATUS_str, *MARGINS_str, *NOMARGINS_str, *INDENT_str;
char *NOINDENT_str, *OVERSTRIKE_str, *NOOVERSTRIKE_str, *LEFTMARGIN_str, *RIGHTMARGIN_str;
char *LINE_str, *FILE_str, *COPYRIGHT_str, *CHARACTER_str, *REDRAW_str;
char *RESEQUENCE_str, *AUTHOR_str, *VERSION_str, *CASE_str, *NOCASE_str;
char *EIGHT_str, *NOEIGHT_str, *WINDOWS_str, *NOWINDOWS_str, *DEFINE_str;
char *SHOW_str, *HELP_str, *PRINT_str, *BUFFER_str, *DELETE_str;
char *GOLD_str, *tab_msg, *file_write_prompt_str, *file_read_prompt_str, *left_mrg_err_msg;
char *right_mrg_err_msg, *left_mrg_setting, *right_mrg_setting, *line_num_str, *lines_from_top;
char *total_lines_str, *current_file_str, *char_str, *key_def_msg, *unkn_syntax_msg;
char *current_buff_msg, *unkn_cmd_msg, *usage_str, *read_only_msg, *no_rcvr_fil_msg;
char *cant_opn_rcvr_fil_msg, *fin_read_file_msg, *rcvr_op_comp_msg, *file_is_dir_msg, *path_not_a_dir_msg;
char *access_not_allowed_msg, *new_file_msg, *cant_open_msg, *bad_rcvr_msg, *reading_file_msg;
char *file_read_lines_msg, *other_buffs_exist_msg, *changes_made_prompt, *no_write_access_msg, *file_exists_prompt;
char *cant_creat_fil_msg, *writing_msg, *file_written_msg, *searching_msg, *fwd_srch_msg;
char *rev_srch_msg, *str_str, *not_fnd_str, *search_prompt_str, *mark_not_actv_str;
char *mark_active_str, *mark_alrdy_actv_str, *no_buff_named_str, *press_ret_to_cont_str, *fn_GOLD_str;
char *fn_DL_str, *fn_DC_str, *fn_CL_str, *fn_NP_str, *fn_PP_str;
char *fn_NB_str, *fn_PB_str, *fn_UDL_str, *fn_UDC_str, *fn_DW_str;
char *fn_UDW_str, *fn_UND_str, *fn_EOL_str, *fn_BOL_str, *fn_BOT_str;
char *fn_EOT_str, *fn_FORMAT_str, *fn_MARGINS_str, *fn_NOMARGINS_str, *fn_IL_str;
char *fn_PRP_str, *fn_RP_str, *fn_MC_str, *fn_PSRCH_str, *fn_SRCH_str;
char *fn_AL_str, *fn_AW_str, *fn_AC_str, *fn_PW_str, *fn_CUT_str;
char *fn_FWD_str, *fn_REV_str, *fn_MARK_str, *fn_UNMARK_str, *fn_APPEND_str;
char *fn_PREFIX_str, *fn_COPY_str, *fn_CMD_str, *fn_PST_str, *fn_RD_str;
char *fn_UP_str, *fn_DOWN_str, *fn_LEFT_str, *fn_RIGHT_str, *fn_BCK_str;
char *fn_CR_str, *fn_EXPAND_str, *fn_NOEXPAND_str, *fn_EXIT_str, *fn_QUIT_str;
char *fn_LITERAL_str, *fn_NOLITERAL_str, *fn_STATUS_str, *fn_NOSTATUS_str, *fn_INDENT_str;
char *fn_NOINDENT_str, *fn_OVERSTRIKE_str, *fn_NOOVERSTRIKE_str, *fn_CASE_str, *fn_NOCASE_str;
char *fn_WINDOWS_str, *fn_NOWINDOWS_str, *fn_HELP_str, *fn_MENU_str, *fwd_mode_str;
char *rev_mode_str, *ECHO_str, *cmd_prompt, *PRINTCOMMAND_str, *replace_action_prompt;
char *replace_prompt_str, *replace_r_char, *replace_skip_char, *replace_all_char, *quit_char;
char *yes_char, *no_char, *cant_find_match_str, *fmting_par_msg, *cancel_string;
char *menu_too_lrg_msg, *shell_cmd_prompt, *shell_echo_msg, *spell_in_prog_msg, *left_marg_prompt;
char *left_mrgn_err_msg, *right_mrgn_prompt, *right_mrgn_err_msg, *cant_redef_msg, *buff_msg;
char *cant_chng_while_mark_msg, *too_many_parms_msg, *buff_is_main_msg, *cant_del_while_mark, *main_buffer_name;
char *cant_del_buf_msg, *HIGHLIGHT_str, *NOHIGHLIGHT_str;
char *non_unique_cmd_msg;
char *ON, *OFF;
char *save_file_name_prompt, *file_not_saved_msg, *cant_reopen_journ;
char *write_err_msg, *jrnl_dir, *CD_str ;
char *no_dir_entered_msg,  *path_not_dir_msg, *path_not_permitted_msg;
char *path_chng_failed_msg, *no_chng_dir_msg, *SPACING_str, *SPACING_msg;
char *help_file_str;
char *pwd_cmd_str, *pwd_err_msg;
char *no_file_string, *no_chng_no_save, *changes_made_title;
char *save_then_delete, *dont_delete, *delete_anyway_msg;
char *edit_cmd_str, *edit_err_msg, *restricted_msg, *rae_no_file_msg;
char *more_above_str, *more_below_str, *recover_name_prompt;
char *no_file_name_string, *recover_menu_title, *other_recover_file_str;
char *info_win_height_prompt, *info_win_height_err, *info_win_height_cmd_str;
char *info_win_height_msg_str;
char *conf_not_saved_msg;     /* message if unable to save configuration */
char *conf_dump_err_msg;
char *conf_dump_success_msg;
char *info_help_msg;
char *unix_text_msg, *dos_text_msg;
char *text_cmd, *binary_cmd;
char *text_msg, *binary_msg, *dos_msg, *unix_msg;
char *DIFF_str;
char *ee_mode_str;

int 
main(argc, argv)        /* beginning of main program        */
int argc;
char *argv[];
{
#ifdef DEBUG
      error_fp = fopen("/tmp/ae.mem_debug", "w");
#endif /* DEBUG */

#ifdef DIAG_DBG
            if (!strcmp(argv[argc-1], "-DEBUG"))
            {
/*
 |    The following code will start an xterm which will in turn execute 
 |    a debugger and "adopt" the process, so it can be debugged.
 |
 |    To compile to allow debug, use the command:
 |
 |          CFLAGS='-DDIAG_DBG -g' make
 |
 */

                  int child_id;
                  char command_line[256];

                  child_id = getpid();
                  if (!fork())
                  {
                        sprintf(command_line, 
                              "xterm -geom =80x40 -fg wheat -bg DarkSlateGrey -n %s -e gdb %s %d", 
                              "hello",  argv[0], child_id);
                        printf("command_line=%s\n", command_line);
                        execl("/bin/sh", "sh", "-c", command_line, NULL);
                        fprintf(stderr, "could not exec new window\n");
                        exit(1);
                  }

/*
 |    When in debugger, set child_id to zero (p child_id=0) to continue 
 |    executing the software.
 */

                  while (child_id != 0)
                        ;
                  argc--;
            }
#endif

      eightbit = FALSE;
#ifndef DIAG_DBG
      mask = 077777777 & (~020000) & (~02);
      for (value = 1; value < 24; value++)
      {
            if ((value != SIGCHLD) && (value != SIGALRM) && (value != SIGSEGV)
#ifdef XAE
               && (value != SIGTSTP)
#endif /* XAE */

            )
                  signal(value, SIG_IGN);
            else
                  signal(value, SIG_DFL);
      }
#endif      /* ifndef DIAG    */
      signal(SIGINT, abort_edit);
#ifdef XAE
      win_width = 0;
      win_height = 0;
#endif



      start_at_line = NULL;
      d_word = NULL;
      d_wrd_len = 0;
      d_line = xalloc(1);
      *d_line = (char) NULL;
      tabs = (struct tab_stops *) xalloc(sizeof( struct tab_stops));
      tabs->next_stop = NULL;
      tabs->column = 0;
      dlt_line = txtalloc();
      dlt_line->line = d_line;
      dlt_line->line_length = 1;
      paste_buff = NULL;
      status_line = FALSE;
      srch_str = u_srch_str = NULL;
      u_old_string = new_string = old_string = NULL;

      /*
       |    initialize literal strings
       */

      strings_init();

      first_buff = curr_buff = buf_alloc();
      first_buff->name = main_buffer_name;
      first_buff->first_line = txtalloc();
      curr_buff->curr_line = curr_buff->first_line;
      first_buff->next_buff = NULL;
      first_buff->footer = NULL;
      first_buff->main_buffer = TRUE;
      first_buff->edit_buffer = TRUE;
      curr_buff->curr_line->line = curr_buff->pointer = xalloc(10);
      curr_buff->curr_line->line_length = 1;
      curr_buff->curr_line->max_length = 10;
      curr_buff->curr_line->prev_line = NULL;
      curr_buff->curr_line->next_line = NULL;
      curr_buff->curr_line->line_number = 1;
      curr_buff->curr_line->vert_len = 1;
      curr_buff->num_of_lines = 1;
      curr_buff->absolute_lin = 1;
      num_of_bufs = 1;
      curr_buff->position = 1;
      curr_buff->abs_pos = curr_buff->scr_pos = 0;
      curr_buff->scr_vert = 0;
      curr_buff->scr_horz = 0;
      bit_bucket = open("/dev/null", O_WRONLY);
      forward = windows = edit = TRUE;
      observ_margins = literal = FALSE;
      expand = indent = overstrike = FALSE;
      clr_cmd_line = change = mark_text = gold = case_sen = FALSE;
      in_pipe = out_pipe = FALSE;
      shell_fork = TRUE;
      left_margin = 0;
      right_margin = 0;
      gold_count = 0;
      info_type = CONTROL_KEYS;
      top_of_stack = NULL;
      echo_flag = TRUE;
      journ_on = TRUE;
      input_file = FALSE;
      recv_file = FALSE;
      recover = FALSE;
      undel_init();
      init_keys();
      ae_init();
      get_options(argc, argv);
      set_up_term();          /* initialize terminal        */
      get_key_assgn();
      com_win = newwin(1, COLS, LINES-1, 0);
      com_win_initialized = TRUE;
      curr_buff->last_col = COLS - 1;
      curr_buff->last_line = LINES - 2;
      first_buff->lines = LINES - 1;
      curr_buff->window_top = 0;
      if (info_window)
      {
            info_win = newwin(info_win_height, COLS, 0, 0);
            paint_info_win();
            curr_buff->window_top = info_win_height;
            first_buff->win = newwin(LINES-info_win_height-1, COLS, info_win_height, 0);
            first_buff->lines = LINES - info_win_height - 1;
            curr_buff->last_line = first_buff->lines - 1;
      }
      else
            first_buff->win = newwin(LINES-1, COLS, 0, 0);
      keypad(curr_buff->win, TRUE);
      nodelay(curr_buff->win, FALSE);
      idlok(curr_buff->win, TRUE);

      /*
       |    If restricted mode, there must have been a file specified on 
       |    the invoking command line.
       */
      if ((restrict_mode()) && (top_of_stack == NULL))
      {
            wmove(com_win, 0, 0);
            werase(com_win);
            wrefresh(com_win);
            menu_op(rae_err_menu);
            abort_edit(0);
      }


      if (top_of_stack != NULL)
            tmp_file = top_of_stack->name;
      else
            tmp_file = "";
      input_file = TRUE;
      recv_file = TRUE;

      if (top_of_stack != NULL)
            top_of_stack = top_of_stack->next_name;

      value = check_fp();

      input_file = FALSE;
      recv_file = FALSE;

      if (right_margin == 0)
            right_margin = COLS - 1;

      wmove(curr_buff->win, curr_buff->last_line, 0);
      wstandout(curr_buff->win);
      wprintw(curr_buff->win, "aee, %s", copyright_notice);
      wstandend(curr_buff->win);
      wmove(curr_buff->win, curr_buff->scr_vert, curr_buff->scr_horz);
      wrefresh(curr_buff->win);
      midscreen(curr_buff->scr_vert, curr_buff->position);

      while (edit) 
      {
            get_input(curr_buff->win);
            if (clr_cmd_line)
            {
                  clr_cmd_line = FALSE;
                  werase(com_win);
                  wrefresh(com_win);
            }
            keyboard();
            status_display();
            wmove(curr_buff->win, curr_buff->scr_vert, curr_buff->scr_horz);
            wrefresh(curr_buff->win);
      }
      exit(0);
}

void 
get_input(win_ptr)
WINDOW *win_ptr;
{
      int value;
      static int counter = 0;
      pid_t parent_pid;

      resize_check();

#ifdef XAE
      event_manage();
#endif /* XAE */

      in = wgetch(win_ptr);
      value = alarm(0);
      signal(SIGALRM, dummy);

      if (in == EOF)          /* somehow lost contact with input  */
            abort_edit(0);

#ifndef XAE
      /*
       |    The above check used to work to detect if the parent 
       |    process died, but now it seems we need a more 
       |    sophisticated check.
       |
       |    Note that this check is only required for the terminal 
       |    version, and may be undesireable for xae, so is ifdef'd 
       |    accordingly.
       */
      if (counter > 50)
      {
            parent_pid = getppid();
            if (parent_pid == 1)
                  abort_edit(0);
            else
                  counter = 0;
      }
      else
            counter++;
#endif /* !XAE */
}

void 
status_display()  /* display status line              */
{
      if ((status_line) && (!clr_cmd_line))
      {
            werase(com_win);
            wmove(com_win, 0, 0);

            if (curr_buff->edit_buffer)
            {
                  if (curr_buff->file_name != NULL)
                        wprintw(com_win, "%s  ", curr_buff->file_name);
                  else
                        wprintw(com_win, "[%s]  ", no_file_string);
            }
            else
            {
                  if (first_buff->file_name != NULL)
                        wprintw(com_win, "%s  ",first_buff->file_name);
                  else
                        wprintw(com_win, "[%s]  ", no_file_string);
            }

            wmove(com_win, 0, 16);
            wclrtoeol(com_win);
            wmove(com_win, 0, 18);
            wprintw(com_win, SL_line_str, curr_buff->curr_line->line_number);
            wmove(com_win, 0, 30);
            wprintw(com_win, SL_col_str, curr_buff->scr_pos);
            wmove(com_win, 0, 40);
            if (literal)
                  wprintw(com_win, SL_lit_str);
            else
                  wprintw(com_win, SL_nolit_str);
            if (forward)
                  wprintw(com_win, SL_fwd_str);
            else
                  wprintw(com_win, SL_rev_str);
            if (overstrike)
                  wprintw(com_win, SL_over_str);
            else
                  wprintw(com_win, SL_insrt_str);
            if (indent)
                  wprintw(com_win, SL_indent_str);
            else
                  wprintw(com_win, SL_noindnt_str);
            if (observ_margins)
                  wprintw(com_win, SL_marg_str);
            else
                  wprintw(com_win, SL_nomarg_str);
            if (mark_text)
            {
                  wstandout(com_win);
                  wprintw(com_win, SL_mark_str);
                  wstandend(com_win);
            }
            else if (text_only)
            {
                  wprintw(com_win, "%s", 
                    curr_buff->dos_file ? dos_text_msg : unix_text_msg);
            }
            wrefresh(com_win);
      }
}

char *
#ifndef DEBUG
xalloc(size)      /* allocate memory, report if errors      */
int size;   /* size of memory to allocate       */
#else
dxalloc(size, line_num)
int size;
int line_num;
#endif /* DEBUG */
{
      int counter;
      char *memory;

#ifdef DEBUG
      fprintf(error_fp, "m s=%d, l#=%d\n", size, line_num);
      fflush(error_fp);
#endif /*   DEBUG */

      if (size == 0)
            size++;
      if ((memory = malloc(size)) == NULL)
      {
            counter = 0;
            werase(com_win);
            wmove(com_win, 0,0);
            wstandout(com_win);
            wprintw(com_win, "memory allocation errors, please wait");
            wstandend(com_win);
            wrefresh(com_win);
            clr_cmd_line = TRUE;
            while (((memory = malloc(size)) == NULL) && (counter < 10000))
                  counter++;
            if (memory == NULL)
                  abort_edit(0);
            werase(com_win);
      }
      return(memory);
}

char *
#ifndef DEBUG
resiz_line(factor, rline, rpos)     /* resize the line to length + factor*/
int factor;       /* resize factor                    */
struct text *rline;     /* pointer to line structure              */
int rpos;         /* position in line                       */
#else
dresiz_line(factor, rline, rpos, line_num) 
int factor;       /* resize factor                    */
struct text *rline;     /* pointer to line structure              */
int rpos;         /* position in line                       */
int line_num;
#endif
{
      char *rpoint;
      int resiz_var;
 
#ifdef DEBUG
      fprintf(error_fp, "r s=%d, l#=%d\n", factor, line_num);
      fflush(error_fp);
#endif /*   DEBUG */

      rline->max_length += factor;
      while ((rpoint = realloc(rline->line, rline->max_length )) == NULL)
            ;
      rline->line = rpoint;
      for (resiz_var = 1 ; (resiz_var < rpos) ; resiz_var++)
            rpoint++;
      return(rpoint);
}

void 
dummy(foo)
int foo;
{/*this is a dummy function to eliminate any unresolved signals         */
}

void 
insert(character)       /* insert character into line       */
int character;                /* new character              */
{
      int counter;
      char *temp;       /* temporary pointer                */
      char *temp2;            /* temporary pointer                */
      int temp_overstrike;

      if ((observ_margins) && (curr_buff->scr_pos < left_margin))
      {
            temp_overstrike = overstrike;
            overstrike = FALSE;
            counter = left_margin;
            left_margin = 0;
            while (curr_buff->scr_pos < counter)
                  insert(' ');
            left_margin = counter;
            overstrike = temp_overstrike;
      }
      change = TRUE;
      curr_buff->curr_line->changed = TRUE;
      curr_buff->changed = TRUE;
      if ((!overstrike) || (curr_buff->position == curr_buff->curr_line->line_length))
      {
            if ((curr_buff->curr_line->max_length - curr_buff->curr_line->line_length) < 5)
                  curr_buff->pointer = resiz_line(10, curr_buff->curr_line, curr_buff->position);
            curr_buff->curr_line->line_length++;
            temp = curr_buff->pointer;
            counter = curr_buff->position;
            while (counter < curr_buff->curr_line->line_length)   /* find end of line */
            {
                  counter++;
                  temp++;
            }
            temp++;                 /* increase length of line by one   */
            while (curr_buff->pointer < temp)
            {
                  temp2=temp - 1;
                  *temp= *temp2;    /* shift characters over by one           */
                  temp--;
            }
      }
      *curr_buff->pointer = character;    /* insert new character             */
      if (curr_buff->position != (curr_buff->curr_line->line_length - 1))
            counter = (scanline(curr_buff->curr_line, curr_buff->curr_line->line_length) / COLS) + 1;
      else
            counter = ((curr_buff->scr_pos + len_char(*curr_buff->pointer, curr_buff->scr_pos)) / COLS) + 1;
      if (counter > curr_buff->curr_line->vert_len)
      {
            curr_buff->curr_line->vert_len = counter;
            if (curr_buff->scr_vert < curr_buff->last_line)
            {
                  wmove(curr_buff->win, (curr_buff->scr_vert+1), 0);
                  winsertln(curr_buff->win);
            }
      }
      wmove(curr_buff->win, curr_buff->scr_vert, curr_buff->scr_horz);
      wclrtoeol(curr_buff->win);
      if ((mark_text) && (((pst_pos == cpste_line->line_length) && (cpste_line->next_line == NULL)) || (overstrike)))
            right(TRUE);
      else
      {
            counter = curr_buff->scr_horz + len_char(character, curr_buff->scr_pos);
            if (counter > curr_buff->last_col)
            {
                  counter = curr_buff->scr_vert + 1;
                  if (counter > curr_buff->last_line)
                  {
                        wmove(curr_buff->win, 0, 0);
                        wdeleteln(curr_buff->win);
                        wmove(curr_buff->win, curr_buff->scr_vert-1, curr_buff->scr_horz);
                  }
            }
            if ((character < 32) || (character > 126))
                  curr_buff->scr_horz += out_char(curr_buff->win, character, curr_buff->scr_pos, curr_buff->scr_vert, 0);
            else
            {
                  waddch(curr_buff->win, character);
                  curr_buff->scr_horz++;
            }
            curr_buff->abs_pos = curr_buff->scr_pos += len_char(*curr_buff->pointer, curr_buff->scr_pos);
            curr_buff->pointer++;
            curr_buff->position++;
            if (curr_buff->scr_horz > curr_buff->last_col)
            {
                  curr_buff->scr_horz = curr_buff->scr_pos % COLS;
                  if (curr_buff->scr_vert < curr_buff->last_line)
                        curr_buff->scr_vert++;
            }
      }
      draw_line(curr_buff->scr_vert, curr_buff->scr_pos, curr_buff->pointer, curr_buff->position, curr_buff->curr_line);
      if ((observ_margins) && (right_margin < curr_buff->scr_pos))
      {
            counter = curr_buff->position;
            while (curr_buff->scr_pos > right_margin)
                  prev_word();
            if (curr_buff->scr_pos == 0)
            {
                  while (curr_buff->position < counter)
                        right(TRUE);
            }
            else
            {
                  counter -= curr_buff->position;
                  insert_line(TRUE);
                  for (value = 0; value < counter; value++)
                        right(TRUE);
            }
      }

      if ((auto_format) && ((character == '\t') || ((character == ' ') && (!formatted))))
            Auto_Format();
      else if ((character != ' ') && (character != '\t'))
            formatted = FALSE;
}

int 
scanline(m_line, pos)   /* find the proper horizontal position for the current position in the line */
struct text *m_line;
int pos;
{
      int temp;
      int count;
      char *ptr;

      ptr = m_line->line;
      count = 1;
      temp = 0;
      while (count < pos)
      {
            if ((*ptr >= 0) && (*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++;
            count++;
      }
      return(temp);
}

void 
tab_insert()      /* insert a tab or spaces according to value of 'expand' */
{
      int temp;
      int counter;

      if (expand)
      {
            counter = tabshift(curr_buff->scr_pos);
            for (temp = 0; temp < counter; temp++)
                  insert(' ');
            if (auto_format)
                  Auto_Format();
      }
      else
            insert('\t');
}

void 
unset_tab(string) /* remove tab setting               */
char *string;
{
      char *pointer;
      int column;
      int loop_on;
      struct tab_stops *temp_stack_point;
      struct tab_stops *stack_point;

      pointer = string;
      while (*pointer != (char) NULL)
      {
            while (((*pointer < '0') || (*pointer > '9')) && (*pointer != (char) NULL))
                  pointer++;
            column = atoi(pointer);
            temp_stack_point = tabs;
            if (column > 0)
            {
                  loop_on = TRUE;
                  while ((temp_stack_point->next_stop != NULL) && (loop_on))
                  {
                        if (temp_stack_point->next_stop->column != column)
                              temp_stack_point = temp_stack_point->next_stop;
                        else
                              loop_on = FALSE;
                  }
                  if (temp_stack_point->next_stop != NULL)
                  {
                        stack_point = temp_stack_point->next_stop;
                        temp_stack_point->next_stop = stack_point->next_stop;
                        free(stack_point);
                  }
            }
            while (((*pointer >= '0') && (*pointer <= '9')) && (*pointer != (char) NULL))
                  pointer++;
      }
}

void 
tab_set(string)   /* get tab settings from the string (columns)   */
char *string;
{
      char *pointer;
      int column;
      int loop_on;
      struct tab_stops *temp_stack_point;
      struct tab_stops *stack_point;

      pointer = string;
      while (*pointer != (char) NULL)
      {
            while (((*pointer < '0') || (*pointer > '9')) && (*pointer != (char) NULL))
                  pointer++;
            column = atoi(pointer);
            temp_stack_point = tabs;
            if (column > 0)
            {
                  loop_on = TRUE;
                  while ((temp_stack_point->next_stop != NULL) && (loop_on))
                  {
                        if (temp_stack_point->next_stop->column <= column)
                              temp_stack_point = temp_stack_point->next_stop;
                        else
                              loop_on = FALSE;
                  }
                  if ((column > temp_stack_point->column) && (column != temp_stack_point->column))
                  {
                        stack_point = (struct tab_stops *) xalloc(sizeof( struct tab_stops));
                        stack_point->column = column;
                        stack_point->next_stop = temp_stack_point->next_stop;
                        temp_stack_point->next_stop = stack_point;
                  }
            }
            while (((*pointer >= '0') && (*pointer <= '9')) && (*pointer != (char) NULL))
                  pointer++;
      }
}

int 
tabshift(temp_int)      /* give the number of spaces to shift to the next 
                     tab stop                         */
int temp_int;     /* current column */
{
      int leftover;
      struct tab_stops *stack_point;

      stack_point = tabs;
      while ((stack_point != NULL) && (stack_point->column <= temp_int))
            stack_point = stack_point->next_stop;
      if (stack_point != NULL)
      {
            leftover = (stack_point->column - temp_int);
            return(leftover);
      }
      leftover = ((temp_int + 1) % tab_spacing);
      if (leftover == 0)
            return (1);
      else
            return ((tab_spacing + 1) - leftover);
}

int 
out_char(window, character, abscolumn, row, offset)   /* output non-printing character */
WINDOW *window;
char character;
int abscolumn;
int row;
int offset;
{
      int i1, i2, iter;
      int column;
      int space;
      char *string;
      char *tmp;

      column = abscolumn % COLS;
      space = FALSE;
      if ((character >= 0) && (character < 32))
      {
            if (character == '\t')
            {
                  i1 = tabshift(abscolumn);
                  for (i2=1; (i2 <= i1)&&((((i2+column)<=curr_buff->last_col)&&(row==curr_buff->last_line))||(row<curr_buff->last_line)); i2++)
                        waddch(window, ' ');
                  return(i1);
            }
            else
                  string = ctrl_table[(int)character];
      }
      else if ((character < 0) || (character >= 127))
      {
            if (character == 127)
                  string = "^?";
            else if (!eightbit)
            {
                  space = TRUE;
                  tmp = string = xalloc(6);
                  *tmp = '<';
                  tmp++;
                  if ((i1=character) < 0)
                        i1 = 256 + character;
                  i2 = i1 / 100;
                  i1 -=i2 * 100;
                  *tmp = i2 + '0';
                  tmp++;
                  i2 = i1 / 10;
                  i1 -= i2 * 10;
                  *tmp = i2 + '0';
                  tmp++;
                  i2 = i1;
                  *tmp = i2 + '0';
                  tmp++;
                  *tmp = '>';
                  tmp++;
                  *tmp = (char) NULL;
            }
            else
            {
                  waddch(window, (unsigned char) character);
                  return(1);
            }
      }
      tmp = string;
      for (iter=0; (iter < offset) && (tmp != NULL) && (character != '\t'); iter++)
            tmp++;
      for (iter = column;
           (((iter <= curr_buff->last_col) && (row == curr_buff->last_line)) || 
           (row < curr_buff->last_line)) && (*tmp != (char) NULL); iter++, tmp++)
            waddch(window, *tmp);
      iter -= column;
      if (space)
            free(string);
      return(iter);
}

void 
draw_line(vertical, horiz, ptr, t_pos, dr_l)    /* redraw line from current position */
int vertical;
int horiz;
char *ptr;
int t_pos;
struct text *dr_l;
{
      int d;
      char *temp;
      int abs_column;
      int column;
      int row;
      int tp_pos;
      int posit;
      int highlight;
      int offset;

      highlight = FALSE;
      abs_column = horiz;
      column = abs_column % COLS;
      row = vertical;
      temp = ptr;
      d = 0;
      posit = t_pos;
      if (row < 0)
      {
            while (row < 0)
            {
                  abs_column += d =  len_char(*temp, abs_column);
                  column += d;
                  if (column > curr_buff->last_col)
                  {
                        row++;
                        if ((d > 1) && (row == 0))
                        {
                              d = d - (column - COLS);
                              abs_column -= column - COLS;
                        }
                        else
                        {
                              posit++;
                              temp++;
                              d = 0;
                        }
                        column %= COLS;
                  }
                  else
                  {
                        posit++;
                        temp++;
                  }
            }
            column = 0;
      }
      wmove(curr_buff->win, row, column);
      wclrtoeol(curr_buff->win);
      if ((mark_text) && (pst_pos == 1) && (curr_buff->pointer == ptr) && 
                  (cpste_line->line_length > 1))
      {
            highlight = TRUE;
            tp_pos = pst_pos;
      }
      else if (mark_text)
            wstandend(curr_buff->win);
      while ((posit < dr_l->line_length) && (((column <= curr_buff->last_col) && 
                  (row == curr_buff->last_line)) || (row < curr_buff->last_line)))
      {
            if ((mark_text) && (pst_pos == 1) && (curr_buff->pointer == ptr) && (highlight))
            {
                  if (tp_pos < cpste_line->line_length)
                        wstandout(curr_buff->win);
                  else
                        wstandend(curr_buff->win);
                  tp_pos++;
            }
            if ((*temp < 32) || (*temp > 126))
            {
                  offset = out_char(curr_buff->win, *temp, abs_column, row, d);
                  column += offset;
                  abs_column += offset;
                  d = 0;
            }
            else
            {
                  abs_column++;
                  column++;
                  waddch(curr_buff->win, *temp);
            }
            if (column > curr_buff->last_col)
            {
                  column = column % COLS;
                  row++;
            }
            posit++;
            temp++;
      }
      if (((column < curr_buff->last_col) && (row == curr_buff->last_line)) || (row < curr_buff->last_line))
            wclrtoeol(curr_buff->win);
      wstandend(curr_buff->win);
      wmove(curr_buff->win, vertical, horiz);
}

void 
insert_line(disp) /* insert new line into file and if disp=TRUE, 
                  reorganize screen accordingly */
int disp;
{
      int temp_pos;
      int temp_pos2;
      int i;
      char *temp;
      char *extra;
      struct text *temp_nod;  /* temporary pointer to new line    */
      int temp_overstrike;

      i = curr_buff->curr_line->vert_len;
      wmove(curr_buff->win, curr_buff->scr_vert, curr_buff->scr_horz);
      wclrtoeol(curr_buff->win);
      change = TRUE;
      temp_nod= txtalloc();
      temp_nod->line = extra = xalloc(6 + curr_buff->curr_line->line_length - curr_buff->position);
      temp_nod->line_length = 1 + curr_buff->curr_line->line_length - curr_buff->position;
      temp_nod->vert_len = 1;
      temp_nod->max_length = temp_nod->line_length + 5;
      if (curr_buff->position == 1)
            temp_nod->line_number = curr_buff->curr_line->line_number;
      else
            temp_nod->line_number = curr_buff->curr_line->line_number + 1;
      temp_nod->next_line = curr_buff->curr_line->next_line;
      if (temp_nod->next_line != NULL)
            temp_nod->next_line->prev_line = temp_nod;
      temp_nod->prev_line = curr_buff->curr_line;
      curr_buff->curr_line->next_line = temp_nod;
      temp_pos2 = curr_buff->position;
      temp = curr_buff->pointer;
      if (temp_pos2 != curr_buff->curr_line->line_length)
      {
            temp_pos = 1;
            while (temp_pos2 < curr_buff->curr_line->line_length)
            {
                  temp_pos++;
                  temp_pos2++;
                  *extra= *temp;
                  extra++;
                  temp++;
            }
            temp = curr_buff->pointer;
            *temp = (char) NULL;
            temp = resiz_line((1 - temp_nod->line_length), curr_buff->curr_line, curr_buff->position);
            curr_buff->curr_line->line_length = curr_buff->position;
            curr_buff->curr_line->vert_len = (scanline(curr_buff->curr_line, curr_buff->curr_line->line_length) / COLS) + 1;
            curr_buff->curr_line->changed = TRUE;
      }
      curr_buff->curr_line->line_length = curr_buff->position;
      curr_buff->curr_line = temp_nod;
      curr_buff->curr_line->vert_len = (scanline(curr_buff->curr_line, curr_buff->curr_line->line_length) / COLS) + 1;
      *extra = (char) NULL;
      curr_buff->position = 1;
      curr_buff->pointer = curr_buff->curr_line->line;
      curr_buff->num_of_lines++;
      curr_buff->absolute_lin++;
      curr_buff->curr_line->changed = TRUE;
      curr_buff->changed = TRUE;

      if (curr_buff->journalling)
      {
            write_journal(curr_buff, curr_buff->curr_line);
            if (curr_buff->curr_line->prev_line->changed)
                  write_journal(curr_buff, curr_buff->curr_line->prev_line);
      }

      if (disp)
      {
            i = (curr_buff->curr_line->vert_len + curr_buff->curr_line->prev_line->vert_len) - i;
            if (curr_buff->scr_vert < curr_buff->last_line)
            {
                  curr_buff->scr_vert++;
                  wclrtoeol(curr_buff->win);
                  wmove(curr_buff->win, curr_buff->scr_vert, 0);
                  if (i > 0)
                        winsertln(curr_buff->win);
            }
            else 
            {
                  wmove(curr_buff->win, 0, 0);
                  wdeleteln(curr_buff->win);
                  wmove(curr_buff->win, curr_buff->last_line, 0);
                  wclrtobot(curr_buff->win);
            }
            curr_buff->abs_pos = curr_buff->scr_pos = curr_buff->scr_horz = 0;
            draw_line(curr_buff->scr_vert, curr_buff->scr_pos, curr_buff->pointer, curr_buff->position, curr_buff->curr_line);
      }
      curr_buff->abs_pos = curr_buff->scr_pos = curr_buff->scr_horz = 0;
      if ((mark_text) && (cpste_line->line_length == pst_pos))
      {
            i = mark_text;
            mark_text = FALSE;
            left(TRUE);
            mark_text = i;
            right(TRUE);
      }
      if (indent)
      {
            int temp_lm = left_margin;

            left_margin = 0;
            if (curr_buff->curr_line->prev_line != NULL)
            {
                  temp = curr_buff->curr_line->prev_line->line;
                  i = overstrike;
                  overstrike = FALSE;
                  while ((*temp == ' ') || (*temp == '\t'))
                  {
                        insert(*temp);
                        temp++;
                  }
                  overstrike = i;
            }
            left_margin = temp_lm;
      }
      if ((observ_margins) && (left_margin != 0) && (curr_buff->scr_pos < left_margin))
      {
            temp_overstrike = overstrike;
            overstrike = FALSE;
            i = left_margin;
            left_margin = 0;
            while (curr_buff->scr_pos < i)
                  insert(' ');
            left_margin = i;
            overstrike = temp_overstrike;
      }
}

struct text *txtalloc()       /* allocate space for line structure      */
{
      struct text *txt_tmp;

      txt_tmp = (struct text *) xalloc(sizeof( struct text));
      txt_tmp->changed = FALSE;
      txt_tmp->file_info.info_location = NO_FURTHER_LINES;
      txt_tmp->file_info.prev_info = NO_FURTHER_LINES;
      txt_tmp->file_info.next_info = NO_FURTHER_LINES;
      return(txt_tmp);
}

struct files *name_alloc()    /* allocate space for file name list node */
{
      struct files *temp_name;

      temp_name = (struct files *) xalloc(sizeof( struct files));
      return(temp_name);
}

struct bufr *buf_alloc()      /* allocate space for buffers       */
{
      struct bufr *temp_buf;

      temp_buf = (struct bufr *) xalloc(sizeof(struct bufr));
      temp_buf->journal_file = NULL;
      temp_buf->file_name = NULL;
      temp_buf->full_name = "";
      temp_buf->orig_dir = NULL;
      temp_buf->journalling = FALSE;
      temp_buf->changed = FALSE;
      temp_buf->main_buffer = FALSE;
      temp_buf->edit_buffer = FALSE;
      temp_buf->dos_file = FALSE;
      return (temp_buf);
}

char *next_word(string)       /* move to next word in string            */
char *string;
{
      while ((*string != (char) NULL) && ((*string != 32) && (*string != 9)))
            string++;
      while ((*string != (char) NULL) && ((*string == 32) || (*string == 9)))
            string++;
      return(string);
}

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 = xalloc(512);
      wmove(com_win,0,0);
      wclrtoeol(com_win);
      waddstr(com_win, prompt);
      wrefresh(com_win);
      nam_str = tmp_string;
      clr_cmd_line = TRUE;
      g_horz = g_position = scan(prompt, strlen(prompt), 0);
      g_pos = 0;
      do
      {
            esc_flag = FALSE;
            get_input(com_win);
            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) < (curr_buff->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;
                        get_input(com_win);
                  }
                  *nam_str = in;
                  g_pos++;
                  if (((in < 32) || (in > 126)) && (g_horz < (curr_buff->last_col - 1)))
                        g_horz += out_char(com_win, in, g_horz, curr_buff->last_line, 0);
                  else
                  {
                        g_horz++;
                        if (g_horz < (curr_buff->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 = xalloc(strlen(nam_str) + 1);
      copy_str(nam_str, string);
      free(tmp_string);
      wrefresh(com_win);
      return(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 
ascii()           /* get ascii code from user and insert into file      */
{
      int i;
      char *string, *t;

      i = 0;
      t = string = get_string(ascii_code_str, TRUE);
      if (*t != (char) NULL)
      {
            while ((*string >= '0') && (*string <= '9'))
            {
                  i= i * 10 + (*string - '0');
                  string++;
            }
            in = i;
            wmove(curr_buff->win, curr_buff->scr_vert, curr_buff->scr_horz);
            insert(in);
      }
      free(t);
}

void 
print_buffer()
{
      char buffer[256];

      sprintf(buffer, ">!%s", print_command);
      wmove(com_win, 0, 0);
      wclrtoeol(com_win);
      wprintw(com_win, printing_msg, curr_buff->name, print_command);
      wrefresh(com_win);
      command(buffer);
}

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)      /* goto first line with the given number  */
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_buff->curr_line;
      while ((t_line->line_number > number) && (t_line->prev_line != NULL))
      {
            i++;
            t_line = t_line->prev_line;
            direction = "u";
      }
      if (i == 0)
      {
            while ((t_line->line_number < number) && (t_line->next_line != NULL))
            {
                  i++;
                  direction = "d";
                  t_line = t_line->next_line;
            }
      }
      if (i != 0)
            move_rel(direction, i);
      wmove(com_win,0,0);
      wclrtoeol(com_win);
      wprintw(com_win, line_num_str, curr_buff->curr_line->line_number);
      wrefresh(com_win);
      clr_cmd_line = TRUE;
      wmove(curr_buff->win, curr_buff->scr_vert, curr_buff->scr_horz);
}

void 
make_win()        /* allow windows        */
{
      if (((!windows) && (!mark_text)) && (num_of_bufs <= ((LINES - 1)/2)))
      {
            windows = TRUE;
            if (num_of_bufs > 1)
            {
                  werase(first_buff->win);
                  wrefresh(first_buff->win);
                  delwin(first_buff->win);
                  t_buff = first_buff;
                  while (t_buff != NULL)
                  {
                        t_buff->win = NULL;
                        t_buff = t_buff->next_buff;
                  }
                  redo_win();
                  new_screen();
                  curr_buff->win = curr_buff->win;
            }
      }
}

void 
no_windows()            /* disallow windows           */
{
      int temp;

      if ((windows) && (!mark_text))
      {
            windows = FALSE;
            if (num_of_bufs > 1)
            {
                  t_buff = first_buff;
                  werase(t_buff->win);
                  wrefresh(t_buff->win);
                  delwin(t_buff->win);
                  werase(t_buff->footer);
                  wrefresh(t_buff->footer);
                  delwin(t_buff->footer);
                  t_buff->footer = NULL;
                  if (info_window)
                  {
                        temp = info_win_height;
                        if (info_win == NULL)
                        {
                              info_win = newwin(info_win_height, COLS, 0, 0);
                              paint_info_win();
                        }
                  }
                  else
                        temp = 0;
                  t_buff->win = newwin(LINES - temp - 1, COLS, temp, 0);
                  t_buff->window_top = temp;
                  keypad(t_buff->win, TRUE);
                  idlok(t_buff->win, TRUE);
                  t_buff->lines = LINES - temp - 1;
                  t_buff->last_col = COLS - 1;
                  t_buff->last_line = t_buff->lines - 1;
                  t_buff = t_buff->next_buff;
                  while (t_buff != NULL)
                  {
                        werase(t_buff->win);
                        wrefresh(t_buff->win);
                        werase(t_buff->footer);
                        wrefresh(t_buff->footer);
                        delwin(t_buff->footer);
                        delwin(t_buff->win);
                        t_buff->footer = NULL;
                        t_buff->win = first_buff->win;
                        t_buff->window_top = first_buff->window_top;
                        t_buff->lines = first_buff->lines;
                        t_buff->last_line = first_buff->last_line;
                        t_buff->last_col = first_buff->last_col;
                        t_buff = t_buff->next_buff;
                  }
                  new_screen();
            }
      }
}

void 
midscreen(line, count)  /* repaint window with current line at the specified line   */
int line;
int count;
{
      struct text *mid_line;
      struct text *a_line;
      struct text *b_line;
      char *tp;         /* temporary pointer          */
      int abs_column;   /* the number of columns from start of line     */
      int ti;                 /* temporary integer          */
      int ti1;          /* another temporary integer  */
      int tppos;        /* temporary paste position   */
      int m;
      int i;

      mid_line = curr_buff->curr_line;

      /*
       |    find the first line visible on the screen (from the top)
       */

      i = (curr_buff->scr_pos / COLS);
      while ((i < line) && (curr_buff->curr_line->prev_line != NULL) && (i < curr_buff->last_line))
      {
            curr_buff->curr_line = curr_buff->curr_line->prev_line;
            i += curr_buff->curr_line->vert_len;
      }

      /*
       |    set up temporary pointers to store the current information
       */

      tp = curr_buff->curr_line->line;
      tppos = 1;
      ti1 = ti = 0;
      curr_buff->scr_vert = curr_buff->scr_horz = 0;
      wmove(curr_buff->win, 0, 0);
      a_line = curr_buff->curr_line;
      if (i > line)
            ti = line - i;
      else
            ti = 0;

      /*
       |    erase the window and paint the information
       */

      werase(curr_buff->win);
      while ((a_line != NULL) && (ti <= curr_buff->last_line))
      {
            draw_line(ti, 0, tp, 1, a_line);
            ti += a_line->vert_len;
            a_line = a_line->next_line;
            if (a_line != NULL)
                  tp = a_line->line;
      }
      if (i > line)
            curr_buff->scr_vert = line;
      else
            curr_buff->scr_vert = i;
      curr_buff->curr_line = mid_line;

      /*
       |    Now highlight areas that have been marked.
       */

      if (mark_text)          /* paint selected text  */
      {
            b_line = cpste_line;
            a_line = curr_buff->curr_line;
            tppos = pst_pos;

            /*
             |    if the marked areas are before the cursor...
             */

            if ((pst_pos == cpste_line->line_length) && (cpste_line->next_line == NULL))
            {

                  /*
                   |    if there are multiple marked lines, find out 
                   |    how much vertical space they use
                   */

                  if (cpste_line->prev_line != NULL)
                  {
                        i = scanline(curr_buff->curr_line, count) / COLS;
                        while ((i <= curr_buff->scr_vert) && (cpste_line->prev_line!= NULL))
                        {
                              curr_buff->curr_line = curr_buff->curr_line->prev_line;
                              cpste_line = cpste_line->prev_line;
                              i += curr_buff->curr_line->vert_len;
                        }
                  }
                  else
                        i = 0;

                  tp = curr_buff->curr_line->line;
                  ti = 1;

                  /*
                   |    set up to highlight a partial line
                   */

                  if (curr_buff->curr_line->line_length != cpste_line->line_length)
                  {
                        if (i != 0)
                        {
                              ti = curr_buff->curr_line->line_length - 
                                    cpste_line->line_length;
                              ti++;
                              for (ti1=1; ti1<ti; ti1++)
                                    tp++;
                        }
                        else 
                        {
                              for (ti = 1; 
                                    ti <= (curr_buff->position - 
                                    cpste_line->line_length); ti++)
                                  tp++;
                        }
                  }

                  abs_column = curr_buff->scr_horz = scanline(curr_buff->curr_line, ti);
                  m = curr_buff->scr_horz / COLS;
                  curr_buff->scr_horz = curr_buff->scr_horz % COLS;
                  wmove(curr_buff->win, (m + curr_buff->scr_vert - 1), curr_buff->scr_horz);
                  wstandout(curr_buff->win);
                  curr_buff->pointer = tp;
                  pst_pos = 1;

                  if (i == 0)
                        i = scanline(curr_buff->curr_line, curr_buff->position) / COLS;

                  draw_line(m + curr_buff->scr_vert - i, abs_column, curr_buff->pointer, ti, 
                                    curr_buff->curr_line);

                  for (ti = i - curr_buff->curr_line->vert_len; ti >= 0; 
                              ti -= curr_buff->curr_line->vert_len)
                  {
                        cpste_line = cpste_line->next_line;
                        curr_buff->curr_line = curr_buff->curr_line->next_line;
                        pst_pos = 1;
                        curr_buff->pointer = curr_buff->curr_line->line;
                        draw_line(curr_buff->scr_vert-ti, 0, curr_buff->curr_line->line, 1, 
                                    curr_buff->curr_line);
                  }
            }
            /*
             |    or the marked text is after the cursor...
             */
            else
            {
                  pst_pos = 1;
                  i = curr_buff->scr_vert;
                  draw_line(curr_buff->scr_vert, curr_buff->scr_pos, curr_buff->pointer, curr_buff->position, curr_buff->curr_line);
                  i += curr_buff->curr_line->vert_len - (scanline(curr_buff->curr_line, curr_buff->position) / COLS);
                  if (curr_buff->curr_line->next_line != NULL)
                  {
                        curr_buff->curr_line = curr_buff->curr_line->next_line;
                        cpste_line = cpste_line->next_line;
                        curr_buff->pointer = curr_buff->curr_line->line;
                        pst_pos = 1;
                        while ((i <= curr_buff->last_line) && (cpste_line != NULL))
                        {
                              draw_line(i, 0, curr_buff->pointer, 1, curr_buff->curr_line);
                              i += curr_buff->curr_line->vert_len;
                              if (curr_buff->curr_line->next_line != NULL)
                              {
                                    curr_buff->curr_line = curr_buff->curr_line->next_line;
                                    cpste_line = cpste_line->next_line;
                                    curr_buff->pointer = curr_buff->curr_line->line;
                              }
                        }
                  }
            }
            pst_pos = tppos;
            curr_buff->curr_line = a_line;
            cpste_line = b_line;
      }
      curr_buff->pointer = curr_buff->curr_line->line;
      for (value = 1; value < count; value++)
            curr_buff->pointer ++;
      curr_buff->abs_pos = curr_buff->scr_pos = scanline(curr_buff->curr_line, count);
      curr_buff->scr_horz = curr_buff->scr_pos % COLS;
      wmove(curr_buff->win, curr_buff->scr_vert, curr_buff->scr_horz);
}

#ifndef xae11
void 
get_options(numargs, arguments)     /* get arguments from original command line     */
int numargs;
char *arguments[];
{
      char *buff;
      char *extens;
      int count;
      struct files *temp_names;

      buff = ae_basename(arguments[0]);
      if (!strcmp(buff, "rae"))
      {
            restricted = TRUE;
            change_dir_allowed = FALSE;
      }

      count = 1;
      while (count < numargs)
      {
            buff = arguments[count];
            if (*buff == '-') /* options  */
            {
                  ++buff;
                  if (*buff == 'j') /* turn off recover file */
                        journ_on = FALSE;
                  else if (*buff == 'r')  /* recover from bad exit */
                        recover = TRUE;
                  else if (*buff == 'e')  /* turn off echo in init file */
                        echo_flag = FALSE;
                  else if (*buff == 'i')  /* turn off info window */
                        info_window = FALSE;
                  else if (!strcmp(arguments[count], "-text"))
                  {
                        text_only = TRUE;
                  }
                  else if (!strcmp(arguments[count], "-binary"))
                  {
                        text_only = FALSE;
                  }
                  else if (!strcmp(arguments[count], "-tab"))
                                    /* expand tabs to spaces */
                        expand = TRUE;
                  else if (*buff == 'n')  /* turn off highlighting on menus*/
                        nohighlight = TRUE;
#ifdef XAE
                  else if (*buff == 'h')  /* get height of window */
                  {
                        buff++;
                        if (*buff == (char) NULL)
                        {
                              count++;
                              buff = arguments[count];
                        }
                        win_height = atoi(buff);
                  }
                  else if (*buff == 'w')  /* get width of window  */
                  {
                        buff++;
                        if (*buff == (char) NULL)
                        {
                              count++;
                              buff = arguments[count];
                        }
                        win_width = atoi(buff);
                  }
#endif
            }
            else if (*buff == '+')
            {
                  buff++;
                  start_at_line = buff;
            }
            else  /* if the argument wasn't an option, must be a file name, right?  */
            {
                  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;
                  }
                  temp_names->next_name = NULL;
                  extens = temp_names->name = xalloc(strlen(buff) + 1);
                  while (*buff != (char) NULL)
                  {
                        *extens = *buff;
                        buff++;
                        extens++;
                  }
                  *extens = (char) NULL;
                  input_file = TRUE;
                  recv_file = TRUE;
            }
            count++;
      }
}
#endif /* xae11   */

void 
finish(string)    /* prepare to EXIT edit session, write out file */
char *string;
{
      char *query;
      int leave;

      leave = TRUE;
      if (mark_text)
      {
            copy();
      }

      if ((num_of_bufs > 1) && (top_of_stack == NULL))
      {
            do
                  query = get_string(other_buffs_exist_msg, TRUE);
            while ((toupper(*query) != toupper(*yes_char)) && 
                  (toupper(*query) != toupper(*no_char)));
            if (toupper(*query) != toupper(*yes_char))
                  leave = FALSE;
            else
            {
                  leave = delete_all_buffers();
            }
      }

      if (leave)
      {
            if (!curr_buff->main_buffer)
                  chng_buf(main_buffer_name);

            if (file_op(SAVE_FILE) == 0)
            {
                  change = FALSE;
                  quit(string);
            }
      }
}

int 
delete_all_buffers()
{
      int success = TRUE;

      t_buff = first_buff->next_buff;
      while ((t_buff != NULL) && (success))
      {
            chng_buf(t_buff->name);
            success = del_buf();
            t_buff = first_buff->next_buff;
      }
      return(success);
}

void 
quit(string)            /* leave editor, or if other files specified in invoking command line, edit next in sequence    */
char *string;
{
      char *query;
      char *ans;
      int editable_buffs = 0;

      if (num_of_bufs > 1)
      {
            t_buff = first_buff;
            while (t_buff != NULL)
            {
                  if (t_buff->edit_buffer)
                        editable_buffs++;
                  t_buff = t_buff->next_buff;
            }
      }

      if ((num_of_bufs > 1) && (top_of_stack == NULL))
      {
            do
                  query = get_string(other_buffs_exist_msg, TRUE);
            while ((toupper(*query) != toupper(*yes_char)) && 
                  (toupper(*query) != toupper(*no_char)));
            if (toupper(*query) != toupper(*yes_char))
                  return;
            else
            {
                  if (mark_text)
                        copy();
                  chng_buf(main_buffer_name);
            }

            if (!delete_all_buffers())
                  return;
      }
      if (first_buff->changed) /* if changes have been made in the file */
      {
            ans = get_string(changes_made_prompt, TRUE);
            if (toupper(*ans) != toupper(*yes_char))
                  return;
      }
      if (mark_text)
      {
            copy();
      }
      chng_buf(main_buffer_name);
      if (curr_buff->journalling)
                  /* if recover file in use, delete it */
      {
            remove_journal_file(curr_buff);
      }
      while ((string != NULL) && (*string != (char) NULL) && (*string != '!'))
            string++;
      if ((string != NULL) && (*string == '!'))
            top_of_stack = NULL;
      if (top_of_stack == NULL)     /* no other files to edit */
      {
            edit = FALSE;
            wrefresh(com_win);
            echo();
            nl();
            resetty();
            resetterm();
            noraw();
            endwin();
#ifndef XAE
            putchar('\n');
#endif      /* XAE */
            exit(0);
      }
      else  /* prepare to edit next file  */
      {
            change = FALSE;
            curr_buff->curr_line = curr_buff->first_line;
            while (curr_buff->curr_line->next_line != NULL)
            {
                  free(curr_buff->curr_line->line);
                  curr_buff->curr_line = curr_buff->curr_line->next_line;
                  free(curr_buff->curr_line->prev_line);
            }
            curr_buff->num_of_lines = 1;
            curr_buff->absolute_lin = 1;
            free(curr_buff->curr_line->line);
            free(curr_buff->curr_line);
            curr_buff->scr_vert = curr_buff->scr_horz = 0;
            curr_buff->curr_line = curr_buff->first_line = txtalloc();
            curr_buff->curr_line->line = curr_buff->pointer = xalloc(10);
            curr_buff->curr_line->line_length = 1;
            curr_buff->curr_line->max_length = 10;
            curr_buff->curr_line->prev_line = NULL;
            curr_buff->curr_line->next_line = NULL;
            curr_buff->curr_line->line_number = 1;
            curr_buff->position = 1;
            curr_buff->scr_pos = curr_buff->abs_pos = curr_buff->scr_horz = curr_buff->scr_vert = 0;
            free(curr_buff->journal_file);
            free(curr_buff->full_name);
            curr_buff->journal_file = NULL;
            curr_buff->file_name = NULL;
            curr_buff->full_name = "";
            werase(curr_buff->win);
            recv_file = TRUE;
            input_file = TRUE;
            tmp_file = top_of_stack->name;
            top_of_stack = top_of_stack->next_name;
            value = check_fp();
      }
}

void 
abort_edit(foo)   /* handle interrupt signal (break key) gracefully     */
int foo;
{
      wrefresh(com_win);
      echo();
      nl();
      resetty();
      resetterm();
      noraw();
      endwin();
      putchar('\n');
      exit(0);
}

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   */
      struct text *line_holder;
      struct bufr *tmp; /* pointer to buffer structure            */

      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++;
      }
      keypad(curr_buff->win, FALSE);
      echo();
      nl();
      noraw();
      resetty();
      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]);
            }
            else  /* if the parent  */
            {
/*
 |  prepare editor to read from the pipe
 */
                  signal(SIGCHLD, SIG_IGN);
                  chng_buf(in_buff_name);
                  line_holder = curr_buff->curr_line;
                  tmp_vert = curr_buff->scr_vert;
                  close(pipe_in[1]);
                  get_fd = pipe_in[0];
                  get_file("");
                  close(pipe_in[0]);
                  curr_buff->scr_vert = tmp_vert;
                  curr_buff->scr_horz = curr_buff->scr_pos = curr_buff->abs_pos = 0;
                  curr_buff->position = 1;
                  curr_buff->curr_line = line_holder;
                  curr_buff->pointer = curr_buff->curr_line->line;
                  midscreen(curr_buff->scr_vert, 1);
                  out_pipe = FALSE;
                  signal(SIGCHLD, SIG_DFL);
/*
 |  since flag "in_pipe" is still TRUE, do not even wait for child to complete
 |  (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("could not exec %s\n", 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]);
                        tmp = first_buff;
                        while ((tmp != NULL) && (strcmp(out_buff_name, tmp->name)))
                              tmp = tmp->next_buff;
                        if (tmp != NULL)
                        {
                              line_holder = tmp->first_line;
                              while (line_holder != NULL)
                              {
                                    write(pipe_out[1], line_holder->line, (line_holder->line_length-1));
                                                if (tmp->dos_file)
                                                   write(pipe_out[1], "\r", 1);
                                    write(pipe_out[1], "\n", 1);
                                    line_holder = line_holder->next_line;
                              }
                        }
                        else
                              printf(no_buff_named_str, out_buff_name);
                        close(pipe_out[1]);
                        out_pipe = FALSE;
                  }
                  wait(&parent);
                  signal(SIGINT, abort_edit);
/*
 |  if this process is actually the child of the editor, exit
 |  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 (!shell_fork)
                        exit(0);
            }
      }
      if (shell_fork)
      {
            printf(press_ret_to_cont_str);
            fflush(stdout);
            while (((in = getchar()) != '\n') && (in != '\r'))
                  ;
#ifdef XAE
            raise_window();
#endif
      }
      fixterm();
      noecho();
      nonl();
      raw();
      keypad(curr_buff->win, TRUE);
      curr_buff->win = curr_buff->win;
      clearok(curr_buff->win, TRUE);
      redraw();
}

void 
redraw()          /* redraw screen              */
{
      repaint_screen();
}

void 
repaint_screen()
{
      struct bufr *t_buff;    /* temporary buffer     */

      for (t_buff = first_buff; t_buff != NULL; t_buff = t_buff->next_buff)
      {
            touchwin(t_buff->win);
            wnoutrefresh(t_buff->win);
            if (t_buff->footer != NULL)
            {
                  touchwin(t_buff->footer);
                  wnoutrefresh(t_buff->footer);
            }
      }
      if (info_window)
      {
            touchwin(info_win);
            wnoutrefresh(info_win);
      }
}

void 
copy_str(str1, str2)    /* copy string1 to string2                */
char *str1, *str2;
{
      char *t1, *t2;

      t1 = str1;
      t2 = str2;
      while (*t1 != (char) NULL)
      {
            *t2 = *t1;
            t2++;
            t1++;
      }
      *t2 = *t1;
}

void 
echo_string(string)     /* echo the given string      */
char *string;
{
      char *temp;
      int Counter;

      if (echo_flag)
      {
            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);
}

char *init_name[4] = {
      "/usr/local/aee/init.ae", 
      "/usr/local/lib/init.ae", 
      NULL, 
      ".init.ae"
      };

void 
ae_init()   /* check for init file and read it if it exists */
{
      FILE *init_file;
      char *string;
      char *str1;
      char *str2;
      char *home;
      char *tmp;
      int c_int;
      int lines;
      int counter;


      home = xalloc(11);
      strcpy(home, "~/.init.ae");
      init_name[2] = resolve_name(home);

      string = xalloc(512);
      for (counter = 0; counter < 4; counter++)
      {
            lines = 1;
            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, DEFINE_str, FALSE))
                        {
                              str1 = next_word(str1);
                              def_key(str1);
                        }
                        else if (compare(str1, WINDOWS_str,  FALSE))
                              windows = TRUE;
                        else if (compare(str1, NOWINDOWS_str,  FALSE))
                              windows = FALSE;
                        else if (compare(str1, CASE_str,  FALSE))
                              case_sen = TRUE;
                        else if (compare(str1, NOCASE_str,  FALSE))
                              case_sen = FALSE;
                        else if (compare(str1, TABS_str,  FALSE))
                              tab_set(str1);
                        else if (compare(str1, UNTABS_str,  FALSE))
                              unset_tab(str1);
                        else if (compare(str1, EXPAND_str,  FALSE))
                              expand = TRUE;
                        else if (compare(str1, SPACING_str, FALSE))
                        {
                              str1 = next_word(str1);
                              if (*str1 != (char) NULL)
                                    tab_spacing = atoi(str1);
                        }
                        else if (compare(str1, NOEXPAND_str,  FALSE))
                              expand = FALSE;
                        else if (compare(str1, NOJUSTIFY_str,  FALSE))
                              right_justify = FALSE;
                        else if (compare(str1, JUSTIFY_str,  FALSE))
                              right_justify = TRUE;
                        else if (compare(str1, LITERAL_str,  FALSE))
                              literal = TRUE;
                        else if (compare(str1, NOLITERAL_str,  FALSE))
                              literal = FALSE;
                        else if (compare(str1, STATUS_str,  FALSE))
                              status_line = TRUE;
                        else if (compare(str1, NOSTATUS_str,  FALSE))
                              status_line = FALSE;
                        else if (compare(str1, INDENT_str,  FALSE))
                              indent = TRUE;
                        else if (compare(str1, NOINDENT_str,  FALSE))
                              indent = FALSE;
                        else if (compare(str1, OVERSTRIKE_str,  FALSE))
                              overstrike = TRUE;
                        else if (compare(str1, NOOVERSTRIKE_str,  FALSE))
                              overstrike = FALSE;
                        else if (compare(str1, AUTOFORMAT_str,  FALSE))
                        {
                              auto_format = TRUE;
                              observ_margins = TRUE;
                              indent = FALSE;
                        }
                        else if (compare(str1, NOAUTOFORMAT_str,  FALSE))
                              auto_format = FALSE;
                        else if (compare(str1, EIGHT_str,  FALSE))
                              eightbit = TRUE;
                        else if (compare(str1, NOEIGHT_str,  FALSE))
                              eightbit = FALSE;
                        else if (compare(str1, MARGINS_str,  FALSE))
                              observ_margins = TRUE;
                        else if (compare(str1, NOMARGINS_str,  FALSE))
                              observ_margins = FALSE;
                        else if (compare(str1, ee_mode_str,  FALSE))
                        {
                              ee_mode_menu = TRUE;
                              main_menu[0].item_string = ee_mode_main_menu_strings[0];
                              main_menu[1].item_string = ee_mode_main_menu_strings[1];
                              main_menu[2].item_string = ee_mode_main_menu_strings[2];
                              main_menu[3].item_string = ee_mode_main_menu_strings[3];
                              main_menu[4].item_string = ee_mode_main_menu_strings[4];
                              main_menu[5].item_string = ee_mode_main_menu_strings[5];
                              main_menu[6].item_string = ee_mode_main_menu_strings[6];
                              main_menu[7].item_string = ee_mode_main_menu_strings[7];
                              main_menu[8].item_string = ee_mode_main_menu_strings[8];
                              main_menu[3].procedure = menu_op;
                              main_menu[3].ptr_argument = file_menu;
                              main_menu[4].procedure = NULL;
                              main_menu[4].ptr_argument = NULL;
                              main_menu[4].iprocedure = NULL;
                              main_menu[4].nprocedure = redraw;
                              main_menu[5].procedure = NULL;
                              main_menu[5].ptr_argument = NULL;
                              main_menu[5].iprocedure = NULL;
                              main_menu[5].nprocedure = modes_op;
                              main_menu[6].procedure = menu_op;
                              main_menu[6].ptr_argument = search_menu;
                              main_menu[6].iprocedure = NULL;
                              main_menu[6].nprocedure = NULL;
                              main_menu[7].procedure = menu_op;
                              main_menu[7].ptr_argument = misc_menu;
                              main_menu[7].iprocedure = NULL;
                              main_menu[7].nprocedure = NULL;
                              main_menu[8].procedure = menu_op;
                              main_menu[8].ptr_argument = edit_menu;
                              main_menu[8].iprocedure = NULL;
                              main_menu[8].nprocedure = NULL;
                        }
                        else if ((compare(str1, LEFTMARGIN_str,  FALSE)) || (compare(str1, RIGHTMARGIN_str,  FALSE)))
                        {
                              tmp = next_word(str1);
                              if ((*tmp >= '0') && (*tmp <= '9'))
                              {
                                    c_int = atoi(tmp);
                                    if (compare(str1, LEFTMARGIN_str,  FALSE))
                                          left_margin = c_int;
                                    else if (compare(str1, RIGHTMARGIN_str,  FALSE))
                                          right_margin = c_int;
                              }
                        }
                        else if (compare(str1, info_win_height_cmd_str,  FALSE))
                        {
                              tmp = next_word(str1);
                              if ((*tmp >= '0') && (*tmp <= '9'))
                              {
                                    c_int = atoi(tmp);
                                    if ((c_int > 0) && (c_int <= MAX_HELP_LINES))
                                          info_win_height = c_int + 1;
                              }
                        }
                        else if (compare(str1, ECHO_str,  FALSE))
                        {
#ifndef XAE
                              str1 = next_word(str1);
                              if (*str1 != (char) NULL)
                                    echo_string(str1);
#endif
                        }
                        else if (compare(str1, PRINTCOMMAND_str, FALSE))
                        {
                              str1 = next_word(str1);
                              print_command = xalloc(strlen(str1)+1);
                              copy_str(str1, print_command);
                        }
                        else if (compare(str1, INFO_str,  FALSE))
                              info_window = TRUE;
                        else if (compare(str1, NOINFO_str,  FALSE))
                              info_window = FALSE;   
                        else if (compare(str1, HIGHLIGHT_str,  FALSE))
                              nohighlight = FALSE;
                        else if (compare(str1, NOHIGHLIGHT_str,  FALSE))
                              nohighlight = TRUE;
                        else if (compare(str1, jrnl_dir,  FALSE))
                        {
                              str1 = next_word(str1);
                              tmp = str1;
                              while ((*tmp != ' ') && 
                                     (*tmp != '\t') && 
                                     (*tmp != (char) NULL))
                                    tmp++;
                              *tmp = (char) NULL;
                              journal_dir = resolve_name(str1);
                              if (str1 == journal_dir)
                              {
                                    journal_dir = 
                                       xalloc(strlen(str1) + 1);
                                    strcpy(journal_dir, str1);
                              }
                              value = create_dir(journal_dir);
                              if (value == -1)
                              {
                                    /*
                                     |  journal dir doesn't exist
                                     */
                                    free(journal_dir);
                                    journal_dir = NULL;
                              }
                        }
                        else if (compare(str1, text_cmd,  FALSE))
                              text_only = TRUE;
                        else if (compare(str1, binary_cmd,  FALSE))
                              text_only = FALSE;
                        else if (compare(str1, help_file_str,  FALSE))
                        {
                              str1 = next_word(str1);
                              tmp = str1;
                              while ((*tmp != ' ') && 
                                     (*tmp != '\t') && 
                                     (*tmp != (char) NULL))
                                    tmp++;
                              *tmp = (char) NULL;
                              ae_help_file = resolve_name(str1);
                              if (str1 == ae_help_file)
                              {
                                    ae_help_file = 
                                       xalloc(strlen(str1) + 1);
                                    strcpy(ae_help_file, str1);
                              }
                        }
                        lines++;
                  }
                  fclose(init_file);
                  if (!compare(curr_buff->name, main_buffer_name, TRUE))
                        chng_buf(main_buffer_name);
            }
      }
      free(string);
      free(home);
}


Generated by  Doxygen 1.6.0   Back to index