annotate 3rdparty/packages/ed/amatch.c @ 994:bef1844de0dc

The ED editor ported from Minix
author roug
date Sun, 23 Feb 2003 21:11:37 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
994
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
1 /* amatch.c */
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
2 #include <stdio.h>
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
3 #include "tools.h"
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
4
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
5 /* Scans throught the pattern template looking for a match
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
6 * with lin. Each element of lin is compared with the template
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
7 * until either a mis-match is found or the end of the template
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
8 * is reached. In the former case a 0 is returned; in the latter,
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
9 * a pointer into lin (pointing to the character following the
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
10 * matched pattern) is returned.
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
11 *
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
12 * "lin" is a pointer to the line being searched.
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
13 * "pat" is a pointer to a template made by makepat().
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
14 * "boln" is a pointer into "lin" which points at the
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
15 * character at the beginning of the line.
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
16 */
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
17 static char *match(); /* Predeclaration */
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
18
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
19 char *paropen[9], *parclose[9];
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
20 int between, parnum;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
21
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
22 char *amatch(lin, pat, boln)
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
23 char *lin;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
24 TOKEN *pat;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
25 char *boln;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
26 {
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
27 between = 0;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
28 parnum = 0;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
29
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
30 lin = match(lin, pat, boln);
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
31
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
32 if (between) return 0;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
33
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
34 while (parnum < 9) {
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
35 paropen[parnum] = parclose[parnum] = "";
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
36 parnum++;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
37 }
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
38 return lin;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
39 }
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
40
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
41 static char *match(lin, pat, boln)
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
42 char *lin;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
43 TOKEN *pat;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
44 char *boln;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
45 {
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
46 register char *bocl, *rval, *strstart;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
47
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
48 if (pat == 0) return 0;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
49
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
50 strstart = lin;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
51
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
52 while (pat) {
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
53 if (pat->tok == CLOSURE && pat->next) {
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
54 /* Process a closure: first skip over the closure
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
55 * token to the object to be repeated. This object
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
56 * can be a character class. */
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
57
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
58 pat = pat->next;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
59
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
60 /* Now match as many occurrences of the closure
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
61 * pattern as possible. */
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
62 bocl = lin;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
63
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
64 while (*lin && omatch(&lin, pat, boln));
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
65
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
66 /* 'Lin' now points to the character that made made
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
67 * us fail. Now go on to process the rest of the
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
68 * string. A problem here is a character following
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
69 * the closure which could have been in the closure.
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
70 * For example, in the pattern "[a-z]*t" (which
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
71 * matches any lower-case word ending in a t), the
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
72 * final 't' will be sucked up in the while loop.
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
73 * So, if the match fails, we back up a notch and try
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
74 * to match the rest of the string again, repeating
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
75 * this process recursively until we get back to the
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
76 * beginning of the closure. The recursion goes, at
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
77 * most two levels deep. */
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
78
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
79 if (pat = pat->next) {
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
80 int savbtwn = between;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
81 int savprnm = parnum;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
82
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
83 while (bocl <= lin) {
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
84 if (rval = match(lin, pat, boln)) {
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
85 /* Success */
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
86 return(rval);
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
87 } else {
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
88 --lin;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
89 between = savbtwn;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
90 parnum = savprnm;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
91 }
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
92 }
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
93 return(0); /* match failed */
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
94 }
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
95 } else if (pat->tok == OPEN) {
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
96 if (between || parnum >= 9) return 0;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
97 paropen[parnum] = lin;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
98 between = 1;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
99 pat = pat->next;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
100 } else if (pat->tok == CLOSE) {
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
101 if (!between) return 0;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
102 parclose[parnum++] = lin;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
103 between = 0;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
104 pat = pat->next;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
105 } else if (omatch(&lin, pat, boln)) {
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
106 pat = pat->next;
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
107 } else {
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
108 return(0);
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
109 }
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
110 }
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
111
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
112 /* Note that omatch() advances lin to point at the next character to
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
113 * be matched. Consequently, when we reach the end of the template,
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
114 * lin will be pointing at the character following the last character
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
115 * matched. The exceptions are templates containing only a BOLN or
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
116 * EOLN token. In these cases omatch doesn't advance.
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
117 *
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
118 * A philosophical point should be mentioned here. Is $ a position or a
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
119 * character? (i.e. does $ mean the EOL character itself or does it
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
120 * mean the character at the end of the line.) I decided here to
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
121 * make it mean the former, in order to make the behavior of match()
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
122 * consistent. If you give match the pattern ^$ (match all lines
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
123 * consisting only of an end of line) then, since something has to be
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
124 * returned, a pointer to the end of line character itself is
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
125 * returned. */
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
126
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
127 return((char *) max(strstart, lin));
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
128 }
bef1844de0dc The ED editor ported from Minix
roug
parents:
diff changeset
129