From harvard!talcott!panda!jpn Tue May 6 20:24:44 1986 Received: by seismo.CSS.GOV; Tue, 6 May 86 20:21:04 EDT Received: from talcott by harvard.HARVARD.EDU with UUCP; Tue, 6 May 86 20:19:40 EDT From: harvard!talcott!panda!jpn Return-Path: Received: by panda.LOCAL on Tue, 6 May 86 18:38:24 edt Date: Tue, 6 May 86 18:38:24 edt Message-Id: <8605062238.AA00889@panda.LOCAL> To: talcott!seismo!rick Status: R From: Jeff Lee Subject: Georgia Tech 'se' screen editor (Part 6 of 8) Keywords: Software Tools, Yet Another Screen Editor, Both BSD and USG Newsgroups: mod.sources Approved: jpn@panda.UUCP Mod.sources: Volume 4, Issue 87 Submitted by: Jeff Lee #! /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: # libchangetty # pat # This archive created: Tue Apr 29 10:41:07 1986 export PATH; PATH=/bin:/usr/bin:$PATH if test ! -d 'libchangetty' then echo shar: "creating directory 'libchangetty'" mkdir 'libchangetty' fi echo shar: "entering directory 'libchangetty'" cd 'libchangetty' echo shar: "extracting 'changetty.c'" '(5419 characters)' if test -f 'changetty.c' then echo shar: "will not over-write existing file 'changetty.c'" else cat << \SHAR_EOF > 'changetty.c' /* ** changetty.c ** ** Localize in one place all the data and functions ** needed to change to and from cbreak mode for ** the se screen editor. ** ** Only functions available to rest of se are: ** ttyedit(), ttynormal(), and getspeed(). ** ** If USG is defined, we use the System V TTY driver. ** Otherwise (the default) we use the Berkeley terminal driver. ** ** If we are using System V, then the Release 2 version does not ** need ospeed. If not release 2, we assume Release 1 that someone ** have moved the BSD termlib to. */ #include "../ascii.h" #include "../constdefs.h" #ifdef USG #include #else #include #endif #if defined (BSD) || ! defined (S5R2) extern short ospeed; /* from the termlib library */ static int set_ospeed = NO; #endif #ifdef USG /* all the info needed for the System V terminal driver */ typedef struct termio TTYINFO; /* S5 control flags */ #else /* all the info needed for the Berkeley terminal driver */ typedef struct junk { /* terminal information */ struct sgttyb sgttyb; /* V7 control flags */ struct tchars tchars; /* V7 control characters */ short local; /* local mode settings */ struct ltchars ltchars; /* local control characters */ } TTYINFO; #endif static TTYINFO OldTtyInfo; /* initial state of terminal */ static TTYINFO NewTtyInfo; /* modified state for editing */ static int first = YES; /* first time anything called */ static init() { if (gttyinfo(1, &OldTtyInfo) == -1) /* get current state */ error ("couldn't get TTY info from system. get help!\n"); NewTtyInfo = OldTtyInfo; /* copy it */ mttyinfo(&NewTtyInfo); /* change, but don't reset terminal */ /* really should check the return value here ... */ } ttyedit() /* set the terminal to correct modes for editing */ { if (first == YES) { first = NO; init(); } sttyinfo(1, &NewTtyInfo); /* make the change */ /* really should check the return value here too ... */ } ttynormal() /* set the terminal to correct modes for normal use */ { if (first) { first = NO; init(); } sttyinfo(1, &OldTtyInfo); /* make the change */ } /* getspeed --- find out the terminal speed in characters/second */ /* this routine only used if terminal types are hardwired */ /* into se, however, since it will be in an archive, the */ /* loader won't grab it if it isn't needed. */ int getspeed(fd) int fd; { register int i; TTYINFO ttybuf; static struct brstruct { int unixrate; int cps; int baudrate; } stab[] = { B0, 0, 0, B50, 5, 50, B75, 8, 75, B110, 10, 110, B134, 14, 134, B150, 15, 150, B200, 20, 200, B300, 30, 300, B600, 60, 600, B1200, 120, 1200, B1800, 180, 1800, B2400, 240, 2400, B4800, 480, 4800, B9600, 960, 9600 }; if (first) /* might as well set it here, too */ { first = NO; init(); } if (gttyinfo(fd, &ttybuf) == -1) return 960; for (i = 0; i < sizeof(stab) / sizeof(struct brstruct); i++) #ifdef USG if (stab[i].unixrate == (ttybuf.c_cflag & 017)) #else if (stab[i].unixrate == (ttybuf.sgttyb.sg_ospeed)) #endif return stab[i].cps; return 960; } /* gttyinfo --- make all necessary calls to obtain terminal status */ static int gttyinfo(fd, buf) int fd; /* file descriptor of terminal */ TTYINFO *buf; /* terminal info buffer to be filled in */ { #ifdef USG if (ioctl(fd, TCGETA, buf) < 0) #else if (gtty(fd, &(buf->sgttyb)) < 0 || ioctl(fd, TIOCGETC, &(buf->tchars)) < 0 || ioctl(fd, TIOCLGET, &(buf->local)) < 0 || ioctl(fd, TIOCGLTC, &(buf->ltchars)) < 0) #endif { return -1; } #if defined (BSD) || ! defined (S5R2) if (set_ospeed == NO) { set_ospeed = YES; #ifdef BSD ospeed = (buf->sgttyb).sg_ospeed; #else ospeed = buf->c_cflag & 017; /* tty speed, see termio(7) */ #endif } #endif return 0; } /* mttyinfo --- modify a TTYINFO structure for interactive operation */ static int mttyinfo(buf) TTYINFO *buf; /* buffer containing TTYINFO to be modified */ { #ifdef USG buf->c_cc[0] = DLE; /* interrupt */ buf->c_cc[1] = -1; /* ignore quit */ buf->c_cc[4] = 1; /* min # chars to read */ buf->c_cc[5] = 1; /* min time to wait */ buf->c_iflag &= ~(INLCR|IGNCR|ICRNL); /* allow CR to come thru */ buf->c_lflag |= ISIG|NOFLSH; /* keep these bits */ buf->c_lflag &= ~(ICANON|XCASE|ECHO|ECHOE|ECHOK|ECHONL); #else #ifdef GITVAX static struct tchars newtchars = {DLE, -1, -1, -1, EOT, -1}; /* allows control-s and -q to be control charactes that se sees */ #else static struct tchars newtchars = {DLE, -1, DC1, DC3, EOT, -1}; #endif static struct ltchars newltchars = {-1, -1, -1, -1, -1, -1}; buf->sgttyb.sg_flags |= (CBREAK); /* keep these bits */ buf->sgttyb.sg_flags &= ~(ECHO|CRMOD|LCASE|RAW|ALLDELAY); buf->tchars = newtchars; /* buf->local |= (LLITOUT); /* Dan Forsyth says to comment out */ buf->local &= ~(LCRTBS|LCRTERA|LPRTERA|LTOSTOP|LFLUSHO|LCRTKIL| #ifndef BSD4_2 LINTRUP| #endif LCTLECH|LPENDIN); buf->ltchars = newltchars; #endif return 0; } /* sttyinfo --- make all necessary calls to set terminal status */ static int sttyinfo(fd, buf) int fd; /* file descriptor of terminal */ TTYINFO *buf; /* terminal info buffer */ { #ifdef USG if (ioctl(fd, TCSETAW, buf) < 0) #else if (ioctl(fd, TIOCSETN, &(buf->sgttyb)) < 0 || ioctl(fd, TIOCSETC, &(buf->tchars)) < 0 || ioctl(fd, TIOCLSET, &(buf->local)) < 0 || ioctl(fd, TIOCSLTC, &(buf->ltchars)) < 0) #endif return -1; return 0; } SHAR_EOF fi echo shar: "extracting 'makefile'" '(478 characters)' if test -f 'makefile' then echo shar: "will not over-write existing file 'makefile'" else cat << \SHAR_EOF > 'makefile' # makefile for libchangetty.a -- terminal resetting functions TARGET= libchangetty.a SRCS= changetty.c OBJS= changetty.o PRINTS= $(SRCS) makefile CFLAGS= -O `cat ../flags` $(TARGET): $(OBJS) ../flags ar ruv $(TARGET) $(OBJS) if test -r /usr/bin/ranlib; then /usr/bin/ranlib $(TARGET); fi clean: rm -fr $(OBJS) clobber: clean rm -fr $(TARGET) print2 print: prt $(PRINTS) | lpr -b 'tty lib' touch print2 print2: $(PRINTS) prt $? | lpr -b 'new tty lib' touch print2 SHAR_EOF fi echo shar: "done with directory 'libchangetty'" cd .. if test ! -d 'pat' then echo shar: "creating directory 'pat'" mkdir 'pat' fi echo shar: "entering directory 'pat'" cd 'pat' echo shar: "extracting 'pat.c'" '(11979 characters)' if test -f 'pat.c' then echo shar: "will not over-write existing file 'pat.c'" else cat << \SHAR_EOF > 'pat.c' /* ** pat.c ** ** pattern matching subroutines for the se screen editor. ** knows about both Unix and SWT style patterns. ** ** routines declared static are not necessary for the rest ** of the editor, therefore make them static in the name ** of modularity. */ #include #include #include "../constdefs.h" /* Definitions used only for pattern matching */ #define AND '&' #define CCL '[' #define CCLEND ']' #define CHAR 'a' #define CLOSIZE 1 #define CLOSURE '*' #define DASH '-' #define DITTO 0200 #define EOL '$' #define NCCL 'n' #define NEWLINE '\n' #define TAB '\t' /* variables which are changeable if using unix style or swt style */ /* initially unix style */ static char ANY = '.'; static char BOL = '^'; static char NOTINCCL = '^'; static char START_TAG = '('; static char STOP_TAG = ')'; static char ESCAPE = '\\'; static int unix_style = YES; /* Array dimensions and other limit values */ #define MAXLINE 128 #define MAXPAT 128 /* Pattern matching subroutines: */ /* set_patterns -- tell the pattern routines what style patterns we're using */ set_patterns(tounix) int tounix; { if (tounix == YES) { ANY = '.'; BOL = '^'; NOTINCCL = '^'; START_TAG = '('; STOP_TAG = ')'; ESCAPE = '\\'; unix_style = YES; } else { ANY = '?'; BOL = '%'; NOTINCCL = '~'; START_TAG = '{'; STOP_TAG = '}'; ESCAPE = '@'; unix_style = NO; } } /* match () --- find match anywhere on line */ match (lin, pat) register char lin[]; register char pat[]; { int junk[9]; register char *pc; for (pc = lin; *pc != EOS; pc++) if (amatch (lin, pc - lin, pat, junk, junk) >= 0) return (YES); return (NO); } /* amatch() --- (recursive) look for match starting at lin[from] */ amatch(lin, from, pat, tagbeg, tagend) int from, tagbeg[], tagend[]; char lin[], pat[]; { char *ch, *lastc; register char *ppat; int k; lastc = lin + from; /* next unexamined input character */ for (ppat = pat; *ppat != EOS; ppat += patsiz (ppat)) if (*ppat == CLOSURE) /* a closure entry */ { ppat++; for (ch = lastc; *ch != EOS; ) /* match as many as possible */ if (omatch (lin, &ch, ppat) == NO) break; /* * ch now points to character that made us fail * try to match rest of pattern against rest of input * shrink the closure by 1 after each failure */ for (ppat += patsiz (ppat); ch >= lastc; ch--) /* successful match of rest of pattern */ if ((k = amatch (lin, ch - lin, ppat, tagbeg, tagend)) >= 0) break; lastc = lin + k; /* if k < 0, failure; * if k >= 0, success */ break; } else if (*ppat == START_TAG) tagbeg[*(ppat + 1)] = lastc - lin; else if (*ppat == STOP_TAG) tagend[*(ppat + 1)] = lastc - lin; /* non-closure */ else if (omatch (lin, &lastc, ppat) == NO) return (-1); /* else omatch succeeded */ return (lastc - lin); } /* omatch () --- try to match a single pattern at ppat */ static omatch (lin, adplin, ppat) char lin[], **adplin, *ppat; { register char *plin; register int bump, retval; plin = *adplin; retval = NO; if (*plin == EOS) return (retval); bump = -1; if (*ppat == CHAR) { if (*plin == *(ppat + 1)) bump = 1; } else if (*ppat == BOL) { if (plin == lin) bump = 0; } else if (*ppat == ANY) { if (*plin != NEWLINE) bump = 1; } else if (*ppat == EOL) { if (*plin == NEWLINE) bump = 0; } else if(*ppat == CCL) { if (locate (*plin, ppat + 1) == YES) bump = 1; } else if(*ppat == NCCL) { if (*plin != NEWLINE && locate (*plin, ppat + 1) == NO) bump = 1; } else error ("in omatch: can't happen."); if (bump >= 0) { *adplin += bump; retval = YES; } return (retval); } /* locate () --- look for c in char class at ppat */ static locate (c, ppat) register char c, *ppat; { register char *pclas; /* size of class is at ppat, characters follow */ for (pclas = ppat + *ppat; pclas > ppat; pclas--) if (c == *pclas) return (YES); return (NO); } /* patsiz () --- returns size of pattern entry at ppat */ static patsiz (ppat) register char *ppat; { if (*ppat == CHAR || *ppat == START_TAG || *ppat == STOP_TAG) return (2); else if (*ppat == BOL || *ppat == EOL || *ppat == ANY) return (1); else if (*ppat == CCL || *ppat == NCCL) return (*(ppat + 1) + 2); else if (*ppat == CLOSURE) return (CLOSIZE); else error ("in patsiz: can't happen."); } /* makpat () --- make pattern from arg[from], terminate at delim */ makpat (arg, from, delim, pat) char arg[], delim, pat[]; int from; { char ch, esc (); int argsub, junk, lastsub, ls, patsub, tag_nest, tag_num, tag_stack[9]; lastsub = patsub = 0; tag_num = -1; tag_nest = -1; for (argsub = from; arg[argsub] != delim && arg[argsub] != EOS; argsub++) { ls = patsub; if (arg[argsub] == ANY) junk = addset (ANY, pat, &patsub, MAXPAT); else if (arg[argsub] == BOL && argsub == from) junk = addset (BOL, pat, &patsub, MAXPAT); else if (arg[argsub] == EOL && arg[argsub + 1] == delim) junk = addset (EOL, pat, &patsub, MAXPAT); else if (arg[argsub] == CCL) { if (getccl (arg, &argsub, pat, &patsub) == ERR) return (ERR); } else if (arg[argsub] == CLOSURE && argsub > from) { ls = lastsub; if (pat[ls] == BOL || pat[ls] == EOL || pat[ls] == CLOSURE || pat[ls] == START_TAG || pat[ls] == STOP_TAG) break; stclos (pat, &patsub, &lastsub); } else if (start_tag(arg, &argsub)) /* start_tag knows about unix or not */ { /* too many tagged sub-patterns */ if (tag_num >= 8) break; tag_num++; tag_nest++; tag_stack[tag_nest] = tag_num; junk = addset (START_TAG, pat, &patsub, MAXPAT); junk = addset (tag_num, pat, &patsub, MAXPAT); } else if (stop_tag(arg, &argsub) && tag_nest > -1) /* stop_tag knows about unix or not */ { junk = addset (STOP_TAG, pat, &patsub, MAXPAT); junk = addset (tag_stack[tag_nest], pat, &patsub, MAXPAT); tag_nest--; } else { junk = addset (CHAR, pat, &patsub, MAXPAT); /* don't allow match of newline other than via $ */ if ((ch = esc(arg, &argsub)) == NEWLINE) return (ERR); junk = addset (ch, pat, &patsub, MAXPAT); } lastsub = ls; } if (arg[argsub] != delim) /* terminated early */ return (ERR); else if (addset (EOS, pat, &patsub, MAXPAT) == NO) /* no room */ return (ERR); else if (tag_nest != -1) return (ERR); else return (argsub); } /* getccl () --- expand char class at arg[*pasub] into pat[*pindex] */ static getccl (arg, pasub, pat, pindex) char arg[], pat[]; int *pasub, *pindex; { int junk, start; (*pasub)++; /* skip over [ */ if (arg[*pasub] == NOTINCCL) { junk = addset (NCCL, pat, pindex, MAXPAT); (*pasub)++; } else junk = addset (CCL, pat, pindex, MAXPAT); start = *pindex; junk = addset (0, pat, pindex, MAXPAT); /* leave room for count */ filset (CCLEND, arg, pasub, pat, pindex, MAXPAT); pat[start] = *pindex - start - 1; if (arg[*pasub] == CCLEND) return (OK); else return (ERR); } /* stclos () --- insert closure entry at pat[*ppatsub] */ static stclos (pat, ppatsub, plastsub) char pat[]; int *ppatsub, *plastsub; { int i, j, junk; for (i = *ppatsub - 1; i >= *plastsub; i--) /* make a hole */ { j = i + CLOSIZE; junk = addset (pat[i], pat, &j, MAXPAT); } *ppatsub += CLOSIZE; /* put closure in it */ junk = addset (CLOSURE, pat, plastsub, MAXPAT); } /* maksub () --- make substitution string in sub */ maksub (arg, from, delim, sub) char arg[], delim, sub[]; int from; { char esc (); int argsub, index, junk; index = 0; for (argsub = from; arg[argsub] != delim && arg[argsub] != EOS; argsub++) if (arg[argsub] == AND) { junk = addset (DITTO, sub, &index, MAXPAT); junk = addset (0, sub, &index, MAXPAT); } else if (arg[argsub] == ESCAPE && isdigit (arg[argsub + 1])) { argsub++; junk = addset (DITTO, sub, &index, MAXPAT); junk = addset (arg[argsub] - '0', sub, &index, MAXPAT); } else junk = addset (esc (arg, &argsub), sub, &index, MAXPAT); if (arg[argsub] != delim) /* missing delimeter */ return (ERR); else if (addset (EOS, sub, &index, MAXPAT) == NO) /* no room */ return (ERR); else return (argsub); } /* catsub () --- add replacement text to end of new */ catsub (lin, from, to, sub, new, k, maxnew) register char lin[], new[], sub[]; int from[], *k, maxnew, to[]; { int junk, ri; register int i, j; for (i = 0; sub[i] != EOS; i++) if ((sub[i] & 0xff) == DITTO) { ri = sub[++i]; for (j = from[ri]; j < to[ri]; j++) junk = addset (lin[j], new, k, maxnew); } else junk = addset (sub[i], new, k, maxnew); } /* filset () --- expand set at array[*pasub] into set[*pindex], stop at delim */ filset (delim, array, pasub, set, pindex, maxset) char array[], delim, set[]; int maxset, *pasub, *pindex; { char esc (); int junk; static char digits[] = "0123456789"; static char lowalf[] = "abcdefghijklmnopqrstuvwxyz"; static char upalf[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; for ( ; array[*pasub] != delim && array[*pasub] != EOS; (*pasub)++) if (array[*pasub] == ESCAPE) junk = addset (esc (array, pasub), set, pindex, maxset); else if (array[*pasub] != DASH) junk = addset (array[*pasub], set, pindex, maxset); /* literal DASH */ else if (*pindex <= 0 || array[*pasub + 1] == EOS || array[*pasub + 1] == delim) junk = addset (DASH, set, pindex, maxset); /* else if (index (digits, set[*pindex - 1]) >= 0) */ else if (isdigit(set[*pindex - 1])) dodash (digits, array, pasub, set, pindex, maxset); /* else if(index (lowalf, set[*pindex - 1]) >= 0) */ else if (islower(set[*pindex - 1])) dodash (lowalf, array, pasub, set, pindex, maxset); /* else if (index (upalf, set[*pindex - 1]) >= 0) */ else if (isupper(set[*pindex - 1])) dodash (upalf, array, pasub, set, pindex, maxset); else junk = addset (DASH, set, pindex, maxset); } /* ** dodash () --- expand array[*pasub - 1]-array[*pasub + 1] into set[*pindex], ** from valid */ static dodash (valid, array, pasub, set, pindex, maxset) char array[], set[], valid[]; int maxset, *pasub, *pindex; { char esc (); int junk, k, limit; (*pasub)++; (*pindex)--; limit = index (valid, esc (array, pasub)); for (k = index (valid, set[*pindex]); k <= limit; k++) junk = addset (valid[k], set, pindex, maxset); } /* addset () --- put c in set[*pindex]; if it fits, increment *pindex */ addset (c, set, pindex, maxsiz) int maxsiz, *pindex; char c, set[]; { if (*pindex >= maxsiz) return (NO); else { set[(*pindex)++] = c; return (YES); } } /* esc () --- map array[*pindex] into escaped character if appropriate */ char esc (array, pindex) char array[]; int *pindex; { if (array[*pindex] != ESCAPE) return (array[*pindex]); else if (array[*pindex + 1] == EOS) /* ESCAPE not special at end */ return (ESCAPE); else { if (array[++(*pindex)] == 'n') return (NEWLINE); else if (array[*pindex] == 't') return (TAB); else return (array[*pindex]); } } /* start_tag --- determine if we've seen the start of a tagged pattern */ static int start_tag(arg, argsub) char *arg; int *argsub; { if (unix_style) if (arg[*argsub] == ESCAPE && arg[*argsub + 1] == START_TAG) { (*argsub)++; return (YES); } else return (NO); else if (arg[*argsub] == START_TAG) return (YES); else return (NO); } /* stop_tag --- determine if we've seen the end of a tagged pattern */ static int stop_tag(arg, argsub) char *arg; int *argsub; { if (unix_style) if (arg[*argsub] == ESCAPE && arg[*argsub + 1] == STOP_TAG) { (*argsub)++; return (YES); } else return (NO); else if (arg[*argsub] == STOP_TAG) return (YES); else return (NO); } SHAR_EOF fi echo shar: "extracting 'makefile'" '(410 characters)' if test -f 'makefile' then echo shar: "will not over-write existing file 'makefile'" else cat << \SHAR_EOF > 'makefile' # makefile for pattern library for 'se' CFLAGS=-O PR=pr libpat.a: pat.o ar ruv libpat.a pat.o if test -r /usr/bin/ranlib; then /usr/bin/ranlib libpat.a; fi pat.o: pat.c install: libpat.a cp libpat.a /usr/lib print: $(PR) pat.c makefile | lpr -b 'pat lib' touch print2 print2: pat.c makefile $(PR) $? | lpr -b 'new pat lib' touch print2 clean: rm -f pat.o clobber: clean rm -f libpat.a print2 SHAR_EOF fi echo shar: "extracting 'llib-lpat'" '(1270 characters)' if test -f 'llib-lpat' then echo shar: "will not over-write existing file 'llib-lpat'" else cat << \SHAR_EOF > 'llib-lpat' /* llib-lpat --- lint library for pattern routines */ /*LINTLIBRARY*/ match (lin, pat) char lin[]; char pat[]; { return 0; } amatch(lin, from, pat, tagbeg, tagend) int from, tagbeg[], tagend[]; char lin[], pat[]; { return 0; } static omatch (lin, adplin, ppat) char lin[], **adplin, *ppat; { return 0; } static locate (c, ppat) char c, *ppat; { return 0; } static patsiz (ppat) char *ppat; { return 0; } makpat (arg, from, delim, pat) char arg[], delim, pat[]; int from; { return 0; } static getccl (arg, pasub, pat, pindex) char arg[], pat[]; int *pasub, *pindex; { return 0; } static stclos (pat, ppatsub, plastsub) char pat[]; int *ppatsub, *plastsub; { } maksub (arg, from, delim, sub) char arg[], delim, sub[]; int from; { return 0; } catsub (lin, from, to, sub, new, k, maxnew) char lin[], new[], sub[]; int from[], *k, maxnew, to[]; { } filset (delim, array, pasub, set, pindex, maxset) char array[], delim, set[]; int maxset, *pasub, *pindex; { } static dodash (valid, array, pasub, set, pindex, maxset) char array[], set[], valid[]; int maxset, *pasub, *pindex; { } addset (c, set, pindex, maxsiz) int maxsiz, *pindex; char c, set[]; { return 0; } char esc (array, pindex) char array[]; int *pindex; { return 0; } SHAR_EOF fi echo shar: "done with directory 'pat'" cd .. exit 0 # End of shell archive