v08i007: stevie 3.69 - part 5 of 8
Brandon S. Allbery - comp.sources.misc
allbery at uunet.UU.NET
Sun Aug 20 10:49:01 AEST 1989
Posting-number: Volume 8, Issue 7
Submitted-by: tony at cs.utexas.edu@wldrdg.UUCP (Tony Andrews)
Archive-name: stevie3.68/part05
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# screen.c
# search.c
# stevie.h
# term.c
# This archive created: Sun Aug 13 11:46:06 1989
export PATH; PATH=/bin:$PATH
echo shar: extracting "'screen.c'" '(16083 characters)'
if test -f 'screen.c'
then
echo shar: will not over-write existing file "'screen.c'"
else
sed 's/^X//' << \HE_HATES_THESE_CANS > 'screen.c'
X/* $Header: /nw/tony/src/stevie/src/RCS/screen.c,v 1.8 89/08/02 09:26:33 tony Exp $
X *
X * Routines to manipulate the screen representations.
X */
X
X#include "stevie.h"
X
X/*
X * This gets set if we ignored an update request while input was pending.
X * We check this when the input is drained to see if the screen should be
X * updated.
X */
Xbool_t need_redraw = FALSE;
X
X/*
X * The following variable is set (in filetonext) to the number of physical
X * lines taken by the line the cursor is on. We use this to avoid extra
X * calls to plines(). The optimized routines lfiletonext() and lnexttoscreen()
X * make sure that the size of the cursor line hasn't changed. If so, lines
X * below the cursor will move up or down and we need to call the routines
X * filetonext() and nexttoscreen() to examine the entire screen.
X */
Xstatic int Cline_size; /* size (in rows) of the cursor line */
Xstatic int Cline_row; /* starting row of the cursor line */
X
Xstatic char *mkline(); /* calculate line string for "number" mode */
X
X/*
X * filetonext()
X *
X * Based on the current value of Topchar, transfer a screenfull of
X * stuff from Filemem to Nextscreen, and update Botchar.
X */
X
Xstatic void
Xfiletonext()
X{
X register int row, col;
X register char *screenp = Nextscreen;
X LPTR memp;
X LPTR save; /* save pos. in case line won't fit */
X register char *endscreen;
X register char *nextrow;
X char extra[16];
X int nextra = 0;
X register int c;
X int n;
X bool_t done; /* if TRUE, we hit the end of the file */
X bool_t didline; /* if TRUE, we finished the last line */
X int srow; /* starting row of the current line */
X int lno; /* number of the line we're doing */
X int coff; /* column offset */
X
X coff = P(P_NU) ? 8 : 0;
X
X save = memp = *Topchar;
X
X if (P(P_NU))
X lno = cntllines(Filemem, Topchar);
X
X /*
X * The number of rows shown is Rows-1.
X * The last line is the status/command line.
X */
X endscreen = &screenp[(Rows-1)*Columns];
X
X done = didline = FALSE;
X srow = row = col = 0;
X /*
X * We go one past the end of the screen so we can find out if the
X * last line fit on the screen or not.
X */
X while ( screenp <= endscreen && !done) {
X
X
X if (P(P_NU) && col == 0 && memp.index == 0) {
X strcpy(extra, mkline(lno++));
X nextra = 8;
X }
X
X /* Get the next character to put on the screen. */
X
X /* The 'extra' array contains the extra stuff that is */
X /* inserted to represent special characters (tabs, and */
X /* other non-printable stuff. The order in the 'extra' */
X /* array is reversed. */
X
X if ( nextra > 0 )
X c = extra[--nextra];
X else {
X c = (unsigned)(0xff & gchar(&memp));
X if (inc(&memp) == -1)
X done = 1;
X /* when getting a character from the file, we */
X /* may have to turn it into something else on */
X /* the way to putting it into 'Nextscreen'. */
X if ( c == TAB && !P(P_LS) ) {
X strcpy(extra," ");
X /* tab amount depends on current column */
X nextra = ((P(P_TS)-1) - (col - coff)%P(P_TS));
X c = ' ';
X }
X else if ( c == NUL && P(P_LS) ) {
X extra[0] = NUL;
X nextra = 1;
X c = '$';
X } else if ( (n = chars[c].ch_size) > 1 ) {
X char *p;
X nextra = 0;
X p = chars[c].ch_str;
X /* copy 'ch-str'ing into 'extra' in reverse */
X while ( n > 1 )
X extra[nextra++] = p[--n];
X c = p[0];
X }
X }
X
X if (screenp == endscreen) {
X /*
X * We're one past the end of the screen. If the
X * current character is null, then we really did
X * finish, so set didline = TRUE. In either case,
X * break out because we're done.
X */
X dec(&memp);
X if (memp.index != 0 && c == NUL) {
X didline = TRUE;
X inc(&memp);
X }
X break;
X }
X
X if ( c == NUL ) {
X srow = ++row;
X /*
X * Save this position in case the next line won't
X * fit on the screen completely.
X */
X save = memp;
X /* get pointer to start of next row */
X nextrow = &Nextscreen[row*Columns];
X /* blank out the rest of this row */
X while ( screenp != nextrow )
X *screenp++ = ' ';
X col = 0;
X continue;
X }
X if ( col >= Columns ) {
X row++;
X col = 0;
X }
X /* store the character in Nextscreen */
X *screenp++ = c;
X col++;
X }
X /*
X * If we didn't hit the end of the file, and we didn't finish
X * the last line we were working on, then the line didn't fit.
X */
X if (!done && !didline) {
X /*
X * Clear the rest of the screen and mark the unused lines.
X */
X screenp = &Nextscreen[srow * Columns];
X while (screenp < endscreen)
X *screenp++ = ' ';
X for (; srow < (Rows-1) ;srow++)
X Nextscreen[srow * Columns] = '@';
X *Botchar = save;
X return;
X }
X /* make sure the rest of the screen is blank */
X while ( screenp < endscreen )
X *screenp++ = ' ';
X /* put '~'s on rows that aren't part of the file. */
X if ( col != 0 )
X row++;
X while ( row < Rows ) {
X Nextscreen[row*Columns] = '~';
X row++;
X }
X if (done) /* we hit the end of the file */
X *Botchar = *Fileend;
X else
X *Botchar = memp; /* FIX - prev? */
X}
X
X/*
X * nexttoscreen
X *
X * Transfer the contents of Nextscreen to the screen, using Realscreen
X * to avoid unnecessary output.
X */
Xstatic void
Xnexttoscreen()
X{
X register char *np = Nextscreen;
X register char *rp = Realscreen;
X register char *endscreen;
X register int row = 0, col = 0;
X int gorow = -1, gocol = -1;
X
X if (anyinput()) {
X need_redraw = TRUE;
X return;
X }
X
X endscreen = &np[(Rows-1)*Columns];
X
X outstr(T_CI); /* disable cursor */
X
X for ( ; np < endscreen ; np++,rp++ ) {
X /* If desired screen (contents of Nextscreen) does not */
X /* match what's really there, put it there. */
X if ( *np != *rp ) {
X /* if we are positioned at the right place, */
X /* we don't have to use windgoto(). */
X if (gocol != col || gorow != row) {
X /*
X * If we're just off by one, don't send
X * an entire esc. seq. (this happens a lot!)
X */
X if (gorow == row && gocol+1 == col) {
X outchar(*(np-1));
X gocol++;
X } else
X windgoto(gorow=row,gocol=col);
X }
X outchar(*rp = *np);
X gocol++;
X }
X if ( ++col >= Columns ) {
X col = 0;
X row++;
X }
X }
X outstr(T_CV); /* enable cursor again */
X}
X
X/*
X * lfiletonext() - like filetonext() but only for cursor line
X *
X * Returns true if the size of the cursor line (in rows) hasn't changed.
X * This determines whether or not we need to call filetonext() to examine
X * the entire screen for changes.
X */
Xstatic bool_t
Xlfiletonext()
X{
X register int row, col;
X register char *screenp;
X LPTR memp;
X register char *nextrow;
X char extra[16];
X int nextra = 0;
X register int c;
X int n;
X bool_t eof;
X int lno; /* number of the line we're doing */
X int coff; /* column offset */
X
X coff = P(P_NU) ? 8 : 0;
X
X /*
X * This should be done more efficiently.
X */
X if (P(P_NU))
X lno = cntllines(Filemem, Curschar);
X
X screenp = Nextscreen + (Cline_row * Columns);
X
X memp = *Curschar;
X memp.index = 0;
X
X eof = FALSE;
X col = 0;
X row = Cline_row;
X
X while (!eof) {
X
X if (P(P_NU) && col == 0 && memp.index == 0) {
X strcpy(extra, mkline(lno));
X nextra = 8;
X }
X
X /* Get the next character to put on the screen. */
X
X /* The 'extra' array contains the extra stuff that is */
X /* inserted to represent special characters (tabs, and */
X /* other non-printable stuff. The order in the 'extra' */
X /* array is reversed. */
X
X if ( nextra > 0 )
X c = extra[--nextra];
X else {
X c = (unsigned)(0xff & gchar(&memp));
X if (inc(&memp) == -1)
X eof = TRUE;
X /* when getting a character from the file, we */
X /* may have to turn it into something else on */
X /* the way to putting it into 'Nextscreen'. */
X if ( c == TAB && !P(P_LS) ) {
X strcpy(extra," ");
X /* tab amount depends on current column */
X nextra = ((P(P_TS)-1) - (col - coff)%P(P_TS));
X c = ' ';
X } else if ( c == NUL && P(P_LS) ) {
X extra[0] = NUL;
X nextra = 1;
X c = '$';
X } else if ( c != NUL && (n=chars[c].ch_size) > 1 ) {
X char *p;
X nextra = 0;
X p = chars[c].ch_str;
X /* copy 'ch-str'ing into 'extra' in reverse */
X while ( n > 1 )
X extra[nextra++] = p[--n];
X c = p[0];
X }
X }
X
X if ( c == NUL ) {
X row++;
X /* get pointer to start of next row */
X nextrow = &Nextscreen[row*Columns];
X /* blank out the rest of this row */
X while ( screenp != nextrow )
X *screenp++ = ' ';
X col = 0;
X break;
X }
X
X if ( col >= Columns ) {
X row++;
X col = 0;
X }
X /* store the character in Nextscreen */
X *screenp++ = c;
X col++;
X }
X return ((row - Cline_row) == Cline_size);
X}
X
X/*
X * lnexttoscreen
X *
X * Like nexttoscreen() but only for the cursor line.
X */
Xstatic void
Xlnexttoscreen()
X{
X register char *np = Nextscreen + (Cline_row * Columns);
X register char *rp = Realscreen + (Cline_row * Columns);
X register char *endline;
X register int row, col;
X int gorow = -1, gocol = -1;
X
X if (anyinput()) {
X need_redraw = TRUE;
X return;
X }
X
X endline = np + (Cline_size * Columns);
X
X row = Cline_row;
X col = 0;
X
X outstr(T_CI); /* disable cursor */
X
X for ( ; np < endline ; np++,rp++ ) {
X /* If desired screen (contents of Nextscreen) does not */
X /* match what's really there, put it there. */
X if ( *np != *rp ) {
X /* if we are positioned at the right place, */
X /* we don't have to use windgoto(). */
X if (gocol != col || gorow != row) {
X /*
X * If we're just off by one, don't send
X * an entire esc. seq. (this happens a lot!)
X */
X if (gorow == row && gocol+1 == col) {
X outchar(*(np-1));
X gocol++;
X } else
X windgoto(gorow=row,gocol=col);
X }
X outchar(*rp = *np);
X gocol++;
X }
X if ( ++col >= Columns ) {
X col = 0;
X row++;
X }
X }
X outstr(T_CV); /* enable cursor again */
X}
X
Xstatic char *
Xmkline(n)
Xregister int n;
X{
X static char lbuf[9];
X register int i = 2;
X
X strcpy(lbuf, " ");
X
X lbuf[i++] = (n % 10) + '0';
X n /= 10;
X if (n != 0) {
X lbuf[i++] = (n % 10) + '0';
X n /= 10;
X }
X if (n != 0) {
X lbuf[i++] = (n % 10) + '0';
X n /= 10;
X }
X if (n != 0) {
X lbuf[i++] = (n % 10) + '0';
X n /= 10;
X }
X if (n != 0) {
X lbuf[i++] = (n % 10) + '0';
X n /= 10;
X }
X return lbuf;
X}
X
X/*
X * updateline() - update the line the cursor is on
X *
X * Updateline() is called after changes that only affect the line that
X * the cursor is on. This improves performance tremendously for normal
X * insert mode operation. The only thing we have to watch for is when
X * the cursor line grows or shrinks around a row boundary. This means
X * we have to repaint other parts of the screen appropriately. If
X * lfiletonext() returns FALSE, the size of the cursor line (in rows)
X * has changed and we have to call updatescreen() to do a complete job.
X */
Xvoid
Xupdateline()
X{
X if (!lfiletonext())
X updatescreen(); /* bag it, do the whole screen */
X else
X lnexttoscreen();
X}
X
Xvoid
Xupdatescreen()
X{
X extern bool_t interactive;
X
X if (interactive) {
X filetonext();
X nexttoscreen();
X }
X}
X
X/*
X * prt_line() - print the given line
X */
Xvoid
Xprt_line(s)
Xchar *s;
X{
X register int si = 0;
X register int c;
X register int col = 0;
X
X char extra[16];
X int nextra = 0;
X int n;
X
X for (;;) {
X
X if ( nextra > 0 )
X c = extra[--nextra];
X else {
X c = s[si++];
X if ( c == TAB && !P(P_LS) ) {
X strcpy(extra, " ");
X /* tab amount depends on current column */
X nextra = (P(P_TS) - 1) - col%P(P_TS);
X c = ' ';
X } else if ( c == NUL && P(P_LS) ) {
X extra[0] = NUL;
X nextra = 1;
X c = '$';
X } else if ( c != NUL && (n=chars[c].ch_size) > 1 ) {
X char *p;
X
X nextra = 0;
X p = chars[c].ch_str;
X /* copy 'ch-str'ing into 'extra' in reverse */
X while ( n > 1 )
X extra[nextra++] = p[--n];
X c = p[0];
X }
X }
X
X if ( c == NUL )
X break;
X
X outchar(c);
X col++;
X }
X}
X
Xvoid
Xscreenclear()
X{
X register char *rp, *np;
X register char *end;
X
X outstr(T_ED); /* clear the display */
X
X rp = Realscreen;
X end = Realscreen + Rows * Columns;
X np = Nextscreen;
X
X /* blank out the stored screens */
X while (rp != end)
X *rp++ = *np++ = ' ';
X}
X
Xvoid
Xcursupdate()
X{
X register LPTR *p;
X register int icnt, c, nlines;
X register int i;
X int didinc;
X
X if (bufempty()) { /* special case - file is empty */
X *Topchar = *Filemem;
X *Curschar = *Filemem;
X } else if ( LINEOF(Curschar) < LINEOF(Topchar) ) {
X nlines = cntllines(Curschar,Topchar);
X /* if the cursor is above the top of */
X /* the screen, put it at the top of the screen.. */
X *Topchar = *Curschar;
X Topchar->index = 0;
X /* ... and, if we weren't very close to begin with, */
X /* we scroll so that the line is close to the middle. */
X if ( nlines > Rows/3 ) {
X for (i=0, p = Topchar; i < Rows/3 ;i++, *Topchar = *p)
X if ((p = prevline(p)) == NULL)
X break;
X } else
X s_ins(0, nlines-1);
X updatescreen();
X }
X else if (LINEOF(Curschar) >= LINEOF(Botchar)) {
X nlines = cntllines(Botchar,Curschar);
X /* If the cursor is off the bottom of the screen, */
X /* put it at the top of the screen.. */
X /* ... and back up */
X if ( nlines > Rows/3 ) {
X p = Curschar;
X for (i=0; i < (2*Rows)/3 ;i++)
X if ((p = prevline(p)) == NULL)
X break;
X *Topchar = *p;
X } else {
X scrollup(nlines);
X }
X updatescreen();
X }
X
X Cursrow = Curscol = Cursvcol = 0;
X for ( p=Topchar; p->linep != Curschar->linep ;p = nextline(p) )
X Cursrow += plines(p);
X
X Cline_row = Cursrow;
X Cline_size = plines(p);
X
X if (P(P_NU))
X Curscol = 8;
X
X for (i=0; i <= Curschar->index ;i++) {
X c = Curschar->linep->s[i];
X /* A tab gets expanded, depending on the current column */
X if ( c == TAB && !P(P_LS) )
X icnt = P(P_TS) - (Cursvcol % P(P_TS));
X else
X icnt = chars[(unsigned)(c & 0xff)].ch_size;
X Curscol += icnt;
X Cursvcol += icnt;
X if ( Curscol >= Columns ) {
X Curscol -= Columns;
X Cursrow++;
X didinc = TRUE;
X }
X else
X didinc = FALSE;
X }
X if (didinc)
X Cursrow--;
X
X if (c == TAB && State == NORMAL && !P(P_LS)) {
X Curscol--;
X Cursvcol--;
X } else {
X Curscol -= icnt;
X Cursvcol -= icnt;
X }
X if (Curscol < 0)
X Curscol += Columns;
X
X if (set_want_col) {
X Curswant = Cursvcol;
X set_want_col = FALSE;
X }
X}
X
X/*
X * The rest of the routines in this file perform screen manipulations.
X * The given operation is performed physically on the screen. The
X * corresponding change is also made to the internal screen image.
X * In this way, the editor anticipates the effect of editing changes
X * on the appearance of the screen. That way, when we call screenupdate
X * a complete redraw isn't usually necessary. Another advantage is that
X * we can keep adding code to anticipate screen changes, and in the
X * meantime, everything still works.
X */
X
X/*
X * s_ins(row, nlines) - insert 'nlines' lines at 'row'
X */
Xvoid
Xs_ins(row, nlines)
Xint row;
Xint nlines;
X{
X register char *s, *d; /* src & dest for block copy */
X register char *e; /* end point for copy */
X register int i;
X
X if (T_IL[0] == NUL) /* can't do it */
X return;
X
X /*
X * It "looks" better if we do all the inserts at once
X */
X outstr(T_SC); /* save position */
X windgoto(row, 0);
X
X for (i=0; i < nlines ;i++)
X outstr(T_IL);
X
X windgoto(Rows-1, 0); /* delete any garbage that may have */
X outstr(T_EL); /* been shifted to the bottom line */
X outstr(T_RC); /* restore the cursor position */
X
X /*
X * Now do a block move to update the internal screen image
X */
X d = Realscreen + (Columns * (Rows - 1)) - 1;
X s = d - (Columns * nlines);
X e = Realscreen + (Columns * row);
X
X while (s >= e)
X *d-- = *s--;
X
X /*
X * Clear the inserted lines
X */
X s = Realscreen + (row * Columns);
X e = s + (nlines * Columns);
X while (s < e)
X *s++ = ' ';
X}
X
X/*
X * s_del(row, nlines) - delete 'nlines' lines at 'row'
X */
Xvoid
Xs_del(row, nlines)
Xint row;
Xint nlines;
X{
X register char *s, *d, *e;
X register int i;
X
X if (T_DL[0] == NUL) /* can't do it */
X return;
X
X /* delete the lines */
X outstr(T_SC); /* save position */
X windgoto(row, 0);
X
X for (i=0; i < nlines ;i++) {
X outstr(T_DL); /* delete a line */
X if (i == 0) {
X windgoto(Rows-2, 0); /* delete any garbage that */
X outstr(T_EL); /* was on the status line */
X windgoto(row, 0);
X }
X }
X outstr(T_RC); /* restore position */
X
X /*
X * do a block move to update the internal image
X */
X d = Realscreen + (row * Columns);
X s = d + (nlines * Columns);
X e = Realscreen + ((Rows - 1) * Columns);
X
X while (s < e)
X *d++ = *s++;
X
X while (d < e) /* clear the lines at the bottom */
X *d++ = ' ';
X}
HE_HATES_THESE_CANS
if test 16083 -ne "`wc -c < 'screen.c'`"
then
echo shar: error transmitting "'screen.c'" '(should have been 16083 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'search.c'" '(18702 characters)'
if test -f 'search.c'
then
echo shar: will not over-write existing file "'search.c'"
else
sed 's/^X//' << \HE_HATES_THESE_CANS > 'search.c'
X/* $Header: /nw/tony/src/stevie/src/RCS/search.c,v 1.16 89/08/06 09:50:51 tony Exp $
X *
X * This file contains various searching-related routines. These fall into
X * three groups: string searches (for /, ?, n, and N), character searches
X * within a single line (for f, F, t, T, etc), and "other" kinds of searches
X * like the '%' command, and 'word' searches.
X */
X
X#include "stevie.h"
X#include "regexp.h" /* Henry Spencer's (modified) reg. exp. routines */
X
X/*
X * String searches
X *
X * The actual searches are done using Henry Spencer's regular expression
X * library.
X */
X
X#define BEGWORD "([^a-zA-Z0-9_]|^)" /* replaces "\<" in search strings */
X#define ENDWORD "([^a-zA-Z0-9_]|$)" /* likewise replaces "\>" */
X
X#define BEGCHAR(c) (islower(c) || isupper(c) || isdigit(c) || ((c) == '_'))
X
Xbool_t begword; /* does the search include a 'begin word' match */
X
X/*
X * mapstring(s) - map special backslash sequences
X */
Xstatic char *
Xmapstring(s)
Xregister char *s;
X{
X static char ns[80];
X register char *p;
X
X begword = FALSE;
X
X for (p = ns; *s ;s++) {
X if (*s != '\\') { /* not an escape */
X *p++ = *s;
X continue;
X }
X switch (*++s) {
X case '/':
X *p++ = '/';
X break;
X
X case '<':
X strcpy(p, BEGWORD);
X p += strlen(BEGWORD);
X begword = TRUE;
X break;
X
X case '>':
X strcpy(p, ENDWORD);
X p += strlen(ENDWORD);
X break;
X
X default:
X *p++ = '\\';
X *p++ = *s;
X break;
X }
X }
X *p++ = NUL;
X
X return ns;
X}
X
Xstatic char *laststr = NULL;
Xstatic int lastsdir;
X
Xstatic LPTR *
Xssearch(dir,str)
Xint dir; /* FORWARD or BACKWARD */
Xchar *str;
X{
X LPTR *bcksearch(), *fwdsearch();
X LPTR *pos;
X char *old_ls = laststr;
X
X reg_ic = P(P_IC); /* tell the regexp routines how to search */
X
X laststr = strsave(str);
X lastsdir = dir;
X
X if (old_ls != NULL)
X free(old_ls);
X
X if (dir == BACKWARD) {
X smsg("?%s", laststr);
X pos = bcksearch(mapstring(laststr));
X } else {
X smsg("/%s", laststr);
X pos = fwdsearch(mapstring(laststr));
X }
X
X /*
X * This is kind of a kludge, but its needed to make
X * 'beginning of word' searches land on the right place.
X */
X if (pos != NULL && begword) {
X if (pos->index != 0 || !BEGCHAR(pos->linep->s[0]))
X pos->index += 1;
X }
X return pos;
X}
X
Xbool_t
Xdosearch(dir,str)
Xint dir;
Xchar *str;
X{
X LPTR *p;
X
X if (str == NULL)
X str = laststr;
X
X got_int = FALSE;
X
X if ((p = ssearch(dir,str)) == NULL) {
X if (got_int)
X msg("Interrupt");
X else
X msg("Pattern not found");
X
X got_int = FALSE;
X return FALSE;
X } else {
X LPTR savep;
X
X cursupdate();
X /*
X * if we're backing up, we make sure the line we're on
X * is on the screen.
X */
X setpcmark();
X *Curschar = savep = *p;
X set_want_col = TRUE;
X cursupdate();
X
X return TRUE;
X }
X}
X
X#define OTHERDIR(x) (((x) == FORWARD) ? BACKWARD : FORWARD)
X
Xbool_t
Xrepsearch(flag)
Xint flag;
X{
X int dir = lastsdir;
X bool_t found;
X
X if ( laststr == NULL ) {
X beep();
X return FALSE;
X }
X
X found = dosearch(flag ? OTHERDIR(lastsdir) : lastsdir, laststr);
X
X /*
X * We have to save and restore 'lastsdir' because it gets munged
X * by ssearch() and winds up saving the wrong direction from here
X * if 'flag' is true.
X */
X lastsdir = dir;
X
X return found;
X}
X
X/*
X * regerror - called by regexp routines when errors are detected.
X */
Xvoid
Xregerror(s)
Xchar *s;
X{
X emsg(s);
X}
X
Xstatic LPTR *
Xfwdsearch(str)
Xregister char *str;
X{
X static LPTR infile;
X register LPTR *p;
X regexp *prog;
X
X register char *s;
X register int i;
X
X if ((prog = regcomp(str)) == NULL) {
X emsg("Invalid search string");
X return NULL;
X }
X
X p = Curschar;
X i = Curschar->index + 1;
X do {
X s = p->linep->s + i;
X
X if (regexec(prog, s, i == 0)) { /* got a match */
X infile.linep = p->linep;
X infile.index = (int) (prog->startp[0] - p->linep->s);
X free((char *)prog);
X return (&infile);
X }
X i = 0;
X
X if (got_int)
X goto fwdfail;
X
X } while ((p = nextline(p)) != NULL);
X
X /*
X * If wrapscan isn't set, then don't scan from the beginning
X * of the file. Just return failure here.
X */
X if (!P(P_WS))
X goto fwdfail;
X
X /* search from the beginning of the file to Curschar */
X for (p = Filemem; p != NULL ;p = nextline(p)) {
X s = p->linep->s;
X
X if (regexec(prog, s, TRUE)) { /* got a match */
X infile.linep = p->linep;
X infile.index = (int) (prog->startp[0] - s);
X free((char *)prog);
X return (&infile);
X }
X
X if (p->linep == Curschar->linep)
X break;
X
X if (got_int)
X goto fwdfail;
X }
X
Xfwdfail:
X free((char *)prog);
X return NULL;
X}
X
Xstatic LPTR *
Xbcksearch(str)
Xchar *str;
X{
X static LPTR infile;
X register LPTR *p = &infile;
X register char *s;
X register int i;
X register char *match;
X regexp *prog;
X
X /* make sure str isn't empty */
X if (str == NULL || *str == NUL)
X return NULL;
X
X if ((prog = regcomp(str)) == NULL) {
X emsg("Invalid search string");
X return NULL;
X }
X
X *p = *Curschar;
X if (dec(p) == -1) { /* already at start of file? */
X *p = *Fileend;
X p->index = strlen(p->linep->s) - 1;
X }
X
X if (begword) /* so we don't get stuck on one match */
X dec(p);
X
X i = p->index;
X
X do {
X s = p->linep->s;
X
X if (regexec(prog, s, TRUE)) { /* match somewhere on line */
X
X /*
X * Now, if there are multiple matches on this line,
X * we have to get the last one. Or the last one
X * before the cursor, if we're on that line.
X */
X match = prog->startp[0];
X
X while (regexec(prog, prog->endp[0], FALSE)) {
X if ((i >= 0) && ((prog->startp[0] - s) > i))
X break;
X match = prog->startp[0];
X }
X
X if ((i >= 0) && ((match - s) > i)) {
X i = -1;
X continue;
X }
X
X infile.linep = p->linep;
X infile.index = (int) (match - s);
X free((char *)prog);
X return (&infile);
X }
X i = -1;
X
X if (got_int)
X goto bckfail;
X
X } while ((p = prevline(p)) != NULL);
X
X /*
X * If wrapscan isn't set, bag the search now
X */
X if (!P(P_WS))
X goto bckfail;
X
X /* search backward from the end of the file */
X p = prevline(Fileend);
X do {
X s = p->linep->s;
X
X if (regexec(prog, s, TRUE)) { /* match somewhere on line */
X
X /*
X * Now, if there are multiple matches on this line,
X * we have to get the last one.
X */
X match = prog->startp[0];
X
X while (regexec(prog, prog->endp[0], FALSE))
X match = prog->startp[0];
X
X infile.linep = p->linep;
X infile.index = (int) (match - s);
X free((char *)prog);
X return (&infile);
X }
X
X if (p->linep == Curschar->linep)
X break;
X
X if (got_int)
X goto bckfail;
X
X } while ((p = prevline(p)) != NULL);
X
Xbckfail:
X free((char *)prog);
X return NULL;
X}
X
X/*
X * dosub(lp, up, cmd)
X *
X * Perform a substitution from line 'lp' to line 'up' using the
X * command pointed to by 'cmd' which should be of the form:
X *
X * /pattern/substitution/g
X *
X * The trailing 'g' is optional and, if present, indicates that multiple
X * substitutions should be performed on each line, if applicable.
X * The usual escapes are supported as described in the regexp docs.
X */
Xvoid
Xdosub(lp, up, cmd)
XLPTR *lp, *up;
Xchar *cmd;
X{
X LINE *cp;
X char *pat, *sub;
X regexp *prog;
X int nsubs;
X bool_t do_all; /* do multiple substitutions per line */
X
X /*
X * If no range was given, do the current line. If only one line
X * was given, just do that one.
X */
X if (lp->linep == NULL)
X *up = *lp = *Curschar;
X else {
X if (up->linep == NULL)
X *up = *lp;
X }
X
X pat = ++cmd; /* skip the initial '/' */
X
X while (*cmd) {
X if (*cmd == '\\') /* next char is quoted */
X cmd += 2;
X else if (*cmd == '/') { /* delimiter */
X *cmd++ = NUL;
X break;
X } else
X cmd++; /* regular character */
X }
X
X if (*pat == NUL) {
X emsg("NULL pattern specified");
X return;
X }
X
X sub = cmd;
X
X do_all = FALSE;
X
X while (*cmd) {
X if (*cmd == '\\') /* next char is quoted */
X cmd += 2;
X else if (*cmd == '/') { /* delimiter */
X do_all = (cmd[1] == 'g');
X *cmd++ = NUL;
X break;
X } else
X cmd++; /* regular character */
X }
X
X reg_ic = P(P_IC); /* set "ignore case" flag appropriately */
X
X if ((prog = regcomp(pat)) == NULL) {
X emsg("Invalid search string");
X return;
X }
X
X nsubs = 0;
X
X for (cp = lp->linep; cp != NULL ;cp = cp->next) {
X if (regexec(prog, cp->s, TRUE)) { /* a match on this line */
X char *ns, *sns, *p;
X
X /*
X * Get some space for a temporary buffer
X * to do the substitution into.
X */
X sns = ns = alloc(2048);
X *sns = NUL;
X
X p = cp->s;
X
X do {
X for (ns = sns; *ns ;ns++)
X ;
X /*
X * copy up to the part that matched
X */
X while (p < prog->startp[0])
X *ns++ = *p++;
X
X regsub(prog, sub, ns);
X
X /*
X * continue searching after the match
X */
X p = prog->endp[0];
X
X } while (regexec(prog, p, FALSE) && do_all);
X
X for (ns = sns; *ns ;ns++)
X ;
X
X /*
X * copy the rest of the line, that didn't match
X */
X while (*p)
X *ns++ = *p++;
X
X *ns = NUL;
X
X free(cp->s); /* free the original line */
X cp->s = strsave(sns); /* and save the modified str */
X cp->size = strlen(cp->s) + 1;
X free(sns); /* free the temp buffer */
X nsubs++;
X CHANGED;
X }
X if (cp == up->linep)
X break;
X }
X
X if (nsubs) {
X updatescreen();
X if (nsubs >= P(P_RP))
X smsg("%d substitution%c", nsubs, (nsubs>1) ? 's' : ' ');
X } else
X msg("No match");
X
X free((char *)prog);
X}
X
X/*
X * doglob(cmd)
X *
X * Execute a global command of the form:
X *
X * g/pattern/X
X *
X * where 'x' is a command character, currently one of the following:
X *
X * d Delete all matching lines
X * p Print all matching lines
X *
X * The command character (as well as the trailing slash) is optional, and
X * is assumed to be 'p' if missing.
X */
Xvoid
Xdoglob(lp, up, cmd)
XLPTR *lp, *up;
Xchar *cmd;
X{
X LINE *cp;
X char *pat;
X regexp *prog;
X int ndone;
X char cmdchar = NUL; /* what to do with matching lines */
X
X /*
X * If no range was given, do every line. If only one line
X * was given, just do that one.
X */
X if (lp->linep == NULL) {
X *lp = *Filemem;
X *up = *Fileend;
X } else {
X if (up->linep == NULL)
X *up = *lp;
X }
X
X pat = ++cmd; /* skip the initial '/' */
X
X while (*cmd) {
X if (*cmd == '\\') /* next char is quoted */
X cmd += 2;
X else if (*cmd == '/') { /* delimiter */
X cmdchar = cmd[1];
X *cmd++ = NUL;
X break;
X } else
X cmd++; /* regular character */
X }
X if (cmdchar == NUL)
X cmdchar = 'p';
X
X reg_ic = P(P_IC); /* set "ignore case" flag appropriately */
X
X if (cmdchar != 'd' && cmdchar != 'p') {
X emsg("Invalid command character");
X return;
X }
X
X if ((prog = regcomp(pat)) == NULL) {
X emsg("Invalid search string");
X return;
X }
X
X msg("");
X ndone = 0;
X got_int = FALSE;
X
X for (cp = lp->linep; cp != NULL && !got_int ;cp = cp->next) {
X if (regexec(prog, cp->s, TRUE)) { /* a match on this line */
X switch (cmdchar) {
X
X case 'd': /* delete the line */
X if (Curschar->linep != cp) {
X LPTR savep;
X
X savep = *Curschar;
X Curschar->linep = cp;
X Curschar->index = 0;
X delline(1, FALSE);
X *Curschar = savep;
X } else
X delline(1, FALSE);
X break;
X
X case 'p': /* print the line */
X prt_line(cp->s);
X outstr("\r\n");
X break;
X }
X ndone++;
X }
X if (cp == up->linep)
X break;
X }
X
X if (ndone) {
X switch (cmdchar) {
X
X case 'd':
X updatescreen();
X if (ndone >= P(P_RP) || got_int)
X smsg("%s%d fewer line%c",
X got_int ? "Interrupt: " : "",
X ndone,
X (ndone > 1) ? 's' : ' ');
X break;
X
X case 'p':
X wait_return();
X break;
X }
X } else {
X if (got_int)
X msg("Interrupt");
X else
X msg("No match");
X }
X
X got_int = FALSE;
X free((char *)prog);
X}
X
X/*
X * Character Searches
X */
X
Xstatic char lastc = NUL; /* last character searched for */
Xstatic int lastcdir; /* last direction of character search */
Xstatic int lastctype; /* last type of search ("find" or "to") */
X
X/*
X * searchc(c, dir, type)
X *
X * Search for character 'c', in direction 'dir'. If type is 0, move to
X * the position of the character, otherwise move to just before the char.
X */
Xbool_t
Xsearchc(c, dir, type)
Xchar c;
Xint dir;
Xint type;
X{
X LPTR save;
X
X save = *Curschar; /* save position in case we fail */
X lastc = c;
X lastcdir = dir;
X lastctype = type;
X
X /*
X * On 'to' searches, skip one to start with so we can repeat
X * searches in the same direction and have it work right.
X */
X if (type)
X (dir == FORWARD) ? oneright() : oneleft();
X
X while ( (dir == FORWARD) ? oneright() : oneleft() ) {
X if (gchar(Curschar) == c) {
X if (type)
X (dir == FORWARD) ? oneleft() : oneright();
X return TRUE;
X }
X }
X *Curschar = save;
X return FALSE;
X}
X
Xbool_t
Xcrepsearch(flag)
Xint flag;
X{
X int dir = lastcdir;
X int rval;
X
X if (lastc == NUL)
X return FALSE;
X
X rval = searchc(lastc, flag ? OTHERDIR(lastcdir) : lastcdir, lastctype);
X
X lastcdir = dir; /* restore dir., since it may have changed */
X
X return rval;
X}
X
X/*
X * "Other" Searches
X */
X
X/*
X * showmatch - move the cursor to the matching paren or brace
X */
XLPTR *
Xshowmatch()
X{
X static LPTR pos;
X int (*move)(), inc(), dec();
X char initc = gchar(Curschar); /* initial char */
X char findc; /* terminating char */
X char c;
X int count = 0;
X
X pos = *Curschar; /* set starting point */
X
X switch (initc) {
X
X case '(':
X findc = ')';
X move = inc;
X break;
X case ')':
X findc = '(';
X move = dec;
X break;
X case '{':
X findc = '}';
X move = inc;
X break;
X case '}':
X findc = '{';
X move = dec;
X break;
X case '[':
X findc = ']';
X move = inc;
X break;
X case ']':
X findc = '[';
X move = dec;
X break;
X default:
X return (LPTR *) NULL;
X }
X
X while ((*move)(&pos) != -1) { /* until end of file */
X c = gchar(&pos);
X if (c == initc)
X count++;
X else if (c == findc) {
X if (count == 0)
X return &pos;
X count--;
X }
X }
X return (LPTR *) NULL; /* never found it */
X}
X
X/*
X * findfunc(dir) - Find the next function in direction 'dir'
X *
X * Return TRUE if a function was found.
X */
Xbool_t
Xfindfunc(dir)
Xint dir;
X{
X LPTR *curr;
X
X curr = Curschar;
X
X do {
X curr = (dir == FORWARD) ? nextline(curr) : prevline(curr);
X
X if (curr != NULL && curr->linep->s[0] == '{') {
X setpcmark();
X *Curschar = *curr;
X return TRUE;
X }
X } while (curr != NULL);
X
X return FALSE;
X}
X
X/*
X * The following routines do the word searches performed by the
X * 'w', 'W', 'b', 'B', 'e', and 'E' commands.
X */
X
X/*
X * To perform these searches, characters are placed into one of three
X * classes, and transitions between classes determine word boundaries.
X *
X * The classes are:
X *
X * 0 - white space
X * 1 - letters, digits, and underscore
X * 2 - everything else
X */
X
Xstatic int stype; /* type of the word motion being performed */
X
X#define C0(c) (((c) == ' ') || ((c) == '\t') || ((c) == NUL))
X#define C1(c) (isalpha(c) || isdigit(c) || ((c) == '_'))
X
X/*
X * cls(c) - returns the class of character 'c'
X *
X * The 'type' of the current search modifies the classes of characters
X * if a 'W', 'B', or 'E' motion is being done. In this case, chars. from
X * class 2 are reported as class 1 since only white space boundaries are
X * of interest.
X */
Xstatic int
Xcls(c)
Xchar c;
X{
X if (C0(c))
X return 0;
X
X if (C1(c))
X return 1;
X
X /*
X * If stype is non-zero, report these as class 1.
X */
X return (stype == 0) ? 2 : 1;
X}
X
X
X/*
X * fwd_word(pos, type) - move forward one word
X *
X * Returns the resulting position, or NULL if EOF was reached.
X */
XLPTR *
Xfwd_word(p, type)
XLPTR *p;
Xint type;
X{
X static LPTR pos;
X int sclass = cls(gchar(p)); /* starting class */
X
X pos = *p;
X
X stype = type;
X
X /*
X * We always move at least one character.
X */
X if (inc(&pos) == -1)
X return NULL;
X
X if (sclass != 0) {
X while (cls(gchar(&pos)) == sclass) {
X if (inc(&pos) == -1)
X return NULL;
X }
X /*
X * If we went from 1 -> 2 or 2 -> 1, return here.
X */
X if (cls(gchar(&pos)) != 0)
X return &pos;
X }
X
X /* We're in white space; go to next non-white */
X
X while (cls(gchar(&pos)) == 0) {
X /*
X * We'll stop if we land on a blank line
X */
X if (pos.index == 0 && pos.linep->s[0] == NUL)
X break;
X
X if (inc(&pos) == -1)
X return NULL;
X }
X
X return &pos;
X}
X
X/*
X * bck_word(pos, type) - move backward one word
X *
X * Returns the resulting position, or NULL if EOF was reached.
X */
XLPTR *
Xbck_word(p, type)
XLPTR *p;
Xint type;
X{
X static LPTR pos;
X int sclass = cls(gchar(p)); /* starting class */
X
X pos = *p;
X
X stype = type;
X
X if (dec(&pos) == -1)
X return NULL;
X
X /*
X * If we're in the middle of a word, we just have to
X * back up to the start of it.
X */
X if (cls(gchar(&pos)) == sclass && sclass != 0) {
X /*
X * Move backward to start of the current word
X */
X while (cls(gchar(&pos)) == sclass) {
X if (dec(&pos) == -1)
X return NULL;
X }
X inc(&pos); /* overshot - forward one */
X return &pos;
X }
X
X /*
X * We were at the start of a word. Go back to the start
X * of the prior word.
X */
X
X while (cls(gchar(&pos)) == 0) { /* skip any white space */
X /*
X * We'll stop if we land on a blank line
X */
X if (pos.index == 0 && pos.linep->s[0] == NUL)
X return &pos;
X
X if (dec(&pos) == -1)
X return NULL;
X }
X
X sclass = cls(gchar(&pos));
X
X /*
X * Move backward to start of this word.
X */
X while (cls(gchar(&pos)) == sclass) {
X if (dec(&pos) == -1)
X return NULL;
X }
X inc(&pos); /* overshot - forward one */
X
X return &pos;
X}
X
X/*
X * end_word(pos, type, in_change) - move to the end of the word
X *
X * There is an apparent bug in the 'e' motion of the real vi. At least
X * on the System V Release 3 version for the 80386. Unlike 'b' and 'w',
X * the 'e' motion crosses blank lines. When the real vi crosses a blank
X * line in an 'e' motion, the cursor is placed on the FIRST character
X * of the next non-blank line. The 'E' command, however, works correctly.
X * Since this appears to be a bug, I have not duplicated it here.
X *
X * There's a strange special case here that the 'in_change' parameter
X * helps us deal with. Vi effectively turns 'cw' into 'ce'. If we're on
X * a word with only one character, we need to stick at the current
X * position so we don't change two words.
X *
X * Returns the resulting position, or NULL if EOF was reached.
X */
XLPTR *
Xend_word(p, type, in_change)
XLPTR *p;
Xint type;
Xbool_t in_change;
X{
X static LPTR pos;
X int sclass = cls(gchar(p)); /* starting class */
X
X pos = *p;
X
X stype = type;
X
X if (inc(&pos) == -1)
X return NULL;
X
X /*
X * If we're in the middle of a word, we just have to
X * move to the end of it.
X */
X if (cls(gchar(&pos)) == sclass && sclass != 0) {
X /*
X * Move forward to end of the current word
X */
X while (cls(gchar(&pos)) == sclass) {
X if (inc(&pos) == -1)
X return NULL;
X }
X dec(&pos); /* overshot - forward one */
X return &pos;
X }
X
X /*
X * We were at the end of a word. Go to the end of the next
X * word, unless we're doing a change. In that case we stick
X * at the end of the current word.
X */
X if (in_change)
X return p;
X
X while (cls(gchar(&pos)) == 0) { /* skip any white space */
X if (inc(&pos) == -1)
X return NULL;
X }
X
X sclass = cls(gchar(&pos));
X
X /*
X * Move forward to end of this word.
X */
X while (cls(gchar(&pos)) == sclass) {
X if (inc(&pos) == -1)
X return NULL;
X }
X dec(&pos); /* overshot - forward one */
X
X return &pos;
X}
HE_HATES_THESE_CANS
if test 18702 -ne "`wc -c < 'search.c'`"
then
echo shar: error transmitting "'search.c'" '(should have been 18702 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'stevie.h'" '(4232 characters)'
if test -f 'stevie.h'
then
echo shar: will not over-write existing file "'stevie.h'"
else
sed 's/^X//' << \HE_HATES_THESE_CANS > 'stevie.h'
X/*
X * $Header: /nw/tony/src/stevie/src/RCS/stevie.h,v 1.19 89/07/12 21:33:32 tony Exp $
X *
X * Main header file included by all source files.
X */
X
X#include "env.h" /* defines to establish the compile-time environment */
X
X#include <stdio.h>
X#include <ctype.h>
X
X#ifdef BSD
X
X#include <strings.h>
X#define strchr index
X
X#else
X
X#ifdef MINIX
X
Xextern char *strchr();
Xextern char *strrchr();
Xextern char *strcpy();
Xextern char *strcat();
Xextern int strlen();
X
X#else
X#include <string.h>
X#endif
X
X#endif
X
X#include "ascii.h"
X#include "keymap.h"
X#include "param.h"
X#include "term.h"
X
Xextern char *strchr();
X
X#define NORMAL 0
X#define CMDLINE 1
X#define INSERT 2
X#define REPLACE 3
X#define FORWARD 4
X#define BACKWARD 5
X
X/*
X * Boolean type definition and constants
X */
Xtypedef short bool_t;
X
X#ifndef TRUE
X#define FALSE (0)
X#define TRUE (1)
X#endif
X
X/*
X * SLOP is the amount of extra space we get for text on a line during
X * editing operations that need more space. This keeps us from calling
X * malloc every time we get a character during insert mode. No extra
X * space is allocated when the file is initially read.
X */
X#define SLOP 10
X
X/*
X * LINEINC is the gap we leave between the artificial line numbers. This
X * helps to avoid renumbering all the lines every time a new line is
X * inserted.
X */
X#define LINEINC 10
X
X#define CHANGED Changed=TRUE
X#define UNCHANGED Changed=FALSE
X
Xstruct line {
X struct line *prev, *next; /* previous and next lines */
X char *s; /* text for this line */
X int size; /* actual size of space at 's' */
X unsigned long num; /* line "number" */
X};
X
X#define LINEOF(x) ((x)->linep->num)
X
Xstruct lptr {
X struct line *linep; /* line we're referencing */
X int index; /* position within that line */
X};
X
Xtypedef struct line LINE;
Xtypedef struct lptr LPTR;
X
Xstruct charinfo {
X char ch_size;
X char *ch_str;
X};
X
Xextern struct charinfo chars[];
X
Xextern int State;
Xextern int Rows;
Xextern int Columns;
Xextern char *Realscreen;
Xextern char *Nextscreen;
Xextern char *Filename;
Xextern LPTR *Filemem;
Xextern LPTR *Filetop;
Xextern LPTR *Fileend;
Xextern LPTR *Topchar;
Xextern LPTR *Botchar;
Xextern LPTR *Curschar;
Xextern LPTR *Insstart;
Xextern int Cursrow, Curscol, Cursvcol, Curswant;
Xextern bool_t set_want_col;
Xextern int Prenum;
Xextern bool_t Changed;
Xextern char Redobuff[], Insbuff[];
Xextern char *Insptr;
Xextern int Ninsert;
Xextern bool_t got_int;
X
Xextern char *malloc(), *strcpy();
X
X/*
X * alloc.c
X */
Xchar *alloc(), *strsave(), *mkstr();
Xvoid screenalloc(), filealloc(), freeall();
XLINE *newline();
Xbool_t bufempty(), buf1line(), lineempty(), endofline(), canincrease();
X
X/*
X * cmdline.c
X */
Xvoid docmdln(), dotag(), msg(), emsg(), smsg(), gotocmd(), wait_return();
Xchar *getcmdln();
X
X/*
X * edit.c
X */
Xvoid edit(), insertchar(), getout(), scrollup(), scrolldown(), beginline();
Xbool_t oneright(), oneleft(), oneup(), onedown();
X
X/*
X * fileio.c
X */
Xvoid filemess(), renum();
Xbool_t readfile(), writeit();
X
X/*
X * help.c
X */
Xbool_t help();
X
X/*
X * linefunc.c
X */
XLPTR *nextline(), *prevline(), *coladvance();
X
X/*
X * main.c
X */
Xvoid stuffin(), stuffnum();
Xvoid do_mlines();
Xint vgetc();
Xbool_t anyinput();
X
X/*
X * mark.c
X */
Xvoid setpcmark(), clrall(), clrmark();
Xbool_t setmark();
XLPTR *getmark();
X
X/*
X * misccmds.c
X */
Xvoid opencmd(), fileinfo(), inschar(), delline();
Xbool_t delchar();
Xint cntllines(), plines();
XLPTR *gotoline();
X
X/*
X * normal.c
X */
Xvoid normal();
X
X/*
X * param.c
X */
Xvoid doset();
X
X/*
X * ptrfunc.c
X */
Xint inc(), dec();
Xint gchar();
Xvoid pchar(), pswap();
Xbool_t lt(), equal(), ltoreq();
X#if 0
X/* not currently used */
Xbool_t gtoreq(), gt();
X#endif
X
X/*
X * screen.c
X */
Xvoid updatescreen(), updateline();
Xvoid screenclear(), cursupdate();
Xvoid s_ins(), s_del();
Xvoid prt_line();
X
X/*
X * search.c
X */
Xvoid dosub(), doglob();
Xbool_t searchc(), crepsearch(), findfunc(), dosearch(), repsearch();
XLPTR *showmatch();
XLPTR *fwd_word(), *bck_word(), *end_word();
X
X/*
X * undo.c
X */
Xvoid u_save(), u_saveline(), u_clear();
Xvoid u_lcheck(), u_lundo();
Xvoid u_undo();
X
X/*
X * Machine-dependent routines.
X */
Xint inchar();
Xvoid flushbuf();
Xvoid outchar(), outstr(), beep();
Xchar *fixname();
X#ifndef OS2
X#ifndef DOS
Xvoid remove(), rename();
X#endif
X#endif
Xvoid windinit(), windexit(), windgoto();
Xvoid delay();
Xvoid doshell();
HE_HATES_THESE_CANS
if test 4232 -ne "`wc -c < 'stevie.h'`"
then
echo shar: error transmitting "'stevie.h'" '(should have been 4232 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'term.c'" '(1685 characters)'
if test -f 'term.c'
then
echo shar: will not over-write existing file "'term.c'"
else
sed 's/^X//' << \HE_HATES_THESE_CANS > 'term.c'
X/* $Header: /nw/tony/src/stevie/src/RCS/term.c,v 1.4 89/03/11 22:43:55 tony Exp $
X *
X * Termcap initialization (optional).
X */
X
X#include <stdio.h>
X#include "stevie.h"
X
X#ifdef TERMCAP
X
Xstatic char buf[1024]; /* termcap entry read here */
Xstatic char cap[256]; /* capability strings go in here */
X
Xchar *T_EL; /* erase the entire current line */
Xchar *T_IL; /* insert one line */
Xchar *T_DL; /* delete one line */
Xchar *T_SC; /* save the cursor position */
Xchar *T_ED; /* erase display (may optionally home cursor) */
Xchar *T_RC; /* restore the cursor position */
Xchar *T_CI; /* invisible cursor (very optional) */
Xchar *T_CV; /* visible cursor (very optional) */
X
Xchar *T_CM; /* cursor motion string */
X
Xextern int tgetent(), tgetnum();
Xextern char *tgetstr();
Xextern char *getenv();
X
Xint
Xt_init()
X{
X char *term;
X int n;
X char *cp = cap;
X
X if ((term = getenv("TERM")) == NULL)
X return 0;
X
X if (tgetent(buf, term) != 1)
X return 0;
X
X if ((n = tgetnum("li")) == -1)
X return 0;
X else
X P(P_LI) = Rows = n;
X
X if ((n = tgetnum("co")) == -1)
X return 0;
X else
X Columns = n;
X
X /*
X * Get mandatory capability strings.
X */
X if ((T_CM = tgetstr("cm", &cp)) == NULL)
X return 0;
X
X if ((T_EL = tgetstr("ce", &cp)) == NULL)
X return 0;
X
X if ((T_ED = tgetstr("cl", &cp)) == NULL)
X return 0;
X
X /*
X * Optional capabilities.
X */
X if ((T_IL = tgetstr("al", &cp)) == NULL)
X T_IL = "";
X
X if ((T_DL = tgetstr("dl", &cp)) == NULL)
X T_DL = "";
X
X if ((T_SC = tgetstr("sc", &cp)) == NULL)
X T_SC = "";
X
X if ((T_RC = tgetstr("rc", &cp)) == NULL)
X T_RC = "";
X
X if ((T_CI = tgetstr("vi", &cp)) == NULL)
X T_CI = "";
X
X if ((T_CV = tgetstr("ve", &cp)) == NULL)
X T_CV = "";
X
X return 1;
X}
X
X#endif
HE_HATES_THESE_CANS
if test 1685 -ne "`wc -c < 'term.c'`"
then
echo shar: error transmitting "'term.c'" '(should have been 1685 characters)'
fi
fi # end of overwriting check
# End of shell archive
exit 0
--
More information about the Comp.sources.misc
mailing list