home *** CD-ROM | disk | FTP | other *** search
- /******************* start of original comments ********************/
- /*
- * Written by Douglas Thomson (1989/1990)
- *
- * This source code is released into the public domain.
- */
-
- /*
- * Name: dte - Doug's Text Editor program - hardware dependent module
- * Purpose: This file contains all the code that needs to be different on
- * different hardware.
- * File: hwibm.c
- * Author: Douglas Thomson
- * System: This particular version is for the IBM PC and close compatibles.
- * It write directly to video RAM, so it is faster than other
- * techniques, but will cause "snow" on most CGA cards. See the
- * file "hwibmcga.c" for a version that avoids snow.
- * The compiler is Turbo C 2.0, using one of the large data memory
- * models.
- * Date: October 10, 1989
- * Notes: This module has been kept as small as possible, to facilitate
- * porting between different systems.
- */
- /********************* end of original comments ********************/
-
-
- /*
- * These routines were rewritten for Microsoft C. They are pretty much system
- * dependent and pretty much Microsoft C dependent. I also renamed this file
- * "main.c" - easier to find the main function.
- *
- * New editor name: TDE, the Thomson-Davis Editor.
- * Author: Frank Davis
- * Date: June 5, 1991, version 1.0
- * Date: July 29, 1991, version 1.1
- * Date: October 5, 1991, version 1.2
- * Date: January 20, 1992, version 1.3
- * Date: February 17, 1992, version 1.4
- * Date: April 1, 1992, version 1.5
- * Date: June 5, 1992, version 2.0
- * Date: October 31, 1992, version 2.1
- * Date: April 1, 1993, version 2.2
- * Date: June 5, 1993, version 3.0
- * Date: August 29, 1993, version 3.1
- * Date: November 13, 1993, version 3.2
- *
- * This modification of Douglas Thomson's code is released into the
- * public domain, Frank Davis. You may distribute it freely.
- */
-
-
- char *greatest_composer_ever = "W. A. Mozart, 1756-1791";
-
-
- #include "tdestr.h" /* tde types */
- #include "common.h"
- #include "define.h"
- #include "help.h"
- #include "tdefunc.h"
-
-
- #include <fcntl.h> /* open flags */
- #if defined( __UNIX__ )
- #include <signal.h> /* unix critical errors */
- #else
- #include <dos.h> /* for renaming files */
- #include <bios.h> /* for direct BIOS keyboard input */
- #include <io.h> /* for file attribute code */
- #if defined( __MSC__ )
- #include <errno.h>
- #include <sys\types.h> /* S_IWRITE etc */
- #endif
- #include <sys\stat.h> /* S_IWRITE etc */
- #endif
-
- #if defined( __MSC__ )
- void (interrupt FAR *old_control_c)( ); /* variable for old CNTL-C */
- void (interrupt FAR *old_int1b)( ); /* variable for old int 1b */
- #endif
-
-
- /*
- * original control-break checking flag
- */
- static int s_cbrk;
-
-
- /*
- * Name: main
- * Purpose: To do any system dependent command line argument processing,
- * and then call the main editor function.
- * Date: October 10, 1989
- * Passed: argc: number of command line arguments
- * argv: text of command line arguments
- */
- void main( int argc, char *argv[] )
- {
- #if defined( __MSC__ )
- union REGS inregs, outregs;
- #endif
-
- g_status.found_first = FALSE;
- g_status.arg = 1;
- g_status.argc = argc;
- g_status.argv = argv;
-
- #if defined( __UNIX__ )
-
- /*
- * unix signals are kinda analagous to DOS critical errors.
- */
- /*
- signal( SIGABRT, crit_err_handler );
- signal( SIGALRM, crit_err_handler );
- signal( SIGCHLD, crit_err_handler );
- signal( SIGCONT, crit_err_handler );
- signal( SIGFPE, crit_err_handler );
- signal( SIGHUP, crit_err_handler );
- signal( SIGILL, crit_err_handler );
- signal( SIGINT, crit_err_handler );
- signal( SIGIO, crit_err_handler );
- signal( SIGIOT, crit_err_handler );
- signal( SIGKILL, crit_err_handler );
- signal( SIGPIPE, crit_err_handler );
- signal( SIGPOLL, crit_err_handler );
- signal( SIGPWR, crit_err_handler );
- signal( SIGQUIT, crit_err_handler );
- signal( SIGSEGV, crit_err_handler );
- signal( SIGSTOP, crit_err_handler );
- signal( SIGTERM, crit_err_handler );
- signal( SIGTRAP, crit_err_handler );
- signal( SIGTSTP, crit_err_handler );
- signal( SIGTTIN, crit_err_handler );
- signal( SIGTTOU, crit_err_handler );
- signal( SIGURG, crit_err_handler );
- signal( SIGUSR1, crit_err_handler );
- signal( SIGUSR2, crit_err_handler );
- signal( SIGVTALRM, crit_err_handler );
- signal( SIGWINCH, crit_err_handler );
- signal( SIGXCPU, crit_err_handler );
- signal( SIGXFSZ, crit_err_handler );
- */
- #else
- /*
- * trap control-break to make it harmless, and turn checking off.
- * trap control-C to make it harmless.
- */
- # if defined( __MSC__ )
- inregs.h.ah = 0x33;
- inregs.h.al = 0;
- intdos( &inregs, &outregs );
- s_cbrk = outregs.h.dl;
- old_control_c = _dos_getvect( (unsigned)0x23 );
- _dos_setvect( 0x23, harmless );
- old_int1b = _dos_getvect( (unsigned)0x1b );
- _dos_setvect( 0x1b, ctrl_break );
- inregs.h.ah = 0x33;
- inregs.h.al = 1;
- inregs.h.dl = 0;
- intdos( &inregs, &outregs );
- # else
- s_cbrk = getcbrk( );
- ctrlbrk( harmless );
- setcbrk( 0 );
- # endif
-
- /*
- * now, install and initialize our simple Critical Error Handler.
- */
- install_ceh( &ceh );
- #endif
-
- ceh.flag = OK;
-
- if (initialize( ) != ERROR)
- editor( );
- terminate( );
- }
-
-
- /*
- * Name: error
- * Purpose: To report an error, and usually make the user type <ESC> before
- * continuing.
- * Date: June 5, 1991
- * Passed: kind: an indication of how serious the error was:
- * WARNING: continue after pressing a key
- * FATAL: abort the editor
- * line: line to display message
- * message: string to be printed
- * Notes: Show user the message and ask for a key if needed.
- */
- void error( int kind, int line, char *message )
- {
- char buff[MAX_COLS+2]; /* somewhere to store error before printing */
- #if defined( __UNIX__ )
- chtype display_buff[MAX_COLS+2]; /* chtype is defined in curses.h */
- #else
- char display_buff[(MAX_COLS+2)*2];
- #endif
-
- /*
- * tell the user what kind of an error it is
- */
- switch (kind) {
- case FATAL:
- /*
- * fatal error
- */
- assert( strlen( main1 ) < (size_t)g_display.ncols );
- strcpy( buff, main1 );
- break;
- case WARNING:
- default:
- /*
- * warning
- */
- assert( strlen( main2 ) < (size_t)g_display.ncols );
- strcpy( buff, main2 );
- break;
- }
-
- /*
- * prepare the error message itself
- */
- strcat( buff, message );
-
- /*
- * tell the user how to continue editing if necessary
- */
- if (kind == WARNING)
- /*
- * press a key
- */
- strcat( buff, main3 );
-
- /*
- * output the error message
- */
- save_screen_line( 0, line, display_buff );
- set_prompt( buff, line );
-
- if (kind == FATAL) {
- /*
- * no point in making the user type <ESC>, since the program is
- * about to abort anyway...
- */
- terminate( );
- exit( 1 );
- }
-
- getkey( );
- restore_screen_line( 0, line, display_buff );
- if (g_status.wrapped) {
- g_status.wrapped = FALSE;
- show_search_message( CLR_SEARCH, g_display.mode_color );
- }
- }
-
-
- /*
- * Name: harmless
- * Purpose: Do nothing when control-C is pressed
- * Date: June 5, 1991
- * Notes: Interrupt 23, the Control-C handler, is a MS DOS system function.
- * Since we want to use Control-C as a regular function key,
- * let's do absolutely nothing when Control-C is pressed.
- */
- #if defined( __UNIX__ )
- void harmless( void )
- #else
- #if defined( __MSC__ )
- void interrupt FAR harmless( void )
- #else
- static int harmless( void )
- #endif
- #endif
- {
- }
-
-
- /*
- * Name: ctrl_break
- * Purpose: Set our control-break flag when control-break is pressed.
- * Date: June 5, 1992
- * Notes: Control-break is a little different from Control-C. When
- * Control-C is pressed, MS DOS processes it as soon as possible,
- * which may be quite a while. On the other hand, when
- * Control-break is pressed on IBM and compatibles, interrupt 0x1b
- * is generated immediately. Since an interrupt is generated
- * immediately, we can gain control of run-away functions, like
- * recursive macros, by checking our Control-break flag.
- */
- #if !defined( __UNIX__ )
- void interrupt FAR ctrl_break( void )
- {
- g_status.control_break = TRUE;
- }
- #endif
-
-
- /*
- * Name: terminate
- * Purpose: To free all dynamic structures and unload anything we loaded
- * Date: June 5, 1991
- */
- void terminate( void )
- {
- #if !defined( __UNIX__ )
- union REGS inregs, outregs;
- #endif
- register TDE_WIN *wp; /* register for scanning windows */
- TDE_WIN *w; /* free window */
- register file_infos *fp; /* register for scanning files */
- file_infos *f; /* free files */
- int i;
-
- /*
- * restore control-break checking
- */
- #if defined( __UNIX__ )
- noraw( );
- endwin( );
-
- /*
- * if we were doing any multi-file searching, close the directory pointer
- */
- if (g_status.dp != NULL)
- closedir( g_status.dp );
- if (g_status.sas_dp != NULL)
- closedir( g_status.sas_dp );
- #elif defined( __MSC__ )
- _dos_setvect( 0x1b, old_int1b );
- _dos_setvect( 0x23, old_control_c );
- inregs.h.ah = 0x33;
- inregs.h.al = 1;
- inregs.h.dl = (char)s_cbrk;
- intdos( &inregs, &outregs );
- #else
- setcbrk( s_cbrk );
- #endif
-
- /*
- * free the file structures, if not already free.
- */
- fp = g_status.file_list;
- while (fp != NULL) {
- f = fp;
- fp = fp->next;
- free( f );
- }
-
- /*
- * free the window structures, if not already free.
- */
- wp = g_status.window_list;
- while (wp != NULL) {
- w = wp;
- wp = wp->next;
- free( w );
- }
-
-
- /*
- * free any character classes in the nfa's.
- */
- for (i=0; i < REGX_SIZE; i++) {
- if (sas_nfa.class[i] == nfa.class[i] && nfa.class[i] != NULL)
- free( nfa.class[i] );
- else if (sas_nfa.class[i] != NULL)
- free( sas_nfa.class[i] );
- else if (nfa.class[i] != NULL)
- free( nfa.class[i] );
- }
-
- #if defined( __UNIX__ )
-
- /*
- * leave residue from the editing session on the screen.
- */
- puts( "" );
- #else
- /*
- * reset the cursor size and unload the 83/84 key keyboard utility
- */
- set_cursor_size( mode.cursor_size == SMALL_INS ? g_display.insert_cursor :
- g_display.overw_cursor );
- if (mode.enh_kbd == FALSE)
- simulate_enh_kbd( 0 );
-
- /*
- * restore the overscan (border) color
- */
- if (g_display.adapter != MDA)
- set_overscan_color( g_display.old_overscan );
- #endif
- }
-
-
- /*
- * Name: initialize
- * Purpose: To initialize all the screen status info that is not hardware
- * dependent, and call the hardware initialization routine to
- * pick up the hardware dependent stuff.
- * Date: June 5, 1991
- * Returns: [g_status and g_display]: all set up ready to go
- * Notes: It is assumed that g_status and g_display are all \0's to begin
- * with (the default if they use static storage). If this may
- * not be the case, then clear them explicitly here.
- */
- int initialize( void )
- {
- int i;
- int rc;
-
- rc = OK;
- /*
- * do the hardware initialization first.
- */
- hw_initialize( );
-
- /*
- * now, initialize the editor modes, pointers, and counters.
- */
- bm.search_defined = ERROR;
- sas_bm.search_defined = ERROR;
- g_status.sas_defined = ERROR;
- g_status.sas_search_type = ERROR;
-
- regx.search_defined = ERROR;
- sas_regx.search_defined = ERROR;
-
- if (mode.undo_max < 2)
- mode.undo_max = 2;
-
- g_status.marked_file = NULL;
- g_status.current_window = NULL;
- g_status.current_file = NULL;
- g_status.window_list = NULL;
- g_status.file_list = NULL;
- g_status.buff_node = NULL;
-
- g_status.window_count = 0;
- g_status.file_count = 0;
- g_status.line_buff_len = 0;
- g_status.tabout_buff_len = 0;
- g_status.command = 0;
- g_status.key_pressed = 0;
- g_status.sas_rcol = 0;
- g_status.sas_rline = 0;
- g_status.recording_key = 0;
-
- g_status.key_pending = FALSE;
- g_status.found_first = FALSE;
- g_status.sas_found_first = FALSE;
- g_status.copied = FALSE;
- g_status.wrapped = FALSE;
- g_status.marked = FALSE;
- g_status.macro_executing = FALSE;
- g_status.replace_defined = FALSE;
-
- g_status.screen_display = TRUE;
-
- g_status.file_chunk = DEFAULT_BIN_LENGTH;
-
- g_status.sas_tokens[0] = '\0';
- g_status.path[0] = '\0';
- g_status.sas_path[0] = '\0';
- g_status.rw_name[0] = '\0';
- g_status.pattern[0] = '\0';
- g_status.subst[0] = '\0';
-
- /*
- * set the number of lines from one page that should still be visible
- * on the next page after page up or page down.
- */
- g_status.overlap = 1;
-
- #if defined( __UNIX__ )
- g_status.dp = NULL;
- g_status.sas_dp = NULL;
- #endif
-
- /*
- * initialize the nodes in the nfa.
- */
- for (i=0; i < REGX_SIZE; i++) {
- sas_nfa.node_type[i] = nfa.node_type[i] = 0;
- sas_nfa.term_type[i] = nfa.term_type[i] = 0;
- sas_nfa.c[i] = nfa.c[i] = 0;
- sas_nfa.next1[i] = nfa.next1[i] = 0;
- sas_nfa.next2[i] = nfa.next2[i] = 0;
- sas_nfa.class[i] = nfa.class[i] = NULL;
- }
-
- /*
- * no macro is executing
- */
- connect_macros( );
-
- /*
- * clear the screen and show the author's names
- */
- cls( );
- show_credits( );
- return( rc );
- }
-
-
- /*
- * Name: hw_initialize
- * Purpose: To initialize the display ready for editor use.
- * Date: June 5, 1991
- */
- void hw_initialize( void )
- {
- #if defined( __UNIX__ )
-
- int i;
- int y;
- int x;
- register int *clr;
-
- clr = &colour.clr[1][0];
-
- /*
- * if we are in a linux environment, init the curses package.
- */
- initscr( );
- keypad( stdscr, TRUE );
- cbreak( );
- noecho( );
- raw( );
- scrollok( stdscr, TRUE );
- if (has_colors( ))
- start_color( );
-
- move( 0, 0 );
- init_pair( 0, COLOR_WHITE, COLOR_BLACK );
- init_pair( 1, COLOR_WHITE, COLOR_BLUE );
- init_pair( 2, COLOR_BLUE, COLOR_BLACK );
- /* init_pair( 2, COLOR_RED, COLOR_GREEN ); */
- init_pair( 3, COLOR_YELLOW, COLOR_CYAN );
- init_pair( 4, COLOR_WHITE, COLOR_RED );
- /* init_pair( 5, COLOR_BLUE, COLOR_CYAN ); */
- init_pair( 5, COLOR_GREEN, COLOR_MAGENTA );
- /* init_pair( 6, COLOR_MAGENTA, COLOR_YELLOW ); */
- init_pair( 6, COLOR_GREEN, COLOR_BLACK );
- init_pair( 7, COLOR_BLUE, COLOR_WHITE );
-
- /*
- * lets try to emulate the PC color table. in normal color mode,
- * there are 8 background colors and 16 foreground colors.
- */
- for (i=0; i<8; i++) {
- tde_color_table[i] = COLOR_PAIR( 0 );
- tde_color_table[i+16] = COLOR_PAIR( 1 );
- tde_color_table[i+32] = COLOR_PAIR( 2 );
- tde_color_table[i+48] = COLOR_PAIR( 3 );
- tde_color_table[i+64] = COLOR_PAIR( 4 );
- tde_color_table[i+80] = COLOR_PAIR( 5 );
- tde_color_table[i+96] = COLOR_PAIR( 6 );
- tde_color_table[i+112] = COLOR_PAIR( 7 ) | A_DIM;
- }
-
- for (i=0; i<8; i++) {
- tde_color_table[i+8] = COLOR_PAIR( 0 ) | A_BOLD;
- tde_color_table[i+24] = COLOR_PAIR( 1 ) | A_BOLD;
- tde_color_table[i+40] = COLOR_PAIR( 2 ) | A_BOLD;
- tde_color_table[i+56] = COLOR_PAIR( 3 ) | A_BOLD;
- tde_color_table[i+72] = COLOR_PAIR( 4 ) | A_BOLD;
- tde_color_table[i+88] = COLOR_PAIR( 5 ) | A_BOLD;
- tde_color_table[i+104] = COLOR_PAIR( 6 ) | A_BOLD;
- tde_color_table[i+120] = COLOR_PAIR( 7 );
- }
-
- g_display.head_color = *clr++;
- g_display.text_color = *clr++;
- g_display.dirty_color = *clr++;
- g_display.mode_color = *clr++;
- g_display.block_color = *clr++;
- g_display.message_color = *clr++;
- g_display.help_color = *clr++;
- g_display.diag_color = *clr++;
- g_display.eof_color = *clr++;
- g_display.curl_color = *clr++;
- g_display.ruler_color = *clr++;
- g_display.ruler_pointer = *clr++;
- g_display.hilited_file = *clr++;
- g_display.overscan = *clr;
-
- g_display.dirty_color = 96;
- g_display.hilited_file = 96;
- /* g_display.head_color = 64;
- g_display.ruler_pointer = 104; */
- g_display.help_color = 48;
- g_display.eof_color = 40;
- /*
- g_display.dirty_color = 96;
- g_display.help_color = 56;
- g_display.hilited_file = 16;
- */
-
- #else
- struct vcfg cfg; /* defined in .h */
- register int *clr;
-
- /*
- * work out what kind of display is in use, and set attributes and
- * display address accordingly. Note that this will only work with
- * close IBM compatibles.
- */
-
- video_config( &cfg );
- g_display.display_address = (char FAR *)cfg.videomem;
-
- /*
- * Use an integer pointer to go thru the color array for setting up the
- * various color fields.
- */
- clr = cfg.color == FALSE ? &colour.clr[0][0] : &colour.clr[1][0];
-
- g_display.head_color = *clr++;
- g_display.text_color = *clr++;
- g_display.dirty_color = *clr++;
- g_display.mode_color = *clr++;
- g_display.block_color = *clr++;
- g_display.message_color = *clr++;
- g_display.help_color = *clr++;
- g_display.diag_color = *clr++;
- g_display.eof_color = *clr++;
- g_display.curl_color = *clr++;
- g_display.ruler_color = *clr++;
- g_display.ruler_pointer = *clr++;
- g_display.hilited_file = *clr++;
- g_display.overscan = *clr;
-
- /*
- * set the overscan color.
- * in terminate( ), the overscan color is returned to old state.
- */
- if (g_display.adapter != MDA)
- set_overscan_color( g_display.overscan );
- #endif
-
-
- /*
- * set up screen size
- */
- #if defined( __UNIX__ )
-
- /*
- * getmaxyx( ) is a curses macro that sets y and x. stdscr is the
- * standard curses screen.
- */
- getmaxyx( stdscr, y, x );
- g_display.ncols = x;
- g_display.nlines = y - 2;
- g_display.mode_line = y - 1;
-
- #else
- g_display.ncols = MAX_COLS;
- g_display.nlines = MAX_LINES - 1;
- g_display.mode_line = MAX_LINES;
- #endif
- g_display.line_length = MAX_LINE_LENGTH;
- }
-
-
- /*
- * Name: get_help
- * Purpose: save the screen and display key definitions
- * Date: June 5, 1991
- * Notes: This routine is dependent on the length of the strings in the
- * help screen. To make it easy to load in a new help screen,
- * the strings are assumed to be 80 characters long followed by
- * the '\0' character. It is assumed each that string contains
- * exactly 81 characters.
- */
- int get_help( TDE_WIN *window )
- {
- register char *help;
- register int line;
-
- xygoto( -1, -1 );
- help = help_screen[1];
- for (line=0; help != NULL; line++) {
- s_output( help, line, 0, g_display.help_color );
- help = help_screen[line+2];
- }
-
- #if defined( __UNIX__ )
- refresh( );
- #endif
-
- line = getkey( );
-
- #if defined( __UNIX__ )
- cls( );
- #endif
-
- redraw_screen( window );
- #if defined( __UNIX__ )
- refresh( );
- #endif
- return( OK );
- }
-
-
- /*
- * Name: show_credits
- * Purpose: display authors
- * Date: June 5, 1991
- */
- void show_credits( void )
- {
- register char *credit;
- int line;
-
- xygoto( -1, -1 );
- credit = credit_screen[0];
- for (line=0; credit != NULL; ) {
- s_output( credit, line+2, 11, g_display.text_color );
- credit = credit_screen[++line];
- }
- }
-