home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-03-14 | 59.7 KB | 2,866 lines |
-
- : This is a shar archive. Extract with sh, not csh.
- : The rest of this file will extract:
- : dos.c minix.c os2.c unix.c setenv.c ctags.c
- echo extracting - dos.c
- sed 's/^X//' > dos.c << '!EOR!'
- X/* $Header:
- X *
- X * MSDOS support for Stevie.
- X * Many of the functions in this file have two versions:
- X * - The original version, using ANSI escape sequences
- X * (by Tim Thompson and/or Tony Andrews).
- X * It requires a non-IBM ANSI driver, such as the shareware NANSI.SYS.
- X * - The BIOS-function version (by Larry A. Shurr). The BIOS version
- X * doesn't require an enhanced console driver such as NANSI.SYS.
- X * Invoke it by #defining BIOS in ENV.H.
- X * Dave Tutelman has incorporated many features of Larry Shurr's BIOS
- X * version (such as colors and 43-line mode) into the ANSI version.
- X */
- X
- X#include "stevie.h"
- X#include <stdio.h>
- X#include <dos.h>
- X#include <signal.h>
- X
- Xchar *getenv();
- X
- Xstatic char getswitch();
- Xstatic void setswitch();
- X
- X#ifdef BIOS
- Xvoid bios_t_ed();
- Xvoid bios_t_el();
- X#endif
- X
- Xenum hostval_e {hIBMPC, hTIPRO};
- Xtypedef enum hostval_e hostval;
- Xstatic hostval host_type = 0; /* Gets host computer type */
- X
- Xstatic char bgn_color = 0x7; /* For saving orig color */
- Xstatic char quitting_now= 0; /* Set for windexit() */
- Xstatic int crt_int = 0; /* Gets CRT BIOS interrupt */
- Xstatic char bgn_page = 0; /* For saving current page (IBM PC) */
- Xstatic char bgn_mode = 0; /* For saving video mode (IBM PC) */
- X
- X#ifdef BIOS
- Xstatic int sav_curattr = 0; /* For saving cursor attributes */
- Xstatic int sav_curpos = 0; /* For saving cursor position */
- X#endif
- X
- X/*
- X * inchar() - get a character from the keyboard
- X */
- Xint
- Xinchar()
- X{
- X int c;
- X
- X got_int = FALSE;
- X
- X for (;;beep()) { /* loop until we get a valid character */
- X
- X flushbuf(); /* flush any pending output */
- X
- X switch (c = getch()) {
- X case 0x1e:
- X return K_CCIRCM;
- X case 0: /* special key */
- X if (State != NORMAL) {
- X c = getch(); /* throw away next char */
- X continue; /* and loop for another char */
- X }
- X switch (c = getch()) {
- X case 0x50:
- X return K_DARROW;
- X case 0x48:
- X return K_UARROW;
- X case 0x4b:
- X return K_LARROW;
- X case 0x4d:
- X return K_RARROW;
- X case 0x47: /* Home key */
- X stuffin("1G");
- X return -1;
- X case 0x4f: /* End key */
- X stuffin("G");
- X return -1;
- X case 0x51: /* PgDn key */
- X stuffin(mkstr(CTRL('F')));
- X return -1;
- X case 0x49: /* PgUp key */
- X stuffin(mkstr(CTRL('B')));
- X return -1;
- X case 0x52: /* insert key */
- X return K_INSERT;
- X case 0x53: /* delete key */
- X stuffin("x");
- X return -1;
- X /*
- X * Hard-code some useful function key macros.
- X */
- X case 0x3b: /* F1 */
- X stuffin(":help\n");
- X return -1;
- X case 0x3c: /* F2 */
- X stuffin(":n\n");
- X return -1;
- X case 0x55: /* SF2 */
- X stuffin(":n!\n");
- X return -1;
- X case 0x3d: /* F3 */
- X stuffin(":N\n");
- X return -1;
- X case 0x56: /* SF3 */
- X stuffin(":N!\n");
- X return -1;
- X case 0x3e: /* F4 */
- X stuffin(":e #\n");
- X return -1;
- X case 0x57: /* SF4 */
- X stuffin(":e! #\n");
- X return -1;
- X case 0x3f: /* F5 */
- X stuffin(":rew\n");
- X return -1;
- X case 0x58: /* SF5 */
- X stuffin(":rew!\n");
- X return -1;
- X case 0x40: /* F6 */
- X stuffin("]]");
- X return -1;
- X case 0x59: /* SF6 */
- X stuffin("[[");
- X return -1;
- X case 0x42: /* F8 - Set up global substitute */
- X stuffin(":1,$s/");
- X return -1;
- X case 0x43: /* F9 - declare C variable */
- X stuffin("yyp!!cdecl\n");
- X return -1;
- X case 0x5C: /* SF9 - explain C declaration */
- X stuffin("yyp^iexplain \033!!cdecl\n");
- X return -1;
- X case 0x44: /* F10 - save & quit */
- X stuffin(":x\n");
- X return -1;
- X case 0x5D: /* F10 - quit without saving */
- X stuffin(":q!\n");
- X return -1;
- X default:
- X break;
- X }
- X break;
- X
- X default:
- X return c;
- X }
- X }
- X}
- X
- X
- Xstatic int bpos = 0;
- X#ifdef BIOS
- X
- X#define BSIZE 256
- Xstatic char outbuf[BSIZE];
- X
- X/* Flushbuf() is used a little differently here in the BIOS-only interface
- X * than in the case of other systems. In general, the other systems buffer
- X * large amounts of text and screen management data (escape sequences).
- X * Here, only text is buffered, screen management is performed using BIOS
- X * calls. Hence, the buffer is much smaller since no more than one line of
- X * text is buffered. Also, screen management calls must assure that the
- X * buffered text is output before performing the requested function.
- X *
- X * O.K. Now I had better explain the tricky code sequences for IBM PC and
- X * TI Pro. In both cases, the tricks involve: 1) getting the text written
- X * to the display as quickly as possible in the desired color and 2) assur-
- X * ing that the cursor is positioned immediately following the latest text
- X * output.
- X *
- X * On the IBM PC, we output the first character using the "write character
- X * with attribute" function followed by code which outputs the buffer, a
- X * character at a time, using the "write tty" function. The first write
- X * sets the display attributes, which are then reused by the "write tty"
- X * function. The "write tty" is then used to quickly write the data while
- X * advancing the cursor. The "write character with attribute" function
- X * does not advance the cursor and so cannot be used to write the entire
- X * buffer without additional code to advance the cursor in a separate oper-
- X * ation. Even though the first character in each buffer gets written
- X * twice, the result is still substantially faster than it would be using a
- X * "write character with attribute" - "[re]position cursor" sequence.
- X *
- X * On the TI Pro, we output the entire buffer using the "write character
- X * string with attribute" function which is fast and convenient. Unfortun-
- X * ately, it does not advance the cursor. Therefore, we include code which
- X * determines the current location of the cursor, writes the buffer, then
- X * positions the cursor at the end of the new data.
- X *
- X * I admit it, this is tricky, but it makes display updates much faster
- X * than the would be using a more straightforward approach.
- X */
- X
- X
- Xvoid
- Xflushbuf() /* Flush buffered output to display */
- X{
- X union REGS inregs, curregs, outregs;
- X
- X if (bpos != 0) {
- X char *bptr = outbuf;
- X
- X switch (host_type) {
- X case hIBMPC:
- X inregs.h.ah = 0x09;
- X inregs.h.al = *bptr;
- X inregs.h.bh = bgn_page;
- X inregs.h.bl = P(P_CO);
- X inregs.x.cx = 1;
- X int86(crt_int, &inregs, &outregs);
- X inregs.h.ah = 0x0E;
- X while (bpos-- > 0) {
- X inregs.h.al = *bptr++;
- X int86(crt_int, &inregs, &outregs);
- X }
- X break;
- X case hTIPRO:
- X curregs.h.ah = 0x03;
- X int86(crt_int, &curregs, &curregs);
- X inregs.h.ah = 0x10;
- X inregs.h.al = P(P_CO);
- X inregs.x.bx = FP_OFF(outbuf);
- X inregs.x.cx = bpos;
- X inregs.x.dx = FP_SEG(outbuf);
- X int86(crt_int, &inregs, &outregs);
- X curregs.h.ah = 0x02;
- X curregs.h.dh += bpos;
- X int86(crt_int, &curregs, &outregs);
- X break;
- X }
- X }
- X bpos = 0;
- X}
- X
- Xvoid
- Xwrite_tty(c) /* Used to execute control chars */
- Xchar c;
- X{
- X int curcol;
- X
- X union REGS inregs, curregs, outregs;
- X
- X flushbuf(); \
- X
- X switch (c) {
- X case '\t':
- X inregs.h.ah = 0x09;
- X inregs.h.al = ' ';
- X inregs.h.bh = bgn_page;
- X inregs.h.bl = P(P_CO);
- X inregs.x.cx = 1;
- X int86(crt_int, &inregs, &outregs);
- X inregs.h.ah = 0x0E;
- X int86(crt_int, &inregs, &outregs);
- X curregs.h.ah = 0x03;
- X curregs.h.bh = bgn_page;
- X int86(crt_int, &curregs, &outregs);
- X curcol = host_type == hIBMPC ? outregs.h.dl : outregs.h.dh;
- X while (curcol++ % P(P_TS)) int86(crt_int, &inregs, &outregs);
- X break;
- X case '\n':
- X if (host_type == hTIPRO) bios_t_el();
- X /* No break, fall through to default action. */
- X default:
- X inregs.h.ah = 0x0E;
- X inregs.h.bh = bgn_page;
- X inregs.h.al = c;
- X int86(crt_int, &inregs, &outregs);
- X break;
- X }
- X}
- X
- X#else /* Not BIOS */
- X
- X#define BSIZE 2048
- Xstatic char outbuf[BSIZE];
- X
- Xvoid
- Xflushbuf()
- X{
- X if (bpos != 0)
- X write(1, outbuf, bpos);
- X bpos = 0;
- X}
- X
- X#endif
- X
- X
- X/*
- X * Macro to output a character. Used within this file for speed.
- X *
- X * This macro had to be upgraded for the BIOS-only version because we
- X * cannot count on flushbuf() to execute control characters such as
- X * end-of-line or tab. Therefore, when we encounter one, we flush
- X * the buffer and call a routine which executes the character.
- X */
- X
- X#ifdef BIOS
- X
- X#define outone(cc) { \
- X register char ch = cc; \
- X if (ch >= ' ') { \
- X outbuf[bpos++] = ch; \
- X if (bpos >= BSIZE) flushbuf(); \
- X } else write_tty(ch); \
- X}
- X
- X#else
- X
- X#define outone(c) outbuf[bpos++] = c; if (bpos >= BSIZE) flushbuf()
- X
- X#endif
- X
- X/*
- X * Function version for use outside this file.
- X */
- X
- Xvoid
- Xoutchar(c)
- Xchar c;
- X{
- X outone(c);
- X}
- X
- X/*
- X * outstr(s) - write a string to the console
- X */
- X
- Xvoid
- Xoutstr(s)
- Xchar *s;
- X{
- X while (*s) {
- X outone(*s++);
- X }
- X}
- X
- Xvoid
- Xbeep()
- X{
- X if ( P(P_VB) )
- X vbeep();
- X else
- X outchar('\007');
- X}
- X
- Xvbeep() /* "Visual Bell" - reverse color flash */
- X{
- X unsigned char oldcolor, revcolor, temp;
- X
- X oldcolor = P(P_CO);
- X
- X /* put reverse color in revcolor */
- X revcolor = (P(P_CO) & 0x07) << 4; /* foregnd -> bkgnd */
- X temp = (P(P_CO) & 0x70) >> 4; /* bkgnd -> foregnd */
- X revcolor |= temp;
- X
- X /* Flash revcolor, then back */
- X setcolor (revcolor);
- X flushbuf();
- X#ifdef TURBOC
- X delay (100);
- X#endif
- X setcolor (oldcolor);
- X windgoto (Cursrow, Curscol);
- X flushbuf();
- X}
- X
- X
- X#ifndef TURBOC
- Xsleep(n)
- Xint n;
- X{
- X /*
- X * Should do something reasonable here.
- X */
- X}
- X#endif
- X
- Xvoid
- Xpause()
- X{
- X long l;
- X
- X flushbuf();
- X
- X#ifdef TURBOC
- X delay (600); /* "stop" for a fraction of a second */
- X#else
- X /*
- X * Should do something better here...
- X */
- X for (l=0; l < 5000 ;l++)
- X ;
- X#endif
- X}
- X
- Xvoid
- Xsig()
- X{
- X signal(SIGINT, sig);
- X
- X got_int = TRUE;
- X}
- X
- Xstatic char schar; /* save original switch character */
- X
- X/* While Larry Shurr's addition of color and mode support was
- X * dependent on #define BIOS, there's no reason it needs to be.
- X * The BIOS is always there, even if NANSI.SYS isn't. We'll
- X * use the BIOS where appropriate, and extend support to
- X * all cases of #define DOS. This is especially true of the
- X * setup in windinit() and the termination in windexit().
- X */
- X
- Xvoid
- Xwindinit()
- X{
- X union REGS regs;
- X struct SREGS sregs;
- X
- X /* The "SYSROM..." string is a signature in the TI Pro's ROM which
- X * which we can look for to determine whether or not we're running
- X * on a TI Pro. If we don't find it at F400:800D,
- X * we assume we're running on an IBM PC or clone.
- X * Unfortunately, the signature is actually
- X * the system ROM's copyright notice though you will note that the
- X * year is omitted. Still, placing it in this program might
- X * inadvertantly make it appear to be an official copyright notice
- X * for THIS program. Hence, I have surrounded the signature
- X * string with disclaimers.
- X */
- X
- X static char far *disclaimer1 =
- X "The following is *NOT* a copyright notice for this program: ";
- X
- X static char far *ti_sig =
- X "SYSROM (c) Copyright Texas Instruments Inc.";
- X
- X static char far *disclaimer2[] = {
- X "\nInstead, it is a signature string we look for ",
- X "to distinguish the TI Pro computer.\n",
- X "Actually, this program is in the public domain."
- X };
- X
- X static char far *ti_sig_addr = (char far *)0xF400800D;
- X static int ti_sig_len = sizeof(ti_sig) - 1;
- X
- X /* Identify the host type. Look for signature in TI Pro ROM. If */
- X /* found, set host type to TI Pro, else assume host is an IBM PC. */
- X
- X host_type = strncmp(ti_sig, ti_sig_addr, ti_sig_len) ? hIBMPC : hTIPRO;
- X
- X /* Next, perform host-dependent initialization. */
- X
- X switch (host_type) {
- X case hIBMPC:
- X /* Get the video mode info */
- X crt_int = 0x10;
- X regs.h.ah = 0x0F;
- X int86(crt_int, ®s, ®s);
- X bgn_page = regs.h.bh;
- X bgn_mode = regs.h.al;
- X Columns = regs.h.ah;
- X /* Find the starting color, and save to restore later */
- X regs.h.ah = 8; /* Read char/attr BIOS fn */
- X regs.h.bh = bgn_page;
- X int86(crt_int, ®s, ®s);
- X bgn_color = (int) regs.h.ah;
- X P(P_CO) = bgn_color;
- X break;
- X case hTIPRO:
- X Columns = 80;
- X crt_int = 0x49;
- X P(P_CO) = 0x0F;
- X break;
- X
- X default:
- X Columns = 80;
- X break;
- X }
- X
- X P(P_LI) = Rows = 25;
- X
- X schar = getswitch();
- X setswitch('/');
- X
- X signal(SIGINT, sig);
- X#ifndef BIOS
- X setraw (1);
- X#endif
- X}
- X
- Xvoid
- Xwindexit(r)
- Xint r;
- X{
- X
- X union REGS regs;
- X
- X quitting_now = 1;
- X
- X /* Restore original color */
- X setcolor (bgn_color);
- X
- X if (host_type == hIBMPC) {
- X /* If we've changed any of the setup, reset the mode.
- X * Otherwise, leave stuff on the screen.
- X */
- X regs.h.ah = 0x0F; /* "Get-mode" BIOS fn */
- X int86(0x10, ®s, ®s);
- X if (bgn_mode != regs.h.al)
- X set_mode (bgn_mode);
- X }
- X
- X flushbuf();
- X setswitch(schar);
- X#ifndef BIOS
- X setraw(0);
- X#endif
- X exit(r);
- X}
- X
- X
- X#ifndef BIOS
- X/* Setraw sets the console driver into raw mode, which makes it run
- X * somewhat faster. Details of the function:
- X * If r=1, remember current mode, and set into raw mode.
- X * r=0, return to the original mode.
- X */
- X
- Xsetraw (r)
- X int r;
- X{
- X static int origr=0; /* save the original r */
- X union REGS rr;
- X
- X /* Do IOCTL call to get current control info */
- X rr.x.ax = 0x4400; /* Read IOCTL info - DOS fn */
- X rr.x.bx = 1; /* Handle for stdout */
- X intdos (&rr, &rr);
- X
- X /* Save relevant info, and modify for "set" call */
- X if (r) {
- X origr = rr.h.dl & 0x20; /* save current "raw" bit */
- X rr.h.dl = rr.h.dl | 0x20; /* set "raw" bit */
- X }
- X else
- X rr.h.dl = (rr.h.dl & (~0x20)) | (origr & 0x20);
- X
- X /* Do IOCTL call to set control info */
- X rr.x.ax = 0x4401; /* Set IOCTL function call */
- X rr.x.bx = 1; /* Handle for stdout */
- X rr.h.dh = 0; /* DL already set up */
- X intdos (&rr, &rr);
- X}
- X#endif
- X
- X
- Xvoid
- Xwindgoto(r, c) /* Move cursor to r'ow & c'olumn */
- Xregister int r, c;
- X{
- X#ifdef BIOS
- X union REGS inregs, outregs;
- X
- X if (bpos > 0) flushbuf();
- X
- X inregs.h.ah = 0x02;
- X
- X switch (host_type) {
- X case hIBMPC :
- X inregs.h.bh = bgn_page;
- X inregs.h.dh = r;
- X inregs.h.dl = c;
- X break;
- X case hTIPRO:
- X inregs.h.dh = c;
- X inregs.h.dl = r;
- X break;
- X }
- X
- X int86(crt_int, &inregs, &outregs);
- X
- X#else /* Not BIOS */
- X
- X r += 1;
- X c += 1;
- X
- X /*
- X * Check for overflow once, to save time.
- X */
- X if (bpos + 8 >= BSIZE)
- X flushbuf();
- X
- X outbuf[bpos++] = '\033';
- X outbuf[bpos++] = '[';
- X if (r >= 10)
- X outbuf[bpos++] = r/10 + '0';
- X outbuf[bpos++] = r%10 + '0';
- X outbuf[bpos++] = ';';
- X if (c >= 10)
- X outbuf[bpos++] = c/10 + '0';
- X outbuf[bpos++] = c%10 + '0';
- X outbuf[bpos++] = 'H';
- X
- X#endif
- X}
- X
- XFILE *
- Xfopenb(fname, mode)
- Xchar *fname;
- Xchar *mode;
- X{
- X FILE *fopen();
- X char modestr[16];
- X
- X sprintf(modestr, "%sb", mode);
- X return fopen(fname, modestr);
- X}
- X
- Xstatic char
- Xgetswitch()
- X{
- X union REGS inregs, outregs;
- X
- X inregs.h.ah = 0x37;
- X inregs.h.al = 0;
- X
- X intdos(&inregs, &outregs);
- X
- X return outregs.h.dl;
- X}
- X
- Xstatic void
- Xsetswitch(c)
- Xchar c;
- X{
- X union REGS inregs, outregs;
- X
- X inregs.h.ah = 0x37;
- X inregs.h.al = 1;
- X inregs.h.dl = c;
- X
- X intdos(&inregs, &outregs);
- X}
- X
- X#define PSIZE 128
- X
- X/*
- X * fixname(s) - fix up a dos name
- X *
- X * Takes a name like:
- X *
- X * \x\y\z\base.ext
- X *
- X * and trims 'base' to 8 characters, and 'ext' to 3.
- X */
- Xchar *
- Xfixname(s)
- Xchar *s;
- X{
- X char *strchr(), *strrchr();
- X static char f[PSIZE];
- X char base[32];
- X char ext[32];
- X char *p;
- X int i;
- X
- X strcpy(f, s);
- X
- X for (i=0; i < PSIZE ;i++)
- X if (f[i] == '/')
- X f[i] = '\\';
- X
- X /*
- X * Split the name into directory, base, extension.
- X */
- X if ((p = strrchr(f, '\\')) != NULL) {
- X strcpy(base, p+1);
- X p[1] = '\0';
- X } else {
- X strcpy(base, f);
- X f[0] = '\0';
- X }
- X
- X if ((p = strchr(base, '.')) != NULL) {
- X strcpy(ext, p+1);
- X *p = '\0';
- X } else
- X ext[0] = '\0';
- X
- X /*
- X * Trim the base name if necessary.
- X */
- X if (strlen(base) > 8)
- X base[8] = '\0';
- X
- X if (strlen(ext) > 3)
- X ext[3] = '\0';
- X
- X /*
- X * Paste it all back together
- X */
- X strcat(f, base);
- X strcat(f, ".");
- X strcat(f, ext);
- X
- X return f;
- X}
- X
- Xvoid
- Xdoshell(cmd)
- Xchar *cmd;
- X{
- X if (cmd == NULL)
- X if ((cmd = getenv ("COMSPEC")) == NULL)
- X cmd = "command.com";
- X
- X system(cmd);
- X wait_return();
- X}
- X
- X
- X/*
- X * setcolor (color)
- X * Set the screen attributes (basically, color) to value co.
- X * The color attributes for a DOS machine are the BIOS colors
- X * for text. Where BIOS is not defined, we map the Escape
- X * sequences to the NANSI.SYS equivalents of the BIOS colors.
- X */
- X
- Xsetcolor (color)
- X int color;
- X{
- X#ifdef BIOS
- X P(P_CO) = host_type == hIBMPC ? color : ((color & 0x17) | 0x08);
- X#else
- X unsigned char work;
- X
- X /* Send the ANSI define-attribute sequence */
- X outone('\033');
- X outone('[');
- X outone('0'); /* Normal color */
- X outone(';');
- X /* BIOS-to-NANSI color conversion may look a little bizarre.
- X * They have different bit orderings to represent the
- X * color (BIOS=RGB, NANSI=BGR).
- X *
- X * First put the foreground color.
- X */
- X work = 0;
- X if (color & 1) work += 4; /* Blue */
- X if (color & 2) work += 2; /* Green */
- X if (color & 4) work += 1; /* Red */
- X outone('3'); /* NANSI foreground starts at 30 */
- X outone(work + '0');
- X outone(';');
- X /* Now the background color */
- X work = 0;
- X if (color & 0x10) work += 4; /* Blue */
- X if (color & 0x20) work += 2; /* Green */
- X if (color & 0x40) work += 1; /* Red */
- X outone('4'); /* NANSI background starts at 40 */
- X outone(work + '0');
- X /* Do the intensity and blinking, if any */
- X if (color & 8) { /* intensity */
- X outone(';');
- X outone('1');
- X }
- X if (color & 0x80) { /* blink */
- X outone(';');
- X outone('5');
- X }
- X /* The 'm' suffix means "set graphic rendition" */
- X outone('m');
- X P(P_CO) = color;
- X
- X#endif /* Not BIOS */
- X
- X if (!quitting_now) {
- X screenclear();
- X updatescreen();
- X }
- X}
- X
- X
- X/* setrows (r)
- X * Sets the screen to "r" rows, or lines, where "r" is a feasible
- X * value for the IBM PC with some common display. In this function:
- X * - We set the mode to 25-line or 43-line mode, assuming the display
- X * supports the requested mode.
- X * - We set the logical number of lines that Stevie uses to "r",
- X * so that the screen USED may not be the same as the physical screen.
- X *
- X * The function returns the number of rows set.
- X */
- Xsetrows (r)
- X int r;
- X{
- X int rphys, rlog; /* physical and logical "r" */
- X
- X rphys = (r <= 25) ? 25 : 43 ;
- X rlog = (r <= 50) ? r : 50;
- X
- X /* Set the mode to correspond to the number of lines */
- X set_mode (rphys);
- X
- X return (rlog);
- X}
- X
- X
- Xset_mode (m)
- X int m;
- X{
- X set_25 ();
- X if (m == 43)
- X set_43 ();
- X}
- X
- X#ifdef BIOS
- X
- Xint
- Xset_25(lines) /* Set display to 25 line mode */
- Xint lines;
- X{
- X union REGS inregs, outregs;
- X
- X switch (host_type) {
- X case hIBMPC:
- X inregs.h.ah = 0x00;
- X inregs.h.al = bgn_mode;
- X int86(crt_int, &inregs, &outregs);
- X break;
- X case hTIPRO:
- X windgoto(0, 0);
- X inregs.h.ah = 0x09;
- X inregs.h.al = ' ';
- X inregs.h.bl = P(P_CO);
- X inregs.x.cx = 80 * 25;
- X int86(crt_int, &inregs, &outregs);
- X if (lines > 25) lines = 25;
- X break;
- X }
- X
- X return(lines);
- X}
- X
- Xint
- Xset_43(lines) /* Set display to 43/50 line mode */
- Xint lines;
- X{
- X union REGS inregs, outregs;
- X
- X switch (host_type) {
- X case hIBMPC:
- X inregs.x.ax = 0x1112;
- X inregs.h.bl = 0;
- X int86(crt_int, &inregs, &outregs);
- X inregs.x.ax = 0x1200;
- X inregs.h.bl = 0x20;
- X int86(crt_int, &inregs, &outregs);
- X inregs.h.ah = 0x01;
- X inregs.x.cx = 0x0707;
- X int86(crt_int, &inregs, &outregs);
- X break;
- X case hTIPRO:
- X if (lines > 25) lines = 25;
- X break;
- X }
- X
- X return(lines);
- X}
- X
- X#else /* Not BIOS */
- X
- Xset_25 ()
- X{
- X send_setmode (bgn_mode);
- X}
- X
- Xset_43 ()
- X{
- X send_setmode (43);
- X}
- X
- Xsend_setmode (m)
- X{
- X outone('\033');
- X outone('[');
- X
- X /* Convert 2-digit decimal to ASCII */
- X if (m >= 10)
- X outone( m/10 + '0' );
- X outone( m%10 + '0' );
- X outone ('h');
- X}
- X
- X#endif /* Not BIOS */
- X
- X#ifdef BIOS
- X/*
- X * The rest of the file is BIOS-specific
- X */
- X
- Xvoid
- Xbios_t_ci() /* Make cursor invisible */
- X{
- X union REGS inregs, outregs;
- X
- X if (sav_curattr == 0) {
- X inregs.h.ah = 0x03;
- X inregs.h.bh = bgn_page;
- X int86(crt_int, &inregs, &outregs);
- X sav_curattr = outregs.x.cx;
- X inregs.h.ah = 0x01;
- X inregs.x.cx = 0x2000;
- X int86(crt_int, &inregs, &outregs);
- X }
- X}
- X
- Xvoid
- Xbios_t_cv() /* Make cursor visible */
- X{
- X union REGS inregs, outregs;
- X
- X if (sav_curattr != 0) {
- X inregs.h.ah = 0x01;
- X inregs.h.bh = bgn_page;
- X inregs.x.cx = sav_curattr;
- X int86(crt_int, &inregs, &outregs);
- X sav_curattr = 0;
- X }
- X}
- X
- X/*
- X * O.K., I have tried to keep bios.c as "pure" as possible. I.e., I have used
- X * BIOS calls for everything instead of going for all-out speed by using
- X * direct-video access for updating the display - after all, I named it this
- X * module bios.c. There is one area, however, where using the BIOS is just
- X * too much of a compromise... the TI Pro's "scroll display" functions are so
- X * slow and ugly that I hate them. True, they are very flexible, but their
- X * poor on-screen appearance and low performance are a liability - you prob-
- X * ably think I'm exaggerating, but you're wrong - it is truly bad. There-
- X * fore, I am bypassing them and scrolling the screen myself; something I
- X * nearly always do. From a purist like me, that really says something.
- X */
- X
- Xvoid
- Xbios_t_dl(r,l) /* Delete lines */
- Xint r, l;
- X{
- X char far *end; /* End ptr for TI Pro screen */
- X char far *dst; /* Dest ptr for scrolling TI Pro scrn */
- X char far *src; /* Src ptr for scrolling TI Pro scrn */
- X
- X union REGS inregs, outregs;
- X
- X switch (host_type) {
- X case hIBMPC:
- X inregs.h.ah = 0x06;
- X inregs.h.al = l;
- X inregs.h.bh = P(P_CO);
- X inregs.h.ch = r;
- X inregs.h.cl = 0;
- X inregs.h.dh = Rows - 1;
- X inregs.h.dl = Columns - 1;
- X int86(crt_int, &inregs, &outregs);
- X break;
- X case hTIPRO:
- X inregs.h.ah = 0x17;
- X int86(crt_int, &inregs, &outregs);
- X dst = MK_FP(0xDE00, outregs.x.dx + (r * Columns));
- X src = dst + (l * Columns);
- X end = MK_FP(0xDE00, outregs.x.dx + ((Rows - 1) * Columns));
- X while (src < end) *dst++ = *src++;
- X while (dst < end) *dst++ = ' ';
- X break;
- X }
- X}
- X
- Xvoid
- Xbios_t_ed() /* Home cursor, erase display */
- X{
- X union REGS inregs, outregs;
- X
- X windgoto(0, 0);
- X
- X inregs.h.ah = 0x09;
- X inregs.h.al = ' ';
- X inregs.h.bh = bgn_page;
- X inregs.h.bl = P(P_CO);
- X inregs.x.cx = Columns * Rows;
- X int86(crt_int, &inregs, &outregs);
- X}
- X
- Xvoid
- Xbios_t_el() /* Erase to end-of-line */
- X{
- X short ccol;
- X
- X union REGS inregs, outregs;
- X
- X inregs.h.ah = 0x03;
- X inregs.h.bh = bgn_page;
- X int86(crt_int, &inregs, &outregs);
- X
- X inregs.h.ah = 0x09;
- X inregs.h.al = ' ';
- X inregs.h.bl = P(P_CO);
- X
- X ccol = host_type == hIBMPC ? outregs.h.dl : outregs.h.dh;
- X
- X inregs.x.cx = Columns - ccol;
- X int86(crt_int, &inregs, &outregs);
- X}
- X
- X/* As in the delete-line function, we scroll the TI display ourselves
- X * rather than the use the slow-and-ugly software scroll in the BIOS. See
- X * the remarks for bios_t_dl() additional information.
- X */
- X
- Xvoid
- Xbios_t_il(r,l) /* Insert lines */
- Xint r, l;
- X{
- X char far *end; /* End ptr for TI Pro screen */
- X char far *dst; /* For scrolling TI Pro screen */
- X char far *src; /* For scrolling TI Pro screen */
- X
- X union REGS inregs, outregs;
- X
- X switch (host_type) {
- X case hIBMPC:
- X inregs.h.ah = 0x07;
- X inregs.h.al = l;
- X inregs.h.bh = P(P_CO);
- X inregs.h.ch = r;
- X inregs.h.cl = 0;
- X inregs.h.dh = Rows - 1;
- X inregs.h.dl = Columns - 1;
- X int86(crt_int, &inregs, &outregs);
- X break;
- X case hTIPRO:
- X inregs.h.ah = 0x17;
- X int86(crt_int, &inregs, &outregs);
- X dst = MK_FP(0xDE00, outregs.x.dx + (Columns * (Rows - 1)) - 1);
- X src = dst - (Columns * l);
- X end = MK_FP(0xDE00, outregs.x.dx + (Columns * r));
- X while (src >= end) *dst-- = *src--;
- X src = MK_FP(0xDE00, outregs.x.dx + (r * Columns));
- X end = src + (l * Columns);
- X while (src < end) *src++ = ' ';
- X break;
- X }
- X}
- X
- Xvoid
- Xbios_t_rc() /* Restore saved cursor position */
- X{
- X union REGS inregs, outregs;
- X
- X inregs.h.ah = 0x02;
- X inregs.h.bh = bgn_page;
- X inregs.x.dx = sav_curpos;
- X int86(crt_int, &inregs, &outregs);
- X}
- X
- Xvoid
- Xbios_t_sc() /* Save cursor position */
- X{
- X union REGS inregs, outregs;
- X
- X inregs.h.ah = 0x03;
- X inregs.h.bh = bgn_page;
- X int86(crt_int, &inregs, &outregs);
- X sav_curpos = outregs.x.dx;
- X}
- X
- X#endif
- X
- !EOR!
- echo extracting - minix.c
- sed 's/^X//' > minix.c << '!EOR!'
- X/* $Header: /nw/tony/src/stevie/src/RCS/minix.c,v 1.5 89/07/11 21:24:18 tony Exp $
- X *
- X * System-dependent routines for Minix-ST
- X */
- X
- X#include "stevie.h"
- X#include <sgtty.h>
- X#include <signal.h>
- X
- X/*
- X * inchar() - get a character from the keyboard
- X */
- Xint
- Xinchar()
- X{
- X char c;
- X
- X flushbuf(); /* flush any pending output */
- X
- X while (read(0, &c, 1) != 1)
- X ;
- X
- X got_int = FALSE;
- X return c;
- X}
- X
- X#define BSIZE 2048
- Xstatic char outbuf[BSIZE];
- Xstatic int bpos = 0;
- X
- Xvoid
- Xflushbuf()
- X{
- X if (bpos != 0)
- X write(1, outbuf, bpos);
- X bpos = 0;
- X}
- X
- X/*
- X * Macro to output a character. Used within this file for speed.
- X */
- X#define outone(c) outbuf[bpos++] = c; if (bpos >= BSIZE) flushbuf()
- X
- X/*
- X * Function version for use outside this file.
- X */
- Xvoid
- Xoutchar(c)
- Xregister char c;
- X{
- X outbuf[bpos++] = c;
- X if (bpos >= BSIZE)
- X flushbuf();
- X}
- X
- Xvoid
- Xoutstr(s)
- Xregister char *s;
- X{
- X while (*s) {
- X outone(*s++);
- X }
- X}
- X
- Xvoid
- Xbeep()
- X{
- X if ( P(P_VB) )
- X vbeep();
- X else
- X outone('\007');
- X}
- X
- X/*
- X * remove(file) - remove a file
- X */
- Xvoid
- Xremove(file)
- Xchar *file;
- X{
- X unlink(file);
- X}
- X
- X/*
- X * rename(of, nf) - rename existing file 'of' to 'nf'
- X */
- Xvoid
- Xrename(of, nf)
- Xchar *of, *nf;
- X{
- X unlink(nf);
- X link(of, nf);
- X unlink(of);
- X}
- X
- Xvoid
- Xpause()
- X{
- X sleep (1);
- X}
- X
- Xstatic struct sgttyb ostate;
- X
- X/*
- X * Go into cbreak mode
- X */
- Xvoid
- Xset_tty()
- X{
- X struct sgttyb nstate;
- X
- X ioctl(0, TIOCGETP, &ostate);
- X nstate = ostate;
- X nstate.sg_flags &= ~(XTABS|ECHO);
- X nstate.sg_flags |= CBREAK;
- X ioctl(0, TIOCSETP, &nstate);
- X}
- X
- X/*
- X * Restore original terminal modes
- X */
- Xvoid
- Xreset_tty()
- X{
- X ioctl(0, TIOCSETP, &ostate);
- X}
- X
- Xvoid
- Xsig()
- X{
- X signal(SIGINT, sig);
- X signal(SIGQUIT, sig);
- X
- X got_int = TRUE;
- X}
- X
- Xvoid
- Xwindinit()
- X{
- X#ifdef TERMCAP
- X if (t_init() != 1) {
- X fprintf(stderr, "unknown terminal type\n");
- X exit(1);
- X }
- X#else
- X Columns = 80;
- X P(P_LI) = Rows = 25;
- X#endif
- X /*
- X * The code here makes sure that there isn't a window during which
- X * we could get interrupted and exit with the tty in a weird state.
- X */
- X signal(SIGINT, sig);
- X signal(SIGQUIT, sig);
- X
- X set_tty();
- X
- X if (got_int)
- X windexit(0);
- X}
- X
- Xvoid
- Xwindexit(r)
- Xint r;
- X{
- X reset_tty();
- X exit(r);
- X}
- X
- Xvoid
- Xwindgoto(r, c)
- Xregister int r, c;
- X{
- X#ifdef TERMCAP
- X char *tgoto();
- X#else
- X r += 1;
- X c += 1;
- X#endif
- X
- X /*
- X * Check for overflow once, to save time.
- X */
- X if (bpos + 8 >= BSIZE)
- X flushbuf();
- X
- X#ifdef TERMCAP
- X outstr(tgoto(T_CM, c, r));
- X#else
- X outbuf[bpos++] = '\033';
- X outbuf[bpos++] = '[';
- X if (r >= 10)
- X outbuf[bpos++] = r/10 + '0';
- X outbuf[bpos++] = r%10 + '0';
- X outbuf[bpos++] = ';';
- X if (c >= 10)
- X outbuf[bpos++] = c/10 + '0';
- X outbuf[bpos++] = c%10 + '0';
- X outbuf[bpos++] = 'H';
- X#endif
- X}
- X
- XFILE *
- Xfopenb(fname, mode)
- Xchar *fname;
- Xchar *mode;
- X{
- X return fopen(fname, mode);
- X}
- X
- Xchar *
- Xstrchr(s, c)
- Xchar *s;
- Xchar c;
- X{
- X char *index();
- X
- X return index(s, c);
- X}
- X
- Xchar *
- Xfixname(s)
- Xchar *s;
- X{
- X return s;
- X}
- X
- X/*
- X * doshell() - run a command or an interactive shell
- X */
- Xvoid
- Xdoshell(cmd)
- Xchar *cmd;
- X{
- X char *cp, *getenv();
- X char cline[128];
- X
- X outstr("\r\n");
- X flushbuf();
- X
- X if (cmd == NULL) {
- X if ((cmd = getenv("SHELL")) == NULL)
- X cmd = "/bin/sh";
- X sprintf(cline, "%s -i", cmd);
- X cmd = cline;
- X }
- X
- X reset_tty();
- X system(cmd);
- X set_tty();
- X
- X wait_return();
- X}
- X
- X/*
- X * FILL IT IN, FOR YOUR SYSTEM, AND SHARE IT!
- X *
- X * The next couple of functions do system-specific stuff.
- X * They currently do nothing; I'm not familiar enough with
- X * system-specific programming on this system.
- X * If you fill it in for your system, please post the results
- X * and share with the rest of us.
- X */
- X
- X
- Xsetcolor (c)
- X/*
- X * Set the color to c, using the local system convention for numbering
- X * colors or video attributes.
- X *
- X * If you implement this, remember to note the original color in
- X * windinit(), before you do any setcolor() commands, and
- X * do a setcolor() back to the original as part of windexit().
- X */
- X int c:
- X{
- X}
- X
- X
- Xsetrows (r)
- X/*
- X * Set the number of lines to r, if possible. Otherwise
- X * "do the right thing". Return the number of lines actually set.
- X *
- X * If you implement this, remember to note the original number of rows
- X * in windinit(), before you do any setrows() commands, and
- X * do a setrows() back to the original as part of windexit().
- X */
- X int r;
- X{
- X /* Since we do nothing, just return the current number of lines */
- X return ( P(P_LI) );
- X}
- X
- X
- Xvbeep ()
- X/*
- X * Do a "visual bell". This generally consists of flashing the screen
- X * once in inverse video.
- X */
- X{
- X int color, revco;
- X
- X color = P( P_CO ); /* get current color */
- X revco = reverse_color (color); /* system-specific */
- X setcolor (revco);
- X flushbuf ();
- X pause ();
- X setcolor (color);
- X windgoto (Cursrow, Curscol);
- X flushbuf ();
- X}
- X
- Xreverse_color (co)
- X/*
- X * Returns the inverse video attribute or color of co.
- X * The existing code below is VERY simple-minded.
- X * Replace it with proper code for your system.
- X */
- X int co;
- X{
- X if (co) return (0);
- X else return (1);
- X}
- X
- X
- X/********** End of do-it-yourself kit **********************/
- X
- !EOR!
- echo extracting - os2.c
- sed 's/^X//' > os2.c << '!EOR!'
- X/* $Header: /nw/tony/src/stevie/src/RCS/os2.c,v 1.7 89/08/07 05:49:19 tony Exp $
- X *
- X * OS/2 System-dependent routines.
- X */
- X
- X#define INCL_BASE
- X#include <os2.h>
- X#include <signal.h>
- X#include "stevie.h"
- X
- X/*
- X * inchar() - get a character from the keyboard
- X */
- Xint
- Xinchar()
- X{
- X register int c;
- X
- X got_int = FALSE;
- X
- X for (;;beep()) { /* loop until we get a valid character */
- X
- X flushbuf(); /* flush any pending output */
- X
- X switch (c = getch()) {
- X case 0x1e:
- X return K_CCIRCM;
- X case 0: /* special key */
- X if (State != NORMAL) {
- X c = getch(); /* throw away next char */
- X continue; /* and loop for another char */
- X }
- X switch (c = getch()) {
- X case 0x50:
- X return K_DARROW;
- X case 0x48:
- X return K_UARROW;
- X case 0x4b:
- X return K_LARROW;
- X case 0x4d:
- X return K_RARROW;
- X case 0x52:
- X return K_INSERT;
- X case 0x47: /* Home key */
- X stuffin("1G");
- X return -1;
- X case 0x4f: /* End key */
- X stuffin("G");
- X return -1;
- X case 0x51: /* PgDn key */
- X stuffin(mkstr(CTRL('F')));
- X return -1;
- X case 0x49: /* PgUp key */
- X stuffin(mkstr(CTRL('B')));
- X return -1;
- X case 0x52: /* insert key */
- X return K_INSERT;
- X case 0x53: /* delete key */
- X stuffin("x");
- X return -1;
- X /*
- X * Hard-code some useful function key macros.
- X */
- X case 0x3b: /* F1 */
- X stuffin(":help\n");
- X return -1;
- X case 0x3c: /* F2 */
- X stuffin(":n\n");
- X return -1;
- X case 0x55: /* SF2 */
- X stuffin(":n!\n");
- X return -1;
- X case 0x3d: /* F3 */
- X stuffin(":N\n");
- X return -1;
- X case 0x56: /* SF3 */
- X stuffin(":N!\n");
- X return -1;
- X case 0x3e: /* F4 */
- X stuffin(":e #\n");
- X return -1;
- X case 0x57: /* SF4 */
- X stuffin(":e! #\n");
- X return -1;
- X case 0x3f: /* F5 */
- X stuffin(":rew\n");
- X return -1;
- X case 0x58: /* SF5 */
- X stuffin(":rew!\n");
- X return -1;
- X case 0x40: /* F6 */
- X stuffin("]]");
- X return -1;
- X case 0x59: /* SF6 */
- X stuffin("[[");
- X return -1;
- X case 0x42: /* F8 - Set up global substitute */
- X stuffin(":1,$s/");
- X return -1;
- X case 0x43: /* F9 - declare C variable */
- X stuffin("yyp!!cdecl\n");
- X return -1;
- X case 0x5C: /* SF9 - explain C declaration */
- X stuffin("yyp^iexplain \033!!cdecl\n");
- X return -1;
- X case 0x44: /* F10 - save & quit */
- X stuffin(":x\n");
- X return -1;
- X case 0x5D: /* F10 - quit without saving */
- X stuffin(":q!\n");
- X return -1;
- X default:
- X break;
- X }
- X break;
- X
- X default:
- X return c;
- X }
- X }
- X}
- X
- X#define BSIZE 2048
- Xstatic char outbuf[BSIZE];
- Xstatic int bpos = 0;
- X
- Xvoid
- Xflushbuf()
- X{
- X if (bpos != 0)
- X write(1, outbuf, bpos);
- X bpos = 0;
- X}
- X
- X/*
- X * Macro to output a character. Used within this file for speed.
- X */
- X#define outone(c) outbuf[bpos++] = c; if (bpos >= BSIZE) flushbuf()
- X
- X/*
- X * Function version for use outside this file.
- X */
- Xvoid
- Xoutchar(c)
- Xregister char c;
- X{
- X outbuf[bpos++] = c;
- X if (bpos >= BSIZE)
- X flushbuf();
- X}
- X
- Xstatic char cell[2] = { 0, 7 };
- X
- X/*
- X * outstr(s) - write a string to the console
- X *
- X * We implement insert/delete line escape sequences here. This is kind
- X * of a kludge, but at least it's localized to a single point.
- X */
- Xvoid
- Xoutstr(s)
- Xregister char *s;
- X{
- X if (strcmp(s, T_DL) == 0) { /* delete line */
- X int r, c;
- X
- X flushbuf();
- X VioGetCurPos(&r, &c, 0);
- X VioScrollUp(r, 0, 100, 100, 1, cell, 0);
- X return;
- X }
- X if (strcmp(s, T_IL) == 0) { /* insert line */
- X int r, c;
- X
- X flushbuf();
- X VioGetCurPos(&r, &c, 0);
- X VioScrollDn(r, 0, 100, 100, 1, cell, 0);
- X return;
- X }
- X
- X while (*s) {
- X outone(*s++);
- X }
- X}
- X
- Xvoid
- Xbeep()
- X{
- X in ( P(P_VB) )
- X vbeep();
- X else
- X outone('\007');
- X}
- X
- Xsleep(n)
- Xint n;
- X{
- X DosSleep(1000L * n);
- X}
- X
- Xvoid
- Xpause()
- X{
- X flushbuf();
- X DosSleep(300L);
- X}
- X
- Xvoid
- Xsig()
- X{
- X signal(SIGINT, sig);
- X
- X got_int = TRUE;
- X}
- X
- Xvoid
- Xwindinit()
- X{
- X Columns = 80;
- X P(P_LI) = Rows = 25;
- X
- X signal(SIGINT, sig);
- X}
- X
- Xvoid
- Xwindexit(r)
- Xint r;
- X{
- X flushbuf();
- X exit(r);
- X}
- X
- Xvoid
- Xwindgoto(r, c)
- Xregister int r, c;
- X{
- X r += 1;
- X c += 1;
- X
- X /*
- X * Check for overflow once, to save time.
- X */
- X if (bpos + 8 >= BSIZE)
- X flushbuf();
- X
- X outbuf[bpos++] = '\033';
- X outbuf[bpos++] = '[';
- X if (r >= 10)
- X outbuf[bpos++] = r/10 + '0';
- X outbuf[bpos++] = r%10 + '0';
- X outbuf[bpos++] = ';';
- X if (c >= 10)
- X outbuf[bpos++] = c/10 + '0';
- X outbuf[bpos++] = c%10 + '0';
- X outbuf[bpos++] = 'H';
- X}
- X
- XFILE *
- Xfopenb(fname, mode)
- Xchar *fname;
- Xchar *mode;
- X{
- X FILE *fopen();
- X char modestr[16];
- X
- X sprintf(modestr, "%sb", mode);
- X return fopen(fname, modestr);
- X}
- X
- X#define PSIZE 128
- X
- X/*
- X * fixname(s) - fix up a dos name
- X *
- X * Takes a name like:
- X *
- X * \x\y\z\base.ext
- X *
- X * and trims 'base' to 8 characters, and 'ext' to 3.
- X */
- Xchar *
- Xfixname(s)
- Xchar *s;
- X{
- X char *strchr(), *strrchr();
- X static char f[PSIZE];
- X char base[32];
- X char ext[32];
- X char *p;
- X int i;
- X
- X strcpy(f, s);
- X
- X for (i=0; i < PSIZE ;i++)
- X if (f[i] == '/')
- X f[i] = '\\';
- X
- X /*
- X * Split the name into directory, base, extension.
- X */
- X if ((p = strrchr(f, '\\')) != NULL) {
- X strcpy(base, p+1);
- X p[1] = '\0';
- X } else {
- X strcpy(base, f);
- X f[0] = '\0';
- X }
- X
- X if ((p = strchr(base, '.')) != NULL) {
- X strcpy(ext, p+1);
- X *p = '\0';
- X } else
- X ext[0] = '\0';
- X
- X /*
- X * Trim the base name if necessary.
- X */
- X if (strlen(base) > 8)
- X base[8] = '\0';
- X
- X if (strlen(ext) > 3)
- X ext[3] = '\0';
- X
- X /*
- X * Paste it all back together
- X */
- X strcat(f, base);
- X strcat(f, ".");
- X strcat(f, ext);
- X
- X return f;
- X}
- X
- Xvoid
- Xdoshell(cmd)
- Xchar *cmd;
- X{
- X if (cmd == NULL)
- X cmd = "cmd.exe";
- X
- X system(cmd);
- X wait_return();
- X}
- X
- X/*
- X * FILL IT IN, FOR YOUR SYSTEM, AND SHARE IT!
- X *
- X * The next couple of functions do system-specific stuff.
- X * They currently do nothing; I'm not familiar enough with
- X * system-specific programming on this system.
- X * If you fill it in for your system, please post the results
- X * and share with the rest of us.
- X */
- X
- X
- Xsetcolor (c)
- X/*
- X * Set the color to c, using the local system convention for numbering
- X * colors or video attributes.
- X *
- X * If you implement this, remember to note the original color in
- X * windinit(), before you do any setcolor() commands, and
- X * do a setcolor() back to the original as part of windexit().
- X */
- X int c:
- X{
- X}
- X
- X
- Xsetrows (r)
- X/*
- X * Set the number of lines to r, if possible. Otherwise
- X * "do the right thing". Return the number of lines actually set.
- X *
- X * If you implement this, remember to note the original number of rows
- X * in windinit(), before you do any setrows() commands, and
- X * do a setrows() back to the original as part of windexit().
- X */
- X int r;
- X{
- X /* Since we do nothing, just return the current number of lines */
- X return ( P(P_LI) );
- X}
- X
- X
- Xvbeep ()
- X/*
- X * Do a "visual bell". This generally consists of flashing the screen
- X * once in inverse video.
- X */
- X{
- X int color, revco;
- X
- X color = P( P_CO ); /* get current color */
- X revco = reverse_color (color); /* system-specific */
- X setcolor (revco);
- X flushbuf ();
- X pause ();
- X setcolor (color);
- X windgoto (Cursrow, Curscol);
- X flushbuf ();
- X}
- X
- Xreverse_color (co)
- X/*
- X * Returns the inverse video attribute or color of co.
- X * The existing code below is VERY simple-minded.
- X * Replace it with proper code for your system.
- X */
- X int co;
- X{
- X if (co) return (0);
- X else return (1);
- X}
- X
- X
- X/********** End of do-it-yourself kit **********************/
- X
- !EOR!
- echo extracting - unix.c
- sed 's/^X//' > unix.c << '!EOR!'
- X/* $Header: /nw/tony/src/stevie/src/RCS/unix.c,v 1.8 89/08/06 09:51:13 tony Exp $
- X *
- X * System-dependent routines for UNIX System V or Berkeley.
- X */
- X
- X#include "stevie.h"
- X#ifdef BSD
- X#include <sgtty.h>
- X#else
- X#include <termio.h>
- X#endif
- X#include <signal.h>
- X
- X/*
- X * inchar() - get a character from the keyboard
- X */
- Xint
- Xinchar()
- X{
- X char c;
- X
- X flushbuf(); /* flush any pending output */
- X
- X do {
- X while (read(0, &c, 1) != 1)
- X ;
- X } while (c == NUL);
- X
- X got_int = FALSE;
- X return c;
- X}
- X
- X#define BSIZE 2048
- Xstatic char outbuf[BSIZE];
- Xstatic int bpos = 0;
- X
- Xvoid
- Xflushbuf()
- X{
- X if (bpos != 0)
- X write(1, outbuf, bpos);
- X bpos = 0;
- X}
- X
- X/*
- X * Macro to output a character. Used within this file for speed.
- X */
- X#define outone(c) outbuf[bpos++] = c; if (bpos >= BSIZE) flushbuf()
- X
- X/*
- X * Function version for use outside this file.
- X */
- Xvoid
- Xoutchar(c)
- Xchar c;
- X{
- X outone(c);
- X}
- X
- Xvoid
- Xoutstr(s)
- Xregister char *s;
- X{
- X while (*s) {
- X outone(*s++);
- X }
- X}
- X
- Xvoid
- Xbeep()
- X{
- X if ( P(P_VB) )
- X vbeep ();
- X else
- X outone('\007');
- X}
- X
- X/*
- X * remove(file) - remove a file
- X */
- Xvoid
- Xremove(file)
- Xchar *file;
- X{
- X unlink(file);
- X}
- X
- X/*
- X * rename(of, nf) - rename existing file 'of' to 'nf'
- X */
- Xvoid
- Xrename(of, nf)
- Xchar *of, *nf;
- X{
- X unlink(nf);
- X link(of, nf);
- X unlink(of);
- X}
- X
- Xvoid
- Xpause()
- X{
- X sleep (1);
- X}
- X
- X#ifdef BSD
- Xstatic struct sgttyb ostate;
- X#else
- Xstatic struct termio ostate;
- X#endif
- X
- X/*
- X * Go into cbreak mode
- X */
- Xvoid
- Xset_tty()
- X{
- X#ifdef BSD
- X struct sgttyb nstate;
- X
- X ioctl(0, TIOCGETP, &ostate);
- X nstate = ostate;
- X nstate.sg_flags &= ~(XTABS|CRMOD|ECHO);
- X nstate.sg_flags |= CBREAK;
- X ioctl(0, TIOCSETN, &nstate);
- X#else
- X struct termio nstate;
- X
- X ioctl(0, TCGETA, &ostate);
- X nstate = ostate;
- X nstate.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
- X nstate.c_cc[VMIN] = 1;
- X nstate.c_cc[VTIME] = 0;
- X ioctl(0, TCSETAW, &nstate);
- X#endif
- X}
- X
- X/*
- X * Restore original terminal modes
- X */
- Xvoid
- Xreset_tty()
- X{
- X#ifdef BSD
- X ioctl(0, TIOCSETP, &ostate);
- X#else
- X ioctl(0, TCSETAW, &ostate);
- X#endif
- X}
- X
- Xvoid
- Xsig()
- X{
- X signal(SIGINT, sig);
- X signal(SIGQUIT, sig);
- X
- X got_int = TRUE;
- X}
- X
- Xvoid
- Xwindinit()
- X{
- X#ifdef TERMCAP
- X if (t_init() != 1) {
- X fprintf(stderr, "unknown terminal type\n");
- X exit(1);
- X }
- X#else
- X Columns = 80;
- X P(P_LI) = Rows = 24;
- X#endif
- X
- X /*
- X * The code here makes sure that there isn't a window during which
- X * we could get interrupted and exit with the tty in a weird state.
- X */
- X signal(SIGINT, sig);
- X signal(SIGQUIT, sig);
- X
- X set_tty();
- X
- X if (got_int)
- X windexit(0);
- X}
- X
- Xvoid
- Xwindexit(r)
- Xint r;
- X{
- X reset_tty();
- X exit(r);
- X}
- X
- Xvoid
- Xwindgoto(r, c)
- Xregister int r, c;
- X{
- X#ifdef TERMCAP
- X char *tgoto();
- X#else
- X r += 1;
- X c += 1;
- X#endif
- X
- X /*
- X * Check for overflow once, to save time.
- X */
- X if (bpos + 8 >= BSIZE)
- X flushbuf();
- X
- X#ifdef TERMCAP
- X outstr(tgoto(T_CM, c, r));
- X#else
- X outbuf[bpos++] = '\033';
- X outbuf[bpos++] = '[';
- X if (r >= 10)
- X outbuf[bpos++] = r/10 + '0';
- X outbuf[bpos++] = r%10 + '0';
- X outbuf[bpos++] = ';';
- X if (c >= 10)
- X outbuf[bpos++] = c/10 + '0';
- X outbuf[bpos++] = c%10 + '0';
- X outbuf[bpos++] = 'H';
- X#endif
- X}
- X
- XFILE *
- Xfopenb(fname, mode)
- Xchar *fname;
- Xchar *mode;
- X{
- X return fopen(fname, mode);
- X}
- X
- Xchar *
- Xfixname(s)
- Xchar *s;
- X{
- X return s;
- X}
- X
- X/*
- X * doshell() - run a command or an interactive shell
- X */
- Xvoid
- Xdoshell(cmd)
- Xchar *cmd;
- X{
- X char *getenv();
- X char cline[128];
- X
- X outstr("\r\n");
- X flushbuf();
- X
- X if (cmd == NULL) {
- X if ((cmd = getenv("SHELL")) == NULL)
- X cmd = "/bin/sh";
- X sprintf(cline, "%s -i", cmd);
- X cmd = cline;
- X }
- X
- X reset_tty();
- X system(cmd);
- X set_tty();
- X
- X wait_return();
- X}
- X
- X
- X/*
- X * FILL IT IN, FOR YOUR SYSTEM, AND SHARE IT!
- X *
- X * The next couple of functions do system-specific stuff.
- X * They currently do nothing; I'm not familiar enough with
- X * system-specific programming on this system.
- X * If you fill it in for your system, please post the results
- X * and share with the rest of us.
- X */
- X
- X
- Xsetcolor (c)
- X/*
- X * Set the color to c, using the local system convention for numbering
- X * colors or video attributes.
- X *
- X * If you implement this, remember to note the original color in
- X * windinit(), before you do any setcolor() commands, and
- X * do a setcolor() back to the original as part of windexit().
- X */
- X int c;
- X{
- X /* Dummy routine, just return 0 */
- X return (0);
- X}
- X
- X
- Xsetrows (r)
- X/*
- X * Set the number of lines to r, if possible. Otherwise
- X * "do the right thing". Return the number of lines actually set.
- X *
- X * If you implement this, remember to note the original number of rows
- X * in windinit(), before you do any setrows() commands, and
- X * do a setrows() back to the original as part of windexit().
- X */
- X int r;
- X{
- X /* Since we do nothing, just return the current number of lines */
- X return ( P(P_LI) );
- X}
- X
- X
- Xvbeep ()
- X/*
- X * Do a "visual bell". This generally consists of flashing the screen
- X * once in inverse video.
- X */
- X{
- X int color, revco;
- X
- X color = P( P_CO ); /* get current color */
- X revco = reverse_color (color); /* system-specific */
- X setcolor (revco);
- X flushbuf ();
- X pause ();
- X setcolor (color);
- X windgoto (Cursrow, Curscol);
- X flushbuf ();
- X}
- X
- Xreverse_color (co)
- X/*
- X * Returns the inverse video attribute or color of co.
- X * The existing code below is VERY simple-minded.
- X * Replace it with proper code for your system.
- X */
- X int co;
- X{
- X if (co) return (0);
- X else return (1);
- X}
- X
- X
- X/********** End of do-it-yourself kit **********************/
- !EOR!
- echo extracting - setenv.c
- sed 's/^X//' > setenv.c << '!EOR!'
- X/*****************************************************************************
- X * A program for adding or changing environment variable values for MSDOS.
- X * The "set" command provided by command.com is very limited. It fails to
- X * provide the ability to use quotation marks and escape characters and
- X * octal/hex constants in the value definition. Setenv provides these
- X * abilities.
- X *
- X * Usage notes:
- X *
- X * setenv <symbol> = <value>
- X *
- X * <symbol> ::= legal MSDOS environment symbol. Lower case converted
- X * to uppercase.
- X *
- X * <value> ::= environment symbol value in one of three forms:
- X *
- X * * No quotation marks. The value is the literal string
- X * of characters starting IMMEDIATELY after the equal
- X * sign and extending to the end-of-line.
- X *
- X * * Single quotation marks ('). The value is the literal
- X * string enclosed in quotation marks.
- X *
- X * * Double quotation marks ("). The value is the string
- X * enclosed in double quotation marks. Backslash escape
- X * constructions are processed -- this includes the usual
- X * C language constructions such as \n for newline and
- X * \r for carriage return plus octal and hexadecimal
- X * constants (\ddd & \0xdd, respectively).
- X *****************************************************************************/
- X
- X/*****************************************************************************
- X * Based on a program by Alan J Myrvold (ajmyrvold@violet.waterloo.edu)
- X *
- X * WARNING WARNING WARNING - virtually no error checking is done !!
- X * use at own risk !!
- X *
- X * This program by Larry A. Shurr (las@cbema.ATT.COM)
- X *
- X * I added checking for env seg overrun, so now it's a little more robust.
- X *****************************************************************************/
- X
- X/*****************************************************************************
- X *
- X * Notes by Alan J Myrgold:
- X *
- X * Technical information : A program's PSP contains a pointer at
- X * offset 44 (decimal) to a COPY of the parent's environment.
- X * The environment is a set of strings of the form NAME=value,
- X * each terminated by a NULL byte.
- X * An additional NULL byte marks the end of the environment.
- X * The environment area is ALWAYS paragraph aligned
- X * i.e. on a 16 byte boundary.
- X *
- X * Searching backwards from the PSP, I consistently find
- X * two copies of the envronment area.
- X *
- X * The program : finds the two areas
- X * reads one into memory
- X * udpates the specified environment variable
- X * writes updated environment to parent environment
- X *****************************************************************************/
- X
- X#include <stdio.h>
- X#include <stdlib.h>
- X#include <string.h>
- X#include <time.h>
- X#include <process.h>
- X#include <conio.h>
- X#include <dos.h>
- X
- X#define FALSE 0
- X#define TRUE 1
- X
- Xstruct mcb { /* MSDOS Memory Control Block */
- X unsigned char tag4D; /* Tag field must = 0x4D */
- X unsigned int next; /* Segment base for next block */
- X unsigned int size; /* Memory block size in paragraphs */
- X};
- X
- X
- Xunsigned env_size = 0; /* Maintain size of environment */
- X/***************************************************************************/
- Xint env_size_bytes(unsigned env_seg)
- X/* Determine the length of the environment area in bytes */
- X{
- X int n;
- X
- X n = 0;
- X while (peekb(env_seg,n) != 0) {
- X while (peekb(env_seg,n) != 0) n++;
- X n++;
- X }
- X return(n);
- X}
- X/***************************************************************************/
- Xint env_size_strings(unsigned env_seg)
- X/* Determine how many strings are in the environment area */
- X{
- X int k,n;
- X
- X k = n = 0;
- X while (peekb(env_seg,n) != 0) {
- X k++;
- X while (peekb(env_seg,n) != 0) n++;
- X n++;
- X }
- X return(k);
- X}
- X/***************************************************************************/
- Xint peek_cmp(unsigned seg1,unsigned seg2,int nbytes)
- X/* A trivial compare routine for segement aligned data items */
- X{
- X int i;
- X
- X for (i = 0; (i < nbytes) && (peekb(seg1,i) == peekb(seg2,i)); i++);
- X return(i == nbytes);
- X}
- X/***************************************************************************/
- Xvoid find_env(unsigned seg_ray[2])
- X{
- X unsigned psp_seg,copy_of_seg,env_seg;
- X int k,n;
- X
- X/* Find first copy of environment */
- X psp_seg = _psp;
- X copy_of_seg = peek(psp_seg,44);
- X
- X/* Set return value to non-garabage */
- X seg_ray[0] = seg_ray[1] = copy_of_seg;
- X
- X/* Search back to find 2 copies of environment */
- X env_size = n = env_size_bytes(copy_of_seg);
- X env_seg = copy_of_seg - 1;
- X for (k = 0; (env_seg != 0) && (k < 2); k++) {
- X while ((env_seg != 0) &&
- X (peek_cmp(copy_of_seg,env_seg,n) == 0)) {
- X env_seg--;
- X }
- X if (env_seg != 0) {
- X seg_ray[k] = env_seg;
- X env_seg--;
- X }
- X }
- X
- X/* If not found, display error message and abort */
- X if (k != 2) {
- X fprintf(stderr,"Two copies of the environment were not found\n");
- X exit(-1);
- X }
- X}
- X/***************************************************************************/
- Xvoid read_env(unsigned env_seg,int *k,char ***s,char ***t)
- X/* Read environment into a malloc'd array of malloc'd strings */
- X{
- X int i,j,n;
- X
- X env_size = env_size_bytes(env_seg);
- X
- X *k = env_size_strings(env_seg);
- X *s = (char **) malloc((*k)*sizeof(char *));
- X *t = (char **) malloc((*k)*sizeof(char *));
- X
- X n = 0;
- X for (i = 0; i < *k; i++) {
- X for (j = 0; peekb(env_seg,n+j) != '='; j++);
- X (*s)[i] = (char *) malloc(j+1);
- X for (j = 0; peekb(env_seg,n+j) != '='; j++)
- X ((*s)[i])[j] = peekb(env_seg,n+j);
- X ((*s)[i])[j] = 0;
- X n += j + 1;
- X for (j = 0; peekb(env_seg,n+j) != 0; j++);
- X (*t)[i] = (char *) malloc(j+1);
- X for (j = 0; peekb(env_seg,n+j) != 0; j++)
- X ((*t)[i])[j] = peekb(env_seg,n+j);
- X ((*t)[i])[j] = 0;
- X n += j + 1;
- X }
- X}
- X/***************************************************************************/
- Xvoid write_env(unsigned env_seg, int k, char **s, char **t)
- X/* Write the environment back out to memory */
- X{
- X int i,j,n;
- X
- X struct mcb far *tmcb = (struct mcb far *)((long)(env_seg-1) << 16);
- X
- X if (tmcb->tag4D == 0x4D) {
- X unsigned env_seg_siz = tmcb->size << 4;
- X if (env_size < env_seg_siz) {
- X for (n = i = 0; i < k; i++) {
- X char *si = s[i];
- X char *ti = t[i];
- X for (j = 0; si[j] != 0; j++) pokeb(env_seg,n++,si[j]);
- X pokeb(env_seg,n++,'=');
- X for (j = 0; ti[j] != 0; j++) pokeb(env_seg,n++,ti[j]);
- X pokeb(env_seg,n++,0);
- X }
- X pokeb(env_seg,n,0);
- X } else {
- X fprintf(stderr,"Insufficient space in environment\n");
- X exit(-1);
- X }
- X } else {
- X fprintf(stderr,"Environment memory control block trashed\n");
- X exit(-1);
- X }
- X}
- X/***************************************************************************/
- Xchar *get_env_var(int k,char **s,char **t,char *var)
- X/* Return the value of the environment variable or NULL if not found */
- X{
- X char *val;
- X int i;
- X
- X val = NULL;
- X for (i = 0; i < k; i++) if (stricmp(s[i],var) == 0) val = t[i];
- X
- X return(val);
- X}
- X
- X/***************************************************************************/
- Xvoid set_env_var(int *k,char ***s,char ***t,char *var,char *val)
- X/* Set a new or existing environment variable to a new value */
- X{
- X int i,done;
- X
- X done = 0;
- X for (i = 0; i < *k; i++) {
- X if (stricmp((*s)[i],var) == 0) {
- X /* Existing variable */
- X done = 1;
- X env_size -= strlen((*t)[i]);
- X free((*t)[i]);
- X (*t)[i] = (char *) malloc(1+strlen(val));
- X strcpy((*t)[i],val);
- X env_size += strlen((*t)[i]);
- X }
- X }
- X
- X if (!done) {
- X /* New environment variable */
- X (*k)++;
- X *s = realloc(*s,(*k)*sizeof(char *));
- X *t = realloc(*t,(*k)*sizeof(char *));
- X (*s)[*k-1] = (char *) malloc(1+strlen(var));
- X strcpy((*s)[*k-1],var);
- X strupr((*s)[*k-1]);
- X (*t)[*k-1] = (char *) malloc(1+strlen(val));
- X strcpy((*t)[*k-1],val);
- X /* Length of name + length of '=' + length of value + length of '\0' */
- X env_size += (strlen((*s)[*k-1]) + 1 + strlen((*t)[*k-1]) + 1);
- X }
- X}
- X/***************************************************************************/
- Xvoid show_env(int k,char **s,char **t)
- X/* Display the array of environment strings */
- X{
- X int i;
- X for (i = 0; i < k; i++) printf("%s=%s\n",s[i],t[i]);
- X}
- X/***************************************************************************/
- Xvoid get_cmdline(char *cmd)
- X/* Read raw command line text into string buffer */
- X{
- X char far *pcmd;
- X
- X int idx,odx;
- X
- X pcmd = (char far *)((long)_psp << 16) + 128L;
- X
- X for (idx = *pcmd++, odx = 0; idx > 0; idx--, odx++) {
- X cmd[odx] = *pcmd++;
- X }
- X
- X cmd[odx] = '\0';
- X}
- X/***************************************************************************/
- Xchar_in(char ch, char *set)
- X/* Determine if a character is in a set of characters */
- X{
- X do {
- X if (ch == *set) return(TRUE);
- X } while ((int)*(++set));
- X return(FALSE);
- X}
- X/***************************************************************************/
- Xchar get_num(char *cmd, int *pidx)
- X/* Interpret octal or hexadecimal constant in string */
- X{
- X int accum = 0;
- X char ch;
- X int f_scan = TRUE;
- X int idx = *pidx;
- X int limit;
- X char *nch = cmd+idx;
- X char *och = nch+1;
- X int radix;
- X
- X#define HEXDIG "0123456789ABCDEFabcdef"
- X
- X if (*nch == '0' && char_in(*och,"xX") && char_in(*(och+1),HEXDIG)) {
- X radix = 16;
- X limit = 2;
- X och += 1;
- X } else {
- X radix = 8;
- X limit = 3;
- X och = nch;
- X }
- X
- X while (limit-- > 0 && f_scan) {
- X
- X f_scan = FALSE;
- X
- X while ((int)(*nch)) *nch++ = *och++;
- X
- X nch = cmd+idx;
- X och = nch+1;
- X
- X switch (ch = *nch) {
- X case '0' :
- X case '1' :
- X case '2' :
- X case '3' :
- X case '4' :
- X case '5' :
- X case '6' :
- X case '7' :
- X case '8' :
- X case '9' :
- X if (ch == 9 && radix == 8) break;
- X accum = accum * radix + (int)(ch - '0');
- X f_scan = TRUE;
- X break;
- X case 'A' :
- X case 'B' :
- X case 'C' :
- X case 'D' :
- X case 'E' :
- X case 'F' :
- X if (radix == 8) break;
- X accum = accum * radix + (int)(ch - 'A') + 10;
- X f_scan = TRUE;
- X break;
- X case 'a' :
- X case 'b' :
- X case 'c' :
- X case 'd' :
- X case 'e' :
- X case 'f' :
- X if (radix == 8) break;
- X accum = accum * radix + (int)(ch - 'a') + 10;
- X f_scan = TRUE;
- X break;
- X default : break;
- X }
- X }
- X
- X *pidx = idx;
- X return(accum);
- X}
- X/***************************************************************************/
- Xget_escape(char *cmd, int *pidx, char quote)
- X/* Interpret escape'd (i.e., '\' (backslash) character */
- X{
- X int idx = *pidx;
- X
- X if (quote == '"') {
- X char *nch = cmd+idx;
- X char *och = nch+1;
- X char *xch = nch;
- X while ((int)(*nch)) *nch++ = *och++;
- X switch (*xch) {
- X case 'a' : *xch = '\a'; break;
- X case 'b' : *xch = '\b'; break;
- X case 'c' : *xch = '\c'; break;
- X case 'd' : *xch = '\d'; break;
- X case 'e' : *xch = '\e'; break;
- X case 'f' : *xch = '\f'; break;
- X case 'g' : *xch = '\g'; break;
- X case 'h' : *xch = '\h'; break;
- X case 'i' : *xch = '\i'; break;
- X case 'j' : *xch = '\j'; break;
- X case 'k' : *xch = '\k'; break;
- X case 'l' : *xch = '\l'; break;
- X case 'm' : *xch = '\m'; break;
- X case 'n' : *xch = '\n'; break;
- X case 'o' : *xch = '\o'; break;
- X case 'p' : *xch = '\p'; break;
- X case 'q' : *xch = '\q'; break;
- X case 'r' : *xch = '\r'; break;
- X case 's' : *xch = '\s'; break;
- X case 't' : *xch = '\t'; break;
- X case 'u' : *xch = '\u'; break;
- X case 'v' : *xch = '\v'; break;
- X case 'w' : *xch = '\w'; break;
- X case 'x' : *xch = '\x'; break;
- X case 'y' : *xch = '\y'; break;
- X case 'z' : *xch = '\z'; break;
- X case '0' :
- X case '1' :
- X case '2' :
- X *xch = get_num(cmd, &idx);
- X break;
- X }
- X }
- X
- X *pidx = idx + 1;
- X}
- X/***************************************************************************/
- Xget_qvalue(char *cmd, int idx, char quote, char **value)
- X/* Extract a quoted value part from command line */
- X{
- X char ch;
- X int f_esc;
- X
- X *value = cmd + (++idx);
- X
- X do {
- X while ((int)(ch = cmd[idx]) && ch != '\\' && ch != quote) idx++;
- X if (!(int)ch) return(-1);
- X if (ch == '\\') {
- X f_esc = TRUE;
- X get_escape(cmd, &idx, quote);
- X } else f_esc = FALSE;
- X } while (f_esc);
- X
- X cmd[idx] = '\0';
- X
- X for (idx += 1; (int)(ch = cmd[idx]) && ch == ' '; idx++);
- X
- X if ((int)ch) return(-1);
- X
- X return(0);
- X}
- X/***************************************************************************/
- Xget_parm(char **name, char **value)
- X/* Extract environment symbol name and value from command line */
- X{
- X char ch;
- X int idx;
- X int sdx;
- X
- X static char cmd[128];
- X
- X get_cmdline(cmd);
- X
- X for (idx = 0; (int)(ch = cmd[idx]) && ch == ' '; idx++);
- X
- X if (!(int)ch) return(1);
- X
- X *name = cmd + idx;
- X
- X for (; (int)(ch = cmd[idx]) && ch != '=' && ch != ' '; idx++);
- X
- X if (!(int)ch) return(-1);
- X
- X if (ch == ' ') {
- X cmd[idx] = '\0';
- X for (idx += 1; (int)(ch = cmd[idx]) && ch != '='; idx++);
- X } else cmd[idx] = '\0';
- X
- X if (!(int)ch) return(-1);
- X
- X for (sdx = (idx += 1); (int)(ch = cmd[idx]) && ch == ' '; idx++);
- X
- X /*if (!(int)ch) return(-1);*/
- X
- X switch (ch) {
- X case '"' : return(get_qvalue(cmd, idx, '"', value));
- X case '\'' : return(get_qvalue(cmd, idx, '\'', value));
- X default : *value = cmd + sdx; break;
- X }
- X
- X return(0);
- X}
- X/***************************************************************************/
- Xmain(int argc,char **argv)
- X{
- X unsigned env_seg[2];
- X char **s,**t;
- X int k;
- X long now;
- X struct tm *local;
- X
- X static char *name = NULL, *value = NULL;
- X
- X switch (get_parm(&name,&value)) {
- X
- X case -1:
- X
- X fprintf(stderr,"Invalid symbol definition syntax\n");
- X exit(-1);
- X
- X case 0:
- X
- X /* Find and read environment */
- X
- X find_env(env_seg);
- X read_env(env_seg[1],&k,&s,&t);
- X
- X /* Set the variable <name> to <value> */
- X
- X set_env_var(&k,&s,&t,name,value);
- X
- X /* Update caller's environment */
- X
- X write_env(env_seg[0],k,s,t);
- X
- X break;
- X
- X case 1:
- X
- X fprintf(stderr,"Usage: setenv <symbol name> = <value>\n");
- X break;
- X }
- X
- X return(0);
- X}
- X/***************************************************************************/
- X
- !EOR!
- echo extracting - ctags.c
- sed 's/^X//' > ctags.c << '!EOR!'
- X/*
- X * ctags - first cut at a UNIX ctags re-implementation
- X */
- X
- X/*
- X * Caveats:
- X *
- X * Only simple function declarations are recognized, as in:
- X *
- X * type
- X * fname(...)
- X *
- X * where "fname" is the name of the function and must come at the beginning
- X * of a line. This is the form I always use, so the limitation doesn't
- X * bother me.
- X *
- X * Macros (with or without parameters) of the following form are also detected:
- X *
- X * "#" [white space] "define" [white space] NAME
- X *
- X * No sorting or detection of duplicate functions is done.
- X *
- X * If there are no arguments, a list of filenames to be searched is read
- X * from the standard input. Otherwise, all arguments are assumed to be
- X * file names.
- X *
- X * Tony Andrews
- X * August 1987
- X */
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <string.h>
- X
- Xint ac;
- Xchar **av;
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X char *fname, *nextfile();
- X FILE *tp, *fopen();
- X
- X ac = argc;
- X av = argv;
- X
- X if ((tp = fopen("tags", "w")) == NULL) {
- X fprintf(stderr, "Can't create tags file\n");
- X exit(1);
- X }
- X
- X while ((fname = nextfile()) != NULL)
- X dofile(fname, tp);
- X
- X fclose(tp);
- X exit(0);
- X}
- X
- Xchar *
- Xnextfile() /* returns ptr to next file to be searched, null at end */
- X{
- X static char buf[128];
- X static int ap = 1;
- X char *gets();
- X
- X if (ac <= 1) { /* read from stdin */
- X if (feof(stdin))
- X return (char *) NULL;
- X return (gets(buf));
- X } else {
- X if (ap < ac)
- X return av[ap++];
- X else
- X return (char *) NULL;
- X }
- X}
- X
- X#define LSIZE 512 /* max. size of a line */
- X
- X#define BEGID(c) (isalpha(c) || (c) == '_')
- X#define MIDID(c) (isalpha(c) || isdigit(c) || (c) == '_')
- X
- Xdofile(fn, tp)
- Xchar *fn;
- XFILE *tp;
- X{
- X FILE *fp, *fopen();
- X char *cp, *strchr();
- X char lbuf[LSIZE];
- X char func[LSIZE];
- X int i, j;
- X
- X if ((fp = fopen(fn, "r")) == NULL) {
- X fprintf(stderr, "Can't open file '%s' - skipping\n", fn);
- X return;
- X }
- X
- X while (fgets(lbuf, LSIZE, fp) != NULL) {
- X
- X lbuf[strlen(lbuf)-1] = '\0'; /* bag the newline */
- X
- X if (BEGID(lbuf[0])) { /* could be a function */
- X for (i=0; MIDID(lbuf[i]) ;i++) /* grab the name */
- X func[i] = lbuf[i];
- X
- X func[i] = '\0'; /* null terminate the name */
- X
- X /*
- X * We've skipped to the end of what may be a function
- X * name. Check to see if the next non-whitespace
- X * char is a paren,
- X * and make sure the closing paren is here too.
- X */
- X while (lbuf[i]==' ' || lbuf[i]=='\t') i++;
- X if (lbuf[i]=='(' && (((cp = strchr(lbuf,')'))!=NULL))) {
- X *++cp = '\0';
- X fprintf(tp, "%s\t%s\t/^%s$/\n", func,fn,lbuf);
- X }
- X
- X } else if (lbuf[0] == '#') { /* could be a define */
- X for (i=1; isspace(lbuf[i]) ;i++)
- X ;
- X if (strncmp(&lbuf[i], "define", 6) != 0)
- X continue;
- X
- X i += 6; /* skip "define" */
- X
- X for (; isspace(lbuf[i]) ;i++)
- X ;
- X
- X if (!BEGID(lbuf[i]))
- X continue;
- X
- X for (j=0; MIDID(lbuf[i]) ;i++, j++)
- X func[j] = lbuf[i];
- X
- X func[j] = '\0'; /* null terminate the name */
- X lbuf[i] = '\0';
- X fprintf(tp, "%s\t%s\t/^%s/\n", func, fn, lbuf);
- X }
- X }
- X fclose(fp);
- X}
- !EOR!
-
-
-