/* TECO for DOS Copyright (C) 1986-1991 Matt Fichtenbaum */ /* Based on Ultrix TECO (C) 1986-1990 GenRad Inc., Concord, MA 01742 */ /* These programs may be copied if this copyright notice is included and */ /* only on a "not for sale or profit" basis */ /* te_main.c main program 12/08/90 20.15 */ /* 8-bit version 08/27/91 22.46 */ /* improve dly_freebuff 01/12/92 14.25 */ /* add change directory command 03/30/92 20.44 */ /* current version 10/31/92 19.51 */ /* four buffers 03/10/93 22.16 */ /* * This is TECO for DOS on a PC. It is mostly compatible with DEC TECO * as explained in the DEC TECO manual. It was written from a manual for * TECO-11 version 34, and so adheres most closely to that version. * * This program consists of several source files, as follows: * * teco.c (this file) Main program - initialize, read command line and * startup file, handle errors, high-level read and * execute command strings. * * te_defs.h Definitions file, to be #included with other files * * * te_graph.h Definitions file specific to display routines; an * artifact of substituting the routines in te_displ.c * for the corresponding Microsoft C library routines. * * keyscans.h Definitions of the character codes used internally to * represent keyboard function, cursor, etc. keys. * * te_data.c Global variables * * te_rdcmd.c Read in a command string * * te_exec0.c First-level command execution - numbers, values, * assemble expressions * * te_exec1.c Most commands * * te_exec2.c "E" and "F" commands, and file I/O * * te_srch.c routines associated with "search" commands * * te_subs.c higher-level subroutines * * te_utils.c lower-level subroutines * * te_chari.c keyboard (stdin), typeout (stdout), suspend * * te_mouse.c mouse interface routines * * te_vga.c vga display window and display special functions * * te_displ.c focused implementation of Microsoft display library routines * * These routines should be compiled and linked to form the TECO executable. */ #include "te_defs.h" static void cleanup(void), print_string(short); static void save_args(int argc, char *argv[], struct qh *q); static void read_startup(void); void free_mem(void), set_term_par(void); short read_cmdstr(void); void main(int argc, char *argv[]) { short i; save_args(argc, argv, &qreg[36]); /* copy command line to Qz */ init_wd(1); /* get name of current directory */ qreg[1].f = (BUFFPTR) &id_cell; qreg[1].z = 62; read_startup(); /* read startup file */ setup_tty(TTY_ON); /* set tty to CBREAK, no echo, asynch mode */ set_term_par(); /* set terminal screen-size parameters */ window(WIN_INIT); /* initialize screen-image buffer */ qsp = &qstack[-1]; /* initialize q-reg stack pointer */ /* set up error restart */ if (err = setjmp(xxx)) { out_str("\r\n? "); out_str(errors[err-1]); if (err == E_EFI) goto quit; /* EOF from standard input - clean up and exit */ if (err == E_SRH) print_string(SERBUF); /* print unfulfilled search string */ else if ((err == E_FNF) || (err == E_COF) || (err == E_AMB)) print_string(filbuf); /* or file string */ else if (err == E_DIR) print_string(DIRNAME); /* or directory string */ crlf(); eisw = 0; /* stop indirect command execution */ et_val &= ~(ET_CTRLC | ET_NOWAIT | ET_CTRLO | ET_NOECHO); /* reset ^C trap, read w/o wait, ^O (unused), no echo */ if (et_val & ET_QUIT) /* if ET has "quit on error" set, exit (phone home) */ { cleanup(); /* reset screen, keyboard, output files */ exit(1); /* and exit */ } } /* forever: read and execute command strings */ for (exitflag = 1; exitflag >= 0; ) /* "exit" sets exitflag to -1; ^C to -2; "hangup" to -3 */ { window(WIN_REFR); /* display the buffer */ free_blist(insert_p); /* free any storage from failed insert */ free_blist(dly_freebuff); /* return any delayed cells and reset q-reg "use" counts */ reset_q_usecounts(); /* reset q-reg use counts to "1" if error occurred */ insert_p = dly_freebuff = NULL; et_val &= ~ET_QUIT; /* clear "abort on error" */ if (read_cmdstr()) goto quit; exitflag = 0; /* enable ^C detector */ if (!WN_scroll) window(WIN_REDRAW); /* if not in scroll mode, force full redraw on first ^W or nW */ exec_cmdstr(); } if (exitflag == -2) ERROR(E_XAB); /* ^C detected during execution */ /* exit from program */ quit: ev_val = es_val = 0; /* no last one-line window */ window(WIN_REFR); /* last display */ cleanup(); /* reset screen, terminal, output files */ free_mem(); /* return allocated memory */ exit(0); /* and quit */ } /* reset screen state, keyboard state; remove open output files */ static void cleanup() { short i; out_flush(); window(WIN_OFF); /* restore screen */ setup_tty(TTY_OFF); /* restore terminal */ for (i = 0; i < MAX_BUFFERS; i++) /* kill any open output files */ kill_output(&out_files[i]); (void)set_wd(1); /* reset original drive and directory */ } /* print string for error message */ /* argument is subscript of a qreg qh, prints text from that buffer */ static void print_string(short arg) { short i, c; BUFFPTR p; unsigned char tc; void out_char(unsigned char), out_stderr(unsigned char); void (*print_ptr)(unsigned char) = (et_val & ET_GRAPH) ? out_stderr : out_char; (*print_ptr)('"'); for (p = qreg[arg].f, c = 0, i = 0; i < qreg[arg].z; i++) { if (!(tc = p->ch[c])) break; if (tc < 040) /* ctrl char */ switch (tc) { case CR: case LF: (*print_ptr)(tc); break; case TAB: (*print_ptr)(' '); (*print_ptr)(' '); break; case ESC: (*print_ptr)('$'); break; default: (*print_ptr)('^'); (*print_ptr)((char)(tc | 0100)); break; } else (*print_ptr)(tc); if (++c > CELLSIZE-1) { p = p->f; c = 0; } } (*print_ptr)('"'); } void out_stderr(unsigned char c) { putc((int) c, stderr); } /* copy invocation command line to a text buffer */ static void save_args(int argc, char *argv[], struct qh *q) { unsigned char c; struct qp ptr; make_buffer(q); /* attach a text buffer */ ptr.p = q->f; /* initialize pointer to output string */ ptr.c = q->z = 0; /* and output char count */ for (; argc > 0; argv++, argc--) /* for each arg */ { while ( ((c = *((*argv)++)) != '\0') && (q->z < CELLSIZE-1) ) { ptr.p->ch[ptr.c] = c; /* copy char to q-reg */ fwdcx(&ptr); ++q->z; /* count characters */ } if (argc > 1) /* if not last argument... */ { ptr.p->ch[ptr.c] = ' '; /* space to separate arguments */ fwdcx(&ptr); ++q->z; } } } /* routine to read startup file */ static unsigned char startup_name[] = "teco.ini"; /* name of startup file */ static void read_startup() { unsigned char *p_init, *p_temp; char *getenv(); unsigned char temp_name[80]; /* look for "teco.ini" in current directory first */ /* if not found, use environment variable "teco" as path */ if (!(eisw = fopen(&startup_name[0], "r"))) { if ((p_init = getenv("TECO")) != 0) { for (p_temp = temp_name; *p_init != 0; ) /* copy path */ *p_temp++ = *p_init++; *p_temp++ = '\\'; /* separator */ for (p_init = startup_name; *p_init != 0; ) /* copy filename */ *p_temp++ = *p_init++; *p_temp = '\0'; eisw = fopen(temp_name, "r"); /* set eisw if file found */ } } }