IMD 1.16: 28/05/2007 16:55:35 -FOG/UTL030   åååååååååå  åååååååååå  åååååååååå  -FOG/UTL030DISK DOC +MYLIB3 C ]PREP C + SORT C 9 SPLIT C SPLTSCANC SSPLTSCANDOCAåTABS C #TAIL C TEE C  TR C !"UNIQ C #UNROT C $%UTDIR C &VSPLIT C '(åWC C )CRCKLISTCRC*åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå/* mylib3.c -- source for deff3.crl author: David H. Wolen last change: 6/12/83 contents: fefc rcarg error out argrange eqs addstr dodash isalpnum esc å cindex amatch patsize omatch locate getpat makepat getccl stclos undoc */ #include "a:bdscio.h" #define STDERR 4 #define MAXI 5 #define ESCAPE '\\' #define NEGATE '!' #define   LITCHAR 'c' #define BOL '%' #define EOL '$' #define ANY '?' #define CCL '[' #define CCLEND ']' #define NCCL '^' #define CLOSURE '*' #define CLOSIZE 1 /* fefc -- end, fflush, close output file */ fefc(iobuf) char *iobuf; { tf(STDERR,"%s\n",string); } /* argrange -- converts an integer range argument of the form n1-n2 to two positive integers. Returns ERROR if no "-" or ni has too many digits or <0 or missing usage:  putc(CPMEOF,iobuf); fflush(iobuf); fclose(iobuf); } /* rcarg -- restore case of argument. Intended to deal with CP/M desire to make command line args upper case. Any characters within # # in in if(argrange(arg,&n1,&n2)==ERROR) ... */ argrange(arg,n1,n2) char *arg; int *n1, *n2; { char cn[MAXI+1]; int i, j; for(i=0; (arg[i]!='-')&&(arg[i]!='\0'); i++) ; if(i>MAXI) return(ERROR); if(arg[i]!='-') retarg are turned to upper case; other characters are turned to lower case. usage: rcarg(outarg,inarg); */ rcarg(outarg,inarg) char *outarg, *inarg; { int makelow; makelow=TRUE; for(; *inarg ; inarg++) urn(ERROR); for(j=0; j= maxset) return(FALSE); else {outset[*j]=c; (*j)++; return(TRUE); } } /* dodash -- expand  if(c >= 'A' && c <= 'Z') return(TRUE); if(c >= 'a' && c <= 'z') return(TRUE); if(c >= '0' && c <= '9') return(TRUE); return(FALSE); } /* esc -- map s[i] into escaped character, increment i. usage: c=esc(inset,&i); set at src[i] into dest[j]. Stop at delim. usage: dodash('\0',inset,&i,outset,&j,maxset); */ dodash(delim,src,i,dest,j,maxset) char delim, *src, *dest; int *i, *j, maxset; { int k; char esc(); while(src[*i] != delim && src[ */ char esc(s,i) char *s; int *i; { if(s[*i] != ESCAPE) return(s[*i]); if(s[*i+1] == '\0') /* \ not special at end */ return(ESCAPE); (*i)++; if(s[*i] == 'n' || s[*i] == 'N') return('\n'); if(s[**i] != '\0') {if(src[*i] == ESCAPE) addstr(esc(src,i),dest,j,maxset); else if(src[*i] != '-') addstr(src[*i],dest,j,maxset); else if(*j <= 0 || src[*i+1] == '\0') addstr('-',di] == 't' || s[*i] == 'T') return('\t'); if(s[*i] == 'b' || s[*i] == 'B') return('\b'); if(s[*i] == 'r' || s[*i] == 'R') return('\r'); if(s[*i] == 'f' || s[*i] == 'F') return('\f'); if(s[*i] == 'p' || s[*i] == 'P') return('#');est,j,maxset); /* literal - */ else if(isalpnum(src[*i-1]) && isalpnum(src[*i+1]) && src[*i-1] <= src[*i+1]) {for(k=src[*i-1]+1; k <= src[*i+1]; k++) addstr(k,dest,j,ma if(s[*i] == 'q' || s[*i] == 'Q') return('"'); return(s[*i]); } /* cindex -- find position of character c in string s. -1 for not found. usage: if(cindex(string,c) >= 0) ... */ cindex(s,c) char *s, c; { int i; xset); (*i)++; } else addstr('-',dest,j,maxset); (*i)++; } } /* isalpnum -- true if c is letter or digit usage: if(isalpnum(c)) ... */ isalpnum(c) char c; { i=0; while(s[i] != c && s[i] != '\0') i++; if(s[i] == '\0') return(-1); else return(i); } /* amatch -- look for match of pat[j]... at lin[offset]... usage: pos=amatch(lin,i,pat,0); */ amatch(lin,offset,pa  t,j) char *lin, *pat; int offset, j; { int i, k, done, offset2; done=FALSE; offset2=offset; while(!done && pat[j] != '\0') {if(pat[j] == CLOSURE) {j += patsize(pat,j); i=offset2;  case CCL: case NCCL: return(pat[n+1]+2); case CLOSURE: return(CLOSIZE); default: error("in patsize: can't happen"); } } /* omatch -- match one pattern element at  while(!done && lin[i] != '\0') if(!omatch(lin,&i,pat,j)) done=TRUE; done=FALSE; while(!done && i >= offset2) {k=amatch(lin,i,pat,j+patsize(pat,pat[j] usage: if(!omatch(lin,&i,pat,j)) ... */ omatch(lin,i,pat,j) char *lin, *pat; int *i, j; { int advance, retval; advance=-1; if(lin[*i] == '\0') retval=FALSE; else switch(pat[j]) j)); if(k >= 0) /* matched rest of pattern */ done=TRUE; else i--; } offset2=k; done=TRUE;  {case LITCHAR: if(lin[*i] == pat[j+1]) advance=1; break; case BOL: if(*i == 0) advance=0; break;  } else if(!omatch(lin,&offset2,pat,j)) {offset2=-1; done=TRUE; } else j += patsize(pat,j); } return(offset2); } /* patsize -- return size of case ANY: if(lin[*i] != '\n') advance=1; break; case EOL: if(lin[*i] == '\n') advance=0;  pattern entry at pat[n] usage: j += patsize(pat,j); */ patsize(pat,n) char *pat; int n; { switch(pat[n]) {case LITCHAR: return(2); case BOL: case EOL: case ANY: return(1); break; case CCL: if(locate(lin[*i],pat,j+1)) advance=1; break; case NCCL: if(lin[*i] != '\n' && !locate(lin[*i],pat,j+1))    advance=1; break; default: error("in omatch: can't happen"); } if(advance >= 0) {(*i) += advance; retval=TRUE; } else j=j; if(arg[i] == ANY) addstr(ANY,pat,&j,MAXLINE); else if(arg[i] == BOL && i == start) addstr(BOL,pat,&j,MAXLINE); else if(arg[i] == EOL && arg[i+1] == delim) addstr(EOL,pat, retval=FALSE; return(retval); } /* locate -- look for c in character class at pat[offset] usage: if(locate(lin[i],pat,j+1)) ... */ locate(c,pat,offset) char c, *pat; int offset; { int i; i=offset+pat[offset]&j,MAXLINE); else if(arg[i] == CCL) done=(getccl(arg,&i,pat,&j) == FALSE); else if(arg[i] == CLOSURE && i > start) {lj=lastj; if(pat[lj] == BOL || pat[lj] == EOL || pat[lj] == CLOSURE) ; while(i > offset) if(c == pat[i]) return(TRUE); else i--; return(FALSE); } /* getpat -- convert argument into pattern usage: if(!getpat(arg,pat)) ... */ getpat(arg,pat) done=TRUE; else stclose(pat,&j,lastj); } else {addstr(LITCHAR,pat,&j,MAXLINE); addstr(esc(arg,&i),pat,&j,MAXLINE); }  char *arg, *pat; { return(makepat(arg,0,'\0',pat) >= 0); } /* makepat -- make pattern from arg[i], terminate at delim. returns i>=0 if ok, else ERROR (-1). usage: if(makepat(arg,0,'\0',pat) == ERROR) ... */ makepat(arg,start, lastj=lj; if(!done) i++; } if(done || arg[i] != delim) return(ERROR); else if(!addstr('\0',pat,&j,MAXLINE)) return(ERROR); else return(i); } /* getccl --delim,pat) char *arg, delim, *pat; int start; { int i, j, lastj, lj, done; j=0; /* pat index */ i=start; /* arg index */ lastj=0; done=FALSE; while(!done && arg[i] != delim && arg[i] != '\0') {l expand char class at arg[i] into pat[j]. Return TRUE if find CCLEND, else FALSE. usage: if(!getccl(arg,&i,pat,&j)) ... */ getccl(arg,i,pat,j) char *arg, *pat; int *i, *j; { int jstart; (*i)++; /* skip over [ */ if(  arg[*i] == NEGATE) {addstr(NCCL,pat,j,MAXLINE); (*i)++; } else addstr(CCL,pat,j,MAXLINE); jstart=*j; addstr(0,pat,j,MAXLINE); /* room for count */ dodash(CCLEND,arg,i,pat,j,MAXLINE)å; pat[jstart]=*j -jstart -1; return(arg[*i] == CCLEND); } /* stclose -- insert closure entry at pat[j] usage: stclose(pat,&j,lastj); */ stclose(pat,j,lastj) char *pat; int *j, lastj; { int jp, jt; for(jp=*j -1/* prep.c -- UTOOL. Convert a text file (including ws doc files) to one word per line. author: David H. Wolen last change: 3/9/83 usage: prep = lastj; jp--) {jt=jp +CLOSIZE; addstr(pat[jp],pat,&jt,MAXLINE); } (*j) += CLOSIZE; pat[lastj] = CLOSURE; /* where orig pattern began */ } /* undoc -- zero hi bit & replace strange chars by  -i list.dat ignore words on file -d preface output words with input sequence numbers input: STDIN output: STDOUT notes: (a) files for -o and -i must be prepared by prep and sortblanks (WS doc files) usage: putchar(undoc(c)); */ char undoc(c) char(c); { c &= 0177; /* zero hi bit */ if(c == '\0' || c == '\n' || c == '\r') /* leave as is */ return(c); else if(c < ' ' || c == 0x7f)  (-f and -u) (b) can't use both -o and -i (c) output is lower case (d) max file size for -o or -i is 1000 lines or about 30K. linkage: a:clink prep -f dio -ca (uses deff3.crl) */ #incl /* replace by blank */ return(' '); else return(c); }  if(c == '\0' || c == '\n' || c == '\r') /* leave as is */ return(c); else if(c < ' ' || c == 0x7f) ude "a:bdscio.h" #include "dio.h" #define STDOUT 1 #define STDERR 4 #define LINES 1000 /* size of list for -o and -i */ char *listp[LINES]; /* pointers to list items */ int nlist; /* number of list items */   main(argc,argv) int argc; char *argv[]; { int only, ignore, sequence, wcount; char *s, word[MAXLINE]; dioinit(&argc,argv); only=ignore=sequence=FALSE; wcount=0; while(--argc > 0 && (*++argv)[0]=='-') d: %s\n",wcount,word); if(pmatch(word) && !sequence) fprintf(STDOUT,"%s\n",word); } else {if(sequence) fprintf(STDOUT,"%d: %s\n",wcount,word);  for(s=argv[0]+1; *s != '\0'; s++) switch(*s) {case 'O': only=TRUE; break; case 'I': ignore=TRUE;  else fprintf(STDOUT,"%s\n",word); } } dioflush(); } /* readlist -- read and store exclusion or inclusion list. Check to be sure list is sorted and unique. */ readlist(filena break; case 'D': sequence=TRUE; break; default: error("prep: invalid option"); } if(only && ignore) me) char *filename; { int len, i; char ibuf[BUFSIZ], line[MAXLINE], *sbrk(), *p; if(fopen(filename,ibuf)==ERROR) error("prep: can't open list file"); nlist=0; while(fgets(line,ibuf)) {if(nlist >  error("prep: can't use both -o and -i"); if(only || ignore) readlist(*argv); while(getword(word)) {wcount++; if(ignore) {if(!pmatch(word) && sequence) fprintf(LINES) error("prep: too many lines in list file"); line[strlen(line)-1]='\0'; /* zap '\n' */ len=strlen(line) +1; if((p=sbrk(len))==ERROR) error("prep: too many chars on list file"); strcpy(p,line); STDOUT,"%d: %s\n",wcount,word); if(!pmatch(word) && !sequence) fprintf(STDOUT,"%s\n",word); } else if(only) {if(pmatch(word) && sequence) fprintf(STDOUT,"% listp[nlist++]=p; } if(nlist < 1) error("prep: empty list file"); for(i=1; i=0) error("prep: list isn't sorted or has duplicates"); } /* pstrcmp   -- compare strings. Return <0 if s0 if s>t. For equality, strings must be equal in length. Fold lower into upper case before comparison. */ pstrcmp(s,t) char *s, *t; { for(; *s != '\0'; s++, t++pmatch -- return TRUE if word is in list, else FALSE. Ignore case in the comparison. */ pmatch(word) char *word; { int low, mid, high; low=0; high=nlist-1; while(low <= high) /* binary search */ {mid=) if(toupper(*s) != toupper(*t)) return(toupper(*s)-toupper(*t)); if(*t == '\0') return(0); else return(-1); } /* getword -- get the next word from the standard input. Return TRUE for(low+high)/2; if(pstrcmp(word,listp[mid]) < 0) high=mid-1; else if (pstrcmp(word,listp[mid]) >0) low=mid+1; else /* found match */ return(TRUE); }  got a word, FALSE for EOF. */ getword(word) char *word; { int i, c; i=0; while(1) /* find start of word */ {if((c=getchar())==EOF) return(FALSE); c &= 0177; /* Wordstar hi bit */ if(is return(FALSE); } ]) >0) low=mid+1; else /* found match */ return(TRUE); } alpha(c)) break; } word[i++]=tolower(c); while(1) {if((c=getchar())==EOF) /* push back EOF for next call */ {ungetch(c); break; } c &= 0177; if(!isåalpha(c) && c!='\'') break; /* allow ' within a word */ else word[i++]=tolower(c); } if(word[i-1]=='\'') word[i-1]='\0'; else word[i]='\0'; return(TRUE); } /* å  /* sort.c -- UTOOL. (ver. 2) Incore sort of ascii lines. Max file size 2000 lines or about 30K. author: David H. Wolen last change: 5/5/83 usage: sort outfile sort 0 && (*++argv)[0]=='- -f fold lower into upper case before comparison -k key fields (n1-n2) 10 max if no key fields and no numeric, whole line is used -r reverse -n numeric (first item on line must be int) ') for(s=argv[0]+1; *s != '\0'; s++) switch(*s) {case 'F': foldflag=TRUE; break; case 'K': keyflag=TRUE; break; case 'R': revflag=TRUE; break;  neither -f nor -k can be used with -n -u unique (according to current sort def of equal) input: STDIN output: STDOUT linkage: a:clink sort -f dio -ca (uses deff3.crl) */ #i case 'N': numflag=TRUE; break; case 'U': uniqflag=TRUE; break; default: fprintf(STDERR, "sort: invalid option %c\n",*s); exinclude "a:bdscio.h" #include "dio.h" #define LINES 2000 /* max input lines */ #define MAXKEYS 10 /* max sort keys */ #define STDIN 0 #define STDERR 4 #define STDOUT 1 int keys[2][MAXKEYS]; t(dioflush()); } if(numflag&&keyflag) {fprintf(STDERR,"sort: -n and -k don't go together\n"); exit(dioflush()); } if(numflag&&foldflag) {fprintf(STDERR,"sort: -n and -f don't go /* starts & ends of key flds */ char *lineptr[LINES]; /* ptrs to text lines */ main(argc,argv) int argc; char *argv[]; { int nlines; /* numb of input lines */ int i, test, foldflag, keyfla together\n"); exit(dioflush()); } /* process key fields, if any */ if(keyflag) {if(argc<=0) {fprintf(STDERR,"sort: missing keys\n"); exit(dioflush()); }    if(argc>MAXKEYS) {fprintf(STDERR,"sort: more than %d keys\n",MAXKEYS); exit(dioflush()); } for(i=0; iMAXLINE-1)||(k2>MAXLINE-1)) return(-5); else return(0); } /* filein -- read input, store lines, store pointers to lines */ filein() { int len, nlines; char *p, *sbrk(), line[MAXLINE]; nlines=0; wh(test=dokey(*argv++,i)) <0) {fprintf(STDERR,"sort: error in dokey %d\n",test); exit(dioflush()); } } /* read input */ if( (nlines=filein()) <0) {fprintf(ile(fgets(line,STDIN)) {if(nlines>LINES) return(-1); line[strlen(line)-1]='\0'; /* zap '\n' */ len=strlen(line) + 1; /* account for null byte */ if((p=sbrk(len))==ERROR) return(-2); strcpy(STDERR, "sort: too much input. Lines(-1) or char(-2): %d\n",nlines); exit(dioflush()); } if(nlines==0) {fprintf(STDERR,"sort: empty input file\n"); exit(dioflush()); } fp,line); lineptr[nlines++]=p; } return(nlines); } /* xsort -- shell sort pointers to text lines */ xsort(v,n,fold,keys,reverse,numeric) char *v[]; int n, fold, keys, reverse, numeric; { int gap, i, j; printf(STDERR,"sort: %d input lines\n",nlines); /* sort */ xsort(lineptr,nlines,foldflag,keyflag,revflag,numflag); /* write output */ output(nlines,uniqflag,foldflag,keyflag,revflag,numflag); dioflush(); }  for(gap=n/2;gap>0;gap/=2) for(i=gap;i=0;j-=gap) {if(scmp(v[j],v[j+gap],fold,keys,reverse,numeric) <= 0) break; swap(&v[j],&v[j+gap]);/* dokey -- process and store a sort key */ dokey(inkey,nkey) char inkey[]; int nkey; { int k1,k2; if(argrange(inkey,&k1,&k2)==ERROR) return(-4); keys[0][nkey]= --k1; keys[1][nkey]= --k2; if((k1<0)||(k2<0)||(k } } /* scmp -- string compare. Return <0 if s0 if s>t (lie if reverse) */ scmp(s,t,fold,keys,reverse,numeric) char *s, *t; int fold, keys, reverse, numeric; { int result; if(numeric  ) /* leading integers */ result=atoi(s) -atoi(t); else if(keys) /* fields */ result=strcmpaf(s,t,fold); else /* whole line */ result=xstrcmp(s,t,fold); if(reverse) /*1][i]; j++) {s1 = (fold) ? toupper(s[j]) : s[j]; t1 = (fold) ? toupper(t[j]) : t[j]; if(s1 != t1) return (s1-t1); } return(0); } /* output -- write output. Delete non-unique lie for descending sort */ result *= -1; return(result); } /* swap -- exchange pointers. K&R p. 117 */ swap(px,py) char *px[], *py[]; { char *temp; temp=*px; *px=*py; *py=temp; } /* xst lines (current sort def of equality) if requested */ output(nlines,unique,fold,keys,reverse,numeric) int nlines, unique, fold, keys, reverse, numeric; { int i; if(unique) /* delete non-unique lines */ {fprintfrcmp -- return <0 if s0 if s>t. If fold, fold lower into upper case before compare. */ xstrcmp(s,t,fold) char *s, *t; int fold; { char s1, t1; for(; *s != '\0'; s++, t++) {s1= (fold) ? toupper(*s) :(STDOUT,"%s\n",lineptr[0]); for(i=1; i < nlines; i++) if(scmp(lineptr[i],lineptr[i-1],fold,keys,reverse,numeric) != 0) fprintf(STDOUT,"%s\n",lineptr[i]); } else /* output all l *s; t1= (fold) ? toupper(*t) : *t; if(s1 != t1) return(s1-t1); } if(*t=='\0') return(0); else return(-1); } /* strcmpaf -- compare using fields. Return <0 for s<ines */ for(i=0; i < nlines; i++) fprintf(STDOUT,"%s\n",lineptr[i]); } se,numeric) != 0) fprintf(STDOUT,"%s\n",lineptr[i]); } else /* output all lt, 0 for s==t, >0 for s>t. If fold, fold lower into upper case before comparison. */ strcmpaf(s,t,fold) char *s, *t; int fold; { int i,j; char s1, t1; for(i=0; keys[0][i]>=0; i++) for(j=keys[0][i]; j<=keys[å  å6th file may have n lines written to it before end of input is reached. In that case, the rest of the input will also be transferred to it. (3) outname can't begin with "-" å (4) outname can contain a drive prefix; e.g. a:outname linkage: a:clink split -f dio -ca (uses deff3.crl) */ #include "a:bdscio.h" #include "dio.h" #define STDIN 0 #define DLINES 100 /* default lines per output file/* split.c -- UTOOL. Read STDIN and write it out in n-line chunks to files author: David H. Wolen last change: 3/31/83 usage: split [-n] [outname] split = 25) /* put rest of input on last output file */ while((gotit=fgets(line,STDIN))) fputs(line,obuf); fefc(obuf); return(gotit); } tname]"); /* main logic */ for(i=0; i < 26; i++) {makename(fnamprfx,i,filename); if( !spcopy(nl,filename,i)) break; } dioflush(); } /* makename -- make filename of the form åfnamprfx.c where c= a ... z */ makename(prefix,index,outname) char *prefix, *outname; int index; { char suffix[3], *letters; letters="abcdefghijklmnopqrstuvwxyz"; /* poor man's static */ strcpy(outname,prefix); suffix[0]=å'.'; suffix[1]=letters[index]; suffix[2]='\0'; strcat(outname,suffix); } /* spcopy -- copy nl lines from STDIN to outname */ spcopy(nl,outname,ifile) int nl, ifile; char *outname; { char line[MAXLINE], obuf[BUFSIZ]; /* split, splitr, scan, scanr, scann, scannr -- character handling functions similar to HIS TEX */ /* split - splits instring. Puts leftmost col characters in starl and the rest in starr. instring must be terminat int gotit, i; if(fcreat(outname,obuf) == ERROR) error("split: can't create output file"); for(i=0; i < nl; i++) {if(!(gotit=fgets(line,STDIN))) break; fputs(line,obuf); } ed by '\0' . starl and starr will be terminated by '\0 . Strange cases are handled as in TEX. */ #include "a:bdscio.h" #define CLASC '_' #define STDERR 4 split(instring,col,starl,starr) /* split from left */ char inst  ring[], starl[], starr[]; int col; { int i,j; /* special cases */ if(instring[0]=='\0') {starl[0]=starr[0]='\0'; return; } if(col<=0) {starl[0]='\0'; strcpy(starr,inst). instring must be terminated by '\0'. Returns TRUE or FALSE. */ scan(instring,pat,starl,starm,starr) /* scan from left */ char instring[], pat[], starl[], starm[], starr[]; { char starlx[MAXLINE], starrx[MAXLINE]; ring); return; } if(col>strlen(instring)) {strcpy(starl,instring); starr[0]='\0'; return; } /* normal case */ for(i=0;i1 char in scann %s",pat); fprintf(STDERR," used first\n"); } for(i=0;instring[i]!='\0';i++) if(pat[0]!=instring[i]) break; if(instring[i]=='\0') {strcpy(starl,instring);  else if((pat[1]=='u')&&(pat[2]=='c')) *up=TRUE; else if((pat[1]=='a')&&(pat[2]=='n')) *alp=*num=TRUE; else return(ERROR); return(OK); } /* scann - scans instring from left for non-match on pat. pat can contain one ch starr[0]=starm[0]='\0'; return(TRUE); } else {split(instring,i,starl,starr); starm[0]='\0'; if(starr[0]=='\0') return(TRUE); else return(FALSE); }    /* normal case with class */ class: if(getclass(pat,&alp,&num,&low,&up)==ERROR) {fprintf(STDERR,"\nbad class in scann is %s",pat); fprintf(STDERR," treated as null\n"); strcpy(starl,instring);  /* special cases */ if(instring[0]=='\0') {starl[0]=starm[0]=starr[0]='\0'; return(FALSE); } if(pat[0]=='\0') {strcpy(starr,instring); starl[0]=starm[0]='\0'; return(FALSE starm[0]=starr[0]='\0'; return(FALSE); } for(i=0;instring[i]!='\0';i++) {if(alp && !isalpha(instring[i])) break; if (num && !isdigit(instring[i])) break; if (low && !islower(instring[i])) b); } /* normal case without class */ if(pat[0]==CLASC) goto class; if(index(instring,pat)<0) {strcpy(starr,instring); starl[0]=starm[0]='\0'; return(FALSE); } else reak; if (up && !isupper(instring[i])) break; } if(instring[i]=='\0') {strcpy(starl,instring); starm[0]=starr[0]='\0'; return(TRUE); } else {split(instring,i,starl {scan(instring,pat,starl,starm,starr); return(TRUE); } /* normal case with class */ class: if(getclass(pat,&alp,&num,&low,&up)==ERROR) {fprintf(STDERR,"\nbad class in scanr %s",pat); fpr,starr); starm[0]='\0'; if(starr[0]=='\0') return(TRUE); else return(FALSE); } } /* scanr - scans instring from right for pat. pat can contain characters or a class intf(STDERR," treated as null\n"); strcpy(starr,instring); starl[0]=starm[0]='\0'; return(FALSE); } for(i=strlen(instring)-1;i>=0;i--) {if(alp && isalpha(instring[i])) break; if(num (prefixed by _). instring must be terminated by '\0'. Returns TRUE or FALSE. */ scanr(instring,pat,starl,starm,starr) /* scan from right */ char instring[], pat[], starl[], starm[], starr[]; { int i, alp, num, low, up;  && isdigit(instring[i])) break; if(low && islower(instring[i])) break; if(up && isupper(instring[i])) break; } if(i<0) {strcpy(starr,instring); starl[0]=starm[0]='\0'; re  turn(FALSE); } else {split(instring,i+1,starl,starr); starm[0]='\0'; return(TRUE); } } /* scannr - scans instring from right for non-match on pat. pat can contain one chara {starl[0]=starm[0]='\0'; strcpy(starr,instring); return(TRUE); } else {starm[0]='\0'; split(instring,i+1,starl,starr); return(FALSE); } /* normal case with ccter or a class (prefixed by _). instring must be terminated by '\0'. Returns TRUE or FALSE (as in TEX, the TRUE and FALSE results are not intuitively obvious). */ scannr(instring,pat,starl,starm,starr) /*lass */ class: if(getclass(pat,&alp,&num,&low,&up)==ERROR) {fprintf(STDERR,"\nbad class in scannr %s",pat); fprintf(STDERR," treated as null\n"); starl[0]=starm[0]=starr[0]='\0'; return(FALSE);  scan from right for non-match */ char instring[], pat[], starl[], starm[], starr[]; { int col, i, alp, num, low, up; /* special cases */ if(pat[0]=='\0') {fprintf(STDERR,"\nerror in scannr null pat\n"); st } for(i=strlen(instring)-1;i >= 0;i--) {if(alp && !isalpha(instring[i])) break; if(num && !isdigit(instring[i])) break; if(low && !islower(instring[i])) break; if(up && !isupper(instring[i])) break;arl[0]=starm[0]=starr[0]='\0'; return(FALSE); } if(instring[0]=='\0') {starl[0]=starm[0]=starr[0]='\0'; return(FALSE); } /* normal case without class */ if(pat[0]==CLASC) goto  } if(i<0) {starl[0]=starm[0]='\0'; strcpy(starr,instring); return(TRUE); } else {starm[0]='\0'; split(instring,i+1,starl,starr); return(FALSE); class; if(pat[1]!='\0') {fprintf(STDERR,"\npat>1 char in scannr %s",pat); fprintf(STDERR," used first\n"); } for(i=strlen(instring)-1;i >= 0;i--) if(pat[0]!=instring[i]) break; if(i<0)  } }  } else {starm[0]='\0'; split(instring,i+1,starl,starr); return(FALSE);   ååå.he spltscan.doc Character handling functions similar to those in Honeywell's TEX. 1. split(instring,col,starl,starr) 2. splitr(instring,col,starl,starr) 3. match=scan(instring,pat,starl,starm,starr) 4. match=scann(instring,paåt,starl,starm,starr) 5. match=scanr(instring,pat,starl,starm,starr) 6. match=scannr(instring,pat,starl,starm,starr) General notes: instring is the input string to be split or scanned. It must be terminated by '\0'. starl,såtarm and starr are output strings. They will be terminated by '\0'. col, input to split and splitr, is an integer. pat, input to the scan functions, is the pattern to be matched and must be terminated by '\0'. If å pat's first character is '_' (CLASC), then it indicates a class match instead of a literal match. The classes available are: _a alphabetic. 52 ascii upper and lower. _n numeric. digits 0-9.    _an alphanumeric. 52 alpha and the 10 digits. _lc lower case. 26 ascii lower case alpha. _uc upper case. 26 ascii upper case alpha. match, output by scan functions, is 0 (FALSE) or 1 (TRUE). Specifiinstring and starl will be null. (c) if col<=0 then starr will be null and starl will contain all of instring. .pa Š3. match=scan(instring,pat,starl,starm,starr) normal case: where pat is a string           Iæ   paôc details on each function follow. .pa Š1. split(instring,col,starl,starr) normal case 0 < col <= strlen(instring) starl will contain the leftmost col characters of instring. starr will contain the rest.   ió  iî  instring¬   starì  wilì  contaiî  thå           characteró tï thå lefô oæ it¬  starí wilì contaiî  pat¬           starò  wilì  contaiî thå characteró tï thå righô oæ  iô           anä matcè wilì bå ± (TRUE)®  Iæ paô isn'ô iî instring¬    special cases (a) if instring is null (instring[0]=='\0') then starl and starr will be null. (b) if col>strlen(instring) then starl will contain all of instring and starr will be null.         starì  wilì contaiî instring¬  starí anä starò wilì  bå           null and match will be 0 (FALSE). normal case: where pat is a class           Iæ  aî occurrencå oæ thå clasó ió  iî  instring¬  starì           wilì  contaiî  thå char(c) if col <=0 then starr will contain all of instring and starl will be null. 2. splitr(instring,col,starl,starr) normal case 0 < col <= strlen(instring) starr will contain the rightmost col characteracteró tï thå lefô oæ thå  firsô           occurrence¬  starí wilì bå null¬ starò wilì contaiî thå           rest¬  anä matcè wilì bå ° (FALSE)® Iæ therå isn'ô anù           occurrencå oæ thå clasó iî instring¬ starì wilì contaiî           instrins of instring. starl will contain the rest. special cases (a) if instring is null, then starl and starr will be null. (b) if col>strlen(instring), then starr will contain all of g¬  starí anä starò wilì bå nulì anä matcè  wilì           be 0 (FALSE). special cases (a) if instring is null, starl, starm and starr will be null and match will be 0 (FALSE). (b) if pat is null and inst  ring isn't null, starl will contain instring, starm and starr will be null and match will be 0 (FALSE). .pa Š4. match=scann(instring,pat,starl,starm,starr) normal case: where pat is a string           paô musô bä  starí           wilì  bå null¬  starò wilì contaiî instrinç  anä  matcè           will be 0 (FALSE). special cases (a) If instring and/or pat is null, starl, starm and starr will be null. match will be 0 (FALSEå á singlå character® Iæ paô ió iî instringº           starì  wilì  contaiî  anù leadinç occurrenceó  oæ  pat¬           starí  wilì  bå null¬  starò wilì contaiî thå  resô  oæ           instrinç  anä matcè wilì bå ± (TRUE© iæ starò  ió  nulì    ). In contrast, TEX considers it an error if pat is null here and doesn't bother to return any values (it just issues the warning message). .pa Š5. match=scanr(instring,pat,starl,starm,starr) norm       (e.g®  iæ  eacè  oæ thå characteró oæ instrinç  matcheó           pat©  anä  °  (FALSE©  otherwise®   Iæ  paô  isn'ô  iî           instringº  starì  anä starí wilì bå null¬  starò  wilì           contain instring and match will be 0 (FALSE).al case: where pat is a string           Iæ paô ió iî instring¬ starì wilì contaiî characteró tï           thå lefô oæ pat¬  starí wilì contaiî paô anä starò wilì           contaiî characteró tï thå righô oæ pat¬  anä matcè wilì           bå ± (TR normal case: where pat is a class           Iæ instrinç containó aî occurrencå oæ thå  class¬  theî           starì  wilì  contaiî  alì leadinç  occurrenceó  oæ  thå           class¬  starí wilì bå null¬ starò wilì contaiî thå resô      UE)® Iæ paô isn'ô iî instring¬ starì anä starí           wilì  bå  null¬  starò wilì contaiî instrinç anä  matcè           will be 0 (FALSE). normal case: where pat is a class           Iæ instrinç containó aî occurrencå oæ thå class¬  sta     oæ  instring¬  anä  matcè wilì bå ± (TRUE© iæ starò  ió           nulì  (e.g®  iæ  alì characteró oæ instrinç  matcè  thå           class©  anä ° (FALSE© otherwise®  Iæ instrinç  doesn'ô           contaiî  anù occurrencå oæ thå class¬  starì anrì           wilì contaiî thå rightmosô occurrencå oæ thå clasó  anä           anù  characteró tï thå lefô oæ it¬  starí wilì bå null¬           starò wilì contaiî thå resô oæ instrinç anä matcè  wilì           bå   ±  (TRUE)®   Iæ  instrinç  does  n'ô  contaiî   anù           occurrencå oæ thå class¬  starì anä starí wilì bå null¬           starò  wilì  contaiî  instrinç  anä  matcè  wilì  bå  °           (FALSE). special cases (a) If instring is null, then starl, starm aæ thå class¬  starì           wilì contaiî thå rightmosô characteò thaô doesn'ô matcè           thå clasó anä alì characteró tï thå lefô oæ it®  starí           wilì bå null¬  starò wilì contaiî thå resô oæ instring®           Iæ  starò  isn'ô nund starr will be null. match will be 0 (FALSE). (b) If pat is null and instring isn't, then starl and starm will be null. starr will contain instring and match will be 0 (FALSE). .pa Š6. matclì (e.g®  iæ alì thå  characteró  oæ           instrinç  matcè thå class© theî matcè wilì bå ± (TRUE)®           Iæ starò ió null¬ matcè wilì bå ° (FALSE)® Iæ instrinç           doesn'ô contaiî anù occurrencå oæ thå class¬ starì wilì           coh=scannr(instring,pat,starl,starm,starr) normal case: where pat is a string           paô musô bå á singlå character® Iæ paô ió iî instring¬           starì wilì contaiî thå rightmosô characteò thaô doesn'ô           matcè  paô anä alì chantaiî  instring¬  starí  anä starò wilì bå  nulì  anä           match will be 0 (FALSE). special cases           Iæ instriî and/oò paô ió null¬  starl¬  starí anä starò           wilì bå null®  matcè wilì bå ° (FALSE)®  Iî contrast¬     racteró tï thå lefô oæ it¬  starí           wilì  bå  null¬  anä  starò wilì contaiî  thå  resô  oæ           instring®  matcè wilì bå ± (TRUE© iæ starò isn'ô  nulì           (e.g® iæ alì thå characteró oæ instrinç matcè pat)¬ anä           ° (FAL      TEØ  consideró iô aî erroò iæ paô ió nulì anä issueó  á           message without bothering to set any variables.  instriî and/oò paô ió null¬  starl¬  starí anä starò           wilì bå null®  matcè wilì bå ° (FALSE)®  Iî contrast¬     SE© iæ starò ió null®  Iæ paô isn'ô iî instring¬           starì  wilì contaiî instring¬  starí anä starò wilì  bå           null and match will be 0 (FALSE). normal case: where pat is a class           Iæ instrinç containó aî occurrencå oå  ååå/* tabs.c -- UTOOL. Convert tabs to blanks (-d) or blanks to tabs and blanks (-e). author: David H. Wolen last change: 2/12/83 usage: tabs -d tabs -e 5 21 &5 options: -d detab (convert tab chars tåo blanks) -e entab (convert blanks to tab chars and blanks) input: STDIN output: STDOUT notes: (1) either -d or -e is required (2) default tab stops are at columns 8, 16, 24, ... å (3) &n in the command line sets tabs every n columns. E.G. "5 21 &5" sets tabs at columns 5, 21, 26, 31, ... Anything after the &n will be ignored. linkage: a:clink tabs -f dio -ca (uses deff3.crl) */ å #include "a:bdscio.h" #include "dio.h" #define TABSPACE 8 /* default tabs every 8 columns */ int tabflags[MAXLINE]; /* [0] isn't used */ main(argc,argv) int argc; char *argv[]; { int dodetab, doentab; char *s; d  ioinit(&argc,argv); dodetab=doentab=FALSE; /* process options */ while(--argc > 0 && (*++argv)[0] == '-') for(s=argv[0]+1; *s != '\0'; s++) switch(*s) {case 'D': * tabs from command line */ doincr=FALSE; while(argc-- > 0) {if( *argv[0] == '&') {*argv[0]=' '; doincr=TRUE; } itab=atoi(*argv); if( itab <= 0)  dodetab=TRUE; break; case 'E': doentab=TRUE; break; default: error("tabs: invalid option. Use -d or -e"); return(ERROR); itab=min(itab,MAXLINE-1); if(doincr) {for(i=lastab+1; i < MAXLINE; i++) tabflags[i]=((i-lastab) % itab == 0); return(OK); } else  } if( (!dodetab && !doentab) || (dodetab && doentab) ) error("tabs: must give -d or -e"); /* main */ if(settabs(argc,argv) == ERROR) error("tabs: bad tab argument"); if(dodetab)  {tabflags[itab]=TRUE; lastab=itab; argv++; } } return(OK); } /* detab -- convert tab chars to blanks */ detab() { int c, col; col=1; while( (c=get detab(); else if(doentab) entab(); dioflush(); } /* settabs -- set initial tab stops from command line or default */ settabs(argc,argv) int argc; char *argv[]; { int i, lastab, itab, doincr; for(i=char()) != EOF) {if(c == '\t') do {putchar(' '); col++; } while(!tabpos(col)); else if(c == '\n') {putchar('\n'); 0; i < MAXLINE; i++) tabflags[i]=FALSE; if(argc <= 0) /* default tab stops */ {for(i=1; i < MAXLINE; i++) tabflags[i]=(i % TABSPACE == 0); return(OK); } lastab=0; / col=1; } else {putchar(c); col++; } } } /* tabpos -- return true if col is a tab stop, else false */ tabpos(col) int col; { if(col >= MAXLIN  E) return(TRUE); else return(tabflags[col]); } /* entab -- convert blanks to tab chars and blanks */ entab() { int c, col, newcol; col=1; do {newcol=col; while( (c=getchar()å) == ' ') /* collect blanks */ {newcol++; if(tabpos(newcol)) {putchar('\t'); col=newcol; } } while(col < newcol) /* output leåftover blanks */ {putchar(' '); col++; } if(c != EOF) {putchar(c); if(c == '\n') col=1; else col++; å } } while(c != EOF); }  {putchar(c); if(c == '\n') col=1; else col++; ååå  /* tail.c -- UTOOL. Print last n lines of file. author: David H. Wolen last change: 01/25/83 usage: tail [n] options: n number of lines to print. Range 1--1000. Default 32. input: STDIN  dioflush(); } /* saveline -- store lines and save pointers to them */ saveline(line,linbuf,nsave,ntail) char *line, *linbuf[]; int *nsave, ntail; { char *alloc(), *p; if(*nsave < ntail) {if((p=alloc(strlen(lin output: STDOUT linkage: a:clink tail -f dio -ca (uses deff3.crl) */ #include "a:bdscio.h" #include "dio.h" #define STDIN 0 #define STDOUT 1 #define LINES 1000 /* max lines to display */ #define OS1LINES 32 /* default linee)+1)) == NULL) error("tail: out of room in saveline #1"); strcpy(p,line); linbuf[(*nsave)++]=p; } else {free(linbuf[0]); movmem(&linbuf[1],&linbuf[0],(ntail-1)*SIZECP); s to display */ #define SIZECP 2 /* size of pointer to char in bytes */ main(argc,argv) int argc; char *argv[]; { int ntail, nsave, i; char *linbuf[LINES], line[MAXLINE]; dioinit(&argc,argv); _allocp=NULL;  if((p=alloc(strlen(line)+1)) == NULL) error("tail: out of room in saveline #2"); strcpy(p,line); linbuf[ntail-1]=p; } } nsave=0; if(argc > 1) /* number of lines to print given on command line */ {ntail=atoi(*++argv); if(ntail < 1 || ntail > LINES) error("tail: lines to print must be 1--1000"); } else /* tee.c -- UTOOL. Copy STDIN to STDOUT and named file. author: David H. Wolen last change: 1/16/83 usage: tee [-a] outfile options: -a append to outfile instead of copying to it input: STDIN output: STDOUT /* use default */ ntail=OS1LINES; while(fgets(line,STDIN)) saveline(line,linbuf,&nsave,ntail); if(nsave <= 0) error("tail: empty input"); for(i=0; i < nsave; i++) fputs(linbuf[i],STDOUT); and file notes: (a) if -a and outfile doesn't exist, the option is ignored. (b) if -a, it creates and releases a temp file (temptee.$$$) on the logged drive. linkage: a:clink   tee -f dio -ca (uses deff3.crl) */ #include "a:bdscio.h" #include "dio.h" #define STDIN 0 #define STDOUT 1 main(argc,argv) int argc; char *argv[]; { int append; char *s, ibuf[BUFSIZ], obuf[BUFSIZ]; dioinit(&argc,argverror during append"); fefc(obuf); unlink(*argv); if(rename("temptee.$$$",*argv) == ERROR) error("tee: output is on temptee.$$$ ; can't rename"); } dioflush(); } /* tfcopy -- cop); append=FALSE; /* process options */ while(--argc > 0 && (*++argv)[0] == '-') for(s=argv[0]+1; *s != '\0'; s++) switch(*s) {case 'A': append=TRUE; y file fin to fout, line by line. Returns OK or ERROR. If echo, output goes to both fout and STDOUT. */ tfcopy(fin,fout,echo) char *fin, *fout; int echo; { int c; char line[MAXLINE]; while(fgets(line,fin)) {if( break; default: error("usage: tee [-a] outfile"); } if(!append) {if(fcreat(*argv,obuf) == ERROR) error("tee: can't create output file"); fputs(line,fout) == ERROR) return(ERROR); if(echo) fputs(line,STDOUT); } return(OK); } /* terror -- release temp file, then normal error */ terror(msg) char *msg; { unlink("temp if(tfcopy(STDIN,obuf,TRUE) == ERROR) error("tee: file output error"); fefc(obuf); } else {if(fcreat("temptee.$$$",obuf) == ERROR) error("tee: can't create temp file"); tee.$$$"); error(msg); }  return(OK); } /* terror -- release temp file, then normal error */ terror(msg) char *msg; { unlink("temp if(fopen(*argv,ibuf) != ERROR) if(tfcopy(ibuf,obuf,FALSE) == ERROR) terror("tee: file output error copying prior to append"); if(tfcopy(STDIN,obuf,TRUE) == ERROR) terror("tee: file output å  å (delete everything but newlines) tr 0-9 9 (change digit strings to single digit 9) input: STDIN output: STDOUT notes: (1) - denotes range (2) ! denotes "all but" å(3) \n (newline) \t (tab) \b (backspace) \r (carr ret) \f (form feed) \p (#) \q (") (4) if dest is absent, all chars represented by src are deleted (5) if dest is shorter than src, allå chars of src that would map to or beyond last char in dest are mapped to last char in dest. Adjacent instances of such chars in src cause a single instance of last char in ådest to be output. (6) use " " to enclose blanks in src and dest (7) use # # to enclose capital letters in src and dest linkage: a:clink tr -f dio -ca (uses deff3.crl) */ #include "a:bdscio.h" #include "dio.h/* tr.c -- UTOOL. Transliterate characters author: David H. Wolen last change: 12/31/82 usage: tr src dest tr #A-Z# a-z (change case) tr " \t\n" \n (make one word per line) tr !\n " #define NEGATE '!' #define ESCAPE '\\' main(argc,argv) int argc; char *argv[]; { int c, i, lastto, allbut, squash; char arg[MAXLINE], fromset[MAXLINE], toset[MAXLINE]; dioinit(&argc,argv); if(argc <= 1) error("u  sage: tr from to"); rcarg(arg,*++argv); allbut=(arg[0] == NEGATE); if(allbut) i=1; else i=0; if(!makset(arg,i,fromset,MAXLINE)) error("tr: from set too large"); if(argc == 2)  /* makset -- make set from inset[k] in outset. Returns FALSE for no room */ makset(inset,k,outset,maxset) char *inset, *outset; int k, maxset; { int j, kk; j=0; kk=k; dodash('\0',inset,&kk,outset,&j,maxset); ret /* empty toset */ toset[0]='\0'; else {rcarg(arg,*++argv); if(!makset(arg,0,toset,MAXLINE)) error("tr: to set too large"); } if(strlen(fromset) < strlen(toset)) error("turn(addstr('\0',outset,&j,maxset)); } /* xindex -- conditionally invert value from cindex */ xindex(inset,c,allbut,lastto) char *inset; int allbut, lastto, c; { if(c == EOF) return(-1); if(!allbut) return(cindex(inset,c)); r: from shorter than to"); lastto=strlen(toset) -1; squash=(strlen(fromset) > lastto +1) || allbut; do {i=xindex(fromset,(c=getchar()),allbut,lastto); if(squash && i >= lastto && lastto >= 0) {pu if(cindex(inset,c) >= 0) return(-1); else return(lastto+1); } to) char *inset; int allbut, lastto, c; { if(c == EOF) return(-1); if(!allbut) return(cindex(inset,c)); tchar(toset[lastto]); do i=xindex(fromset,(c=getchar()),allbut,lastto); while(i >= lastto); } if(c != EOF) {if(i >= 0 && lastto >= 0) /* translate */ å putchar(toset[i]); else if(i < 0) /* copy */ putchar(c); } /* else delete */ } while(c != EOF); dioflush(); } å  /* uniq.c -- UTOOL. Filters out adjacent duplicate lines in sorted file. Lines must be identical (including same length) to be filtered out. author: David H. Wolen last change: 12/2/82 option: -c prefixes eactrcpy(line1,line2); count=1; } if(cflag) fprintf(STDOUT,"%d %s",count,line1); else fputs(line1,STDOUT); dioflush(); } h output line with count usage: sort outfile -c input: STDIN output: STDOUT linkage: a:clink uniq -f dio -ca (uses deff3.crl) */ #include "a:bdscio.h" #include "dio.h" #define STDIN 0 #define STDOåUT 1 #define STDERR 4 main(argc,argv) int argc; char *argv[]; { int count, cflag; char *s, line1[MAXLINE], line2[MAXLINE]; dioinit(&argc, argv); cflag=FALSE; while( --argc>0 && (*++argv)[0]=='-') forå(s=argv[0]+1; *s != '\0'; s++) switch(*s) {case 'C': cflag=TRUE; break; default: error("uniq: -c is only valid option"); } if(!fgets(line1,STDIN)) error("uniq: empt/* unrot.c -- UTOOL. Unrotate lines rotated by kwic. Last step in making keyword-in-context index. author: David H. Wolen last change: 12/2/82 usage: kwic outfile input: STDIN output: y input file"); count=1; while(fgets(line2,STDIN)) if(eqs(line1,line2)) count++; else {if(cflag) fprintf(STDOUT,"%d %s",count,line1); else fputs(line1,STDOUT); sSTDOUT linkage: a:clink unrot -f dio -ca */ #include "a:bdscio.h" #include "dio.h" #define STDIN 0 #define STDOUT 1 #define FOLD '$' /* indicates begin of folded line */ #define MAXOUT 92 /* width of output lines */   main(argc,argv) int argc; char *argv[]; { char inline[MAXLINE], outline[MAXOUT]; int i, j, middle; dioinit(&argc,argv); middle = max(MAXOUT/2,0) -1; while(fgets(inline,STDIN)) {for(i=0; i 0 && inline[i-1] == ' ') if(nextj(1,inline,i,j) >= MAXOUT-3) see if enough space for another word */ nextj(incr,lbuf,i,j) char *lbuf; int incr, i, j; { int k; for(k=i; k >= 0; k += incr) {if(lbuf[k] == ' ' || lbuf[k] == FOLD || lbuf[k] == '\n') break; j += in j=0; if(j >= MAXOUT -3) j=0; outline[j]=inline[i]; } if(inline[i] == FOLD) /* copy 2nd half working backwards */ {j=middle-1; cr; } return(j); }  >= 0; k += incr) {if(lbuf[k] == ' ' || lbuf[k] == FOLD || lbuf[k] == '\n') break; j += in for(i=strlen(inline)-2; i >= 0; i--) { if(inline[i] == FOLD) break; j--; if(inline[i+1] == ' ') if(nextj(-1,inline,i,jå) < 0) j=MAXOUT-3; if(j < 0) j=MAXOUT-3; outline[j]=inline[i]; } } for(i=MAXOUT-3; i >= 0; i--) å!  å utdir b:*.* !b:*.c all files on b: except .c utdir ?.com all .com files with single letter file name on current drive options: none input: command line only outåput: STDOUT notes: 1. max of 200 files after expansion 2. metacharacters in filename: ! except ? wildcard match a single character * wildcard match 1 or more charåacters linkage: a:clink utdir -f a:dio -f a:wildexp -ca */ #include "a:bdscio.h" #include "a:dio.h" main(argc,argv) int argc; char *argv[]; { int i, strcmp(); if(wildexp(&argc,&argv) == ERROR) error("utdir: åerror in wildexp"); dioinit(&argc,argv); if(argc == 1) error("utdir: no matching files"); qsort(&argv[1],argc-1,2,&strcmp); /* skip first argv */ for(i=1; i < argc; i++) printf("%s\n",argv[i]); d/* utdir.c -- UTOOL. Sorted file directory. author: David H. Wolen last change: 6/5/83 usage: utdir *.* all files on current drive utdir !*.com all files on current drive except .com ioflush(); } /* strcmp -- special version. Library version has args *s, *t */ strcmp(s,t) char **s, **t; { char *s1, *t1; int i; s1=*s; t1=*t; i=0; while(s1[i] == t1[i]) if(s1[i++] == '\0') "   return(0); return(s1[i] - t1[i]); } r *s1, *t1; int i; s1=*s; t1=*t; i=0; while(s1[i] == t1[i]) if(s1[i++] == '\0')  and col > line length, output will be whole line 3. If lr and col > line length, output will be 4. If ll and col <= 0, output will be 5. If lr and col <= 0, output will be whole line å 6. If rl and col > line length, output will be 7. If rr and col > line length, output will be whole line 8. If rl and col <= 0, output will be whole line 9. If rr and col <= 0, output will /* vsplit.c -- UTOOL. Vertically split a text file. author: David H. Wolen last change: 2/20/83 usage: vsplit cc col vsplit ll 80 (output first 80 cols of each line) vsplit lr 10 (delete first be linkage: a:clink vsplit spltscan -f dio -ca (uses deff3.crl) */ #include "a:bdscio.h" #include "dio.h" #define STDIN 0 #define STDOUT 1 main(argc,argv) int argc; char *argv[]; { int leftsplt, leftout, col; 10 cols, output rest) vsplit rl 10 (delete last 10 cols, output rest) vsplit rr 15 (output last 15 cols) options: ll split from left, output left part lr split from left, output right part  char line[MAXLINE], left[MAXLINE], right[MAXLINE]; dioinit(&argc,argv); /* process options */ if(argc < 3) error("usage: vsplit option col"); if(eqs(argv[1],"LL")) leftsplt=leftout=TRUE; else i rl split from right, output left part rr split from right, output right part input: STDIN output: STDOUT notes: 1. If input line contains only , so will output 2. If llf(eqs(argv[1],"LR")) {leftsplt=TRUE; leftout=FALSE; } else if(eqs(argv[1],"RL")) {leftsplt=FALSE; leftout=TRUE; } else if(eqs(argv[1],"RR")) leftsplt=leftout=FALSE; #   else error("vsplit: valid options are ll lr rl rr"); col=atoi(argv[2]); /* main */ while(fgets(line,STDIN)) {line[strlen(line)-1]='\0'; /* zap newline */ if(leftsplt) split(liåne,col,left,right); else splitr(line,col,left,right); if(leftout) fprintf(STDOUT,"%s\n",left); else fprintf(STDOUT,"%s\n",right); } dioflush(); } åååå/* wc.c -- UTOOL. Count lines, words and characters in standard input. Can handle Wordstar doc files. author: David H. Wolen last change: 9/9/82 usage: wc FILE: -FOG/UTL.030 CRC = 00 00 --> FILE: DISK .DOC CRC = BB 84 --> FILE: MYLIB3 .C CRC = D0 AC --> FILE: PREP .C CRC = 53 EE --> FILE: SORT .C CRC = E3 0C --> FILE: SPLIT .C CRC = F2 6D --> FILE: SPLåTSCAN.C CRC = 39 B4 --> FILE: SPLTSCAN.DOC CRC = 93 70 --> FILE: TABS .C CRC = DA 92 --> FILE: TAIL .C CRC = 16 A1 --> FILE: TEE .C CRC = AB 45 --> FILE: TR .C CRC = F4 E0 --> FILE: UNIQ .C CRC =å AA 6E --> FILE: UNROT .C CRC = 81 FC --> FILE: UTDIR .C CRC = AE 0B --> FILE: VSPLIT .C CRC = A7 3B --> FILE: WC .C CRC = D1 D9 ---------------------> SUM OF CRCS = 67 9C åitè thå KWIÃ tooì tï makå thå keyworä iî contexô indeø containeä iî UTKWIC.OUT® Eacè oæ theså fileó maù bå founä oî FOG/UTL.026. Thå actuaì tooló arå containeä oî FOG/UTL.02¶ thrõ 029® Sourcå fileó arå oî 02¹ anä 030® README.UTÓ on 029 descri%  bes the source files. Jií Woolley FOÇ Disë Librarian October 1983  Tools publications by Kernighan and Plauger. They are written in the BDS version of C; source files are included. They provide functions similar to UNIX; hence, the name UTOOLS. README.UT is a text file describing an overview of the system.å The file UTOOL.DOC provides examples of use of the various tools. UTOOL.MAN contains a structured description of each, after the pattern of UNIX manual pages. The file UTKWIC.DAT, which briefly identifies the function of each tool, was used wåith the KWIC tool to make the keyword in context index contained in UTKWIC.OUT. Each of these files may be found on FOG/UTL.026. The actual tools are contained on FOG/UTL.026 thru 029. Source files are on 029 and 030. README.UTS on 029 descriåbes the source files. Jim Woolley FOG Disk Librarian October 1983  DISK.DOC FOG/UTL.030 First Osborne Group (FOG) Utilities Disk FOG/UTL.026 thru 030 contain the UTOOLS system of utilities (tools) submitted by David H. Wolen. Most were derived from the Softwareå&  åååååååååå'  åååååååååå