#! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'stevie/fileio.c' <<'END_OF_FILE' X/* $Header: /nw/tony/src/stevie/src/RCS/fileio.c,v 1.12 89/08/06 09:50:01 tony Exp $ X * X * Basic file I/O routines. X */ X X#ifndef VxWorks X# include /* For stat() and chmod() */ X# include /* Ditto */ X#endif X#include "stevie.h" X Xvoid Xfilemess(s) Xchar *s; X{ X smsg("\"%s\" %s", (Filename == NULL) ? "" : Filename, s); X flushbuf(); X} X Xvoid Xrenum() X{ X LPTR *p; X unsigned long l = 0; X X for (p = Filemem; p != NULL ;p = nextline(p), l += LINEINC) X p->linep->num = l; X X Fileend->linep->num = 0xffffffff; X} X X#define MAXLINE 256 /* maximum size of a line */ X Xbool_t Xreadfile(fname,fromp,nochangename) X/*------------------------------------------------- X * Note that this will try to expand the file name using environment X * variables. For this reason, we copy it into an 80-byte buffer, X * so that there's room to expand it. X * X * It uses the environment-variable convention of UNIX, even X * under systems with other conventions. That is, your home directory X * would be called $HOME (even in DOS, where you might want to say %HOME%) X *-----------------------------------------------------*/ Xchar *fname; XLPTR *fromp; Xbool_t nochangename; /* if TRUE, don't change the Filename */ X{ X FILE *f, *fopen(); X register LINE *curr; X char buff[MAXLINE], buf2[80]; X char namebuf[80]; X register int i, c; X register long nchars = 0; X int linecnt = 0; X bool_t wasempty = bufempty(); X int nonascii = 0; /* count garbage characters */ X int nulls = 0; /* count nulls */ X bool_t incomplete = FALSE; /* was the last line incomplete? */ X bool_t toolong = FALSE; /* a line was too long */ X X curr = fromp->linep; X X strncpy (namebuf, fname, 80); X EnvEval (namebuf, 80); X X if ( ! nochangename ) X Filename = strsave(namebuf); X X if ( (f=fopen(fixname(namebuf),"r")) == NULL ) X return TRUE; X X filemess(""); X X i = 0; X do { X c = getc(f); X X if (c == EOF) { X if (i == 0) /* normal loop termination */ X break; X X /* X * If we get EOF in the middle of a line, note the X * fact and complete the line ourselves. X */ X incomplete = TRUE; X c = NL; X } X X /* X * Abort if we get an interrupt, but finished reading the X * current line first. X */ X if (got_int && i == 0) X break; X X if (c >= 0x80) { X c -= 0x80; X nonascii++; X } X X /* X * If we reached the end of the line, OR we ran out of X * space for it, then process the complete line. X */ X if (c == NL || i == (MAXLINE-1)) { X LINE *lp; X X if (c != NL) X toolong = TRUE; X X buff[i] = '\0'; X if ((lp = newline(strlen(buff))) == NULL) X exit(1); X X strcpy(lp->s, buff); X X curr->next->prev = lp; /* new line to next one */ X lp->next = curr->next; X X curr->next = lp; /* new line to prior one */ X lp->prev = curr; X X curr = lp; /* new line becomes current */ X i = 0; X linecnt++; X X } else if (c == NUL) X nulls++; /* count and ignore nulls */ X else { X buff[i++] = c; /* normal character */ X } X X nchars++; X X } while (!incomplete && !toolong); X X fclose(f); X X /* X * If the buffer was empty when we started, we have to go back X * and remove the "dummy" line at Filemem and patch up the ptrs. X */ X if (wasempty && nchars != 0) { X LINE *dummy = Filemem->linep; /* dummy line ptr */ X X free(dummy->s); /* free string space */ X Filemem->linep = Filemem->linep->next; X free((char *)dummy); /* free LINE struct */ X Filemem->linep->prev = Filetop->linep; X Filetop->linep->next = Filemem->linep; X X Curschar->linep = Filemem->linep; X Topchar->linep = Filemem->linep; X } X X renum(); X X if (got_int) { X smsg("\"%s\" Interrupt", namebuf); X got_int = FALSE; X return FALSE; /* an interrupt isn't really an error */ X } X X if (toolong) { X smsg("\"%s\" Line too long", namebuf); X return FALSE; X } X X sprintf(buff, "\"%s\" %s%d line%s, %ld character%s", X namebuf, X incomplete ? "[Incomplete last line] " : "", X linecnt, (linecnt != 1) ? "s" : "", X nchars, (nchars != 1) ? "s" : ""); X X buf2[0] = NUL; X X if (nonascii || nulls) { X if (nonascii) { X if (nulls) X sprintf(buf2, " (%d null, %d non-ASCII)", X nulls, nonascii); X else X sprintf(buf2, " (%d non-ASCII)", nonascii); X } else X sprintf(buf2, " (%d null)", nulls); X } X strcat(buff, buf2); X msg(buff); X X return FALSE; X} X X X/* X * writeit - write to file 'fname' lines 'start' through 'end' X * X * If either 'start' or 'end' contain null line pointers, the default X * is to use the start or end of the file respectively. X */ Xbool_t Xwriteit(fname, start, end) Xchar *fname; XLPTR *start, *end; X{ X int err; X FILE *f, *fopen(); X FILE *fopenb(); /* open in binary mode, where needed */ X char *backup; X register char *s; X register long nchars; X register int lines; X register LPTR *p; X#ifndef VxWorks X struct stat statbuf; X int statres; X#endif X X smsg("\"%s\"", fname); X X /* Expand any environment variables left in the name. X * fname better be in a variable big enough to handle the X * expansion (80 bytes). X */ X EnvEval (fname, 80); X X#ifndef VxWorks X /* If the file already exists, get what we need to know X * (like current mode). X */ X statres = stat (fname, &statbuf); X#endif X X /* X * Form the backup file name - change foo.* to foo.bak X */ X backup = alloc((unsigned) (strlen(fname) + 5)); X if (backup == NULL) { X emsg("Out of malloc() memory!"); X return FALSE; X } X X strcpy(backup, fname); X for (s = backup; *s && *s != '.' ;s++) X ; X *s = NUL; X strcat(backup, ".bak"); X X /* X * Delete any existing backup and move the current version X * to the backup. For safety, we don't remove the backup X * until the write has finished successfully. And if the X * 'backup' option is set, leave it around. X * For VxWorks, renaming is conditional on the 'backup' option, X * and we never leave the backup around. X */ X#ifdef VxWorks X if (P(P_BK)) X _rename(fname, backup); /* we use _rename() to not step on rename() X in usrLib */ X else X delete(fname); /* delete original file, so that we can X do optimum squeeze below */ X# ifdef RT11 X /* squeeze RT-11 disk */ X squeeze(fname); /* no use checking for errors */ X# endif X#else X rename(fname, backup); X#endif X X X /* in VxWorks, and in fact unix in general, P_CR has no effect */ X f = P(P_CR) ? fopen(fixname(fname), "w") : fopenb(fixname(fname), "w"); X X if (f == NULL) { X emsg("Can't open file for writing!"); X free(backup); X return FALSE; X } X X /* X * If we were given a bound, start there. Otherwise just X * start at the beginning of the file. X */ X if (start == NULL || start->linep == NULL) X p = Filemem; X else X p = start; X X lines = nchars = 0; X do { X err=fprintf(f, "%s\n", p->linep->s); X if (err==EOF) { X emsg("Error: write failed or disk full!"); X fclose(f); X free(backup); X return FALSE; X } X X nchars += strlen(p->linep->s) + 1; X lines++; X X /* X * If we were given an upper bound, and we just did that X * line, then bag it now. X */ X if (end != NULL && end->linep != NULL) { X if (end->linep == p->linep) X break; X } X X } while ((p = nextline(p)) != NULL); X X err=fclose(f); X if (err==EOF) { X emsg("Error: write failed or disk full!"); X free(backup); X return FALSE; X } X X smsg("\"%s\" %d line%s, %ld character%s", fname, X lines, (lines > 1) ? "s" : "", X nchars, (nchars > 1) ? "s" : ""); X X UNCHANGED; X X /* X * Remove the backup unless they want it left around X * (always remove in VxWorks) X */ X#ifndef VxWorks X if (!P(P_BK)) X#endif X remove(backup); X X free(backup); X X#ifndef VxWorks X /* X * Set the mode of the new file to agree with the old. X */ X if (statres==0) X chmod (fname, statbuf.st_mode); X#endif X X return TRUE; X} END_OF_FILE if test 7765 -ne `wc -c <'stevie/fileio.c'`; then echo shar: \"'stevie/fileio.c'\" unpacked with wrong size! fi # end of 'stevie/fileio.c' fi if test -f 'stevie/main.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'stevie/main.c'\" else echo shar: Extracting \"'stevie/main.c'\" \(8183 characters\) sed "s/^X//" >'stevie/main.c' <<'END_OF_FILE' X/* $Header: /nw/tony/src/stevie/src/RCS/main.c,v 1.12 89/08/02 19:53:27 tony Exp $ X * X * The main routine and routines to deal with the input buffer. X */ X X#include "stevie.h" X Xint Rows; /* Number of Rows and Columns */ Xint Columns; /* in the current window. */ X Xchar *Realscreen = NULL; /* What's currently on the screen, a single */ X /* array of size Rows*Columns. */ Xchar *Nextscreen = NULL; /* What's to be put on the screen. */ X Xchar *Filename = NULL; /* Current file name */ X XLPTR *Filemem; /* Pointer to the first line of the file */ X XLPTR *Filetop; /* Line 'above' the start of the file */ X XLPTR *Fileend; /* Pointer to the end of the file in Filemem. */ X /* (It points to the byte AFTER the last byte.) */ X XLPTR *Topchar; /* Pointer to the byte in Filemem which is */ X /* in the upper left corner of the screen. */ X XLPTR *Botchar; /* Pointer to the byte in Filemem which is */ X /* just off the bottom of the screen. */ X XLPTR *Curschar; /* Pointer to byte in Filemem at which the */ X /* cursor is currently placed. */ X Xint Cursrow, Curscol; /* Current position of cursor */ X Xint Cursvcol; /* Current virtual column, the column number of */ X /* the file's actual line, as opposed to the */ X /* column number we're at on the screen. This */ X /* makes a difference on lines that span more */ X /* than one screen line. */ X Xint Curswant = 0; /* The column we'd like to be at. This is used */ X /* try to stay in the same column through up/down */ X /* cursor motions. */ X Xbool_t set_want_col; /* If set, then update Curswant the next time */ X /* through cursupdate() to the current virtual */ X /* column. */ X Xint State = NORMAL; /* This is the current state of the command */ X /* interpreter. */ X Xint Prenum = 0; /* The (optional) number before a command. */ X XLPTR *Insstart; /* This is where the latest insert/append */ X /* mode started. */ X Xbool_t Changed = 0; /* Set to 1 if something in the file has been */ X /* changed and not written out. */ X Xchar Redobuff[1024]; /* Each command should stuff characters into this */ X /* buffer that will re-execute itself. */ X Xchar Insbuff[1024]; /* Each insertion gets stuffed into this buffer. */ X Xint Ninsert = 0; /* Number of characters in the current insertion. */ Xchar *Insptr = NULL; X Xbool_t got_int=FALSE; /* set to TRUE when an interrupt occurs (if possible) */ X Xbool_t interactive = FALSE; /* set TRUE when main() is ready to roll */ X X#ifdef VxWorks Xchar* DfltTerm = NULL; /* terminal type if specified in cmd line */ X#endif X Xchar **files; /* list of input files */ Xint numfiles; /* number of input files */ Xint curfile; /* number of the current file */ X Xstatic void Xusage() X{ X X#ifdef VxWorks X fprintf(stderr, "Usage: vi [\"file\" ...]\n"); X fprintf(stderr, " vi \"-t[erm]\",\"term\"[,\"file\" ...]\n"); X/* fprintf(stderr, " vi \"-ta[g]\",\"tag\"\n"); */ X fprintf(stderr, " vi \"+[num]\",\"file\"\n"); X fprintf(stderr, " vi \"+/pat\",\"file\"\n"); X#else X fprintf(stderr, "Usage: stevie [file ...]\n"); X fprintf(stderr, " stevie -t tag\n"); X fprintf(stderr, " stevie +[num] file\n"); X fprintf(stderr, " stevie +/pat file\n"); X#endif /* VxWorks */ X exit(1); X} X Xmain(argc,argv) Xint argc; Xchar *argv[]; X{ X char *initstr, *getenv(); /* init string from the environment */ X char *tag = NULL; /* tag from command line */ X char *pat = NULL; /* pattern from command line */ X int line = -1; /* line number from command line */ X int l; /* length of option word */ X X /* X * Process the command line arguments. X */ X if (argc > 1) { X switch (argv[1][0]) { X X case '-': /* -tag or -term */ X l=strlen(argv[1]); X if (l<2 || argv[2]==NULL) { X usage(); X } X X#ifdef VxWorks X if (strncmp("-term",argv[1],l)==0) { X DfltTerm=argv[2]; X if (argc>3) { X Filename = strsave(argv[3]); X files = &(argv[3]); X numfiles = argc - 3; X } X else { X Filename = NULL; X numfiles = 1; X } X } X else X#endif /* VxWorks */ X if (strncmp("-tag",argv[1],l)==0) { X Filename = NULL; X tag = argv[2]; X numfiles = 1; X } X else { X usage(); X } X break; X X case '+': /* +n or +/pat */ X if (argv[1][1] == '/') { X if (argv[2] == NULL) X usage(); X Filename = strsave(argv[2]); X pat = &(argv[1][1]); X numfiles = 1; X X } else if (isdigit(argv[1][1]) || argv[1][1] == NUL) { X if (argv[2] == NULL) X usage(); X Filename = strsave(argv[2]); X numfiles = 1; X X line = (isdigit(argv[1][1])) ? X atoi(&(argv[1][1])) : 0; X } else X usage(); X X break; X X default: /* must be a file name */ X Filename = strsave(argv[1]); X files = &(argv[1]); X numfiles = argc - 1; X break; X } X } else { X Filename = NULL; X numfiles = 1; X } X curfile = 0; X X if (numfiles > 1) X fprintf(stderr, "%d files to edit\n", numfiles); X X windinit(); X X /* X * Allocate LPTR structures for all the various position pointers X */ X if ((Filemem = (LPTR *) malloc(sizeof(LPTR))) == NULL || X (Filetop = (LPTR *) malloc(sizeof(LPTR))) == NULL || X (Fileend = (LPTR *) malloc(sizeof(LPTR))) == NULL || X (Topchar = (LPTR *) malloc(sizeof(LPTR))) == NULL || X (Botchar = (LPTR *) malloc(sizeof(LPTR))) == NULL || X (Curschar = (LPTR *) malloc(sizeof(LPTR))) == NULL || X (Insstart = (LPTR *) malloc(sizeof(LPTR))) == NULL || X (screenalloc() == -1) ) { X fprintf(stderr, "Can't allocate data structures\n"); X windexit(0); X } X X filealloc(); /* Initialize Filemem, Filetop, and Fileend */ X X screenclear(); X X if ((initstr = getenv("EXINIT")) != NULL) { X char *lp, buf[128]; X X if ((lp = getenv("LINES")) != NULL) { X sprintf(buf, "%s lines=%s", initstr, lp); X docmdln(buf); X } else X docmdln(initstr); X } X X if (Filename != NULL) { X if (readfile(Filename, Filemem, FALSE)) X filemess("[New File]"); X } else if (tag == NULL) X msg("Empty Buffer"); X X setpcmark(); X X if (tag) { X stuffin(":ta "); X stuffin(tag); X stuffin("\n"); X X } else if (pat) { X stuffin(pat); X stuffin("\n"); X X } else if (line >= 0) { X if (line > 0) X stuffnum(line); X stuffin("G"); X } X X interactive = TRUE; X X edit(); X X windexit(0); X X return 1; /* shouldn't be reached */ X} X X#define RBSIZE 1024 Xstatic char getcbuff[RBSIZE]; Xstatic char *getcnext = NULL; X Xvoid Xstuffin(s) Xchar *s; X{ X if (s == NULL) { /* clear the stuff buffer */ X getcnext = NULL; X return; X } X X if (getcnext == NULL) { X strcpy(getcbuff,s); X getcnext = getcbuff; X } else X strcat(getcbuff,s); X} X Xvoid Xstuffnum(n) Xint n; X{ X char buf[32]; X X sprintf(buf, "%d", n); X stuffin(buf); X} X Xint Xvgetc() X{ X register int c; X X /* X * inchar() may map special keys by using stuffin(). If it does X * so, it returns -1 so we know to loop here to get a real char. X */ X do { X if ( getcnext != NULL ) { X int nextc = *getcnext++; X if ( *getcnext == NUL ) { X *getcbuff = NUL; X getcnext = NULL; X } X return(nextc); X } X c = inchar(); X } while (c == -1); X X return c; X} X X/* X * anyinput X * X * Return non-zero if input is pending. X */ X Xbool_t Xanyinput() X{ X return (getcnext != NULL); X} X X/* X * do_mlines() - process mode lines for the current file X * X * Returns immediately if the "ml" parameter isn't set. X */ X#define NMLINES 5 /* no. of lines at start/end to check for modelines */ X Xvoid Xdo_mlines() X{ X void chk_mline(); X int i; X register LPTR *p; X X if (!P(P_ML)) X return; X X p = Filemem; X for (i=0; i < NMLINES ;i++) { X chk_mline(p->linep->s); X if ((p = nextline(p)) == NULL) X break; X } X X if ((p = prevline(Fileend)) == NULL) X return; X X for (i=0; i < NMLINES ;i++) { X chk_mline(p->linep->s); X if ((p = prevline(p)) == NULL) X break; X } X} X X/* X * chk_mline() - check a single line for a mode string X */ Xstatic void Xchk_mline(s) Xregister char *s; X{ X register char *cs; /* local copy of any modeline found */ X register char *e; X X for (; *s != NUL ;s++) { X if (strncmp(s, "vi:", 3) == 0 || strncmp(s, "ex:", 3) == 0) { X cs = strsave(s+3); X if ((e = strchr(cs, ':')) != NULL) { X *e = NUL; X stuffin(mkstr(CTRL('o'))); X docmdln(cs); X } X free(cs); X } X } X} END_OF_FILE if test 8183 -ne `wc -c <'stevie/main.c'`; then echo shar: \"'stevie/main.c'\" unpacked with wrong size! fi # end of 'stevie/main.c' fi if test -f 'stevie/term.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'stevie/term.h'\" else echo shar: Extracting \"'stevie/term.h'\" \(7477 characters\) sed "s/^X//" >'stevie/term.h' <<'END_OF_FILE' X/* $Header: /nw/tony/src/stevie/src/RCS/term.h,v 1.7 89/08/01 17:25:18 tony Exp $ X * X * System-dependent escape sequence definitions. X */ X X#ifdef TERMCAP X Xextern char *T_EL; /* erase the entire current line */ Xextern char *T_IL; /* insert one line */ Xextern char *T_DL; /* delete one line */ Xextern char *T_SC; /* save the cursor position */ Xextern char *T_ED; /* erase display (may optionally home cursor) */ Xextern char *T_RC; /* restore the cursor position */ Xextern char *T_CI; /* invisible cursor (very optional) */ Xextern char *T_CV; /* visible cursor (very optional) */ X Xextern char *T_CM; /* cursor motion string */ X Xextern char *T_KU; /* code sequence sent by up-arrow key */ Xextern char *T_KD; /* code sequence sent by down-arrow key */ Xextern char *T_KL; /* code sequence sent by left-arrow key */ Xextern char *T_KR; /* code sequence sent by right-arrow key */ X X#else X X/* X * This file contains the machine dependent escape sequences that X * the editor needs to perform various operations. Some of the sequences X * here are optional. Anything not available should be indicated by X * a null string. In the case of insert/delete line sequences, the X * editor checks the capability and works around the deficiency, if X * necessary. X * X * Currently, insert/delete line sequences are used for screen scrolling. X * There are lots of terminals that have 'index' and 'reverse index' X * capabilities, but no line insert/delete. For this reason, the editor X * routines s_ins() and s_del() should be modified to use 'index' X * sequences when the line to be inserted or deleted line zero. X */ X X/* X * The macro names here correspond (more or less) to the actual ANSI names X */ X X#ifdef ATARI X#ifdef MINIX X X#define T_EL "\033[2K" /* erase the entire current line */ X#define T_IL "\033[L" /* insert one line */ X#define T_DL "\033[M" /* delete one line */ X#define T_SC "\0337" /* save the cursor position */ X#define T_ED "\033[2J" /* erase display (may optionally home cursor) */ X#define T_RC "\0338" /* restore the cursor position */ X#define T_CI "" /* invisible cursor (very optional) */ X#define T_CV "" /* visible cursor (very optional) */ X X#else X X#define T_EL "\033l" /* erase the entire current line */ X#define T_IL "\033L" /* insert one line */ X#define T_DL "\033M" /* delete one line */ X#define T_SC "\033j" /* save the cursor position */ X#define T_ED "\033E" /* erase display (may optionally home cursor) */ X#define T_RC "\033k" /* restore the cursor position */ X#define T_CI "\033f" /* invisible cursor (very optional) */ X#define T_CV "\033e" /* visible cursor (very optional) */ X X#endif X#endif X X#ifdef UNIX X/* X * The following sequences are hard-wired for ansi-like terminals. To get X * termcap support, define TERMCAP in env.h and these sequences go away. X */ X#define T_EL "\033[2K" /* erase the entire current line */ X#define T_IL "\033[L" /* insert one line */ X#define T_DL "\033[M" /* delete one line */ X#define T_ED "\033[2J" /* erase display (may optionally home cursor) */ X#define T_SC "\0337" /* save the cursor position */ X#define T_RC "\0338" /* restore the cursor position */ X#define T_CI "" /* invisible cursor (very optional) */ X#define T_CV "" /* visible cursor (very optional) */ X X#define T_KU "\033OA" /* sent by cursor up */ X#define T_KD "\033OB" /* sent by cursor down */ X#define T_KR "\033OC" /* sent by cursor right */ X#define T_KL "\033OD" /* sent by cursor left */ X X#endif X X#ifdef OS2 X/* X * The OS/2 ansi console driver is pretty deficient. No insert or delete line X * sequences. The erase line sequence only erases from the cursor to the end X * of the line. For our purposes that works out okay, since the only time X * T_EL is used is when the cursor is in column 0. X * X * The insert/delete line sequences marked here are actually implemented in X * the file os2.c using direct OS/2 system calls. This makes the capability X * available for the rest of the editor via appropriate escape sequences X * passed to outstr(). X */ X#define T_EL "\033[K" /* erase the entire current line */ X#define T_IL "\033[L" /* insert one line - fake (see os2.c) */ X#define T_DL "\033[M" /* delete one line - fake (see os2.c) */ X#define T_ED "\033[2J" /* erase display (may optionally home cursor) */ X#define T_SC "\033[s" /* save the cursor position */ X#define T_RC "\033[u" /* restore the cursor position */ X#define T_CI "" /* invisible cursor (very optional) */ X#define T_CV "" /* visible cursor (very optional) */ X#endif X X X#ifdef DOS X/* X * DOS sequences X * X * Some of the following sequences require the use of the "nansi.sys" X * console driver. The standard "ansi.sys" driver doesn't support X * sequences for insert/delete line. X */ X#define T_EL "\033[K" /* erase the entire current line */ X#define T_IL "\033[L" /* insert line (requires nansi.sys driver) */ X#define T_DL "\033[M" /* delete line (requires nansi.sys driver) */ X#define T_ED "\033[2J" /* erase display (may optionally home cursor) */ X#define T_SC "\033[s" /* save the cursor position */ X#define T_RC "\033[u" /* restore the cursor position */ X#define T_CI "" /* invisible cursor (very optional) */ X#define T_CV "" /* visible cursor (very optional) */ X#endif X X#endif X X/* X * Machine-variant screen handling definitions. X * X * Define some macros which for invoking screen functions, whether by X * callling a bios function or outputting an escape sequence to be X * interpreted by a PC console driver or terminal. X * X * At this writing, not all of Stevie has been converted to use these X * macros. So far, only DOS and PC BIOS versions are completely converted. X * Other versions are partly converted (because of changes I made in Stevie's X * common code), but they have not been tested. I'll convert others which I'm X * in a position to test, but I'll leave any I can't test alone. Hopefully, X * this will minimize any damage to working versions which I can't test. -LAS X */ X X#ifdef BIOS X X#define CANDL TRUE /* Can delete lines */ X#define CANIL TRUE /* Can insert lines */ X#define CLEOL bios_t_el() /* Erase to end-of-line */ X#define CLS bios_t_ed() /* Erase entire display */ X#define CRTDL(r,l) bios_t_dl(r,l) /* Delete lines from display */ X#define CRTIL(r,l) bios_t_il(r,l) /* Insert lines in display */ X#define CUROFF bios_t_ci() /* Make cursor invisible */ X#define CURON bios_t_cv() /* Make cursor visible */ X#define RESCUR bios_t_rc() /* Restore saved cursor position */ X#define SAVCUR bios_t_sc() /* Save cursor position */ X X#else /* Not BIOS */ X X#define CANDL (T_DL[0]!='\0') /* Determine if can delete lines */ X#define CANIL (T_IL[0]!='\0') /* Determine if can insert lines */ X#ifdef TERMCAP X# define CLEOL flushbuf(); outstr(T_EL); flushbuf_pad() /* Erase to EOL */ X# define CLS flushbuf(); outstr(T_ED); flushbuf_pad() /* Erase display */ X#else X# define CLEOL outstr(T_EL) /* Erase to end-of-line */ X# define CLS outstr(T_ED) /* Erase entire display */ X#endif X#define CRTDL(r,l) DO_DL(r,l) /* Delete lines from display */ X#define CRTIL(r,l) DO_IL(r,l) /* Insert lines in display */ X#define CUROFF outstr(T_CI) /* Make cursor invisible */ X#define CURON outstr(T_CV) /* Make cursor visible */ X#define RESCUR outstr(T_RC) /* Restore saved cursor position */ X#define SAVCUR outstr(T_SC) /* Save cursor position */ X X#define DO_DL(r,l) {\ X int __xx_knt = l;\ X while (__xx_knt-- > 0) {outstr(T_DL);}\ X} X X#define DO_IL(r,l) {\ X int __xx_knt = l;\ X while (__xx_knt-- > 0) {outstr(T_IL);}\ X} X X#endif /* Not BIOS */ X X END_OF_FILE if test 7477 -ne `wc -c <'stevie/term.h'`; then echo shar: \"'stevie/term.h'\" unpacked with wrong size! fi # end of 'stevie/term.h' fi if test -f 'stevie/tos.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'stevie/tos.c'\" else echo shar: Extracting \"'stevie/tos.c'\" \(7202 characters\) sed "s/^X//" >'stevie/tos.c' <<'END_OF_FILE' X/* $Header: /nw/tony/src/stevie/src/RCS/tos.c,v 1.5 89/07/13 22:45:31 tony Exp $ X * X * System-dependent routines for the Atari ST. X */ X X#include "stevie.h" X X#include X X/* X * inchar() - get a character from the keyboard X * X * Certain special keys are mapped to values above 0x80. These X * mappings are defined in keymap.h. If the key has a non-zero X * ascii value, it is simply returned. Otherwise it may be a X * special key we want to map. X * X * The ST has a bug involving keyboard input that seems to occur X * when typing quickly, especially typing capital letters. Sometimes X * a value of 0x02540000 is read. This doesn't correspond to anything X * on the keyboard, according to my documentation. My solution is to X * loop when any unknown key is seen. Normally, the bell is rung to X * indicate the error. If the "bug" value is seen, we ignore it completely. X */ Xint Xinchar() X{ X register long c; X X for (;;) { X c = Bconin(2); X X if ((c & 0xff) != 0) X return ((int) c); X X switch ((int) (c >> 16) & 0xff) { X X case 0x62: return K_HELP; X case 0x61: return K_UNDO; X case 0x52: return K_INSERT; X case 0x47: return K_HOME; X case 0x48: return K_UARROW; X case 0x50: return K_DARROW; X case 0x4b: return K_LARROW; X case 0x4d: return K_RARROW; X case 0x29: return K_CCIRCM; /* control-circumflex */ X X /* X * Occurs due to a bug in TOS. X */ X case 0x54: X break; X /* X * Add the function keys here later if we put in support X * for macros. X */ X X default: X beep(); X break; X X } X } X} X Xvoid Xoutchar(c) Xchar c; X{ X if (c < ' ') X Bconout(2, c); X else X Bconout(5, c); X} X Xvoid Xoutstr(s) Xregister char *s; X{ X while (*s) X Bconout(2, *s++); X} X X/* X * flushbuf() - a no-op for TOS X */ Xvoid Xflushbuf() X{ X} X X#define BGND 0 X#define TEXT 3 X X/* X * vbeep() - visual bell X */ Xstatic void Xvbeep() X{ X int text, bgnd; /* text and background colors */ X long l; X X text = Setcolor(TEXT, -1); X bgnd = Setcolor(BGND, -1); X X Setcolor(TEXT, bgnd); /* swap colors */ X Setcolor(BGND, text); X X for (l=0; l < 5000 ;l++) /* short pause */ X ; X X Setcolor(TEXT, text); /* restore colors */ X Setcolor(BGND, bgnd); X} X Xvoid Xbeep() X{ X if (P(P_VB)) X vbeep(); X else X outchar('\007'); X} X X/* X * remove(file) - remove a file X */ Xvoid Xremove(file) Xchar *file; X{ X Fdelete(file); X} X X/* X * rename(of, nf) - rename existing file 'of' to 'nf' X */ Xvoid Xrename(of, nf) Xchar *of, *nf; X{ X Fdelete(nf); /* if 'nf' exists, remove it */ X Frename(0, of, nf); X} X Xvoid Xwindinit() X{ X if (Getrez() == 0) X Columns = 40; /* low resolution */ X else X Columns = 80; /* medium or high */ X X P(P_LI) = Rows = 25; X X Cursconf(1,NULL); X} X Xvoid Xwindexit(r) Xint r; X{ X exit(r); X} X Xstatic char gobuf[5] = { '\033', 'Y', '\0', '\0', '\0' }; X Xvoid Xwindgoto(r, c) Xint r, c; X{ X gobuf[2] = r + 040; X gobuf[3] = c + 040; X outstr(gobuf); X} X X/* X * System calls or library routines missing in TOS. X */ X Xvoid Xsleep(n) Xint n; X{ X int k; X X k = Tgettime(); X while ( Tgettime() <= k+n ) X ; X} X Xvoid Xpause() X{ X long n; X X for (n = 0; n < 8000 ;n++) X ; X} X Xint Xsystem(cmd) Xchar *cmd; X{ X char arg[1]; X X arg[0] = (char) 0; /* no arguments passed to the shell */ X X if (Pexec(0, cmd, arg, 0L) < 0) X return -1; X else X return 0; X} X X#ifdef SOZOBON X XFILE * Xfopenb(fname, mode) Xchar *fname; Xchar *mode; X{ X char modestr[10]; X X sprintf(modestr, "%sb", mode); X X return fopen(fname, modestr); X} X X#endif X X#ifndef SOZOBON X/* X * getenv() - get a string from the environment X * X * Both Alcyon and Megamax are missing getenv(). This routine works for X * both compilers and with the Beckemeyer and Gulam shells. With gulam, X * the env_style variable should be set to either "mw" or "gu". X */ Xchar * Xgetenv(name) Xchar *name; X{ X extern long _base; X char *envp, *p; X X envp = *((char **) (_base + 0x2c)); X X for (; *envp ;envp += strlen(envp)+1) { X if (strncmp(envp, name, strlen(name)) == 0) { X p = envp + strlen(name); X if (*p++ == '=') X return p; X } X } X return (char *) 0; X} X#endif X X/* X * mktemp() - quick hack since there isn't one here X */ Xchar * Xmktemp(name) Xchar *name; X{ X int num; /* pasted into the string to make it unique */ X char cbuf[7]; X char *s; /* where the X's start in name */ X int fd; X X if ((s = strchr(name, 'X')) == NULL) /* needs to be an X */ X return (char *) NULL; X X if (strlen(s) != 6) /* should be 6 X's */ X return (char *) NULL; X X for (num = 0; num < 1000 ;num++) { X sprintf(cbuf, "%06d", num); X strcpy(s, cbuf); X if ((fd = open(name, 0)) < 0) X return name; X close(fd); X } X return (char *) NULL; X} X Xvoid Xdoshell(cmd) Xchar *cmd; X{ X if (cmd == NULL) { X shell(); X return; X } X system(cmd); X wait_return(); 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 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 END_OF_FILE if test 7202 -ne `wc -c <'stevie/tos.c'`; then echo shar: \"'stevie/tos.c'\" unpacked with wrong size! fi # end of 'stevie/tos.c' fi echo shar: End of archive 5 \(of 13\). cp /dev/null ark5isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 13 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0