home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / TDE31.ZIP / MAIN.C < prev    next >
C/C++ Source or Header  |  1993-08-29  |  15KB  |  533 lines

  1. /*******************  start of original comments  ********************/
  2. /*
  3.  * Written by Douglas Thomson (1989/1990)
  4.  *
  5.  * This source code is released into the public domain.
  6.  */
  7.  
  8. /*
  9.  * Name:    dte - Doug's Text Editor program - hardware dependent module
  10.  * Purpose: This file contains all the code that needs to be different on
  11.  *           different hardware.
  12.  * File:    hwibm.c
  13.  * Author:  Douglas Thomson
  14.  * System:  This particular version is for the IBM PC and close compatibles.
  15.  *           It write directly to video RAM, so it is faster than other
  16.  *           techniques, but will cause "snow" on most CGA cards. See the
  17.  *           file "hwibmcga.c" for a version that avoids snow.
  18.  *          The compiler is Turbo C 2.0, using one of the large data memory
  19.  *           models.
  20.  * Date:    October 10, 1989
  21.  * Notes:   This module has been kept as small as possible, to facilitate
  22.  *           porting between different systems.
  23.  */
  24. /*********************  end of original comments   ********************/
  25.  
  26.  
  27. /*
  28.  * These routines were rewritten for Microsoft C.  They are pretty much system
  29.  * dependent and pretty much Microsoft C dependent.  I also renamed this file
  30.  * "main.c" - easier to find the main function.
  31.  *
  32.  * New editor name:  TDE, the Thomson-Davis Editor.
  33.  * Author:           Frank Davis
  34.  * Date:             June 5, 1991, version 1.0
  35.  * Date:             July 29, 1991, version 1.1
  36.  * Date:             October 5, 1991, version 1.2
  37.  * Date:             January 20, 1992, version 1.3
  38.  * Date:             February 17, 1992, version 1.4
  39.  * Date:             April 1, 1992, version 1.5
  40.  * Date:             June 5, 1992, version 2.0
  41.  * Date:             October 31, 1992, version 2.1
  42.  * Date:             April 1, 1993, version 2.2
  43.  * Date:             June 5, 1993, version 3.0
  44.  * Date:             August 29, 1993, version 3.1
  45.  *
  46.  * This modification of Douglas Thomson's code is released into the
  47.  * public domain, Frank Davis.  You may distribute it freely.
  48.  */
  49.  
  50.  
  51. char *greatest_composer_ever = "W. A. Mozart, 1756-1791";
  52.  
  53.  
  54. #include "tdestr.h"             /* tde types */
  55. #include "common.h"
  56. #include "define.h"
  57. #include "help.h"
  58. #include "tdefunc.h"
  59.  
  60.  
  61. #include <dos.h>                /* for renaming files */
  62. #include <bios.h>               /* for direct BIOS keyboard input */
  63. #include <io.h>                 /* for file attribute code */
  64. #include <fcntl.h>              /* open flags */
  65. #if defined( __MSC__ )
  66.    #include <errno.h>
  67.    #include <sys\types.h>       /* S_IWRITE etc */
  68. #endif
  69. #include <sys\stat.h>           /* S_IWRITE etc */
  70.  
  71. #if defined( __MSC__ )
  72. void (interrupt far *old_control_c)( ); /* variable for old CNTL-C */
  73. void (interrupt far *old_int1b)( );     /* variable for old int 1b */
  74. #endif
  75.  
  76.  
  77. /*
  78.  * original control-break checking flag
  79.  */
  80. static int s_cbrk;
  81.  
  82.  
  83. /*
  84.  * Name:    main
  85.  * Purpose: To do any system dependent command line argument processing,
  86.  *           and then call the main editor function.
  87.  * Date:    October 10, 1989
  88.  * Passed:  argc:   number of command line arguments
  89.  *          argv:   text of command line arguments
  90.  */
  91. void main( int argc, char *argv[] )
  92. {
  93. #if defined( __MSC__ )
  94.    union REGS inregs, outregs;
  95. #endif
  96.  
  97.    g_status.found_first = FALSE;
  98.    g_status.arg         = 1;
  99.    g_status.argc        = argc;
  100.    g_status.argv        = argv;
  101.  
  102.    /*
  103.     * trap control-break to make it harmless, and turn checking off.
  104.     *   trap control-C to make it harmless.
  105.     */
  106. #if defined( __MSC__ )
  107.    inregs.h.ah = 0x33;
  108.    inregs.h.al = 0;
  109.    intdos( &inregs, &outregs );
  110.    s_cbrk = outregs.h.dl;
  111.    old_control_c = _dos_getvect( (unsigned)0x23 );
  112.    _dos_setvect( 0x23, harmless );
  113.    old_int1b = _dos_getvect( (unsigned)0x1b );
  114.    _dos_setvect( 0x1b, ctrl_break );
  115.    inregs.h.ah = 0x33;
  116.    inregs.h.al = 1;
  117.    inregs.h.dl = 0;
  118.    intdos( &inregs, &outregs );
  119. #else
  120.    s_cbrk = getcbrk( );
  121.    ctrlbrk( harmless );
  122.    setcbrk( 0 );
  123. #endif
  124.  
  125.  
  126.    /*
  127.     * now, install and initialize our simple Critical Error Handler.
  128.     */
  129.    install_ceh( &ceh );
  130.    ceh.flag = OK;
  131.  
  132.    initialize( );
  133.    editor( );
  134.    terminate( );
  135. }
  136.  
  137.  
  138. /*
  139.  * Name:    error
  140.  * Purpose: To report an error, and usually make the user type <ESC> before
  141.  *           continuing.
  142.  * Date:    June 5, 1991
  143.  * Passed:  kind:   an indication of how serious the error was:
  144.  *                      WARNING: continue after pressing a key
  145.  *                      FATAL:   abort the editor
  146.  *          line:    line to display message
  147.  *          message: string to be printed
  148.  * Notes:   Show user the message and ask for a key if needed.
  149.  */
  150. void error( int kind, int line, char *message )
  151. {
  152. char buff[MAX_COLS+2];          /* somewhere to store error before printing */
  153. char line_buff[(MAX_COLS+2)*2]; /* buffer for char and attribute  */
  154.  
  155.    /*
  156.     * tell the user what kind of an error it is
  157.     */
  158.    switch (kind) {
  159.       case FATAL:
  160.          /*
  161.           * fatal error
  162.           */
  163.          assert( strlen( main1 ) < MAX_COLS );
  164.          strcpy( buff, main1 );
  165.          break;
  166.      case WARNING:
  167.      default:
  168.          /*
  169.           * warning
  170.           */
  171.          assert( strlen( main2 ) < MAX_COLS );
  172.          strcpy( buff, main2 );
  173.          break;
  174.    }
  175.  
  176.    /*
  177.     * prepare the error message itself
  178.     */
  179.    strcat( buff, message );
  180.  
  181.    /*
  182.     * tell the user how to continue editing if necessary
  183.     */
  184.    if (kind == WARNING)
  185.       /*
  186.        * press a key
  187.        */
  188.       strcat( buff, main3 );
  189.  
  190.    /*
  191.     * output the error message
  192.     */
  193.    save_screen_line( 0, line, line_buff );
  194.    set_prompt( buff, line );
  195.  
  196.    if (kind == FATAL) {
  197.       /*
  198.        * no point in making the user type <ESC>, since the program is
  199.        *  about to abort anyway...
  200.        */
  201.       terminate( );
  202.       exit( 1 );
  203.    }
  204.  
  205.    getkey( );
  206.    restore_screen_line( 0, line, line_buff );
  207.    if (g_status.wrapped) {
  208.       g_status.wrapped = FALSE;
  209.       show_search_message( CLR_SEARCH, g_display.mode_color );
  210.    }
  211. }
  212.  
  213.  
  214. /*
  215.  * Name:    harmless
  216.  * Purpose: Do nothing when control-C is pressed
  217.  * Date:    June 5, 1991
  218.  * Notes:   Interrupt 23, the Control-C handler, is a MS DOS system function.
  219.  *            Since we want to use Control-C as a regular function key,
  220.  *            let's do absolutely nothing when Control-C is pressed.
  221.  */
  222. #if defined( __MSC__ )
  223. void interrupt far harmless( void )
  224. #else
  225. static int harmless( void )
  226. #endif
  227. {
  228. }
  229.  
  230.  
  231. /*
  232.  * Name:    ctrl_break
  233.  * Purpose: Set our control-break flag when control-break is pressed.
  234.  * Date:    June 5, 1992
  235.  * Notes:   Control-break is a little different from Control-C.  When
  236.  *           Control-C is pressed, MS DOS processes it as soon as possible,
  237.  *           which may be quite a while.  On the other hand, when
  238.  *           Control-break is pressed on IBM and compatibles, interrupt 0x1b
  239.  *           is generated immediately.  Since an interrupt is generated
  240.  *           immediately, we can gain control of run-away functions, like
  241.  *           recursive macros, by checking our Control-break flag.
  242.  */
  243. void interrupt far ctrl_break( void )
  244. {
  245.    g_status.control_break = TRUE;
  246. }
  247.  
  248.  
  249. /*
  250.  * Name:    terminate
  251.  * Purpose: To free all dynamic structures and unload anything we loaded
  252.  * Date:    June 5, 1991
  253.  */
  254. void terminate( void )
  255. {
  256. union REGS inregs, outregs;
  257. register WINDOW     *wp;        /* register for scanning windows */
  258. WINDOW              *w;         /* free window */
  259. register file_infos *fp;        /* register for scanning files */
  260. file_infos          *f;         /* free files */
  261. int                 i;
  262.  
  263.    /*
  264.     * restore control-break checking
  265.     */
  266. #if defined( __MSC__ )
  267.    _dos_setvect( 0x1b, old_int1b );
  268.    _dos_setvect( 0x23, old_control_c );
  269.    inregs.h.ah = 0x33;
  270.    inregs.h.al = 1;
  271.    inregs.h.dl = (char)s_cbrk;
  272.    intdos( &inregs, &outregs );
  273. #else
  274.    setcbrk( s_cbrk );
  275. #endif
  276.  
  277.    /*
  278.     * free the file structures, if not already free.
  279.     */
  280.    fp = g_status.file_list;
  281.    while (fp != NULL) {
  282.       f  = fp;
  283.       fp = fp->next;
  284.       free( f );
  285.    }
  286.  
  287.    /*
  288.     * free the window structures, if not already free.
  289.     */
  290.    wp = g_status.window_list;
  291.    while (wp != NULL) {
  292.       w  = wp;
  293.       wp = wp->next;
  294.       free( w );
  295.    }
  296.  
  297.  
  298.    /*
  299.     * free any character classes in the nfa's.
  300.     */
  301.    for (i=0; i < REGX_SIZE; i++) {
  302.       if (sas_nfa.class[i] == nfa.class[i]  &&  nfa.class[i] != NULL)
  303.          free( nfa.class[i] );
  304.       else if (sas_nfa.class[i] != NULL)
  305.          free( sas_nfa.class[i] );
  306.       else if (nfa.class[i] != NULL)
  307.          free( nfa.class[i] );
  308.    }
  309.  
  310.  
  311.    /*
  312.     * reset the cursor size and unload the 83/84 key keyboard utility
  313.     */
  314.    set_cursor_size( mode.cursor_size == SMALL_INS ? g_display.insert_cursor :
  315.                                                     g_display.overw_cursor );
  316.    if (mode.enh_kbd == FALSE)
  317.       simulate_enh_kbd( 0 );
  318.  
  319.    /*
  320.     * restore the overscan (border) color
  321.     */
  322.    if (g_display.adapter != MDA)
  323.       set_overscan_color( g_display.old_overscan );
  324. }
  325.  
  326.  
  327. /*
  328.  * Name:    initialize
  329.  * Purpose: To initialize all the screen status info that is not hardware
  330.  *           dependent, and call the hardware initialization routine to
  331.  *           pick up the hardware dependent stuff.
  332.  * Date:    June 5, 1991
  333.  * Returns: [g_status and g_display]: all set up ready to go
  334.  * Notes:   It is assumed that g_status and g_display are all \0's to begin
  335.  *           with (the default if they use static storage). If this may
  336.  *           not be the case, then clear them explicitly here.
  337.  */
  338. void initialize( void )
  339. {
  340. int i;
  341.  
  342.    /*
  343.     * do the hardware initialization first.
  344.     */
  345.    hw_initialize( );
  346.  
  347.    /*
  348.     * now, initialize the editor modes, pointers, and counters.
  349.     */
  350.    bm.search_defined        = ERROR;
  351.    sas_bm.search_defined    = ERROR;
  352.    g_status.sas_defined     = ERROR;
  353.    g_status.sas_search_type = ERROR;
  354.  
  355.    regx.search_defined      = ERROR;
  356.    sas_regx.search_defined  = ERROR;
  357.  
  358.    if (mode.undo_max < 2)
  359.       mode.undo_max = 2;
  360.  
  361.    g_status.marked_file = NULL;
  362.    g_status.current_window = NULL;
  363.    g_status.current_file = NULL;
  364.    g_status.window_list = NULL;
  365.    g_status.file_list = NULL;
  366.    g_status.buff_node = NULL;
  367.  
  368.    g_status.window_count = 0;
  369.    g_status.file_count = 0;
  370.    g_status.line_buff_len = 0;
  371.    g_status.tabout_buff_len = 0;
  372.    g_status.command = 0;
  373.    g_status.key_pressed = 0;
  374.    g_status.sas_rcol  = 0;
  375.    g_status.sas_rline = 0;
  376.    g_status.recording_key = 0;
  377.  
  378.    g_status.key_pending = FALSE;
  379.    g_status.found_first = FALSE;
  380.    g_status.sas_found_first = FALSE;
  381.    g_status.copied = FALSE;
  382.    g_status.wrapped = FALSE;
  383.    g_status.marked = FALSE;
  384.    g_status.macro_executing = FALSE;
  385.    g_status.replace_defined = FALSE;
  386.  
  387.    g_status.screen_display = TRUE;
  388.  
  389.    g_status.file_chunk = DEFAULT_BIN_LENGTH;
  390.  
  391.    g_status.sas_tokens[0] = '\0';
  392.    g_status.path[0] = '\0';
  393.    g_status.sas_path[0] = '\0';
  394.    g_status.rw_name[0] = '\0';
  395.    g_status.pattern[0] = '\0';
  396.    g_status.subst[0] = '\0';
  397.  
  398.  
  399.    /*
  400.     * set the number of lines from one page that should still be visible
  401.     *  on the next page after page up or page down.
  402.     */
  403.    g_status.overlap = 1;
  404.  
  405.  
  406.    /*
  407.     * initialize the nodes in the nfa.
  408.     */
  409.    for (i=0; i < REGX_SIZE; i++) {
  410.       sas_nfa.node_type[i] = nfa.node_type[i] = 0;
  411.       sas_nfa.term_type[i] = nfa.term_type[i] = 0;
  412.       sas_nfa.c[i] = nfa.c[i] = 0;
  413.       sas_nfa.next1[i] = nfa.next1[i] = 0;
  414.       sas_nfa.next2[i] = nfa.next2[i] = 0;
  415.       sas_nfa.class[i] = nfa.class[i] = NULL;
  416.    }
  417.  
  418.    /*
  419.     * no macro is executing
  420.     */
  421.    connect_macros( );
  422.  
  423.  
  424.    /*
  425.     * clear the screen and show the author's names
  426.     */
  427.    cls( );
  428.    show_credits( );
  429. }
  430.  
  431.  
  432. /*
  433.  * Name:    hw_initialize
  434.  * Purpose: To initialize the display ready for editor use.
  435.  * Date:    June 5, 1991
  436.  */
  437. void hw_initialize( void )
  438. {
  439. struct vcfg cfg;       /* defined in .h */
  440. register int *clr;
  441.  
  442.    /*
  443.     * set up screen size
  444.     */
  445.    g_display.ncols     = MAX_COLS;
  446.    g_display.nlines    = MAX_LINES - 1;
  447.    g_display.mode_line = MAX_LINES;
  448.    g_display.line_length = MAX_LINE_LENGTH;
  449.  
  450.    /*
  451.     * work out what kind of display is in use, and set attributes and
  452.     *  display address accordingly. Note that this will only work with
  453.     *  close IBM compatibles.
  454.     */
  455.  
  456.    video_config( &cfg );
  457.    g_display.display_address = (char far *)cfg.videomem;
  458.  
  459.    /*
  460.     * Use an integer pointer to go thru the color array for setting up the
  461.     * various color fields.
  462.     */
  463.    clr =  cfg.color == FALSE ? &colour.clr[0][0] : &colour.clr[1][0];
  464.  
  465.    g_display.head_color    = *clr++;
  466.    g_display.text_color    = *clr++;
  467.    g_display.dirty_color   = *clr++;
  468.    g_display.mode_color    = *clr++;
  469.    g_display.block_color   = *clr++;
  470.    g_display.message_color = *clr++;
  471.    g_display.help_color    = *clr++;
  472.    g_display.diag_color    = *clr++;
  473.    g_display.eof_color     = *clr++;
  474.    g_display.curl_color    = *clr++;
  475.    g_display.ruler_color   = *clr++;
  476.    g_display.ruler_pointer = *clr++;
  477.    g_display.hilited_file  = *clr++;
  478.    g_display.overscan      = *clr;
  479.  
  480.    /*
  481.     * set the overscan color.
  482.     * in terminate( ), the overscan color is returned to old state.
  483.     */
  484.    if (g_display.adapter != MDA)
  485.       set_overscan_color( g_display.overscan );
  486. }
  487.  
  488.  
  489. /*
  490.  * Name:    get_help
  491.  * Purpose: save the screen and display key definitions
  492.  * Date:    June 5, 1991
  493.  * Notes:   This routine is dependent on the length of the strings in the
  494.  *          help screen.  To make it easy to load in a new help screen,
  495.  *          the strings are assumed to be 80 characters long followed by
  496.  *          the '\0' character.  It is assumed each that string contains
  497.  *          exactly 81 characters.
  498.  */
  499. int  get_help( WINDOW *window )
  500. {
  501. register char *help;
  502. register int line;
  503.  
  504.    xygoto( -1, -1 );
  505.    help = help_screen[1];
  506.    for (line=0; help != NULL; line++) {
  507.       s_output( help, line, 0, g_display.help_color );
  508.       help = help_screen[line+2];
  509.    }
  510.    line = getkey( );
  511.    redraw_screen( window );
  512.    return( OK );
  513. }
  514.  
  515.  
  516. /*
  517.  * Name:    show_credits
  518.  * Purpose: display authors
  519.  * Date:    June 5, 1991
  520.  */
  521. void show_credits( void )
  522. {
  523. register char *credit;
  524. int  line;
  525.  
  526.    xygoto( -1, -1 );
  527.    credit = credit_screen[0];
  528.    for (line=0; credit != NULL; ) {
  529.       s_output( credit, line+2, 11, g_display.text_color );
  530.       credit = credit_screen[++line];
  531.    }
  532. }
  533.