home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / thesrc15.zip / the.c < prev    next >
C/C++ Source or Header  |  1993-11-17  |  30KB  |  824 lines

  1. /***********************************************************************/
  2. /* THE.C - The Hessling Editor                                         */
  3. /***********************************************************************/
  4. /*
  5.  * THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
  6.  * Copyright (C) 1991-1993 Mark Hessling
  7.  *
  8.  * This program is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU General Public License as
  10.  * published by the Free Software Foundation; either version 2 of
  11.  * the License, or any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16.  * General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to:
  20.  *
  21.  *    The Free Software Foundation, Inc.
  22.  *    675 Mass Ave,
  23.  *    Cambridge, MA 02139 USA.
  24.  *
  25.  *
  26.  * If you make modifications to this software that you feel increases
  27.  * it usefulness for the rest of the community, please email the
  28.  * changes, enhancements, bug fixes as well as any and all ideas to me.
  29.  * This software is going to be maintained and enhanced as deemed
  30.  * necessary by the community.
  31.  *
  32.  * Mark Hessling                     email: M.Hessling@gu.edu.au
  33.  * 36 David Road                     Phone: +61 7 849 7731
  34.  * Holland Park                      Fax:   +61 7 875 5314
  35.  * QLD 4121
  36.  * Australia
  37.  */
  38.  
  39. /*
  40. $Header: C:\THE\RCS\the.c 1.4 1993/09/01 16:27:17 MH Interim MH $
  41. */
  42.  
  43. #include <stdio.h>
  44.  
  45. #define MAIN 1
  46. #include "the.h"
  47. #include "proto.h"
  48. #include <signal.h>
  49.  
  50. #if defined(DOS) || defined(OS2)
  51. #  if !defined(EMX) && !defined(GO32)
  52. #    include <direct.h>
  53. #  endif
  54. #endif
  55.  
  56. /*--------------------------- global data -----------------------------*/
  57.  WINDOW *foot,*error_window,*divider;
  58.  VIEW_DETAILS *vd_current=(VIEW_DETAILS *)NULL;
  59.  VIEW_DETAILS *vd_first=(VIEW_DETAILS *)NULL;
  60.  VIEW_DETAILS *vd_mark=(VIEW_DETAILS *)NULL;
  61.  char number_of_views = 0;                          /* number of views */
  62.  char number_of_files = 0;                          /* number of files */
  63.  char display_screens = 1;                        /* number of screens */
  64.  char current_screen = 0;
  65.  SCREEN_DETAILS screen[MAX_SCREENS];            /* 2 screen structures */
  66.  bool horizontal=TRUE;
  67.  short save_coord_x[VIEW_WINDOWS];
  68.  short save_coord_y[VIEW_WINDOWS];
  69.  
  70.  LINE *next_line,*curr_line;
  71.  LINE *first_file_name=NULL,*current_file_name=NULL;
  72.  bool error_on_screen=FALSE;
  73.  bool colour_support=TRUE;         /* indicates if colour is supported */
  74.  char *rec;
  75.  unsigned short rec_len = 0;                          /* length of rec */
  76.  char *cmd_rec;
  77.  unsigned short cmd_rec_len = 0;                  /* length of cmd_rec */
  78.  char *pre_rec;
  79.  unsigned short pre_rec_len = 0;                  /* length of cmd_rec */
  80.  char focus_changed = NO;   /* indicates if focus line has changed */
  81.  char current_changed = NO; /* indicates if current line has changed */
  82.  char mode_insert=NO;           /* defines insert mode toggle */
  83.  char in_profile;          /* indicates if processing profile */
  84.  char execute_profile; /* indicates if we are to process any profile */
  85.  char in_macro;         /* indicates if processing REXX macro */
  86.  char file_read=NO;     /* indicates if we have read the file */
  87.  char curses_started=NO;  /* indicates if cureses has started */
  88.  
  89. #if defined(DOS) || defined(OS2)
  90.  bool extended_display_mode=TRUE;      /* display all 256 characters ? */
  91. #else
  92.  bool extended_display_mode=FALSE;     /* display all 256 characters ? */
  93. #endif
  94.  
  95.  char *the_version = (char *)"1.5";
  96.  char term_name[20];  /* $TERM value */
  97. #if defined(UNIX)
  98.  char user_home_dir[MAX_FILE_NAME+1];
  99. #   define THE_PROFILE_FILE ".therc"
  100. #else
  101. #   define THE_PROFILE_FILE "PROFILE.THE"
  102. #endif
  103.  char *helpfilename = (char *)"THE.HLP";
  104.  char *tempfilename = (char *)"THE.$$$";
  105. #if !defined(NOREXX)
  106.  char *rexxoutname = (char *)"REXX.$$$";
  107.  char rexx_pathname[MAX_FILE_NAME+1];
  108.  char rexx_filename[10];
  109. #endif
  110. #ifdef VMS
  111.  char *dirfilename = (char *)"DIR.THE";
  112. #else
  113.  char *dirfilename = (char *)"DIR.DIR";
  114. #endif
  115.  char macro_suffix[12] = ".the";  /* default extension for macros */
  116.  char dir_pathname[MAX_FILE_NAME+1];
  117.  char dir_filename[10];
  118.  char curr_path[MAX_FILE_NAME+1];
  119.  char sp_path[MAX_FILE_NAME+1];
  120.  char sp_fname[MAX_FILE_NAME+1];
  121.  char dir_path[MAX_FILE_NAME+1];   /* for dir and ls commands */
  122.  
  123.  char the_home_dir[MAX_FILE_NAME+1];
  124.  char the_macro_path[MAX_FILE_NAME+1];   /* for macro command */
  125.  char the_help_file[MAX_FILE_NAME+1];
  126.  char the_profile_file[MAX_FILE_NAME+1];
  127.  
  128.  char *prf_arg=(char *)NULL;
  129.  bool profile_specified=FALSE;
  130.  
  131.  char tabkey_insert='C';
  132.  char tabkey_overwrite='T';
  133.  unsigned short file_start = 36;
  134.  char *last_target;
  135.  
  136. #if defined(UNIX) || defined(OS2)
  137.  char *spooler_name;
  138. #endif
  139.  
  140. char file_disposition;
  141.  
  142. struct stat stat_buf;
  143.  
  144. int reserved_top=0;
  145. int reserved_bottom=0;
  146.  
  147. int lastrc=0;
  148. extern DEFINE *first_define;
  149. #if !defined(NOREXX)
  150. extern LINE *first_prefix_synonym;
  151. #endif
  152. /*---------------------------------------------------------------------*/
  153. /* Following are for getopt function(s).                               */
  154. /*---------------------------------------------------------------------*/
  155. extern char *optarg;
  156. extern int optind;
  157.  
  158. /***********************************************************************/
  159. #ifdef PROTO
  160. int main(int argc, char *argv[])
  161. #else
  162. int main(argc,argv)
  163. int argc;
  164. char *argv[];
  165. #endif
  166. /***********************************************************************/
  167. {
  168. /*-------------------------- external data ----------------------------*/
  169. extern bool CLEARSCREENx;
  170. /*---------------------- function definitions -------------------------*/
  171.  
  172. /*--------------------------- local data ------------------------------*/
  173.  register int i,j,k;
  174.  char *prf=(char *)NULL;
  175.  int c;
  176.  int malloc_fd;
  177.  bool trap_signals=TRUE;
  178.  bool pause_for_errors=FALSE;
  179.  int rc;
  180. /*--------------------------- processing ------------------------------*/
  181. #ifdef __EMX__
  182.  _wildcard(&argc,&argv);
  183. #endif
  184. #ifdef TRACE
  185.  trace_initialise();
  186.  trace_function("the.c:     main");
  187. #endif
  188. /*---------------------------------------------------------------------*/
  189. /* Set up flag to indicate that we are not interactive...yet.          */
  190. /*---------------------------------------------------------------------*/
  191.  in_profile = TRUE;
  192.  execute_profile = TRUE;
  193.  in_macro = FALSE;
  194. /*---------------------------------------------------------------------*/
  195. /* Initialise the printer spooler.                                     */
  196. /*---------------------------------------------------------------------*/
  197. #if defined(UNIX) || defined(OS2)
  198.  if ((spooler_name = (char *)malloc(4*sizeof(char))) == NULL)
  199.    {
  200.     display_error(30,(char *)"");
  201.     exit_clean(1);
  202.    }
  203. #  ifdef UNIX
  204.  strcpy(spooler_name,(char *)"lpr");
  205. #  else
  206.  strcpy(spooler_name,(char *)"LPT1");
  207. #  endif
  208. #endif
  209. /*---------------------------------------------------------------------*/
  210. /* Get all environment variables here. Some may be overridden by       */
  211. /* command-line switches. (future possibility)                        */
  212. /*---------------------------------------------------------------------*/
  213. #if defined(UNIX)
  214.  if (getenv("HOME") != NULL)
  215.     strcpy(user_home_dir,getenv("HOME"));
  216.  else
  217.     strcpy(user_home_dir,"./");
  218.  if (*(user_home_dir+strlen(user_home_dir)-1) != ISLASH)
  219.     strcat(user_home_dir,ISTR_SLASH);
  220.  if (getenv("TERM") != NULL)
  221.     strcpy(term_name,getenv("TERM"));
  222.  else
  223.     strcpy(term_name,"default");
  224. #endif
  225. #if defined(DOS)
  226.  strcpy(term_name,"DOS");
  227. #endif
  228. #if defined(OS2)
  229.  strcpy(term_name,"OS2");
  230. #endif
  231. /*---------------------------------------------------------------------*/
  232. /* Get THE_HOME_DIR first (as all other paths rely on this value)      */
  233. /*---------------------------------------------------------------------*/
  234.  if (getenv("THE_HOME_DIR") != NULL)
  235.    {
  236.     strcpy(the_home_dir,getenv("THE_HOME_DIR"));
  237.     (void *)strtrans(the_home_dir,OSLASH,ISLASH);
  238.     if ((the_home_dir[strlen(the_home_dir)-1]) != ISLASH)
  239.        strcat(the_home_dir,ISTR_SLASH);
  240.    }
  241.  else
  242.    {
  243. #if defined(UNIX)
  244.     strcpy(the_home_dir,THE_HOME_DIRECTORY);
  245. #else
  246.     strcpy(the_home_dir,argv[0]);
  247.     (void *)strtrans(the_home_dir,OSLASH,ISLASH);
  248.     i = strzreveq(the_home_dir,ISLASH);
  249.     if (i != (-1))
  250.        the_home_dir[i+1] = '\0';
  251.     else
  252.        the_home_dir[0] = '\0';
  253. #endif
  254.    }
  255. /*---------------------------------------------------------------------*/
  256. /* Get THE_MACRO_PATH environment variable. If not set set up default  */
  257. /* to be THE_HOME_DIR followed by the current directory.               */
  258. /*---------------------------------------------------------------------*/
  259.  if (getenv("THE_MACRO_PATH") != NULL)
  260.     strcpy(the_macro_path,getenv("THE_MACRO_PATH"));
  261.  else
  262.    {
  263.     strcpy(the_macro_path,the_home_dir);
  264. #if defined(UNIX)
  265.     strcat(the_macro_path,":.");
  266. #else
  267.     strcat(the_macro_path,";.");
  268. #endif
  269.    }
  270.  (void *)strtrans(the_macro_path,OSLASH,ISLASH);
  271. #ifdef VMS
  272.  strcpy(the_macro_path,"");
  273. #endif
  274. /*---------------------------------------------------------------------*/
  275. /* Set up help file name.                                              */
  276. /*---------------------------------------------------------------------*/
  277.  if (getenv("THE_HELP_FILE") != NULL)
  278.     strcpy(the_help_file,getenv("THE_HELP_FILE"));
  279.  else
  280.    {
  281.     strcpy(the_help_file,the_home_dir);
  282.     strcat(the_help_file,term_name);
  283.     strcat(the_help_file,".hlp");
  284.    }
  285.  (void *)strtrans(the_help_file,OSLASH,ISLASH);
  286. /*---------------------------------------------------------------------*/
  287. /* Set up profile file name.                                           */
  288. /*---------------------------------------------------------------------*/
  289.  if (getenv("THE_PROFILE_FILE") != NULL)
  290.     strcpy(the_profile_file,getenv("THE_PROFILE_FILE"));
  291.  else
  292.    {
  293. #if defined(UNIX)
  294.     strcpy(the_profile_file,user_home_dir);
  295. #else
  296.     strcpy(the_profile_file,the_home_dir);
  297. #endif
  298.     strcat(the_profile_file,THE_PROFILE_FILE);
  299.    }
  300.  (void *)strtrans(the_profile_file,OSLASH,ISLASH);
  301. /*---------------------------------------------------------------------*/
  302. /* Process the command line arguments.                                 */
  303. /*---------------------------------------------------------------------*/
  304.  while ((c = getopt(argc,argv,"smnp:w:a:h?")) != EOF)
  305.    switch((char)c)
  306.      {
  307.       case 's':        /* don't trap signals */
  308.                trap_signals = FALSE;
  309.                break;
  310.       case 'm':        /* force into MONO */
  311.                colour_support = FALSE;
  312.                break;
  313.       case 'n':        /* do not execute any profile file */
  314.                execute_profile = FALSE;
  315.                break;
  316.       case 'p':        /* profile file name */
  317.                if ((prf = (char *)malloc((strlen(optarg)+1)*sizeof(char))) == NULL)
  318.                  {
  319.                   display_error(30,(char *)"");
  320.                   exit_clean(1);
  321.                  }
  322.                strcpy(prf,optarg);
  323.                break;
  324.       case 'a':        /* profile arguments */
  325.                if ((prf_arg = (char *)malloc((strlen(optarg)+1)*sizeof(char))) == NULL)
  326.                  {
  327.                   display_error(30,(char *)"");
  328.                   exit_clean(1);
  329.                  }
  330.                strcpy(prf_arg,optarg);
  331.                break;
  332.       case 'w':        /* width of line */
  333.                max_line_length = (short)atoi(optarg);
  334.                if (max_line_length < 10)
  335.                  {
  336.                   display_error(5,(char *)"width MUST be >= 10");
  337.                   exit_clean(1);
  338.                  }
  339.                break;
  340.       case 'h':
  341.       case '?':
  342.                display_info(argv[0]);
  343.                exit_clean(0);
  344.                break;
  345.       default:
  346.                break;
  347.      }
  348.  
  349.  if (optind<argc)
  350.    {
  351.     while(optind<argc)
  352.       {
  353.        if ((current_file_name = add_line(first_file_name,
  354.                                          current_file_name,
  355.                                          strtrans(argv[optind],OSLASH,ISLASH),
  356.                                          strlen(argv[optind]))) == NULL)
  357.            {
  358.             display_error(30,(char *)"");
  359.             exit_clean(1);
  360.            }
  361.        if (first_file_name == NULL)
  362.           first_file_name = current_file_name;
  363.        optind++;
  364.       }
  365.    }
  366.  else
  367.    {
  368.     if ((current_file_name = add_line(first_file_name,
  369.                                       current_file_name,
  370.                                       CURRENT_DIR,
  371.                                       strlen(CURRENT_DIR))) == NULL)
  372.         {
  373.          display_error(30,(char *)"");
  374.          exit_clean(1);
  375.         }
  376.     if (first_file_name == NULL)
  377.        first_file_name = current_file_name;
  378.    }
  379. /*---------------------------------------------------------------------*/
  380. /* Override any default paths,filenames etc if supplied on command line*/
  381. /*---------------------------------------------------------------------*/
  382.  if (prf != NULL)
  383.    {
  384.     strcpy(the_profile_file,prf);
  385.     (void *)strtrans(the_profile_file,OSLASH,ISLASH);
  386.     profile_specified = TRUE;
  387.    }
  388. /*---------------------------------------------------------------------*/
  389. /* Allocate some memory to last_target and set it to a blank value.    */
  390. /*---------------------------------------------------------------------*/
  391.  if ((last_target = (char *)malloc(80*sizeof(char))) == NULL)
  392.     exit_clean(1);
  393.  strcpy(last_target,"");
  394. /*---------------------------------------------------------------------*/
  395. /* Allocate some memory to rec.                                        */
  396. /*---------------------------------------------------------------------*/
  397.  if ((rec = (char *)malloc((max_line_length+1)*sizeof(char))) == NULL)
  398.     exit_clean(1);
  399. /*---------------------------------------------------------------------*/
  400. /* Allocate some memory for temporary space...                         */
  401. /*---------------------------------------------------------------------*/
  402.  if (allocate_temp_space(max_line_length,TEMP_PARAM) != RC_OK)
  403.     exit_clean(1);
  404.  if (allocate_temp_space(max_line_length,TEMP_TMP_CMD) != RC_OK)
  405.     exit_clean(1);
  406.  if (allocate_temp_space(max_line_length,TEMP_TEMP_CMD) != RC_OK)
  407.     exit_clean(1);
  408. /* if (allocate_temp_space(max_line_length,TEMP_MACRO) != RC_OK)
  409.     exit_clean(1);*/
  410. /*---------------------------------------------------------------------*/
  411. /* Allocate memory to pre_rec and set it to blanks.                    */
  412. /*---------------------------------------------------------------------*/
  413.  if ((pre_rec = (char *)malloc((PREFIX_WIDTH+1)*sizeof(char))) == NULL)
  414.     exit_clean(1);
  415.  memset(pre_rec,' ',PREFIX_WIDTH+1);
  416.  pre_rec_len = 0;
  417. /*---------------------------------------------------------------------*/
  418. /* Determine the current working directory.                            */
  419. /* Do this before any other file setting up so that we don't change the*/
  420. /* current directory from the default.                                 */
  421. /*---------------------------------------------------------------------*/
  422. #if defined(EMX)
  423.  _getcwd2(curr_path,MAX_FILE_NAME);
  424. #else
  425.  getcwd(curr_path,MAX_FILE_NAME);
  426. #endif
  427. /*---------------------------------------------------------------------*/
  428. /* Set up filename for directory temporary file (DIR.DIR).             */
  429. /* Set up filename for REXX capture file (REXX.$$$).                   */
  430. /*---------------------------------------------------------------------*/
  431. #ifdef UNIX
  432.  strcpy(dir_pathname,user_home_dir);
  433. #endif
  434. #if defined(DOS) || defined(OS2)
  435.  strcpy(dir_pathname,ISTR_SLASH);
  436. #endif
  437. #ifdef VMS
  438.  strcpy(dir_pathname,"");
  439. #endif
  440.  
  441. #if !defined(NOREXX)
  442.  strcpy(rexx_pathname,dir_pathname);
  443. #endif
  444.  
  445.  strcat(dir_pathname,dirfilename);
  446.  if (splitpath(dir_pathname) != RC_OK)
  447.     exit_clean(1);
  448.  strcpy(dir_pathname,sp_path);
  449.  strcpy(dir_filename,sp_fname);
  450.  
  451. #if !defined(NOREXX)
  452.  strcat(rexx_pathname,rexxoutname);
  453.  if (splitpath(rexx_pathname) != RC_OK)
  454.     exit_clean(1);
  455.  strcpy(rexx_pathname,sp_path);
  456.  strcpy(rexx_filename,sp_fname);
  457. #endif
  458. /*---------------------------------------------------------------------*/
  459. /* Set up default values for SET commands etc.                         */
  460. /*---------------------------------------------------------------------*/
  461.  set_defaults();
  462. /*---------------------------------------------------------------------*/
  463. /* Set up initial colours to 0.                                        */
  464. /*---------------------------------------------------------------------*/
  465.  for (i=0;i<ATTR_MAX;i++)
  466.      colour[i] = (chtype)0;
  467. /*---------------------------------------------------------------------*/
  468. /* Initialise command array to empty strings.                          */
  469. /*---------------------------------------------------------------------*/
  470.  init_command();
  471. /*---------------------------------------------------------------------*/
  472. /* Initialise rexx support if appropriate.                             */
  473. /*---------------------------------------------------------------------*/
  474. #if !defined(NOREXX)
  475.  if (initialise_rexx() != RC_OK)
  476.    {
  477.     display_error(54,(char *)"");
  478.     exit_clean(6);
  479.    }
  480. #endif
  481. /*---------------------------------------------------------------------*/
  482. /* Read each file into memory and apply the profile file to each of the*/
  483. /* files.                                                              */
  484. /*---------------------------------------------------------------------*/
  485.  current_file_name = first_file_name;
  486.  while(current_file_name != NULL)
  487.    {
  488.    if ((rc = get_file(current_file_name->line)) != RC_OK)
  489.      {
  490.       if (rc == RC_DISK_FULL)
  491.          display_error(57,(char *)"...probably");
  492.       exit_clean(2);
  493.      }
  494.    pre_process_line(0L);
  495.    if (execute_profile)
  496.      {
  497.       (void)get_profile(prf_arg);
  498.       if (error_on_screen)
  499.         {
  500.          pause_for_errors = TRUE;
  501.          error_on_screen = FALSE;
  502.         }
  503.      }
  504.    current_file_name = current_file_name->next;
  505.    }
  506.  if (number_of_files == 0)
  507.     exit_clean(0);
  508. #ifdef USE_VOID
  509.  ll_free((void *)first_file_name);
  510. #else
  511.  lll_free(first_file_name);
  512. #endif
  513.  CURRENT_VIEW = CURRENT_SCREEN.screen_view = vd_first;
  514.  pre_process_line(CURRENT_VIEW->focus_line);
  515.  CURRENT_VIEW->current_window = WINDOW_COMMAND;
  516.  
  517. /*---------------------------------------------------------------------*/
  518. /* If we have had an error in the profile file we need to pause so the */
  519. /* user sees the messages. This pause should only occur if the number  */
  520. /* of files > 0. ie the profile file does not contain a 'file' or 'quit*/
  521. /* command.                                                            */
  522. /*---------------------------------------------------------------------*/
  523.  if (pause_for_errors && number_of_files != 0)
  524.    {
  525.     fprintf(stderr,"\n%s","Hit RETURN to continue...");
  526.     fflush(stderr);
  527.     (void)getchar();
  528.     error_on_screen = FALSE;
  529.    }
  530.  
  531. /*---------------------------------------------------------------------*/
  532. /* Trap signals to exit gracefully, unless user has specified they not */
  533. /* be trapped.                                                         */
  534. /*---------------------------------------------------------------------*/
  535.  if (trap_signals)
  536.     init_signals();
  537. /*---------------------------------------------------------------------*/
  538. /* Start up curses. This allows profile commands to be processed before*/
  539. /* curses starts.                                                      */
  540. /*---------------------------------------------------------------------*/
  541.  initscr();
  542.  curses_started = YES;
  543. /*---------------------------------------------------------------------*/
  544. /* Determine if colour support available.                              */
  545. /*---------------------------------------------------------------------*/
  546.  if (colour_support) /* if default setting not overridden on command line */
  547.    {
  548.     colour_support = FALSE;
  549. #ifdef A_COLOR
  550.     if (has_colors())
  551.       {
  552.        start_color();
  553.        colour_support = TRUE;
  554.       }
  555. #endif
  556.    }
  557. /*---------------------------------------------------------------------*/
  558. /* Set various terminal characteristics...                             */
  559. /*---------------------------------------------------------------------*/
  560. #if !defined(VMS)
  561.  cbreak();
  562. #endif
  563. #if !defined(MINIX)
  564.  raw();
  565. #endif
  566. #if defined(USE_EXTCURSES)
  567.  extended(FALSE);
  568. #endif
  569. #if defined(DOS) || defined(OS2)
  570.  raw_output(TRUE);
  571. #endif
  572.  nonl();
  573.  noecho();
  574. #if !defined(NO_KEYPAD)
  575.  keypad(stdscr,TRUE);
  576. #endif
  577. /*---------------------------------------------------------------------*/
  578. /* Set up default colours for each window component.                   */
  579. /*---------------------------------------------------------------------*/
  580.  set_default_colours();
  581. /*---------------------------------------------------------------------*/
  582. /* We are now finished with profile commands.                          */
  583. /*---------------------------------------------------------------------*/
  584.  in_profile = FALSE;
  585. /*---------------------------------------------------------------------*/
  586. /* Call insertmode command to set default mode to whatever the current */
  587. /* setting is. If set in profile, could be anything.                   */
  588. /* Run AFTER initscr() as it uses curs_set().                          */
  589. /*---------------------------------------------------------------------*/
  590.  Insertmode(mode_insert ? (char *)"ON" : (char *)"OFF");
  591. /*---------------------------------------------------------------------*/
  592. /* Allocate memory to cmd_rec and set it to blanks.                    */
  593. /* This is done here so that COLS is valid; set up by initscr().       */
  594. /*---------------------------------------------------------------------*/
  595.  if ((cmd_rec = (char *)malloc((COLS+1)*sizeof(char))) == NULL)
  596.     exit_clean(1);
  597.  memset(cmd_rec,' ',COLS);
  598.  cmd_rec_len = 0;
  599. /*---------------------------------------------------------------------*/
  600. /* Set up screen default sizes.                                        */
  601. /*---------------------------------------------------------------------*/
  602.  set_screen_defaults();
  603. /*---------------------------------------------------------------------*/
  604. /* For each file being edited, set up the curses windows for each of  */
  605. /* them.                                                               */
  606. /*---------------------------------------------------------------------*/
  607.  CURRENT_VIEW = CURRENT_SCREEN.screen_view = vd_first;
  608.  while(CURRENT_VIEW != NULL)
  609.    {
  610.     if (set_up_windows() != RC_OK)
  611.        exit_clean(1);
  612.     CURRENT_VIEW = CURRENT_VIEW->next;
  613.    }
  614.  CURRENT_VIEW = CURRENT_SCREEN.screen_view = vd_first;
  615.  pre_process_line(CURRENT_VIEW->focus_line);
  616.  CURRENT_VIEW->current_window = WINDOW_COMMAND;
  617. /*---------------------------------------------------------------------*/
  618. /* Set up the other "global" windows.                                  */
  619. /*---------------------------------------------------------------------*/
  620.  foot = newwin(1,COLS,LINES-1,0);
  621.  error_window = newwin(1,COLS,LINES-1,0);
  622.  divider = newwin(LINES-1,2,0,(COLS/2)-1);
  623.  wattrset(foot,colour[ATTR_STATAREA]);
  624.  wattrset(error_window,colour[ATTR_MSGLINE]);
  625.  wattrset(divider,colour[ATTR_DIVIDER]);
  626.  
  627.  clear_footing();
  628.  wmove(divider,0,0);
  629.  for (i=0;i<LINES-1;i++)
  630.     mvwaddstr(divider,i,0,"||");
  631. /*---------------------------------------------------------------------*/
  632. /* This is where it all happens.                                       */
  633. /*---------------------------------------------------------------------*/
  634.  editor();
  635. /*---------------------------------------------------------------------*/
  636. /* Finalise rexx support if appropriate.                               */
  637. /*---------------------------------------------------------------------*/
  638. #if !defined(NOREXX)
  639.  finalise_rexx();
  640. #endif
  641. /*---------------------------------------------------------------------*/
  642. /* Get rid of any temporary directory file or REXX capture file.       */
  643. /*---------------------------------------------------------------------*/
  644.  strcpy(sp_path,dir_pathname);
  645.  strcat(sp_path,dir_filename);
  646.  remove_file(sp_path);
  647.  
  648. #if !defined(NOREXX)
  649.  strcpy(sp_path,rexx_pathname);
  650.  strcat(sp_path,rexx_filename);
  651.  remove_file(sp_path);
  652. #endif
  653. /*---------------------------------------------------------------------*/
  654. /* Free up the dynamically allocated memory.                           */
  655. /*---------------------------------------------------------------------*/
  656.  if (first_define != NULL)
  657.     first_define = dll_free(first_define);
  658. #if !defined(NOREXX)
  659.  if (first_prefix_synonym != NULL)
  660.     first_prefix_synonym = lll_free(first_prefix_synonym);
  661. #endif
  662.  free(last_target);
  663.  free(rec);
  664.  free(cmd_rec);
  665. /*---------------------------------------------------------------------*/
  666. /* Free memory for temp_params and tmp_cmd                             */
  667. /*---------------------------------------------------------------------*/
  668.  free_temp_space(TEMP_PARAM);
  669.  free_temp_space(TEMP_MACRO);
  670.  free_temp_space(TEMP_TEMP_CMD);
  671.  free_temp_space(TEMP_TMP_CMD);
  672.  
  673.  if (prf != (char*)NULL)
  674.     free(prf);
  675.  if (prf_arg != (char*)NULL)
  676.     free(prf_arg);
  677.  add_to_recovery_list(NULL,(-1));      /* frees up memory for recovery */
  678.  
  679. #if defined(UNIX) || defined(OS2)
  680.  free(spooler_name);
  681. #endif
  682.  
  683.  delwin(divider);
  684.  delwin(error_window);
  685. /*---------------------------------------------------------------------*/
  686. /* If the user wants a clearscreen done before exiting, do it...       */
  687. /*---------------------------------------------------------------------*/
  688.  if (CLEARSCREENx)
  689.    {
  690.     wclear(stdscr);
  691.     move(0,0);
  692.     attrset(A_NORMAL);
  693.     refresh();
  694.    }
  695.  else
  696. /*---------------------------------------------------------------------*/
  697. /* ...otherwise, get the cursor to the bottom line.                    */
  698. /*---------------------------------------------------------------------*/
  699.    {
  700.     wattrset(foot,A_NORMAL);
  701.     mvwaddstr(foot,0,0,"THE - END");
  702.     wrefresh(foot);
  703.    }
  704.  delwin(foot);
  705.  exit_clean(0);
  706. }
  707. /***********************************************************************/
  708. #ifdef PROTO
  709. void init_signals(void)
  710. #else
  711. void init_signals()
  712. #endif
  713. /***********************************************************************/
  714. {
  715. /*--------------------------- local data ------------------------------*/
  716. /*--------------------------- processing ------------------------------*/
  717. #ifdef TRACE
  718.  trace_function("the.c:     init_signals");
  719. #endif
  720. #ifdef UNIX
  721.  signal(SIGQUIT,handle_signal);
  722.  signal(SIGHUP,handle_signal);
  723.  signal(SIGABRT,handle_signal);
  724.  signal(SIGFPE,handle_signal);
  725.  signal(SIGSEGV,handle_signal);
  726.  signal(SIGINT,handle_signal);
  727.  signal(SIGTERM,handle_signal);
  728. #if defined(SIGBUS)
  729.  signal(SIGBUS,handle_signal);
  730. #endif
  731. #endif
  732. #ifdef TRACE
  733.  trace_return();
  734. #endif
  735.  return;
  736. }
  737. #ifdef UNIX
  738. /***********************************************************************/
  739. #ifdef PROTO
  740. void handle_signal(int err)
  741. #else
  742. void handle_signal(err)
  743. int err;
  744. #endif
  745. /***********************************************************************/
  746. {
  747. /*--------------------------- local data ------------------------------*/
  748. /*--------------------------- processing ------------------------------*/
  749. #ifdef TRACE
  750.  trace_function("the.c:     handle_signal");
  751. #endif
  752.  endwin();
  753.  fprintf(stderr,"\nTHE terminated with signal: %d\n\n",err);
  754.  exit_clean(2);
  755. }
  756. #endif
  757. /***********************************************************************/
  758. #ifdef PROTO
  759. void display_info(char *argv0)
  760. #else
  761. void display_info(argv0)
  762. char *argv0;
  763. #endif
  764. /***********************************************************************/
  765. {
  766. /*--------------------------- local data ------------------------------*/
  767. /*--------------------------- processing ------------------------------*/
  768.  
  769.  fprintf(stderr,"\nTHE %s Copyright (C) 1991-1993 Mark Hessling. All rights reserved.\n",the_version);
  770.  fprintf(stderr,"THE is distributed under the terms of the GNU General Public License \n");
  771.  fprintf(stderr,"and comes with NO WARRANTY. See the file COPYING for details.\n");
  772.  fprintf(stderr,"\nUsage:\n\n%s [-h?nms] [-p profile] [-a profile_arg] [-w width] [[dir] [file [...]]]\n",argv0);
  773.  fprintf(stderr,"\nwhere:\n\n");
  774.  fprintf(stderr,"-h,-?                  show this message\n");
  775.  fprintf(stderr,"-n                     do not execute a profile file\n");
  776.  fprintf(stderr,"-m                     force display into mono\n");
  777.  fprintf(stderr,"-s                     turn off signal trapping (Unix only)\n");
  778.  fprintf(stderr,"-p profile             filename of profile file\n");
  779.  fprintf(stderr,"-a profile_arg         argument(s) to profile file (only with REXX)\n");
  780.  fprintf(stderr,"-w width               maximum width of line (default 2048)\n");
  781.  fprintf(stderr,"[dir [file [...]]]     file(s) and/or directory to be edited\n\n");
  782.  fflush(stderr);
  783.  return;
  784. }
  785. /***********************************************************************/
  786. #ifdef PROTO
  787. void exit_clean(short err_num)
  788. #else
  789. void exit_clean(err_num)
  790. short err_num;
  791. #endif
  792. /***********************************************************************/
  793. {
  794. /*-------------------------- external data ----------------------------*/
  795. extern bool CLEARSCREENx;
  796. /*--------------------------- local data ------------------------------*/
  797. #ifdef DOS
  798. char get_mode(void);
  799. #endif
  800. /*--------------------------- processing ------------------------------*/
  801. #ifdef TRACE
  802.  trace_function("the.c:     exit_clean");
  803. #endif
  804.  
  805.  if (curses_started)
  806.    {
  807.     mode_insert=NO;
  808.     draw_cursor(ON);
  809. #ifdef BSD
  810.     nl();
  811.     echo();
  812. #endif
  813.     endwin();
  814.    }
  815.  if (!CLEARSCREENx)
  816.     printf("\n");
  817.  if (file_exists(tempfilename))
  818.     remove_file(tempfilename);
  819. #ifdef TRACE
  820.  trace_return();
  821. #endif
  822.  exit(err_num);
  823. }
  824.