IMD 1.16: 31/05/2007 20:05:27 FOGCPM.116 åååååååååååååååCAL C 0§¨©ª«README UT2™README UTSšUTOOL DOC1›œ�žUTOOL MANw Ÿ ¡¢£²³´UTOOL2 MAN1-07-00 86 CAT C &'(CH C )*+,CMP C -.COMM C "/0123CRT C 45FIND C $6789:HCAT C ;<=>INCL C ?@AKWIC C BCLLINE C DLPR C EFGMAKDOC C HIJMYLIB3 C ]KLMNOP¬­®¯°±PREP C +QRSTUVSORT C 9WXYZ[\]^SPLIT C _`abSPLTSCANC ScdefghijklmSPLTSCANDOCAnopqrstuvTABS C #wxyz{TAIL C |}TEE C ~€TR C �‚ƒ„UNIQ C …†UNROT C ‡ˆ‰UTDIR C Š‹VSPLIT C Œ�ŽWC COM<��‘’“”•–WC C —README UT ˜-CPM116 DOC--FOGCPM116¦åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå/* cal.c -- UTOOL. Calendar. Print lines with date match. author: David H. Wolen last change: 6/2/83 usage: cal file mm/dd/yy prog |cal -r mm/dd/yy mm/dd/yy cal file -ge mm/dd/yy options: -g (>) -l (<) -e (=) -r (>= date1 and <= date2) input: file or STDIN output: STDOUT notes: -ge, -le, -gl, are ok (effect is "or" relation) only first valid date on line is examined for match if -r, no other options are allowed if no options, default is -e linkage: a:clink cal -f dio -ca (uses deff3.crl) */ #include "a:bdscio.h" #include "a:dio.h" #define STDIN 0 #define STDOUT 1 #define BASEYR 45 /* yy < BASEYR converted to 20yy */ /* yy >= BASEYR converted to 19yy */ struct date {int day; int month; int year; }; main(argc,argv) int argc; char *argv[]; { struct dateThis library contains updates and a few bug fixes to the utools programs on -fog/utl.026 through .030. The following files are included: readme.ut2 - this file utool2.mqn - squeezed "manual pages" for the .com files included field.com - select fields from a file. This works with fields that are comma separated. You could use it to re-arrange a MailMerge address file. This is a new program. fieldcc.com - select column delimited fields from a file. This works with fields that are always in the same columns on a file. You could use it to re-arrange dates from yy/mm/dd to mm/dd/yy. This is a new program. find.com - find patterns in text files. This is an update of the version currently in foglib. The main addition is the ability to handle "index cards". These are multi-line records (up to 2K characters each) that are treated as one continued line. findmf.com - simple pattern match over multiple files (uses wildcards). This is a new program. lpr.com - send stdin tfile: readme.uts date: 9/10/83 author: David H. Wolen This disk contains the source for the UTOOLS -- a set of utility programs I recently submitted to the foglib. See the appropriate foglib disks for user oriented documentation. The programs are written in C, using version 1.46 of the BDS compiler. The following notes about bringing up the UTOOLS on your own are disorganized and probably incomplete -- that should be fair warning. Also, note that you'll need some files from the BDS C distribution package to complete this package. I'm not including them because I'm not sure if the source for them is public domain. 1. I've enabled alloc and free by making the appropriate change to bdscio.h and recompiling the indicated libraries. See the instructions in bdscio.h. Alloc and free are only (I think) used by the tail tool. The other tools that do storage allocation don't need to free it so they use sbrk instead (reducing memory requirements and the size of the .com file). 2. I've enabled console buffering by making the appropriate change to dio.h. See the instructions in dio.h. 3. Just about all the UTOOLS use something from mylib3.c. I've made it my deff3.crl. There are probably some routines on mylib3.c that aren't used by the UTOOLS. Note -- there's a bug in 1.46 that prevents deff3.crl from being picked up automatically if you compile with source on b and b as the logged drive. 4. Before my upgrade to double density, I kept dio.h and dio.crl on the same drive as the source. With double density, I keep everything but the source on A and compile with A as the logged drive. Some of the "linkage" comments in the source code reflect the first method, while others reflect the second -- you've been warned. Also, you may have to change the drive designation in the #include lines to correspond to your compile procedure. 5. The utdir tool needs wildexp.c which comes with the WTW Associates 341 N. First St. Campbell, Ca. 95008 Documentation for the UTOOLS (utool.doc 2/23/83) (author of both tools and documentation: David H. Wolen) Mosô  oæ  thå UTOOLÓ arå deriveä froí thå programó  describeä  iî � Softwarå  Tooló anä Softwarå Tooló iî Pascaì (botè  bù  Kernighaî � anä Plauger)® Theù werå writteî iî à anä testeä oî aî Osbornå ± � (Z80A¬  CP/Í 2.2¬  singlå density)®  Thå UTOOLÓ providå featureó � calleä  I/Ï redirectioî anä pipes®  Externally¬  theså  featureó � resemblå  thoså provideä undeò thå UNIØ operatinç systeí -- hencå � thå namå UTOOLS® Thå manuaì pagå foò eacè UTOOÌ describeó allow � ablå inpuô anä output®  Iæ thå inpuô ió STDIN¬  thaô meanó inpuô � caî  comå  froí thå keyboarä oò froí á file®  Iæ thå  outpuô  ió � STDOUT¬  thaô meanó thå outpuô caî gï tï thå screen¬ á file¬ botè � screeî anä file¬ oò servå aó inpuô tï anotheò UTOOL® Thå follow� inç exampleó assumå thaô thå UTOOLÓ arå oî thå Á drive¬  anù filå � tï bå reaä oò writteî wilì bå oî thå  drive¬ anä  ió thå loggeä � drive®  It'ó besô tï makå  thå loggeä drivå becauså thå  UTOOLÓ � sometimeó havå tï makå anä releaså á temporarù filå oî thå loggeä � drive® Therå probablù isn'ô enougè rooí oî Á foò that. Examples of I/O redirection and piping: 1®  Keyboarä inpuô anä screeî outpuô (usefuì foò learninç ho÷  á � UTOOL works). B>a:cat      caô  wilì  wait foò yoõ tï typå iî datá anä wilì echï iô  tï �      thå screeî afteò yoõ typå eacè line®  Enä eacè linå witè  á �      a:cat >outfile 3® Keyboarä input® Outpuô tï botè thå screeî anä á file® Noteº � no space between the + and the file name. B>a:cat +outfile .pa Š4®  Filå inpuô anä screeî output®  Again¬ notå thaô therå can'ô � be any space between the < and the file name. B>a:cat a:cat |a:lpr      Thió examplå woulä senä thå lineó yoõ typeä aô thå  keyboarä �      to the printer (after you typed the ^z to finish). Here are some useful pipelines. 1®  Makå  á keyworä iî contexô index¬  treatinç uppeò anä  loweò � caså alphá thå same®  Displaù oî thå screen¬  pausinç afteò eacè � screen full. Input is a normal ascii file. B>a:kwic ) -l (<) -e (=) -r (>= date1 and <= date2) input: file or STDIN output: STDOUT notes: -ge, -le, -gl, are ok (effect is "or" relation) only first valid date on line is examined for match if -r, no other options are allowed if no options, default is -e */ /* cat.c -- UTOOL. Concatenate files ver 2. author: David H. Wolen last change: 6/12/83 usage: (1) copy console input to file (^z to stop) cat >ofile (2) concat inp files and write on output file cat ifile1 ifile2 >ofile (3) concat input files and pass to std input of prog2 cat ifile1 ifile2 |prog2 (4) clean up WordStar doc file cat -w file.doc >ofile option: -w clean up WordStar doc files by zeroing hi bits and converting strange characters to blanks input: files or STDIN output: STDOUT */ /* ch.c -- UTOOL. Change pattern in text file. author: David H. Wolen last change: 3/4/83 usage: ch pattern [newstuff] input: STDIN output: STDOUT notes: 1. metacharacters in pattern (same as find) % begin of line # # enclose capital letters " " enclose imbedded blanks ? match any char except newline $ end of line [c1-c2] char class [!c1-c2] negated char class * closure (0 or more occurrences of prev 1 char pattern) escaped chars: \n (newline) \t (tab) \r (cr) \f (form feed) \b (backspace) \q (") \p (#) 2. If newstuff is omitted, deletion of pattern occurs. 3. Newstuff consists of zero or more of the following: c literal char & ditto, i.e. whatever was matched \c escaped char # # and " " as above */ /* cmp.c -- UTOOL. Compare 2 files or file and std input for equality. author: David H. Wolen last change: 11/23/82 usage: cmp file1 file2 prog |cmp file1 input: 2 files or file and STDIN output: STDOUT */ /* comm.c -- UTOOL. Print lines common to two sorted files author: David H. Wolen last change: 11/29/82 usage: comm -123 file1 file2 prog |comm file1 options: -n (n=1,2,3) print only named columns (default is print all 3) input: 2 files or file and STDIN  output: STDOUT notes: (1) if only one file is given, STDIN is file 2 (2) col 1 is lines only in file 1 col 2 is lines only in file 2 col 3 is lines in both files */ /* crt.c -- UTOOL. Display text file (including ws doc) a screen at a time. author: David H. Wolen last change: 6/12/83 usage: crt -n file prog |crt forward a screen anything else to quit option: -n line numbers input: file or STDIN output: STDOUT */ /* find.c -- UTOOL. Find patterns in text files (ver. 3) author: David H. Wolen last change: 5/2/83 usage: find [-axn] pattern1 [pattern2 ... pattern10] options: -a output lines which contain all patterns (default is output lines matching any pattern) -x output lines that fail the match criteria -n line numbers for output  -c just output count of matching lines -f fold (ignore case in character comparisons) input: STDIN output: STDOUT notes: 1. -x pat1 pat2 : output if line contains neither pat 2. -ax pat1 pat2 : output if line doesn't contain both pats 3. metacharacters in pattern % match pattern at beginning of line # # enclose capital letters " " enclose embedded blanks ? match any char except newline $ end of line [c1-c2] character class [!c1-c2] negated character class * closure (0 or more occurrences of prev pattern) escaped chars: \n (newline) \t (tab) \r (cr) \f (form feed) \b (backspace) \q (") \p (#) 4. first pattern can't begin with "-" 5. up to MAXPATS patterns allowed (currently 10) 6. if -c and -n, the latter will be ignored */ /* hcat.c -- UTOOL. Horizontally concatenate text files. author: David H. Wolen last change: 3/16/83 usage: hcat file1 n2 file2 n3 file3 ... hcat file1 31 file2 51 file3 (begin file1 in col 1, file2 in col 31, file3 in col 51) input: one or more files output: STDOUT notes: 1. max of 6 input files 2. first file starts in col 1 */ /* incl.c -- UTOOL. Expand included files author: David H. Wolen last change: 12/5/82 usage: incl to resume, anything else to quit. (default false) input: STDIN output: printer notes: (1) form feed after each page and at eof (2) if both -l and -n are used, margin value must preceed page size value. */ /* 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 outfile n1-n2 n3-n4 ... fieldcc outfile 1-5 8-12 6-7 input: STDIN output: STDOUT notes: (a) ni are origin 1. (b) if a field is invalid for a particular line, the output for that field will be null. (c) a maximum of 10 fields are allowed */ /* find.c -- UTOOL. Find patterns in text files (ver. 3.1) author: David H. Wolen last change: 12/18/83 usage: find [-axn] pattern1 [pattern2 ... pattern10] options: -a output lines which contain all patterns (default is output lines matching any pattern) -x output lines that fail the match criteria -n line numbers for output -c just output count of matching lines -f fold (ignore case in character comparisons) input: STDIN output: STDOUT notes: 1. -x pat1 pat2 : output if line contains neither pat 2. -ax pat1 pat2 : output if line doesn't contain both pats 3. metacharacters in pattern % match pattern at beginning of line # # enclose capital letters " " enclose embedded blanks ? match any char except newline $ end of line  [c1-c2] character class [!c1-c2] negated character class * closure (0 or more occurrences of prev pattern) escaped chars: \n (newline) \t (tab) \r (cr) \f (form feed) \b (backspace) \q (") \p (#) 4. first pattern can't begin with "-" 5. up to MAXPATS patterns allowed (currently 10) 6. if -c and -n, the latter will be ignored 7. version 3.1 handles continued input lines indicated by & in column one. The max continued line length is 2048 char. With keyboard input and output, there is now a lag since it has to see if the following line begins with &. */ /* findmf.c -- UTOOL. Simple pattern match with multiple file input (including wildcards). Ignores case. author: David H. Wolen last change: 12/14/83 usage: findmf pat filespec  findmf pat *.c findmf pat *.* !*.com (the *.* is required for this program) findmf pat fn.ft fn.ft fn.ft findmf pat test?.c findmf "last change" *.c input: files output: STDOUT notes: (a) wildcards of * (match one or more characters) and ? (match a single character) are allowed in filespec (b) the construction *.* !*.com means all files except .com (c) drive prefixes are allowed (d) output lines are prefixed with file name (e) the expanded filespec can't contain more than 200 files */ /* lpr.c -- UTOOL. Send stdin to printer author: David H. Wolen last change: 10/14/84 usage: prog |lpr -lnp 5 55 lpr to resume, anything else to quit.  (default false) input: STDIN output: printer notes: (1) form feed after each page and at eof (2) if both -l and -n are used, margin value must preceed page size value. (3) handles tabs (tabs every 8 spaces) (4) ignores any imbedded form feeds in input */ /* sort.c -- UTOOL. (ver. 2.2) Incore sort of ascii lines. Max file size 2000 lines or about 30K. author: David H. Wolen last change: 9/22/85 usage: sort outfile sort as part of the description of a file indicates that the program is distributed on a "try first, pay if you like it" basis. If you find the program(s) meet your need, please refer to the author's documentation for information on becoming a registered user. Only by registering and paying for the programs you like and use will the authors of such programs continue development. Often, more complete documentation, additional modules, and new releases are available only to registered users. DISK 1 of 3. UTOOLS -- collection of utilities written in 'C' Filename Description -07-00 .86 This is the release date of the disk. -CPM116 .DOC This is the description of the disk contents. UTOOL .DOC BDA0 7K [UTOOLS 1 of 67] A collection of Unix-like utilities written in 'C' (from Kernighan and Plauger books. Written in BDS 'C' ver 1.46 Includes source code, sample programs, and much more. UTOOL2 .MAN 2192 7K [UTOOLS 2 of 67] UTOOL .MAN 87D6 15K [UTOOLS 3 of 67] CMP .C C5D6 2K [UTOOLS 4 of 67] COMM .C 1999 5K [UTOOLS 5 of 67] CRT .C 0FBA 2K [UTOOLS 6 of 67] FIND .C 0C7C 5K [UTOOLS 7 of 67] HCAT .C DF7E 4K [UTOOLS 8 of 67] INCL .C 8340 3K [UTOOLS 9 of 67] KWIC .C E3A3 2K [UTOOLS 10 of 67] LLINE .C 8DB2 1K [UTOOLS 11 of 67] LPR .C 174F 3K [UTOOLS 12 of 67] MAKDOC .C 231B 3K [UTOOLS 13 of 67] MYLIB3 .C 4067 12K [UTOOLS 14 of 67] PREP .C 97F0 6K [UTOOLS 15 of 67] SORT .C 9B72 8K [UTOOLS 16 of 67] SPLIT .C 248D 4K [UTOOLS 17 of 67] SPLTSCAN.C 266A 11K [UTOOLS 18 of 67] SPLTSCAN.DOC E3AC 9K [UTOOLS 19 of 67] TABS .C 879B 5K [UTOOLS 20 of 67] TAIL .C 07C9 2K [UTOOLS 21 of 67] TEE .C 5459 3K [UTOOLS 22 of 67] TR .C EEA3 4K [UTOOLS 23 of 67] UNIQ .C EC89 2K [UTOOLS 24 of 67] UNROT .C 9D17 3K [UTOOLS 25 of 67] UTDIR .C 521C 2K [UTOOLS 26 of 67] VSPLIT .C 2173 3K [UTOOLS 27 of 67] WC .COM B7CF 8K [UTOOLS 28 of 67] Counts lines, words, and characters. WC .C 1383 1K [UTOOLS 29 of 67] README .UT D67D 1K [UTOOLS 30 of 67] README .UT2 35C2 2K [UTOOLS 31 of 67] README .UTS 0268 3K [UTOOLS 32 of 67] CAL .C E3D6 6K [UTOOLS 33 of 67] CAT .C FBAF 3K [UTOOLS 34 of 67] CH .C A21F 4K [UTOOLS 35 of 67] INCL .C 8340 3K [UTOOLS 9 of 67] KWIC .C E3A3 2K [UTOOLS 10 of 67] LLINE .C 8DB2 1K [UTOOLS 11 of 67] LPR .C 174F 3K [UTOOLS 12 of 67] MAKDOC .C 231B 3K [UTOOLS 13 of 67] MYLIB3 .C 4067 12char 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 */ /* 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 each output line with count usage: sort outfile -c input: STDIN output: STDOUT */ /* 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: STDOUT */ /* 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 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 output: STDOUT notes: 1. max of 200 files after expansion 2. metacharacters in filename: ! except ? wildcard match a single character * wildcard match 1 or more characters */ /* 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 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 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 ll 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 be */ /* 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 , so will output 2. If ll and col /* field.c -- UTOOL. select fields from a file author: David H. Wolen last change: 11/14/83 usage: field n1 n2 ... input: STDIN output: STDOUT notes: (a) fields are numbered from 1 (b) a field may be selected more than once (c) fields are separated by commas on input and output (d) maximum input and output line length is 149 characters (e) maximum number of input fields is 70 */ /* fieldcc.c -- UTOOL. Select column delimited fields from a file author: David H. Wolen last change: 5/26/84 usage: fieldcc outfile n1-n2 n3-n4 ... fieldcc outfile 1-5 8-12 6-7 input: STDIN output: STDOUT notes: (a) ni are origin 1. (b) if a field is invalid for a particular line, the output for that field will be null. (c) a maximum of 10 fields are allowed */ /* find.c -- UTOOL. Find patterns in text files (ver. 3.1) author: David H. Wolen last change: 12/18/83 usage: find [-axn] pattern1 [pattern2 ... pattern10] options: -a output lines which contain all patterns (default is output lines matching any pattern) -x output lines that fail the match criteria -n line numbers for output -c just output count of matching lines -f fold (ignore case in character comparisons) input: STDIN output: STDOUT notes: 1. -x pat1 pat2 : output if line contains neither pat 2. -ax pat1 pat2 : output if line doesn't contain both pats 3. metacharacters in pattern % match pattern at beginning of line # # enclose capital letters " " enclose embedded blanks ? match any char except newline $ end of line  [c1-c2] character class [!c1-c2] negated character class * closure (0 or more occurrences of prev pattern) escaped chars: \n (newline) \t (tab) \r (cr) \f (form feed) \b (backspace) \q (") \p (#) 4. first pattern can't begin with "-" 5. up to MAXPATS patterns allowed (currently 10) 6. if -c and -n, the latter will be ignored 7. version 3.1 handles continued input lines indicated by & in column one. The max continued line length is 2048 char. With keyboard input and output, there is now a lag since it has to see if the following line begins with &. */ /* findmf.c -- UTOOL. Simple pattern match with multiple file input (including wildcards). Ignores case. author: David H. Wolen last change: 12/14/83 usage: findmf pat filespec  findmf pat *.c findmf pat *.* !*.com (the *.* is required for this program) findmf pat fn.ft fn.ft fn.ft findmf pat test?.c findmf "last change" *.c input: files output: STDOUT notes: (a) wildcards of * (match one or more characters) and ? (match a single character) are allowed in filespec (b) the construction *.* !*.com means all files except .com (c) drive prefixes are allowed (d) output lines are prefixed with file name (e) the expanded filespec can't contain more than 200 files */ /* lpr.c -- UTOOL. Send stdin to printer author: David H. Wolen last change: 10/14/84 usage: prog |lpr -lnp 5 55 lpr to resume, anything else to quit.   (default false) input: STDIN output: printer notes: (1) form feed after each page and at eof (2) if both -l and -n are used, margin value must preceed page size value. (3) handles tabs (tabs every 8 spaces) (4) ignores any imbedded form feeds in input */ /* sort.c -- UTOOL. (ver. 2.2) Incore sort of ascii lines. Max file size 2000 lines or about 30K. author: David H. Wolen last change: 9/22/85 usage: sort outfile sort to stop) cat >ofile (2) concat inp files and write on output file cat ifile1 ifile2 >ofile (3) concat input files and pass to std input of prog2 cat ifile1 ifile2 |prog2 (4) clean up WordStar doc file cat -w file.doc >ofile option: -w clean up WordStar doc files by zeroing hi bits and converting strange characters to blanks input: files or STDIN output: STDOUT linkage: a:clink cat -f dio -ca */ #include "a:bdscio.h" #include "a:dio.h" #define STDERR 4 main(argc,argv) int argc; char *argv[]; { char ibuf[BUFSIZ], undoc(), *s; int c, isstdin, wsflg; dioinit(&argc,argv); wsflg=FALSE; while(--argc > 0 && (*++argv)[0] == '-') for(s=argv[0]+1; *s != '\0'; s++) switch(*s) {case 'W': wsflg=TRUE; break; default: fprintf(STDERR,"cat: invalid option\n"); exit(dioflush()); } if(argc <= 0) isstdin=TRUE; else isstdin=FALSE; if(isstdin) /* std input */ while((c=getchar()) != EOF) {if(wsflg) putchar(undoc(c)); else putchar(c); } if(!isstdin) /* files */ while(argc-- > 0) {if(fopen(*argv++,ibuf)==ERROR) {fprintf(STDERR,"cat: can't open %s\n",*argv); exit(dioflush()); } while((c=getc(ibuf)) != EOF && c != CPMEOF) {if(wsflg) putchar(undoc(c)); else putchar(c);  } } dioflush(); }  default: fprintf(STDERR,"cat: invalid option\n"); exit(dioflush()); } if(argc <= 0) isstdin=TRUE; else isstdin=FALSE; if(isstdin) /* std input */ while((c=getchar()) != EOF) {if(wsflg) putchar(undoc(c)); else putchar(c); } if(!isstdin) /* files */ while(argc-- > 0) {if(fopen(*argv++,ibuf)==ERROR) {fprintf(STDERR,"cat: can't open %s\n",*argv); exit(dioflush()); } while((c=getc(ibuf)) != EOF && c != CPMEOF) {if(wsflg) putchar(undoc(c)); else putchar(c);/* ch.c -- UTOOL. Change pattern in text file. author: David H. Wolen last change: 3/4/83 usage: ch pattern [newstuff] input: STDIN output: STDOUT notes: 1. metacharacters in pattern (same as find) % begin of line # # enclose capital letters " " enclose imbedded blanks ? match any char except newline $ end of line [c1-c2] char class [!c1-c2] negated char class * closure (0 or more occurrences of prev 1 char pattern) escaped chars: \n (newline) \t (tab) \r (cr) \f (form feed) \b (backspace) \q (") \p (#) 2. If newstuff is omitted, deletion of pattern occurs. 3. Newstuff consists of zero or more of the following: c literal char & ditto, i.e. whatever was matched  \c escaped char # # and " " as above linkage: a:clink ch -f dio -ca (uses deff3.crl) */ #include "a:bdscio.h" #include "dio.h" #define STDIN 0 #define DITTO 127 /* rubout */ main(argc,argv) int argc; char *argv[]; { char lin[MAXLINE], pat[MAXLINE], sub[MAXLINE], arg[MAXLINE]; dioinit(&argc,argv); if(argc <= 1) error("ch: missing pattern"); rcarg(arg,*++argv); if(!getpat(arg,pat)) error("ch: illegal 'from' pattern"); if(argc == 2) /* null 'to' string */ arg[0]='\0'; else rcarg(arg,*++argv); if(!getsub(arg,sub)) error("ch: illegal 'to' string"); while(fgets(lin,STDIN)) subline(lin,pat,sub); dioflush(); } /* subline -- substitute sub for pat in lin and print */ subline(lin,pat,sub) char *lin, *pat, *sub; { int i, lastm, m; lastm= -1; i=0; while(lin[i] != '\0') {m=amatch(lin,i,pat,0); if(m >= 0 && lastm != m) /* replace matched text */ {putsub(lin,i,m,sub); lastm=m; } if(m < 0 || m == i) /* no match or null match */ {putchar(lin[i]); i++; } else /* skip matched text */ i=m; } } /* getsub -- get substitution string into sub */ getsub(arg,sub) char *arg, *sub; { return(makesub(arg,0,'\0',sub) >= 0); } /* makesub -- make substitution string from arg in sub */ makesub(arg,from,delim,sub) char *arg, delim, *sub; { int i, j; j=0; i=from; while(arg[i] != delim && arg[i] != '\0') {if(arg[i] == '&') addstr(DITTO,sub,&j,MAXLINE); else addstr(esc(arg,&i),sub,&j,MAXLINE); i++; } if(arg[i] != delim) /* missing delimiter */ return(-1); else if(!addstr('\0',sub,&j,MAXLINE)) /* no room */ return(-1); else return(i); } /* putsub -- output substitution text */ putsub(lin,s1,s2,sub) char *lin, *sub; int s1, s2; { int i, j; i=0; while(sub[i] != '\0') {if(sub[i] == DITTO) for(j=s1; j <= s2-1; j++) putchar(lin[j]); else putchar(sub[i]); i++; } } ub) char *arg, *sub; { return(makesub(arg,0,'\0',sub) >= 0); } /* makesub -- make substitution string from arg in sub */ makesub(arg,from,delim,sub) char *arg, delim, *sub; { int i, j; j=0; i=from; while(arg[i] != delim && arg[i] != '\0') {if(arg[i] == '&') addstr(DITTO,sub,&j,MAXLINE); else addstr(esc(arg,&i),sub,&j,MAXLINE); i++; } if(arg[i] != delim) /* missing delimite /* cmp.c -- UTOOL. Compare 2 files or file and std input for equality. author: David H. Wolen last change: 11/23/82 usage: cmp file1 file2 prog |cmp file1 input: 2 files or file and STDIN output: STDOUT linkage: a:clink cmp -f dio -ca (uses deff3.crl) */ #include "a:bdscio.h" #include "dio.h" #define STDIN 0 main(argc,argv) int argc; char *argv[]; { char buf1[BUFSIZ], buf2[BUFSIZ], line1[MAXLINE], line2[MAXLINE]; int isstdin, lineno, m1, m2; dioinit(&argc,argv); switch(argc) { case 2: /* stdin and 1 file */ isstdin=TRUE; if(fopen(argv[1],buf2)==ERROR) error("cmp: can't open file"); break; case 3: /* 2 files */ isstdin=FALSE; if(fopen(argv[1],buf1)==ERROR) error("cmp: can't open file 1"); if(fopen(argv[2],buf2)==ERROR)  error("cmp: can't open file 2"); break; default: error("usage: cmp file1 file2 or STDIN file"); } lineno=0; while(1) {m1=(isstdin) ? fgets(line1,STDIN) : fgets(line1,buf1); m2=fgets(line2,buf2); if(!m1 || !m2) break; lineno++; if(!eqs(line1,line2)) printf("%d\n%s%s",lineno,line1,line2); } if(!m1 && m2) out("cmp: eof on file 1"); else if(!m2 && m1) out("cmp: eof on file 2"); dioflush(); }  1 file */ isstdin=TRUE; if(fopen(argv[1],buf2)==ERROR) error("cmp: can't open file"); break; case 3: /* 2 files */ isstdin=FALSE; if(fopen(argv[1],buf1)==ERROR) error("cmp: can't open file 1"); if(fopen(argv[2],buf2)==ERROR) /* comm.c -- UTOOL. Print lines common to two sorted files author: David H. Wolen last change: 11/29/82 usage: comm -123 file1 file2 prog |comm file1 options: -n (n=1,2,3) print only named columns (default is print all 3) input: 2 files or file and STDIN output: STDOUT notes: (1) if only one file is given, STDIN is file 2 (2) col 1 is lines only in file 1 col 2 is lines only in file 2 col 3 is lines in both files linkage: a:clink comm -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 isstdin, c1flg, c2flg, c3flg, stat1, stat2, k; char *s, buf1[BUFSIZ], buf2[BUFSIZ], line1[MAXLINE], line2[MAXLINE]; dioinit(&argc,argv); c1flg=c2flg=c3flg=FALSE; /* process options */ while(--argc > 0 && (*++argv)[0] == '-') for(s=argv[0]+1; *s != '\0'; s++) switch(*s) {case '1': c1flg=TRUE; break; case '2': c2flg=TRUE; break; case '3': c3flg=TRUE; break; default: error("comm: invalid option"); } if(!c1flg && !c2flg && !c3flg) c1flg=c2flg=c3flg=TRUE; /* open file or files */ switch(argc) {case 1: /* 1 file and STDIN */ isstdin=TRUE; if(fopen(*argv,buf1)==ERROR) error("comm: can't open file"); break; case 2: /* 2 files */ isstdin=FALSE; if(fopen(*argv++,buf1)==ERROR) error("comm: can't open file 1"); if(fopen(*argv,buf2)==ERROR) error("comm: can't open file 2"); break; default: error("usage: comm [-123] file1 file2 or file STDIN"); } /* process */ stat1=fgets(line1,buf1); stat2=(isstdin) ? fgets(line2,STDIN) : fgets(line2,buf2); while(1) {if(!stat1 || !stat2) break; k=strcmp(line1,line2); if(k < 0) /* line only in file 1 */ {if(c1flg) prntcol(line1,1,c1flg,c2flg,c3flg); stat1=fgets(line1,buf1); } else if(k > 0) /* line only in file 2 */ {if(c2flg) prntcol(line2,2,c1flg,c2flg,c3flg); stat2=(isstdin) ? fgets(line2,STDIN) : fgets(line2,buf2); } else /* line in both files */ {if(c3flg) prntcol(line1,3,c1flg,c2flg,c3flg); stat1=fgets(line1,buf1); stat2=(isstdin) ? fgets(line2,STDIN) : fgets(line2,buf2); } } if(!stat1 && c2flg) /* end of file 1, print rest of file 2 */ while(stat2) {prntc ol(line2,2,c1flg,c2flg,c3flg); stat2=(isstdin) ? fgets(line2,STDIN) : fgets(line2,buf2); } else if(!stat2 && c1flg) /* end of file 2, print rest of file 1 */ while(stat1) {prntcol(line1,1,c1flg,c2flg,c3flg); stat1=fgets(line1,buf1); } dioflush(); } /* prntcol -- print line as column col */ prntcol(line,col,c1flg,c2flg,c3flg) char *line; int col, c1flg, c2flg, c3flg; { int i; for(i=0; isspace(line[i]); i++) ; /* skip leading white space */ switch(col) {case 1: fputs(&line[i],STDOUT); break; case 2: if(c1flg) /* 15 blanks */ fputs(" ",STDOUT); fputs(&line[i],STDOUT); break; case 3: if(c1flg) /* 10 blanks */ fputs(" ",STDOUT); if(c2flg) /* 15 blanks */  fputs(" ",STDOUT); fputs(&line[i],STDOUT); break; default: error("prntcol: can't happen"); } } lg,c2flg,c3flg); stat1=fgets(line1,buf1); } dioflush(); } /* prntcol -- print line as column col */ prntcol(line,col,c1flg,c2flg,c3flg) char *line; int col, c1flg, c2flg, c3flg; { int i; for(i=0; isspace(line[i]); i++) ; /* skip leading white space */ switch(col) {case 1: fputs(&line[i],STDOUT); break; case 2: if(c1flg) /* 15 blanks */ fputs(" ",STDOUT); fputs(&line[i],STDOUT); break; case 3: if(c1flg) /* 10 blanks */ fputs(" ",STDOUT); if(c2flg) /* 15 blanks */ /* crt.c -- UTOOL. Display text file (including ws doc) a screen at a time. author: David H. Wolen last change: 6/12/83 usage: crt -n file prog |crt forward a screen anything else to quit option: -n line numbers input: file or STDIN output: STDOUT linkage: a:clink crt -f dio -ca (uses deff3.crl) */ #include "a:bdscio.h" #include "a:dio.h" #define PSIZE 22 /* lines per screen */ #define STDIN 0 main(argc,argv) int argc; char *argv[]; { char ibuf[BUFSIZ], line[MAXLINE], *s; int lnflag, lcount, lineno, i, isstdin, len; dioinit(&argc,argv); lnflag=FALSE; lineno=1; lcount=1; while(--argc>0 && (*++argv)[0]=='-') for(s=argv[0]+1; *s != '\0'; s++) switch(*s) {case 'N': /* line numbers */ lnflag=TRUE; break; default: error("usage: crt -n file or STDIN"); } switch(argc) {case 0: /* STDIN */ isstdin=TRUE; break; case 1: /* file input */ isstdin=FALSE; if(fopen(*argv,ibuf)==ERROR) error("crt: can't open file"); break; default: error("usage: crt -n file or STDIN"); } while(isstdin ? fgets(line,STDIN) : fgets(line,ibuf)) {len=strlen(line); for(i=0; i < len; i++) line[i]=undoc(line[i]); if(lnflag) printf("%4d: ",lineno++); puts(line); if(++lcount <= PSIZE) continue; if(bdos(1)=='\r') /* console input */ {lcount=1; continue; } else break; } dioflush(); } /* find.c -- UTOOL. Find patterns in text files (ver. 3) author: David H. Wolen last change: 5/2/83 usage: find [-axn] pattern1 [pattern2 ... pattern10] options: -a output lines which contain all patterns (default is output lines matching any pattern) -x output lines that fail the match criteria -n line numbers for output -c just output count of matching lines -f fold (ignore case in character comparisons) input: STDIN output: STDOUT notes: 1. -x pat1 pat2 : output if line contains neither pat 2. -ax pat1 pat2 : output if line doesn't contain both pats 3. metacharacters in pattern % match pattern at beginning of line # # enclose capital letters " " enclose embedded blanks ? match any char except newline $ end of line [c1-c2] character class [!c1-c2] negated character class * closure (0 or more occurrences of prev pattern) escaped chars: \n (newline) \t (tab) \r (cr) \f (form feed) \b (backspace) \q (") \p (#) 4. first pattern can't begin with "-" 5. up to MAXPATS patterns allowed (currently 10) 6. if -c and -n, the latter will be ignored linkage: a:clink find -f dio -ca (uses deff3.crl) */ #include "a:bdscio.h" #include "dio.h" #define STDIN 0 #define MAXPATS 10 /* max patterns */ main(argc,argv) int argc; char *argv[]; { int lineno, except, number, all, numpats, print, count, icount, fold; char line[MAXLINE], *s, newarg[MAXLINE], foldtemp[MAXLINE], pat[MAXPATS][MAXLINE]; dioinit(&argc,argv); lineno=0; except=number=all=count=fold=FALSE; numpats=icount=0; /* process options */ while(--argc > 0 && (*++argv)[0] == '-') for(s=argv[0]+1; *s != '\0'; s++) switch(*s) {case 'A': all=TRUE; break; case 'N': number=TRUE; break; case 'X': except=TRUE; break; case 'C': count=TRUE; break; case 'F': fold=TRUE; break; default: error("find: invalid option"); } /* process patterns */ if(argc <= 0) error("find: missing pattern"); while(argc > 0) {if(++numpats > MAXPATS) error("find: too many patterns"); rcarg(newarg,*argv++); if(fold) {stoupper(foldtemp,newarg); strcpy(newarg,foldtemp); } if(!getpat(newarg,pat[numpats-1])) error("find: illegal pattern"); argc--; } /* look for patterns in stdin */  while(fgets(line,STDIN)) {lineno++; if(fold) stoupper(foldtemp,line); else strcpy(foldtemp,line); if(gmatch(foldtemp,pat,numpats,all)) print=TRUE; else print=FALSE; if(except) print= !print; if(print && !count) {if(number) printf("%d: ",lineno); printf("%s",line); } else if(print && count) icount++; } if(count) printf("%d matched\n",icount); dioflush(); } /* gmatch -- match patterns */ gmatch(line,pat,numpats,all) char *line, pat[MAXPATS][MAXLINE]; int numpats, all; { int gotone, i; for(i=0; i < numpats; i++) {gotone=match(line,pat[i]); if(!all && gotone) return(TRUE); else if(all && !gotone) return(FALSE); } return(all); } /* match -- find match anywhere in line */ match(lin,pat) char *lin, *pat; { int i, pos; pos= -1; i=0; while(lin[i] != '\0' && pos < 0) {pos=amatch(lin,i,pat,0); i++; } return(pos >= 0); } /* stoupper -- convert string to upper case usage: stoupper(outstr,instr); */ stoupper(s,t) char *s, *t; { while(*s++ = toupper(*t++)) ; }  icount++; } if(count) printf("%d matched\n",icount); dioflush(); } /* gmatch -- match patterns */ gmatch(line,pat,numpats,all) char *line, pat[MAXPATS][MAXLINE]; int numpats, all; { int gotone, i; for(i=0; i < numpats; i++) {gotone=match(line,pat[i]); if(!all && gotone) return(TRUE); else if(all && !gotone) return(FALSE); } return(all); } /* match -- find match anywhere in/* hcat.c -- UTOOL. Horizontally concatenate text files. author: David H. Wolen last change: 3/16/83 usage: hcat file1 n2 file2 n3 file3 ... hcat file1 31 file2 51 file3 (begin file1 in col 1, file2 in col 31, file3 in col 51) input: one or more files output: STDOUT notes: 1. max of 6 input files 2. first file starts in col 1 linkage: a:clink hcat -f dio -ca (uses deff3.crl) */ #include "a:bdscio.h" #include "dio.h" #define MAXHCFILS 6 /* max input files */ struct fs /* file data */ {char ibuf[BUFSIZ]; char line[MAXLINE]; int iseof; int col; }; main(argc,argv) int argc; char *argv[]; { int i, nfiles; char outline[MAXLINE]; struct fs fstuff[MAXHCFILS]; dioinit(&argc,argv); if(argc/2 > MAXHCFILS) error("hcat: too many input files"); /* process arguments */ for(i=0; i < argc/2; i++) {if(i == 0) /* start cols (1 for first file) */ fstuff[i].col=1; else if((fstuff[i].col=atoi(*++argv)) <= 0) error("hcat: bad column argument"); if(fopen(*++argv,fstuff[i].ibuf) == ERROR) /* files */ error("hcat: can't open file"); fstuff[i].iseof = FALSE; } nfiles=i; /* process */ while(hcmore(fstuff,nfiles)) /* until all files are at eof */ {for(i=0; i < nfiles; i++) /* get line from each file */ {if(!fstuff[i].iseof) if(!fgets(fstuff[i].line,fstuff[i].ibuf)) fstuff[i].iseof=TRUE; } setmem(outline,MAXLINE,' '); for(i=0; i < nfiles; i++) /* form output line */ {if(!fstuff[i].iseof) dohc(fstuff[i].line,fstuff[i].col,outline,MAXLINE); } if(hcmore(fstuff,nfiles))  {trail(outline,MAXLINE); /* delete trailing blanks */ puts(outline); } } dioflush(); } /* hcmore -- return false if all input files at eof; else true */ hcmore(fstuff,nfiles) struct fs fstuff[]; int nfiles; { int i; for(i=0; i < nfiles; i++) {if(!fstuff[i].iseof) return(TRUE); } return(FALSE); } /* dohc -- insert line into outline starting at col. Won't insert past end of outline. */ dohc(line,col,outline,maxout) char *line, *outline; int col, maxout; { int i, j; for(i=0, j=col-1; j < (maxout-1) && line[i] != '\n'; i++, j++) outline[j]=line[i]; } /* trail -- delete trailing blanks from line */ trail(outline,maxout) char *outline; int maxout; { int i, nfiles; for(i=maxout-3; i >= 0; i--) if(outline[i] != ' ') break; outline[++i]='\n'; outline[++i]='\0'; }  } dioflush(); } /* hcmore -- return false if all input files at eof; else true */ hcmore(fstuff,nfiles) struct fs fstuff[]; int nfiles; { int i; for(i=0; i < nfiles; i++) {if(!fstuff[i].iseof) return(TRUE); } return(FALSE); } /* dohc -- insert line into outline starting at col. Won't insert past end of outline. */ dohc(line,col,outline,maxout) char *line, *outline; int col, maxout; { int i, j; for(i=0, j=col-1; j < (maxout-1) && line[i] != '\n'; i++, j++) outline[j]=line[i]; } /* trail -- delete trailing blanks from line */ trail(outline,maxout) char *outline; int maxout; { int i, nfiles; for(i=maxout-3; i >= 0; i--) if(outline[i] != ' ') break; outline[++i]='\n'; outline[++i]='\0'; }/* incl.c -- UTOOL. Expand included files author: David H. Wolen last change: 12/5/82 usage: incl outfile input: STDIN output: STDOUT compiler: BDS C ver. 1.46 (with dio) linkage: clink b:lline -f a:dio -o b: (uses deff3.crl) */ #include "a:bdscio.h" #include "a:dio.h" #define STDIN 0 main(argc,argv) int argc; char *argv[]; { int len, maxlen; char line[MAXLINE], savline[MAXLINE]; dioinit(&argc,argv); maxlen=0; while(fgets(line,STDIN)) {len=strlen(line) -1; /* don't count \n */ if(len > maxlen) {maxlen=len; strcpy(savline,line); } } if(maxlen == 0) error("lline: empty input"); printf("longest line is %d characters long:\n",maxlen); printf("%s",savline); dioflush(); } /* lpr.c -- UTOOL. Send stdin to printer author: David H. Wolen last change: 12/1/82 usage: prog |lpr -lnp 5 55 lpr to resume, anything else to quit. (default false) input: STDIN output: printer notes: (1) form feed after each page and at eof (2) if both -l and -n are used, margin value must preceed page size value. linkage: a:clink lpr -f dio -ca (uses deff3.crl) */ #include "a:bdscio.h" #include "dio.h" #define STDIN 0 #define STDLST 2 main(argc,argv) int argc; char *argv[]; { int margflg, lmarg, psflg, psize, pause, lcount, i; char line[MAXLINE], *s; dioinit(&argc,argv); margflg=psflg=pause=FALSE; lmarg=8; psize=50; while(--argc > 0 && (*++argv)[0]=='-') for(s=argv[0]+1; *s != '\0'; s++) switch(*s) {case 'L': margflg=TRUE; break; case 'N': psflg=TRUE; break; case 'P': pause=TRUE; break; default: error("lpr: invalid option"); } if(margflg) {if( (lmarg=atoi(*argv++)) < 0) error("lpr: left margin < 0"); } if(psflg) {if( (psize=atoi(*argv)) < 1) error("lpr: page size < 1"); } lcount=1; while(fgets(line,STDIN)) {for(i=0; i 1) fputs("\f",STDLST); dioflush(); } flg=TRUE; break; case 'N': psflg=TRUE; break; case 'P': pause=TRUE; break; default: error("lpr: invalid option"); } if(margflg) {if( (lmarg=atoi(*argv++)) < 0) error("lpr: left margin < 0"); } if(psflg) {if( (psize=atoi(*argv)) < 1) error("lpr: page size < 1"); } lcount=1; while(fgets(line,STDIN)) {for(i=0; iprog.pdo (programmer doc) makdoc prog.c >prog.hlp (user help file) options: -p output programmer oriented material in addition to user's manual page input: file or STDIN output: STDOUT notes: (1) -p prints program preface and function descriptions. Normal usage omits the linkage and compiler lines from the preface and omits the function descriptions. (2) filename can't begin with - compiler: BDS C ver. 1.46 (with dio) linkage: clink b:makdoc -f dio (uses deff3.crl) */ #include "a:bdscio.h" #include "a:dio.h" #define STDIN 0 #define STDOUT 1 main(argc,argv) int argc; char *argv[]; { int isstdin, print, udoc; char line[MAXLINE], ibuf[BUFSIZ], *s; dioinit(&argc,argv); udoc=TRUE; while(--argc > 0 && (*++argv)[0]=='-') for(s=argv[0]+1; *s != '\0'; s++) switch(*s) {case 'P': udoc=FALSE; break; default: error("makdoc: invalid option"); } if(argc <= 0) isstdin=TRUE; else {isstdin=FALSE; if(fopen(*argv,ibuf) == ERROR) error("makdoc: can't open file"); } print=FALSE; if(udoc) /* make user doc */ {while(isstdin ? fgets(line,STDIN) : fgets(line,ibuf)) {if(index(line,"/*")==0) print=TRUE; if(print && index(line,"linkage:") < 0 && index(line,"compiler:") < 0) fputs(line,STDOUT); if(index(line,"*/") >= 0) break; } } if(!udoc) /* make programmer doc */ {while(isstdin ? fgets(line,STDIN) : fgets(line,ibuf)) {if(index(line,"/*")==0) print=TRUE;  if(print) fputs(line,STDOUT); if(index(line,"*/") >= 0) print=FALSE; } } dioflush(); }  <= 0) isstdin=TRUE; else {isstdin=FALSE; if(fopen(*argv,ibuf) == ERROR) error("makdoc: can't open file"); } print=FALSE; if(udoc) /* make user doc */ {while(isstdin ? fgets(line,STDIN) : fgets(line,ibuf)) {if(index(line,"/*")==0) print=TRUE; if(print && index(line,"linkage:") < 0 && index(line,"compiler:") < 0) fputs(line,STDOUT); if(index(line,"*/") >= 0) break; } } if(!udoc) /* make programmer doc */ {while(isstdin ? fgets(line,STDIN) : fgets(line,ibuf)) {if(index(line,"/*")==0) print=TRUE; /* 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; { 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 inarg 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++) {if(*inarg=='#') makelow=!makelow; else if(makelow) *outarg++ = tolower(*inarg); else if(!makelow) *outarg++ = *inarg; } *outarg = '\0'; } /* error -- print error message, dioflush and stop */ error(msg) char *msg; { fputs(msg,STDERR); fputs("\n",STDERR); exit(dioflush()); } /* out -- display message on console regardless of dio */ out(string) char *string; { fprintf(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:  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]!='-') return(ERROR); for(j=0; j= maxset) return(FALSE); else {outset[*j]=c; (*j)++; return(TRUE); } } /* dodash -- expand 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[*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('-',dest,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,maxset); (*i)++; } else addstr('-',dest,j,maxset); (*i)++; } } /* isalpnum -- true if c is letter or digit usage: if(isalpnum(c)) ... */ isalpnum(c) char c; { 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); */ 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] == '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('#'); 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; 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,pat,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; 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,/* 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 0 && (*++argv)[0]=='-') for(s=argv[0]+1; *s != '\0'; s++) switch(*s) {case 'O': only=TRUE; break; case 'I': ignore=TRUE; break; case 'D': sequence=TRUE; break; default: error("prep: invalid option"); } if(only && ignore) 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(STDOUT,"%d: %s\n",wcount,word); if(!pmatch(word) && !sequence) fprintf(STDOUT,"%s\n",word); } else if(only) {if(pmatch(word) && sequence) fprintf(STDOUT,"%d: %s\n",wcount,word); if(pmatch(word) && !sequence) fprintf(STDOUT,"%s\n",word); } else {if(sequence) fprintf(STDOUT,"%d: %s\n",wcount,word); 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(filename) 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 > 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); 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++) 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 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(isalpha(c)) break; } word[i++]=tolower(c); while(1) {if((c=getchar())==EOF) /* push back EOF for next call */ {ungetch(c); break; } c &= 0177; if(!isalpha(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); } /* 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=(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); } return(FALSE); } F for next call */ {ungetch(c); break; } c &= 0177; if(!isalpha(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); } /* 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=/* 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]=='-') 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; case 'N': numflag=TRUE; break; case 'U': uniqflag=TRUE; break; default: fprintf(STDERR, "sort: invalid option %c\n",*s); exit(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 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; while(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(p,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; 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]); } } /* 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) /* 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; } /* xstrcmp -- 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) : *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<t, 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[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 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 */ {fprintf(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 lines */ for(i=0; i < nlines; i++) fprintf(STDOUT,"%s\n",lineptr[i]); } *t; int fold; { int i,j; char s1, t1; for(i=0; keys[0][i]>=0; i++) for(j=keys[0][i]; j<=keys[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 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 */ {fprintf(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/* 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); } 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 terminated 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 instring[], 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,instring); 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); 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); 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])) break; 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,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 (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; /* 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); } /* 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 {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); fprintf(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 && 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'; return(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 character 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) /* 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"); starl[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 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) {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 class */ 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); } 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; } 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); } } {starm[0]='\0'; split(instring,i+1,starl,starr); return(FALSE); } /* normal case with class */ 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); } 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;.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,pat,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,starm 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). Specific 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. 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. (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 characters 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 instring 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ô  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¬ �           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å characteró 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î �           instring¬  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 instring 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å á 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ì �           (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). 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ô �           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ì anä  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). 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) normal 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å ± (TRUE)® 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¬  starì �           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ç  doesn'ô  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 and 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. match=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ì characteró 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ä �           ° (FALSE© 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æ 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'ô nulì (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ì �           contaiî  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¬ �           TEØ  consideró iô aî erroò iæ paô ió nulì anä issueó  á �           message without bothering to set any variables.   null and match will be 0 (FALSE). normal case: where pat is a class           Iæ instrinç containó aî occurrencå oæ 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'ô nulì (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ì �           contaiî  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¬ �     /* 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 to 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; dioinit(&argc,argv); dodetab=doentab=FALSE; /* process options */ while(--argc > 0 && (*++argv)[0] == '-') for(s=argv[0]+1; *s != '\0'; s++) switch(*s) {case 'D': dodetab=TRUE; break; case 'E': doentab=TRUE; break; default: error("tabs: invalid option. Use -d or -e"); } 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) 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=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; /* tabs from command line */ doincr=FALSE; while(argc-- > 0) {if( *argv[0] == '&') {*argv[0]=' '; doincr=TRUE; } itab=atoi(*argv); if( itab <= 0) 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 {tabflags[itab]=TRUE; lastab=itab; argv++; } } return(OK); } /* detab -- convert tab chars to blanks */ detab() { int c, col; col=1; while( (c=getchar()) != EOF) {if(c == '\t') do {putchar(' '); col++; } while(!tabpos(col)); else if(c == '\n') {putchar('\n'); col=1; } else {putchar(c); col++; } } } /* tabpos -- return true if col is a tab stop, else false */ tabpos(col) int col; { if(col >= MAXLINE) 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 leftover blanks */ {putchar(' '); col++; } if(c != EOF) {putchar(c); if(c == '\n') col=1; else col++; } } while(c != EOF); }  } } /* tabpos -- return true if col is a tab stop, else false */ tabpos(col) int col; { if(col >= MAXLINE) 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/* 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 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 lines 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; 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  /* 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); 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(line)+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); if((p=alloc(strlen(line)+1)) == NULL) error("tail: out of room in saveline #2"); strcpy(p,line); linbuf[ntail-1]=p; } } /* 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 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,argv); append=FALSE; /* process options */ while(--argc > 0 && (*++argv)[0] == '-') for(s=argv[0]+1; *s != '\0'; s++) switch(*s) {case 'A': append=TRUE;  break; default: error("usage: tee [-a] outfile"); } if(!append) {if(fcreat(*argv,obuf) == ERROR) error("tee: can't create output file"); 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"); 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 error during append"); fefc(obuf); unlink(*argv); if(rename("temptee.$$$",*argv) == ERROR) error("tee: output is on temptee.$$$ ; can't rename"); } dioflush(); } /* tfcopy -- copy 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(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("temptee.$$$"); error(msg); } utput error copying prior to append"); if(tfcopy(STDIN,obuf,TRUE) == ERROR) terror("tee: file output error during append"); fefc(obuf); unlink(*argv); if(rename("temptee.$$$",*argv) == ERROR) error("tee: output is on temptee.$$$ ; can't rename"); } dioflush(); } /* tfcopy -- cop/* 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 (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" #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("usage: 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) /* 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("tr: 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) {putchar(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(); } /* 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); return(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)); if(cindex(inset,c) >= 0) return(-1); else return(lastto+1); }  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(); } /* 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/* 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 each 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 STDOUT 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: empty 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); strcpy(line1,line2); count=1; } if(cflag) fprintf(STDOUT,"%d %s",count,line1); else fputs(line1,STDOUT); dioflush(); } 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: STDOUT 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)  j=0; if(j >= MAXOUT -3) j=0; outline[j]=inline[i]; } if(inline[i] == FOLD) /* copy 2nd half working backwards */ {j=middle-1; 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--) if(outline[i] != ' ') /* delete trail blanks and terminate line */ break; outline[++i]='\n'; outline[++i]='\0'; fputs(outline,STDOUT); } dioflush(); } /* nextj -- 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 += incr; } return(j); }  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--) if(outline[i] != ' ') /* delete trail blanks and terminate line */ break; outline[++i]='\n'; outline[++i]='\0'; fputs(outline,STDOUT); } dioflush(); } /* nextj -- /* 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 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 output: STDOUT notes: 1. max of 200 files after expansion 2. metacharacters in filename: ! except ? wildcard match a single character * wildcard match 1 or more characters 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]); dioflush(); } /* 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]); }  ! except ? wildcard match a single character * wildcard match 1 or more characters 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: /* 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 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 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 ll 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 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; 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 if(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(line,col,left,right); else splitr(line,col,left,right); if(leftout) fprintf(STDOUT,"%s\n",left); else fprintf(STDOUT,"%s\n",right); } dioflush(); }  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 if(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; *ùÍKÍžÃ+ÊžÊÐÃ'Ã+ÃFÃŽÃrÃÃû Í– þ8Ê{ æÄ‚w#w#wÑÁÉÍÆÃÞá^#V#å*~#foÉá^#å*~#foÉá^#V#å*nÉá^#å*nÉá^#V#åë ~#foÉá^#åë& ~#foÉ!È+É!È#É!Ø+É!Ø#É!ð+É!ø+ÉÈÉÈÉØÉØÉðÉøÉ}»À|ºÉëz¼À{½Éë|ºÀ}»Éë|ªòìz·ð7Éë|ªòó|·ð7ÉzõÍZëÍZëÍ)ñ·ð|/g}/o#É|µÈÕå͉ÑÍk|/g}/o#Ñɯ2qÍZëÍZÍk:qÐ|/g}/o#É|·ð/g}/o#:q<2qÉÅÍqÁÉDM!x±ÈxGyOÒƒë)ëÃv|µÈÅÍ”`iÁÉ|·ú )ÖëxõÍÝÚ·Õz/W{/_ѯzW{_ñ=ÈõyOxGæ¯2qÍZëÍZë͉ÃM|ºØÀ}»Éëȯ|g}oÃæëÈ)Ãô|/g}/o#Éz/W{/_É!9~#foÉ!à !à ! à ! à !à !à Ÿ!9Å~#ÂAÁÉá"s!`å*"³!è"µ!ÜY"—>Û2­>Ó2°>É2¯2²!Ì"�!"“!@"‘!"• Í·ÊžÍ!€ßF#x·Â±Ã~#±¯!ßb¯2r~#þ ÊÈ·Êþ"ÂÞ2rÃß+}|~#·ÊÅG:r·xÁÊþ"Âæ¯2r+w#þ Âæ+6#ÃÈÕ!×6#¯2w2x*sé!ÿÿÉ>õÍrÚ<o&åÍFáñ=þÂ-ÃÍ`Í ÍrÚ'~æÊhåÍÅÍëÍÁá6þÿ!À+ÉÍ`WÖØþ?ØÕ_!×~æ7ÑzÈ?ÉÍ`ÅÍ åþ:>ªÍÖ@w#ÍGþ.¶ÍƯww#Ã?Åþ*>?ÊéÍñÚçw#ÂÇÁÍñØÃÞ> w#ÂéÁÉÍþ.7Èþ:7Èþ7Èþ!ÉþaØþ{ÐÖ Éþ Ê þ Ê ÉÅÍ`·OÂE×!·æyÂ6ÁÉÕ$Ñ Â-7ÁÉÍrÚBÖo&))T])))ë!·yÁÉÕÅõå€ÍáñÁÑÉÈ':7?·Âh#D/ÍÞ6ñÉå:?æÂ>$:?æÂÕ$:)?æÊ$Íl,:å>·ÂÎ#Íà)Ÿ#>6Í7:+?Í7Ãû#*+?|µÂ°#»2Í©7Ãû#>6Í7:+?Í7>#Í7>6Í7:,?Í7Ãû#*+?"?Íà)Âò#>Í7:+?Í7>sÍ7>@2?Ãû#À2Í©7Ãê#ÍÇ)Â$:"?=2"?áñÍ÷)ÉÍà)Â$>sÍ7Ãê#ÍŽ)Â5$Æ2:å>·Ê/$Ë2Í©7Ãê#ü3Í©7Ãê#* ?"?*+?"?:)?æÊŸ$:å>·Â€$Íà)Âs$>>Í7:+?Í7Ñ2Í©7Ãû#Ô2Í©7¯2?Ãû#Íà)Âs$>Í7:+?Í7>{Í7Ñ2Í©7Ãê#Íà)¸$:)?æÀ‘$>}Í7Ñ2Ãv$:)?æÀÄ1.ÍŽ)ÂÏ$>&Í7¯Í7Ú3Ãv$:)?æÊã$Íl,Ä#:?æÂô$Íu-Íl,Ã$:)?æÀ>åÊ%>ÕÍ7Íl,>ÑÍ7>@2)?Ã$å* ?"?áR3Í©7:?æþö2?É"?|·ÂO%}·Â@%Ï3Í©7Éõñõ·ÊV%ÂC%ñÏ4Í©7Éñ>�GÈ>)Í7Ã[%#Í”+Í:*ñõÍ…-ÍÍíÃÄÃÆ Ãàæ Å!öÿ9ùDMÍ�å! åÍ¡ÑÑ! s#r! s#r! s#r! ¯w#wͤë`is#rz³Ê}`iå~#fo|¢g}£oëás#r! ^#Vr+sÍ�öÿ|µÂ+! ^#Vr+sÍ�àÿ|µÊRÍ�öÿ|µÊRÍ�÷ÿ|µÂ]! ¯w#wÃzÍ�|µÂz! 6#6! ^#Vr+sÃäÍ�åÍ�åÍ�å!¨å!åͧÑÑÑÑÑͪë! 9ùëÁÉlines=%u words=%u chars=%u ÃÙÃÃàÃÃ]ÆÃìÅ!úÿ9ùDM*sÕ*ÑsÕ*Ñs!  ~#foåÍ� ~#fo)Ñå* Ñs#r*6*ëÕ*¤Ñs#r! 6#6`i6#6Í�åÍ� ~#foÑÍúÒE Íw}·Êl ÃE ! ~#foåÍ�)Ñ~#fon}þ<Ê™ þ|ÊM þ+ÊÉ þ>Êà Ã. ! ~#foåÍ�)Ñ~#fo#n}·Â· Ãû *å! ~#foåÍ�)Ñ~#fo#åÍÇÑÑ#|µÂ ! ~#foåÍ�)Ñ~#fo#å!N å!åÍÊÑÑÑÍÍ*6!] å! ~#foåÍ�)Ñ~#foåÍÐÑÑ|µÂJ *ån&|²g}³oëásÃ} *4! ~#foåÍ�)Ñ~#fo#å* Ñs#r! ~#foåÍ�)Ñ~#fo#n}·ÊÆ ! ~#foåÍ�)Ñå!i ëás#r! ~#foåÍ�)Ñå* Ñs#rÃà *ån&|²g}³oëás! ~#foåÍ�)Ñ~#fo#n}·Â !v å!åÍÊÑÑÍÍ! ~#foåÍ�)Ñ~#fo#åÍÓÑ*å! ~#foåÍ�)Ñ~#fo#åÍÖÑÑ#|µÂu ! ~#foåÍ�)Ñ~#fo#å!• å!åÍÊÑÑÑÍÍ*4Íw}·Â Í�ë! s#rÍ�åÍ� ~#foÑÍúÒß ! ~#foåÍ�)Ñå! ~#foåÍ�#)Ñ~#foëás#r! ^#Vr+sÃ’ Í� ^#Vr+s`i^#Vr+s* ^#Vr+sÃ+ Í� åÍ�ëás#r! ~#foåÍ� ~#fo)ѯw#wÃ9 ! ^#Vr+s`i^#Vr+sÃL ë!9ùëÁÉCan't open %s ½Â¢>¼ÊÉ>½Â®>¼Ê×>½Âº>¼Êê>½ÂÆ>¼ÊýÃ(! n&åÍvÑÁÉ! n&å!åÍyÑÑÁÉ! n&å!åÍyÑÑÁÉ! n}þ Â! å!åÍyÑÑ! n&å!åÍyÑÑÁÉÍ�##^#Vr+së|µÂ‡!åÍ�åÍ�~#foåÍ|ÑÑÑøÿ|µÊf!ÿÿÁÉÍ�##6ÿ#6Í�åÍ�ëás#rÍ�^#Vr+sÕ! nëásë&ÁÉÁÉóÃïÃWèÅ!þÿ9ùDMÍ�üÿÚÌ!ÃéÍ�##~#foü|µÂå!ÃéÍ�##~#fo€ëÍËÍúë`is#rÍ�åÍ�åÍ�~#foåͪÑÑÑåÍ�ÑÍåÊ2!ÿÿÃéÍ�+€Í?ë`is#rÍ�##~#fo|µÊÂ!€åÍ�åÍ�åÍ�ÑåÍ­ÑÑÑÍ�##å~#foåÍ�Ñëás#rÍ�å~#foåÍ�ÑÍúëás#r!å!ÿÿåÍ�~#foåͰÑÑÑÃéÍ�##6#6Í�åÍ�ëás#r!Ãéë!9ùëÁÉÃþÃÆ ÃfÃÅ!þÿ9ùDMÍ�|µÂÍõÃÁÍ�+++|µÂ,!åÍøÑÃÁÍ�##^#Vr+së|µÂª!åÍ�åÍ�~#foåÍûÑÑÑë`is#r!ÿÿ|Ò}Í�##^#Vr+sëÃÁÍ�##åÍ�€Í?+ëás#rÍ�åÍ�ëás#rÍ�^#Vr+sën&ÃÁë!9ùëÁÉÅ!þÿ9ùDM`i¯w#w! ^#Vr+sën}·Ê÷`i^#Vr+sÃØÍ�Ãþë!9ùëÁÉÃÃàÈ÷ÃÅ!hÿ9ùDM!ž ^#Vr+së~#foë! s#rÍ�žë!– s#r! ^#Vr+sënë`is{·Êg`in}þ%ÂQ! ë!� s#r!” 6#6!‘ s!� s!� sÍ�n}þ-¦! ^#Vr+s!� 4Í�n}þ0¶!‘ 4Í�n&åÍ Ñ}·ÊÓ! åÍÑÃÖ!ë!’ s#r! ^#Vr+sënë`is{þ.Â! åÍÑë!” s#r!� 4! ^#Vr+sënë`is`in&åÍÑ}þDÊJþUʆþXÊ�þOʘþCÊÞþSÊÃ;Í�–~#fo|Ò†!� ^#Vr+së6-Í�–åÍ�–~#foÍúëás#r!’ ^#Vr+s! 6 Þ! 6Þ! 6!’ å~#foå! n&å!– ^#Vr+së~#foå!� åÍ ÑÑÑѯgÍúëás#rÇ!� ^#Vr+sÕ!– ^#Vr+së~#foëás!’ ^#Vr+sÇ!� n}·Â"!” 6È#6!– ^#Vr+së~#foë! s#rÍ�n}·Ê‡Í�”|µÊ‡!� ^#Vr+sÕ! ^#Vr+sënëás!” ^#Vr+s!’ ^#Vr+sÃ=Í��6! ë!� s#r!� n}·ÂÞ!’ ^#Vr+s!ÿÿ|ÚÞ!œ ^#Vr+sÕ!‘ n}·ÊÕ!0ÃØ! ëásãÍ�œå!� ^#Vr+sënëás{·Ê!œ ^#Vr+sÃÞ!� n}·Ê8!’ ^#Vr+s!ÿÿ|Ú8!œ ^#Vr+së6 ÃÃN!œ ^#Vr+sÕ`inëásÃd!œ ^#Vr+sÕ`inëásÃEÍ�œ6ë!˜9ùëÁÉÃ|ÃsÅ!ÿÿ9ùDM! ^#Vr+sënë`is{·ÊÑ`in}þ ²Í�å! åÍyÑÑÍ�å`in&åÍyÑÑ#|µÂÎ!ÿÿÃ×Ä!Ã×ë!9ùëÁÉÃæÃàÅ!ÿÿ9ùDMÍ�åÍ� ÑÍìÒ4Í�^#Vr+sÕÍ�öÿÚ!Í�0Ã)Í�7ëás!&ÃÍ� åÍ�åÍ� Ñ͉åÍ�åÍãÑÑÑë`isÍ� åÍ�åÍ� ÑÍ)åÍ�åÍãÑÑÑ`in&#&Ãë!9ùëÁÉÅ!9ùDM! n&Ðÿ|ͯÚ³! n&Æÿ|Í©ÁÉÁÉýÈÅ!þÿ9ùDM`i¯w#wÍ�~#fon&åͺÑ}·Ê Í� Í?åÍ�^#Vr+sënѯgÐÿë`is#rÃËÍ�Ãë!9ùëÁÉà ÃTÅ!9ùDM! n&åÍÑ|µÊG! n&àÿÃN! n&&ÁÉÁÉÅ!9ùDM! n&Ÿÿ|ͯÚ! n&…ÿ|Í©ÁÉÁÉà Í Åë!\Í&Í!ÁÉÍ7Å*Ÿë!ÅÍ&*¡ë!ÕÍ&ÅÍÁþÿÊ!ÉÅÅÃ&Íèå=Â"ÅÃ&ÍèåÑÁ! ãéÍBÊLÍèÚ<"eæ=ÊLÍè=ÃÉÍ7*¡^#V#z³Âx24+V+^+ÕÂ*ŸåÍý:4‡o&9ù!ÿÿÉÒÍ Ååå!jÿ9å6ˆ ëÍ Íá#F#Ñx·Êa~#ÃT¯áÁÉÍ7Å:ŸO*¡ëÍÁÉÍ7¯Í,Ú2që*ŸëÅÍ&ÍþÿÁÊ:qÍ):¡·ʳ=ʳ=Âr:qo&ÉÃÄÆÃwÍ7*ŸÅå;Ñ\ÍþÿÁÊ!å*ŸåÍÁÑÑÉÃ#Í7:ŸÍ)Ú~æÊÅ:ŸÍ,"s!"u€Í*£|µ*uÊU*¡€€~#Â,"¡*sëÍ·*uÂU#"u*£+"£ÃÁÉÍ7*£|µÈÅDM*¡ë*ŸÍÝÚ†><êzí°ÁÉ~# x±ÂzÁÉ ë ë><ê–í¸ÁÉ~+ x±Â–ÁÉ|ºÀ}»ÉîäÍ7:ŸÍ,ÚÅå*ŸåÍ«Ñë:£*¡·ÊÐ}|æ2qã å¾ÊãëÕÍÑáþÿÂ÷ÑÁÃ:qwÕÍ!ÑþÿÊò! Ñ{æwëÁÉÍ7:ŸÍ)Ú~æÊÅ:ŸÍ,"s!"u*£|µÊi*¡ëÍ*sëÕÍÑþÁÊÅþÂn! ~þ€Âi6*uÁÉ*£+"£*¡€"¡*u#"uÃ5Í7Å*Ÿë!Äÿ9åååÍ&á 6C#6O#6MÑÍþÿ¸áÁÃ*¡|µÂΡÕ!\Í&áÃàë!\Í&*£|µÂà!£ë!lÍ&�¯!9å~#fo´Ê> +Íq#~·Âþá##ÃòáxþSÚ:" ÍóEXECL: Too much text $!€pz!Ö*w#ÂFÁ*:þ1Â`*Ãiþ!Âiþ÷ù!åÃÖþaØþ{ÐÖ ÉÕÅÍÑÕÍÁÑ·Êø€ÍÃ!€ëÃÙÍ Í,ÚÅ FN¯xg>G�oy òÈ$ÁÉÍ7*¡^#V#z³Âx24+V+^+ÕÂ*ŸåÍý:4‡o&9ù!ÿÿÉÒÍ Ååå!jÿ9å6ˆ ëÍ Íá#F#Ñx·Êa~#ÃT¯áÁÉÍ7Å:ŸO*¡ëÍÁÉÍ7¯Í,Ú2që*ŸëÅÍ&ÍþÿÁÊ:qÍ):¡·ʳ=ʳ=Âr:qo&ÉÃÄÆÃwÍ7*ŸÅå;Ñ\ÍþÿÁÊ!å*ŸåÍÁÑÑÉÃ#Í7:ŸÍ)Ú~æÊÅ:ŸÍ,"s!"u€Í*£|µ*uÊU*¡€€~#Â,"¡*sëÍ·*uÂU#"u*£+"£ÃÁÉÍ7*£|µÈÅDM*¡ë*ŸÍÝÚ†><êzí°ÁÉ~# x±ÂzÁÉ ë ë><ê–í¸ÁÉ~+ x±Â–ÁÉ|ºÀ}»ÉîäÍ7:ŸÍ,ÚÅå*ŸåÍ«Ñë:£*¡·ÊÐ}|æ2qã å¾ÊãëÕÍÑáþÿÂ÷ÑÁÃ:qwÕÍ/* 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 a:prep a:prep a:cat file1.dat file2.dat file3.dat |a:sort -fu |a:lpr 5®  Sorteä  lisô oæ alì wordó iî á WordStaò doã file®  Onå worä � peò line®  Distinguisè betweeî uppeò anä loweò caså alpha® Sho÷ � only one occurrence of each word. B>a:cat outfile a:cat outfile a:cat outfile -w k® Wherå á UTOOÌ aî takå á regulaò filå aó inpuô (withouô thå <© � anä  haó optionó (-xyz)¬  consulô thå manuaì pagå tï seå  whetheò � thå  optionó  musô bå giveî beforå oò afteò thå filå  name®  Thå � optioî  usuallù  preceedó thå filå namå buô  É  wasn'ô  perfectlù � consistent. E.g. a:cal file -g 01/01/83 (option follows file name) a:cat -w file (option preceeds file name) a:comm -12 file (option preceeds file name) a:crt -n file (option preceeds file name) l® Thå followinç arå registereä trademarksº Osbornå ± bù Osbornå � Computer¬  CP/Í bù Digitaì Research¬  Z80Á bù Zilog¬ UNIØ bù Belì � Labs, WordStar by MicroPro.  or -abc. j®  Optionó  anä  redirecteä inpuô anä outpuô caî appeaò iî  anù � order. E.g. all of the following are o.k. a:cat -w outfile a:cat outfile a:cat outfile -w k® Wherå á UTOOÌ aî takå á regulaò filå aó inpuô (withouô thå <© � anä  haó optionó (-xyz)¬  consulô thå manuaì pagå tï seå  whetheò � thå  optionó  musô bå giveî beforå oò afteò thå filå  name®  Thå � optioî  usuallù  preceedó thå filå namå buô  É  wasn'ô  perfectlù � consistent. E.g. a:cal file -g 01/01/83 (option follows file name) a:cat -w file (option preceeds file name) a:comm -12 file (option preceeds file name) a:crt -n file (option preceeds file name) l® Thå followinç arå registereä trademarksº Osbornå ± bù Osbornå � Computer¬  CP/Í bù Digitaì Research¬  Z80Á bù Zilog¬ UNIØat only do words on file -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 sort (-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. */ /* 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] == '-') for(s=argv[0]+1; *s != '\0'; s++) switch (*s) {case 'E': eq=TRUE; break; case 'G': gt=TRUE; break; case 'L': lt=TRUE; break; case 'R': range=TRUE; break; default: error("cal: invalid option"); } if(convdate(*argv++,&argdate1)==ERROR) error("cal: invalid date1"); if(range) {if(convdate(*argv,&argdate2)==ERROR) error("cal: invalid date2"); if(eq || gt || lt) error("cal: no other options allowed with -r"); } if(!eq && !gt && !lt && !range) /* default -e if no options */ eq=TRUE; while(isstdin ? fgets(line,STDIN) : fgets(line,ibuf)) {if(!finddate(line,cdate)) continue; else convdate(cdate,&linedate); if(eq && datecmp(&linedate,&argdate1)==0) fputs(line,STDOUT); if(gt && datecmp(&linedate,&argdate1) > 0) fputs(line,STDOUT); if(lt && datecmp(&linedate,&argdate1) < 0) fputs(line,STDOUT); if(range && datecmp(&linedate,&argdate1) >= 0 && datecmp(&linedate,&argdate2) <= 0) fputs(line,STDOUT); } dioflush(); } /* convdate -- convert mm/dd/yy to structure date */ convdate(mmddyy,pd) char *mmddyy; struct date *pd; { int tmonth, tday, tyear; char mm[3], dd[3], yy[3]; mm[0]=mmddyy[0]; mm[1]=mmddyy[1]; dd[0]=mmddyy[3]; dd[1]=mmddyy[4]; yy[0]=mmddyy[6]; yy[1]=mmddyy[7]; mm[2]=dd[2]=yy[2]='\0'; tmonth=atoi(mm); tday=atoi(dd); tyear=atoi(yy); if(tyear < BASEYR) tyear += 2000; else tyear += 1900; if(tmonth < 1 || tmonth > 12) return(ERROR); if(tday < 1 || tday > 31) return(ERROR); switch(tmonth) {case 1: case 3: case 5: case 7: case 8: case 10: case 12: if(tday > 31) return(ERROR); break; case 4: case 6: case 9: case 11: if(tday > 30) return(ERROR); break; case 2: if(tyear % 4 == 0 && tyear % 100 != 0 || tyear % 400 == 0) {if(tday > 29) /* leap year */ % return(ERROR); break; } else {if(tday > 28) /* not leap year */ return(ERROR); break; } default: error("in convdate -- can't happen"); } pd->day=tday; pd->month=tmonth; pd->year=tyear; return(OK); } /* finddate -- find mm/dd/yy in line */ finddate(line,mmddyy) char *line, *mmddyy; { struct date dtest; char ctemp[9]; int i, len, start; if((start=index(line,"/")) < 0) return(FALSE); start=max(start-2,0); len=strlen(line); for(i=start; i0 if first is <,==,> second. */ datecmp(pd1,pd2) struct date *pd1, *pd2; { if(pd1->year > pd2->year) return(1); if(pd1->year < pd2->year) return(-1); if(pd1->month > pd2->month) return(1); if(pd1->month < pd2->month) return(-1); if(pd1->day > pd2->day) return(1); if(pd1->day < pd2->day) return(-1); return(0); } j)); if(k >= 0) /* matched rest of pattern */ done=TRUE; else i--; } offset2=k; done=TRUE; } else if(!omatch(lin,&offset2,pat,j)) {offset2=-1; done=TRUE; } else j += patsize(pat,j); } return(offset2); } /* patsize -- return size of 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); 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 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]) {case LITCHAR: if(lin[*i] == pat[j+1]) advance=1; break; case BOL: if(*i == 0) advance=0; break; case ANY: if(lin[*i] != '\n') advance=1; break; case EOL: if(lin[*i] == '\n') advance=0; 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 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]; 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) 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,&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') {lj=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,&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) done=TRUE; else stclose(pat,&j,lastj); } else {addstr(LITCHAR,pat,&j,MAXLINE); addstr(esc(arg,&i),pat,&j,MAXLINE); }  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 -- 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; jp >= 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 blanks (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) /* replace by blank */ return(' '); else return(c); } 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. author: David H. Wolen last change: 12/2/82 option: -c prefixes each output line with count usage: sort outfile -c input: STDIN output: STDOUT */ /* 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: STDOUT */ /* 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 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 output: STDOUT notes: 1. max of 200 files after expansion 2. metacharacters in filename: ! except ? wildcard match a single character * wildcard match 1 or more characters */ /* 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 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 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 ll 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 be */ /* 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 , so will output 2. If ll and col åååå