Mercurial > hg > Members > kono > nitros9-code
view 3rdparty/packages/ed/amatch.c @ 3158:927ba5ebc06e
mc09 l2: move MMU bit-field defines to defs file.
author | Neal Crook <foofoobedoo@gmail.com> |
---|---|
date | Thu, 06 Apr 2017 21:43:58 +0100 |
parents | bef1844de0dc |
children |
line wrap: on
line source
/* amatch.c */ #include <stdio.h> #include "tools.h" /* Scans throught the pattern template looking for a match * with lin. Each element of lin is compared with the template * until either a mis-match is found or the end of the template * is reached. In the former case a 0 is returned; in the latter, * a pointer into lin (pointing to the character following the * matched pattern) is returned. * * "lin" is a pointer to the line being searched. * "pat" is a pointer to a template made by makepat(). * "boln" is a pointer into "lin" which points at the * character at the beginning of the line. */ static char *match(); /* Predeclaration */ char *paropen[9], *parclose[9]; int between, parnum; char *amatch(lin, pat, boln) char *lin; TOKEN *pat; char *boln; { between = 0; parnum = 0; lin = match(lin, pat, boln); if (between) return 0; while (parnum < 9) { paropen[parnum] = parclose[parnum] = ""; parnum++; } return lin; } static char *match(lin, pat, boln) char *lin; TOKEN *pat; char *boln; { register char *bocl, *rval, *strstart; if (pat == 0) return 0; strstart = lin; while (pat) { if (pat->tok == CLOSURE && pat->next) { /* Process a closure: first skip over the closure * token to the object to be repeated. This object * can be a character class. */ pat = pat->next; /* Now match as many occurrences of the closure * pattern as possible. */ bocl = lin; while (*lin && omatch(&lin, pat, boln)); /* 'Lin' now points to the character that made made * us fail. Now go on to process the rest of the * string. A problem here is a character following * the closure which could have been in the closure. * For example, in the pattern "[a-z]*t" (which * matches any lower-case word ending in a t), the * final 't' will be sucked up in the while loop. * So, if the match fails, we back up a notch and try * to match the rest of the string again, repeating * this process recursively until we get back to the * beginning of the closure. The recursion goes, at * most two levels deep. */ if (pat = pat->next) { int savbtwn = between; int savprnm = parnum; while (bocl <= lin) { if (rval = match(lin, pat, boln)) { /* Success */ return(rval); } else { --lin; between = savbtwn; parnum = savprnm; } } return(0); /* match failed */ } } else if (pat->tok == OPEN) { if (between || parnum >= 9) return 0; paropen[parnum] = lin; between = 1; pat = pat->next; } else if (pat->tok == CLOSE) { if (!between) return 0; parclose[parnum++] = lin; between = 0; pat = pat->next; } else if (omatch(&lin, pat, boln)) { pat = pat->next; } else { return(0); } } /* Note that omatch() advances lin to point at the next character to * be matched. Consequently, when we reach the end of the template, * lin will be pointing at the character following the last character * matched. The exceptions are templates containing only a BOLN or * EOLN token. In these cases omatch doesn't advance. * * A philosophical point should be mentioned here. Is $ a position or a * character? (i.e. does $ mean the EOL character itself or does it * mean the character at the end of the line.) I decided here to * make it mean the former, in order to make the behavior of match() * consistent. If you give match the pattern ^$ (match all lines * consisting only of an end of line) then, since something has to be * returned, a pointer to the end of line character itself is * returned. */ return((char *) max(strstart, lin)); }