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