home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume3 / match < prev    next >
Internet Message Format  |  1986-11-30  |  21KB

  1. From: Peter Bain <genrad!ihnp4!watmath!wateng!pdbain>
  2. Subject: match - faster than bm
  3. Newsgroups: mod.sources
  4. Approved: jpn@panda.UUCP
  5.  
  6. Mod.sources:  Volume 3, Issue 2
  7. Submitted by: Peter Bain <ihnp4!watmath!wateng!pdbain>
  8.  
  9.  
  10. Match is functionally identical to bm, but uses the Vax MATCHC instruction
  11. to do the pattern matcher. On 780s, 785s, probably Microvax 2s, 730s
  12. and 750s (but NOT microvax 1s) it runs considerably faster. Here is
  13. a run on our 780 under 4.2 BSD:
  14.  
  15.     /bin/time grep foobar /usr/dict/words
  16.            16.7 real         4.6 user         0.6 sys  
  17.     /bin/time bm foobar /usr/dict/words 
  18.             3.0 real         0.9 user         0.5 sys  
  19.     /bin/time match foobar /usr/dict/words 
  20.             3.5 real         0.3 user         0.5 sys  
  21.  
  22. Note that it runs ONLY on Vaxen, and possibly only under 4.2.
  23.  
  24. ------------------ tear here ----------------------------------
  25. : This is a shar archive.    Extract with sh, not csh.
  26. : The rest of this file will extract:
  27. : Execute.c Extern.h GetPatFile.c Global.c MakeDesc.c match.h match.c MatchFound.c MkDescVec.c MoveResidue.c PrintLine.c PutUsage.c Search.s Makefile README match.p
  28. echo Extracting Execute.c
  29. sed 's/^X//' > Execute.c << 'e-o-f'
  30. X#include <stdio.h>
  31. X#include "match.h"
  32. X#include "Extern.h"
  33. XExecute(DescVec, NPats, TextFile, Buffer)
  34. Xregister struct PattDesc *DescVec[];
  35. X/* pointers to status vectors for the different
  36. X    * patterns, including skip tables, position in buffer, etc. */
  37. Xint NPats; /* number of patterns */
  38. Xregister char Buffer[]; /* holds text from file */
  39. Xint TextFile; /* file to search */
  40. X{
  41. X    int NRead, /* number of chars read from file */
  42. X        NWanted, /* number of chars wanted */
  43. X        NAvail, /* number of chars actually read */
  44. X        BuffSize, /* number of chars in buffer */
  45. X        BuffPos, /* offset of first char in Buffer in TextFile */
  46. X        BuffEx, /* flag to indicate that buffer has been searched */
  47. X        ResSize,
  48. X        /* number of characters in the last, incomplete line */
  49. X        Found, /* flag indicates whether pattern found
  50. X        * completely and all matches printed */
  51. X        Valid; /* was the match "valid", i.e. if -x used,
  52. X        * did the whole line match? */
  53. X    register char *BuffEnd;
  54. X    /* pointer to last char of last complete line */
  55. X
  56. X    /* misc working variables */
  57. X    register int i;
  58. X
  59. X    /* initialize */
  60. X    ResSize = 0;
  61. X    Found = 0;
  62. X    BuffPos = 0;
  63. X    for (i=0; i < NPats; i++) {
  64. X        DescVec[i] -> Success = 0;
  65. X        DescVec[i] -> Start = Buffer;
  66. X    } /* for */
  67. X    /* now do the searching */
  68. X    do {
  69. X        /* first, read a bufferfull and set up the variables */
  70. X        NWanted = MAXBUFF - ResSize; NRead = 0;
  71. X        do {
  72. X            NAvail =
  73. X               read(TextFile,Buffer + ResSize + NRead, NWanted);
  74. X            if (NAvail == -1) {
  75. X                fprintf(stderr,
  76. X                  "bm: error reading from input file\n");
  77. X                exit(2);
  78. X            } /* if */
  79. X            NRead += NAvail; NWanted -= NAvail;
  80. X        } while (NAvail && NWanted);
  81. X        BuffEx = 0;
  82. X        BuffSize = ResSize + NRead;
  83. X        BuffEnd = Buffer + BuffSize - 1;
  84. X        /* locate the end of the last complete line */
  85. X        while (*BuffEnd != '\n' && BuffEnd >= Buffer)
  86. X            --BuffEnd;
  87. X        if (BuffEnd < Buffer)
  88. X            BuffEnd = Buffer + BuffSize - 1;
  89. X        while (!BuffEx) { /* work through one buffer full */
  90. X            BuffEx = 1; /* set it provisionally, then clear
  91. X            * it if we find the buffer non-empty */
  92. X            for (i=0; i< NPats; i++) {
  93. X                if (!DescVec[i]->Success)
  94. X                /* if the pattern  has not been found */
  95. X                    DescVec[i]-> Success =
  96. X                    Search(DescVec[i]->Pattern,
  97. X                    DescVec[i]->PatLen, DescVec[i]->Start,
  98. X                    BuffEnd - DescVec[i]->Start + 1,
  99. X                    DescVec[i]);
  100. X                if (DescVec[i]->Success){
  101. X                /* if a match occurred */
  102. X                    BuffEx = 0;
  103. X                    Valid = MatchFound(DescVec[i],BuffPos,
  104. X                    Buffer, BuffEnd);
  105. X                    Found |= Valid;
  106. X                    if ((sFlag || lFlag) && Found)
  107. X                        return(0);
  108. X                } /* if */
  109. X            } /* for */
  110. X        } /* while */
  111. X        if(NRead) {
  112. X            ResSize = MoveResidue(DescVec,NPats,Buffer,
  113. X                Buffer + BuffSize -1);
  114. X            BuffPos += BuffSize - ResSize;
  115. X        } /* if */
  116. X    } while (NRead);
  117. X    return(!Found);
  118. X} /* Execute */
  119. e-o-f
  120. echo Extracting Extern.h
  121. sed 's/^X//' > Extern.h << 'e-o-f'
  122. X/* global flags for bm */
  123. Xextern int    cFlag, /* true if we want only a count of matching lines */
  124. X    eFlag, /* indicates that next argument is the pattern */
  125. X    fFlag, /* true if the patterns arew to come from a file */
  126. X    lFlag, /* true if we want a list of files containing the pattern */
  127. X    nFlag, /* true if we want the character offset of the pattern */
  128. X    sFlag, /* true if we want silent mode */
  129. X    xFlag, /* true if we want only lines which match entirely */
  130. X    hFlag, /* true if we want no filenames in output */
  131. X
  132. X    MatchCount; /* count of number of times a search string was found
  133. X    * in the text */
  134. Xextern char *FileName;
  135. e-o-f
  136. echo Extracting GetPatFile.c
  137. sed 's/^X//' > GetPatFile.c << 'e-o-f'
  138. X#include <stdio.h>
  139. X#include <sys/types.h>
  140. X#include <sys/stat.h>
  141. X#include "match.h"
  142. Xint
  143. XGetPatFile(PatFile, DescVec)
  144. Xchar *PatFile;
  145. Xstruct PattDesc *DescVec[];
  146. X/* read patterns from a file and set up a pattern descriptor vector */
  147. X{
  148. X    extern char *malloc();
  149. X    FILE *PFile;
  150. X    struct stat StatBuff;
  151. X    int PatSize; /* the number of chars in all the patterns */
  152. X    char *PatBuff; /* hold the patterns */
  153. X    if (!(PFile = fopen(PatFile,"r"))) {
  154. X        fprintf(stderr,"match: can't open pattern file %s\n",PatFile);
  155. X        exit(2);
  156. X    } /* if */
  157. X    /* find out how big the patterns are */
  158. X    if (fstat(fileno(PFile),&StatBuff) == -1) {
  159. X        fprintf(stderr,"match: can't fstat %s\n",PatFile);
  160. X        exit(2);
  161. X    } /* if */
  162. X    PatSize = StatBuff.st_size;
  163. X    if (!PatSize) {
  164. X        fprintf(stderr,"match: pattern file is empty\n");
  165. X        exit(2);
  166. X    } /* if */
  167. X    if (!(PatBuff = malloc(PatSize))) {
  168. X           fprintf(stderr,"match: insufficient memory to store patterns\n");
  169. X        exit(2);
  170. X    } /* if */
  171. X    fread(PatBuff,1,PatSize,PFile); /* get the patterns */
  172. X    /* make sure the patterns are null-terminated. We can't have
  173. X    * nulls in the patterns */
  174. X    if (PatBuff[PatSize-1] == '\n')
  175. X        PatBuff[PatSize-1] = '\0';
  176. X    else
  177. X        PatBuff[PatSize] = '\0';
  178. X    return(MkDescVec(DescVec,PatBuff));
  179. X} /* GetPatFile */
  180. e-o-f
  181. echo Extracting Global.c
  182. sed 's/^X//' > Global.c << 'e-o-f'
  183. X/* global flags for match */
  184. Xint    cFlag=0, /* true if we want only a count of matching lines */
  185. X    eFlag=0, /* indicates that next argument is the pattern */
  186. X    fFlag=0, /* true if the patterns are to come from a file */
  187. X    lFlag=0, /* true if we want a list of files containing the pattern */
  188. X    nFlag=0, /* true if we want the character offset of the pattern */
  189. X    sFlag=0, /* true if we want silent mode */
  190. X    xFlag=0, /* true if we want only lines which match entirely */
  191. X    hFlag=0, /* true if we want no filenames in output */
  192. X
  193. X    MatchCount=0; /* count of number of times a search string was found
  194. X    * in the text */
  195. Xchar *FileName = 0;
  196. e-o-f
  197. echo Extracting MakeDesc.c
  198. sed 's/^X//' > MakeDesc.c << 'e-o-f'
  199. X#include <stdio.h>
  200. X#include "match.h"
  201. X#include "Extern.h"
  202. Xextern char * malloc();
  203. X/* makes a pattern descriptor */
  204. Xstruct PattDesc *MakeDesc(Pattern)
  205. Xchar *Pattern;
  206. X{
  207. X    struct PattDesc *Desc;
  208. X    Desc = (struct PattDesc *) malloc(sizeof(struct PattDesc));
  209. X    Desc->Pattern=Pattern;
  210. X    Desc->PatLen = strlen(Desc->Pattern);
  211. X    return(Desc);
  212. X} /* main */
  213. e-o-f
  214. echo Extracting match.h
  215. sed 's/^X//' > match.h << 'e-o-f'
  216. X#define FIRSTCHAR ' '
  217. X#define MAXCHAR 0377
  218. X#define MAXBUFF 8192
  219. X#define MAXSIZE 100
  220. X#define MAXPATS 100 /* max number of patterns */
  221. X#define min(x,y) (x) < (y) ? (x) : (y)
  222. X#define max(x,y) (x) > (y) ? (x) : (y)
  223. Xstruct PattDesc {
  224. X    char *Pattern;
  225. X    int PatLen; /* pattern length */
  226. X    char *Start; /* starting position of search (at beginning of pattern) */
  227. X    int Success; /* true when pattern found */
  228. X};
  229. e-o-f
  230. echo Extracting match.c
  231. sed 's/^X//' > match.c << 'e-o-f'
  232. X#include <stdio.h>
  233. X#include <sys/file.h>
  234. X#include <strings.h>
  235. X#include "match.h"
  236. X#include "Extern.h"
  237. Xmain(argc,argv)
  238. Xint argc;
  239. Xchar *argv[];
  240. X{
  241. X    /* test driver for grep based on Boyer-Moore algorithm */
  242. X    char BigBuff[MAXBUFF + 2];
  243. X    /*
  244. X    * We leave one extra character at the beginning and end of the buffer,
  245. X    * but don't tell Execute about it. This is so when someone is
  246. X    * scanning the buffer and scans past the end (or beginning)
  247. X    * we are still technically in the buffer (picky, but there ARE
  248. X    * machines which would complain)
  249. X    */
  250. X    int ret = 1, /* return code from Execute */
  251. X        NotFound = 0, /* non-zero if file not readable */
  252. X        NFiles,
  253. X        NPats; /* number of patterns to search for */
  254. X    char i,
  255. X        *FlagPtr,
  256. X        **OptPtr; /* used to scan command line */
  257. X    int TextFile /* file to search */;
  258. X    struct PattDesc *DescVec[MAXPATS];
  259. X
  260. X    --argc;
  261. X    OptPtr = argv + 1;
  262. X    while ( argc && **OptPtr == '-') {
  263. X        FlagPtr = *OptPtr + 1;
  264. X        while (*FlagPtr) {
  265. X            switch (*FlagPtr) {
  266. X                case 'c': cFlag = 1; break;
  267. X                case 'e': eFlag = 1;
  268. X                    /* get the patterns from next arg */
  269. X                    NPats = MkDescVec(DescVec,*++OptPtr);
  270. X                    --argc;
  271. X                    break;
  272. X                case 'f': fFlag = 1; 
  273. X                    /* read the patterns from a file */
  274. X                    NPats = GetPatFile(*++OptPtr,DescVec);
  275. X                    --argc;
  276. X                    break;
  277. X                case 'l': lFlag = 1; break;
  278. X                case 'n': nFlag = 1; break;
  279. X                case 's': sFlag = 1; break;
  280. X                case 'x': xFlag = 1; break;
  281. X                case 'h': hFlag = 1; break;
  282. X                default:
  283. X                    fprintf(stderr,
  284. X                    "match: invalid option: -%c \n",
  285. X                    *FlagPtr);
  286. X                    PutUsage();
  287. X                    exit(2);
  288. X            } /* switch */
  289. X            ++FlagPtr;
  290. X        } /* while */
  291. X        ++OptPtr; --argc;
  292. X    } /* while */
  293. X    /* OptPtr now points to patterns */
  294. X    if (!fFlag && !eFlag) {
  295. X        if (!argc) {
  296. X            fprintf(stderr,"match: no pattern specified\n");
  297. X            PutUsage();
  298. X            exit(2);
  299. X        } else
  300. X            NPats = MkDescVec(DescVec,*OptPtr);
  301. X        ++OptPtr; --argc;
  302. X    }
  303. X    /* OptPtr now points to first file */
  304. X    NFiles = argc;
  305. X    if (!NFiles)
  306. X        ret &= Execute(DescVec,NPats,0,BigBuff+1);
  307. X    else while (argc--) {
  308. X        if ((NFiles > 1) || lFlag) FileName = *OptPtr;
  309. X        if ((TextFile = open(*OptPtr,O_RDONLY,0)) < 0) {
  310. X            fprintf(stderr,"match: can't open %s\n",*OptPtr);
  311. X            NotFound++;
  312. X        } else {
  313. X            ret &= Execute(DescVec,NPats,TextFile,BigBuff+1);
  314. X            if (sFlag && !ret)
  315. X                exit(0);
  316. X            close(TextFile);
  317. X        } /* if */
  318. X        ++OptPtr;
  319. X    } /* while */
  320. X    if (cFlag) printf("%d\n",MatchCount);
  321. X    exit(NotFound ? 2 : ret);
  322. X} /* main */
  323. e-o-f
  324. echo Extracting MatchFound.c
  325. sed 's/^X//' > MatchFound.c << 'e-o-f'
  326. X#include <stdio.h>
  327. X#include "match.h"
  328. X#include "Extern.h"
  329. XMatchFound(Desc, BuffPos, Buffer, BuffEnd)
  330. Xstruct PattDesc *Desc; /* state info about search for one string */
  331. Xint BuffPos; /* offset of first char of buffer into the file being searched */
  332. Xchar *Buffer, /* pointer to the first character in the buffer */
  333. X    *BuffEnd; /* pointer to the last character in the buffer */
  334. X{
  335. X    register char *MLineBegin, *MLineEnd;
  336. X    
  337. X    Desc->Success = 0;
  338. X    /* Start points to first character after a successful match */
  339. X    MLineBegin = MLineEnd = Desc->Start - 1;
  340. X    while(MLineBegin >=Buffer && *MLineBegin != '\n') --MLineBegin;
  341. X    ++MLineBegin;
  342. X    while( MLineEnd <= BuffEnd && *MLineEnd != '\n') ++MLineEnd;
  343. X    if (MLineEnd > BuffEnd) --MLineEnd;
  344. X    /* fixed 25jun85 pdbain. suppress multiple matches of the same
  345. X    * pattern on one line */
  346. X    Desc->Start = MLineEnd + 1;
  347. X    /* check if exact match */
  348. X    if (xFlag && !( Desc->PatLen == (*MLineEnd != '\n' ? ((MLineEnd -
  349. X    MLineBegin) + 1) : (MLineEnd - MLineBegin))))
  350. X        return(0); /* failure */
  351. X    if (sFlag) return(1);
  352. X    if (cFlag) {
  353. X        ++MatchCount;
  354. X        return(1);
  355. X    } /* if */
  356. X    PrintLine(BuffPos+(Desc->Start-Buffer),MLineBegin,MLineEnd);
  357. X    return(1);
  358. X} /* MatchFound */
  359. e-o-f
  360. echo Extracting MkDescVec.c
  361. sed 's/^X//' > MkDescVec.c << 'e-o-f'
  362. X#include "match.h"
  363. X#include <strings.h>
  364. X/* scan a newline-separated string of patterns and set up the
  365. X* vector of descriptors, one pattern descriptor per pattern. 
  366. X* Return the number of patterns */
  367. Xint
  368. XMkDescVec(DescVec, Pats)
  369. Xstruct PattDesc *DescVec[];
  370. Xchar *Pats;
  371. X{
  372. X    int NPats = 0;
  373. X    char *EndPat;
  374. X    extern struct PattDesc *MakeDesc();
  375. X    while (*Pats && (EndPat = index(Pats,'\n')) && NPats < MAXPATS) {
  376. X        *EndPat = '\0';
  377. X        DescVec[NPats] = MakeDesc(Pats);
  378. X        Pats = EndPat + 1;
  379. X        ++NPats;
  380. X    } /* while */
  381. X    if (*Pats && NPats < MAXPATS) {
  382. X        DescVec[NPats] = MakeDesc(Pats);
  383. X        ++NPats;
  384. X    } /* if */
  385. X    return(NPats);
  386. X} /* MkDescVec */
  387. e-o-f
  388. echo Extracting MoveResidue.c
  389. sed 's/^X//' > MoveResidue.c << 'e-o-f'
  390. X#include "match.h"
  391. X/* Moves the text which has not been completely searched at the end of
  392. X* the buffer to the beginning of the buffer
  393. X* and returns number of bytes moved */
  394. Xint MoveResidue(DescVec, NPats,Buffer, BuffEnd)
  395. Xregister struct PattDesc **DescVec;
  396. Xint NPats;
  397. Xchar *Buffer, *BuffEnd;
  398. X{
  399. X    char *FirstStart;
  400. X    register char *Residue;
  401. X    register int i;
  402. X    int ResSize;
  403. X
  404. X    FirstStart = BuffEnd;
  405. X    /* find the earliest point which has not been
  406. X    * completely searched */
  407. X    for (i=0; i < NPats; i++) {
  408. X        FirstStart = 
  409. X            min(FirstStart, DescVec[i]-> Start );
  410. X    } /* for */
  411. X    /* now scan to the beginning of the line containing the
  412. X    * unsearched text */
  413. X    for (Residue = FirstStart; *Residue != '\n' &&
  414. X    Residue >= Buffer; Residue--);
  415. X    if (Residue < Buffer)
  416. X        Residue = FirstStart;
  417. X    else ++Residue;
  418. X    /* now move the residue to the beginning of
  419. X    * the file */
  420. X    ResSize = BuffEnd - Residue + 1;
  421. X    bcopy(Residue, Buffer, ResSize);
  422. X    /* now fix the status vectors */
  423. X    for (i=0; i < NPats; i++) {
  424. X        DescVec[i]->Start -= (Residue - Buffer);
  425. X    } /* for */
  426. X    return(ResSize);
  427. X} /* MoveResidue */
  428. e-o-f
  429. echo Extracting PrintLine.c
  430. sed 's/^X//' > PrintLine.c << 'e-o-f'
  431. X#include <stdio.h>
  432. X#include <strings.h>
  433. X#include "Extern.h"
  434. XPrintLine(OffSet,LineStart,LineEnd)
  435. Xint OffSet; /* offset of LineStart from beginning of file */
  436. Xchar *LineStart,
  437. X    *LineEnd;
  438. X{
  439. X    char OffStr[80];
  440. X    if (lFlag) {
  441. X        sprintf(OffStr,"%s\n",FileName);
  442. X        write(1,OffStr,strlen(OffStr));
  443. X        return;
  444. X    } /* if */
  445. X    if (FileName && !hFlag) {
  446. X        sprintf(OffStr,"%s: ",FileName);
  447. X        write(1,OffStr,strlen(OffStr));
  448. X    } /* if */
  449. X    if (nFlag) {
  450. X        sprintf(OffStr,"%d: ",OffSet);
  451. X        write(1,OffStr,strlen(OffStr));
  452. X    } /* if */
  453. X    write(1,LineStart,LineEnd-LineStart+1);
  454. X    if (*LineEnd != '\n') write (1,"\n",1);
  455. X} /* PrintLine */
  456. e-o-f
  457. echo Extracting PutUsage.c
  458. sed 's/^X//' > PutUsage.c << 'e-o-f'
  459. X#include <stdio.h>
  460. XPutUsage()
  461. X{
  462. X    fprintf(stderr,
  463. X    "match: search for a given string or strings in a file or files\n");
  464. X    fprintf(stderr,
  465. X    "synopsis: match [option]* [string(s)] [file]*\n");
  466. X    fprintf(stderr,
  467. X    "options:\n");
  468. X    fprintf(stderr,
  469. X    "-c print only a count of matching lines \n");
  470. X    fprintf(stderr,
  471. X    "-e Take next argument as the pattern\n");
  472. X    fprintf(stderr,
  473. X    "-f PFile read patterns from a file PFile\n");
  474. X    fprintf(stderr,
  475. X    "-h Do not print file names\n");
  476. X    fprintf(stderr,
  477. X    "-l print a list of files containing the pattern(s) \n");
  478. X    fprintf(stderr,
  479. X    "-n print the character offset of the pattern(s) \n");
  480. X    fprintf(stderr,
  481. X    "-s silent mode. Return only success (0) or failure (1)\n");
  482. X    fprintf(stderr,
  483. X    "-x print only lines which match entirely \n");
  484. X} /*PutUsage */
  485. e-o-f
  486. echo Extracting Search.s
  487. sed 's/^X//' > Search.s << 'e-o-f'
  488. XLL0:
  489. X    .data
  490. X    .text
  491. X    .align    1
  492. X    .globl    _Search
  493. X_Search:
  494. X    .word    L20
  495. X    matchc    8(ap),*4(ap),16(ap),*12(ap)
  496. X    beql    match
  497. X    movl    20(ap),r0
  498. X    movl    r3,8(r0)
  499. X    movl    $0,r0
  500. X    ret
  501. Xmatch:
  502. X    movl    20(ap),r0
  503. X    movl    r3,8(r0)
  504. X    movl    $1,r0
  505. X    ret
  506. X    .set    L20,0xf00
  507. X    .data
  508. e-o-f
  509. echo Extracting Makefile
  510. sed 's/^X//' > Makefile << 'e-o-f'
  511. XCFLAGS =  -O
  512. XSOURCES =  Execute.c Extern.h\
  513. X    GetPatFile.c Global.c MakeDesc.c \
  514. X    match.h match.c MatchFound.c \
  515. X    MkDescVec.c MoveResidue.c PrintLine.c PutUsage.c Search.s
  516. XOBJECTS = Execute.o \
  517. X    GetPatFile.o Global.o MakeDesc.o \
  518. X    match.o MatchFound.o \
  519. X    MkDescVec.o MoveResidue.o Search.o PrintLine.o PutUsage.o
  520. XBASEFILES = $(SOURCES) Makefile README match.p
  521. Xmatch: $(OBJECTS)
  522. X    cc -o match $(CFLAGS) $(OBJECTS)
  523. Xshar:
  524. X    /usr/public/shar $(BASEFILES) >match.shar
  525. Xinstall: match
  526. X    install -c match /usr/public/match
  527. Xman: /usr/man/manp/match.p
  528. X/usr/man/manp/match.p: match.p
  529. X    rm -f /usr/man/manp/match.p
  530. X    cp match.p /usr/man/manp/match.p
  531. X    man match > /dev/null
  532. Xmatch.o: match.c match.h Extern.h
  533. XPutUsage.o: PutUsage.c match.h 
  534. XSearch.o: Search.s
  535. XExecute.o: Execute.c match.h 
  536. XMoveResidue.o: MoveResidue.c match.h Extern.h
  537. XMatchFound.o: MatchFound.c match.h Extern.h
  538. XPrintLine.o: PrintLine.c Extern.h
  539. XMkDescVec.o: MkDescVec.c match.h
  540. XGetPatFile.o: GetPatFile.c match.h
  541. XMakeDesc.o: MakeDesc.c match.h
  542. XGlobal.o: Global.c
  543. Xlisting:
  544. X    print -i $(SOURCES) Makefile
  545. Xclean:
  546. X    rm -f *.o match
  547. e-o-f
  548. echo Extracting README
  549. sed 's/^X//' > README << 'e-o-f'
  550. XMatch is a fast pattern matching utility, intended to be almost
  551. Xidentical in functionality to fgrep (ugh!) but much faster. It uses
  552. XMATCHC instruction on VAX computers. Apparently, it is faster than
  553. XBM only on the VAX 780 - on the Microvax it is much slower than bm.
  554. X
  555. XThe files are:
  556. XExecute.c: search a file for the patterns
  557. XExtern.h: declarations of externs
  558. XGetPatFile.c: read in patterns from a file and set up a vector of
  559. X    pattern descriptors
  560. XGlobal.c: global variables (complement to Extern.h)
  561. XMakeDesc.c: create a pattern descriptor for one pattern
  562. XMakefile: you can figure this one out for yourself
  563. XMatchFound.c: what to do when you actually FIND a pattern - print it,
  564. X    update flags, etc.
  565. XMkDescVec.c: make a vector of pattern descriptors, given a string
  566. X    of newline-separated patterns
  567. XMoveResidue.c: when you come to the end of the buffer, move the
  568. X    unsearched "residue" to the beginning and start again
  569. XPrintLine.c: print the appropriate stuff after finding a match
  570. XPutUsage.c: mini-man page.
  571. XREADME: this file
  572. XSearch.s: the guts. Calls MATCH
  573. Xmatch.c: mainline. mostly interpreting the command line and tidying
  574. X    up at the end. Calls Execute for each file.
  575. Xmatch.h: constants
  576. Xmatch.p: man page
  577. e-o-f
  578. echo Extracting match.p
  579. sed 's/^X//' > match.p << 'e-o-f'
  580. X.TH MATCH PUBLIC "11 July 1985"
  581. X.UC 4
  582. X.SH NAME
  583. Xmatch \- search a file for a string
  584. X.SH SYNOPSIS
  585. X.B /usr/public/match
  586. X[ option ] ...
  587. X[ strings ]
  588. X[ file ]
  589. X.SH DESCRIPTION
  590. X.I Match
  591. Xsearches the input
  592. X.I files
  593. X(standard input default) for lines matching a string.
  594. XNormally, each line found is copied to the standard output.
  595. XIt is blindingly fast.
  596. X.I Match
  597. Xstrings are fixed sequences of characters:
  598. Xthere are no wildcards, repetitions, or other features
  599. Xof regular expressions.
  600. XMatch is also case sensitive.
  601. XThe following options are recognized.
  602. X.TP
  603. X.B \-x
  604. X(Exact) only lines matched in their entirety are printed
  605. X.TP
  606. X.B \-l
  607. XThe names of files with matching lines are listed (once) separated by newlines.
  608. X.TP
  609. X.B \-c
  610. XOnly a count of the number of matches
  611. Xis printed
  612. X.TP
  613. X.B \-e "string"
  614. XThe string is the next argument after the
  615. X.B \-e
  616. Xflag. This allows strings beginning with '-'.
  617. X.TP
  618. X.B \-h
  619. XNo filenames are printed, even if multiple files are searched.
  620. X.TP
  621. X.B \-n
  622. XEach line is preceded by the number
  623. Xof characters from the beginning of the file
  624. Xto the match.
  625. X.TP
  626. X.B \-s
  627. XSilent mode.  Nothing is printed (except error messages).
  628. XThis is useful for checking the error status.
  629. X.TP
  630. X.BI \-f " file"
  631. XThe string list
  632. Xis taken from the
  633. X.I file.
  634. X.LP
  635. XUnless the
  636. X.B \-h
  637. Xoption is specified
  638. Xthe file name is shown if there is more than one input file.
  639. XCare should be taken when using the characters $ * [ ^ | ( ) and \\ in the
  640. X.I strings
  641. X(listed on the command line)
  642. Xas they are also meaningful to the Shell.  It is safest to enclose the entire
  643. X.I expression
  644. Xargument in single quotes \' \'.
  645. X.LP
  646. X.I Match
  647. Xsearches for lines that contain one of the (newline-separated)
  648. X.I strings,
  649. Xusing
  650. Xthe VAX MATCHC instruction
  651. XIt is far superior in terms of speed to the grep (egrep, fgrep)
  652. Xfamily of pattern matchers, as well as bm(p) for fixed-pattern searching
  653. Xon a VAX 780.
  654. X.SH "SEE ALSO"
  655. Xgrep(1), bm(p)
  656. X.SH DIAGNOSTICS
  657. XExit status is 0 if any matches are found,
  658. X1 if none, 2 for syntax errors or inaccessible files.
  659. X.SH AUTHOR
  660. XPeter Bain (pdbain@wateng)
  661. X.SH BUGS
  662. XWorks slowly on VAXen other than the 780, and doesn't work at all
  663. Xon other architectures.
  664. X.LP
  665. XOnly 100 patterns are allowed.
  666. X.LP
  667. XPatterns may not contain newlines.
  668. X.LP
  669. XIf a line (delimited by newlines, and the beginning and end of the file)
  670. Xis longer than 8000 charcters (e.g. in a core dump),
  671. Xit will not be completely printed.
  672. X.LP
  673. XIf multiple patterns are specified, the order of the ouput lines is not
  674. Xnecessarily the same as the order of the input lines.
  675. X.LP
  676. XA line will be printed once for each different string on that line.
  677. X.LP
  678. XThe algorithm cannot count lines.
  679. X.LP
  680. XThe
  681. X.B -n
  682. Xand
  683. X.B -c
  684. Xwork differently from fgrep.
  685. X.LP
  686. XThe
  687. X.B -v,
  688. X.B -i,
  689. Xand
  690. X.B -b
  691. Xare not available.
  692. e-o-f
  693. exit 0
  694. -- 
  695.    - peter bain
  696. ...!{allegra|decvax|clyde|ihnp4 }!watmath!wateng!pdbain
  697. hard mail:    CCNG, CPH-2369A, University of Waterloo,
  698.     Waterloo, Ont. Canada N2M 5G4
  699. telephone:    (519) 885-1211 x2810
  700.  
  701.  
  702.