1333fc21eSDavid E. O'Brien #include <sys/cdefs.h> 2333fc21eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 3333fc21eSDavid E. O'Brien 48ca5c256SDaniel C. Sobral #include <sys/types.h> 58ca5c256SDaniel C. Sobral #include <assert.h> 6*1dce0e77SEnji Cooper #include <regex.h> 7*1dce0e77SEnji Cooper #include <stdio.h> 8*1dce0e77SEnji Cooper #include <stdlib.h> 9*1dce0e77SEnji Cooper #include <string.h> 10*1dce0e77SEnji Cooper #include <unistd.h> 118ca5c256SDaniel C. Sobral 128ca5c256SDaniel C. Sobral #include "main.ih" 138ca5c256SDaniel C. Sobral 148ca5c256SDaniel C. Sobral char *progname; 158ca5c256SDaniel C. Sobral int debug = 0; 168ca5c256SDaniel C. Sobral int line = 0; 178ca5c256SDaniel C. Sobral int status = 0; 188ca5c256SDaniel C. Sobral 198ca5c256SDaniel C. Sobral int copts = REG_EXTENDED; 208ca5c256SDaniel C. Sobral int eopts = 0; 218ca5c256SDaniel C. Sobral regoff_t startoff = 0; 228ca5c256SDaniel C. Sobral regoff_t endoff = 0; 238ca5c256SDaniel C. Sobral 248ca5c256SDaniel C. Sobral 258ca5c256SDaniel C. Sobral extern int split(); 268ca5c256SDaniel C. Sobral extern void regprint(); 278ca5c256SDaniel C. Sobral 288ca5c256SDaniel C. Sobral /* 298ca5c256SDaniel C. Sobral - main - do the simple case, hand off to regress() for regression 308ca5c256SDaniel C. Sobral */ 31f76918a8SEnji Cooper int 32f76918a8SEnji Cooper main(int argc, char **argv) 338ca5c256SDaniel C. Sobral { 348ca5c256SDaniel C. Sobral regex_t re; 358ca5c256SDaniel C. Sobral # define NS 10 368ca5c256SDaniel C. Sobral regmatch_t subs[NS]; 378ca5c256SDaniel C. Sobral char erbuf[100]; 388ca5c256SDaniel C. Sobral int err; 398ca5c256SDaniel C. Sobral size_t len; 408ca5c256SDaniel C. Sobral int c; 418ca5c256SDaniel C. Sobral int errflg = 0; 428fb3f3f6SDavid E. O'Brien int i; 438ca5c256SDaniel C. Sobral extern int optind; 448ca5c256SDaniel C. Sobral extern char *optarg; 458ca5c256SDaniel C. Sobral 468ca5c256SDaniel C. Sobral progname = argv[0]; 478ca5c256SDaniel C. Sobral 488f9872ccSKevin Lo while ((c = getopt(argc, argv, "c:e:S:E:x")) != -1) 498ca5c256SDaniel C. Sobral switch (c) { 508ca5c256SDaniel C. Sobral case 'c': /* compile options */ 518ca5c256SDaniel C. Sobral copts = options('c', optarg); 528ca5c256SDaniel C. Sobral break; 538ca5c256SDaniel C. Sobral case 'e': /* execute options */ 548ca5c256SDaniel C. Sobral eopts = options('e', optarg); 558ca5c256SDaniel C. Sobral break; 568ca5c256SDaniel C. Sobral case 'S': /* start offset */ 578ca5c256SDaniel C. Sobral startoff = (regoff_t)atoi(optarg); 588ca5c256SDaniel C. Sobral break; 598ca5c256SDaniel C. Sobral case 'E': /* end offset */ 608ca5c256SDaniel C. Sobral endoff = (regoff_t)atoi(optarg); 618ca5c256SDaniel C. Sobral break; 628ca5c256SDaniel C. Sobral case 'x': /* Debugging. */ 638ca5c256SDaniel C. Sobral debug++; 648ca5c256SDaniel C. Sobral break; 658ca5c256SDaniel C. Sobral case '?': 668ca5c256SDaniel C. Sobral default: 678ca5c256SDaniel C. Sobral errflg++; 688ca5c256SDaniel C. Sobral break; 698ca5c256SDaniel C. Sobral } 708ca5c256SDaniel C. Sobral if (errflg) { 718ca5c256SDaniel C. Sobral fprintf(stderr, "usage: %s ", progname); 728ca5c256SDaniel C. Sobral fprintf(stderr, "[-c copt][-C][-d] [re]\n"); 738ca5c256SDaniel C. Sobral exit(2); 748ca5c256SDaniel C. Sobral } 758ca5c256SDaniel C. Sobral 768ca5c256SDaniel C. Sobral if (optind >= argc) { 778ca5c256SDaniel C. Sobral regress(stdin); 788ca5c256SDaniel C. Sobral exit(status); 798ca5c256SDaniel C. Sobral } 808ca5c256SDaniel C. Sobral 818ca5c256SDaniel C. Sobral err = regcomp(&re, argv[optind++], copts); 828ca5c256SDaniel C. Sobral if (err) { 838ca5c256SDaniel C. Sobral len = regerror(err, &re, erbuf, sizeof(erbuf)); 848ca5c256SDaniel C. Sobral fprintf(stderr, "error %s, %d/%d `%s'\n", 858ca5c256SDaniel C. Sobral eprint(err), len, sizeof(erbuf), erbuf); 868ca5c256SDaniel C. Sobral exit(status); 878ca5c256SDaniel C. Sobral } 888ca5c256SDaniel C. Sobral regprint(&re, stdout); 898ca5c256SDaniel C. Sobral 908ca5c256SDaniel C. Sobral if (optind >= argc) { 918ca5c256SDaniel C. Sobral regfree(&re); 928ca5c256SDaniel C. Sobral exit(status); 938ca5c256SDaniel C. Sobral } 948ca5c256SDaniel C. Sobral 958ca5c256SDaniel C. Sobral if (eopts®_STARTEND) { 968ca5c256SDaniel C. Sobral subs[0].rm_so = startoff; 978ca5c256SDaniel C. Sobral subs[0].rm_eo = strlen(argv[optind]) - endoff; 988ca5c256SDaniel C. Sobral } 998ca5c256SDaniel C. Sobral err = regexec(&re, argv[optind], (size_t)NS, subs, eopts); 1008ca5c256SDaniel C. Sobral if (err) { 1018ca5c256SDaniel C. Sobral len = regerror(err, &re, erbuf, sizeof(erbuf)); 1028ca5c256SDaniel C. Sobral fprintf(stderr, "error %s, %d/%d `%s'\n", 1038ca5c256SDaniel C. Sobral eprint(err), len, sizeof(erbuf), erbuf); 1048ca5c256SDaniel C. Sobral exit(status); 1058ca5c256SDaniel C. Sobral } 1068ca5c256SDaniel C. Sobral if (!(copts®_NOSUB)) { 1078ca5c256SDaniel C. Sobral len = (int)(subs[0].rm_eo - subs[0].rm_so); 1088ca5c256SDaniel C. Sobral if (subs[0].rm_so != -1) { 1098ca5c256SDaniel C. Sobral if (len != 0) 1108ca5c256SDaniel C. Sobral printf("match `%.*s'\n", len, 1118ca5c256SDaniel C. Sobral argv[optind] + subs[0].rm_so); 1128ca5c256SDaniel C. Sobral else 1138ca5c256SDaniel C. Sobral printf("match `'@%.1s\n", 1148ca5c256SDaniel C. Sobral argv[optind] + subs[0].rm_so); 1158ca5c256SDaniel C. Sobral } 1168ca5c256SDaniel C. Sobral for (i = 1; i < NS; i++) 1178ca5c256SDaniel C. Sobral if (subs[i].rm_so != -1) 1188ca5c256SDaniel C. Sobral printf("(%d) `%.*s'\n", i, 1198ca5c256SDaniel C. Sobral (int)(subs[i].rm_eo - subs[i].rm_so), 1208ca5c256SDaniel C. Sobral argv[optind] + subs[i].rm_so); 1218ca5c256SDaniel C. Sobral } 1228ca5c256SDaniel C. Sobral exit(status); 1238ca5c256SDaniel C. Sobral } 1248ca5c256SDaniel C. Sobral 1258ca5c256SDaniel C. Sobral /* 1268ca5c256SDaniel C. Sobral - regress - main loop of regression test 1278ca5c256SDaniel C. Sobral == void regress(FILE *in); 1288ca5c256SDaniel C. Sobral */ 1298ca5c256SDaniel C. Sobral void 130f76918a8SEnji Cooper regress(FILE *in) 1318ca5c256SDaniel C. Sobral { 1328ca5c256SDaniel C. Sobral char inbuf[1000]; 1338ca5c256SDaniel C. Sobral # define MAXF 10 1348ca5c256SDaniel C. Sobral char *f[MAXF]; 1358ca5c256SDaniel C. Sobral int nf; 1368ca5c256SDaniel C. Sobral int i; 1378ca5c256SDaniel C. Sobral char erbuf[100]; 1388ca5c256SDaniel C. Sobral size_t ne; 1398ca5c256SDaniel C. Sobral char *badpat = "invalid regular expression"; 1408ca5c256SDaniel C. Sobral # define SHORT 10 1418ca5c256SDaniel C. Sobral char *bpname = "REG_BADPAT"; 1428ca5c256SDaniel C. Sobral regex_t re; 1438ca5c256SDaniel C. Sobral 1448ca5c256SDaniel C. Sobral while (fgets(inbuf, sizeof(inbuf), in) != NULL) { 1458ca5c256SDaniel C. Sobral line++; 1468ca5c256SDaniel C. Sobral if (inbuf[0] == '#' || inbuf[0] == '\n') 1478ca5c256SDaniel C. Sobral continue; /* NOTE CONTINUE */ 1488ca5c256SDaniel C. Sobral inbuf[strlen(inbuf)-1] = '\0'; /* get rid of stupid \n */ 1498ca5c256SDaniel C. Sobral if (debug) 1508ca5c256SDaniel C. Sobral fprintf(stdout, "%d:\n", line); 1518ca5c256SDaniel C. Sobral nf = split(inbuf, f, MAXF, "\t\t"); 1528ca5c256SDaniel C. Sobral if (nf < 3) { 1538ca5c256SDaniel C. Sobral fprintf(stderr, "bad input, line %d\n", line); 1548ca5c256SDaniel C. Sobral exit(1); 1558ca5c256SDaniel C. Sobral } 1568ca5c256SDaniel C. Sobral for (i = 0; i < nf; i++) 1578ca5c256SDaniel C. Sobral if (strcmp(f[i], "\"\"") == 0) 1588ca5c256SDaniel C. Sobral f[i] = ""; 1598ca5c256SDaniel C. Sobral if (nf <= 3) 1608ca5c256SDaniel C. Sobral f[3] = NULL; 1618ca5c256SDaniel C. Sobral if (nf <= 4) 1628ca5c256SDaniel C. Sobral f[4] = NULL; 1638ca5c256SDaniel C. Sobral try(f[0], f[1], f[2], f[3], f[4], options('c', f[1])); 1648ca5c256SDaniel C. Sobral if (opt('&', f[1])) /* try with either type of RE */ 1658ca5c256SDaniel C. Sobral try(f[0], f[1], f[2], f[3], f[4], 1668ca5c256SDaniel C. Sobral options('c', f[1]) &~ REG_EXTENDED); 1678ca5c256SDaniel C. Sobral } 1688ca5c256SDaniel C. Sobral 1698ca5c256SDaniel C. Sobral ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, sizeof(erbuf)); 1708ca5c256SDaniel C. Sobral if (strcmp(erbuf, badpat) != 0 || ne != strlen(badpat)+1) { 1718ca5c256SDaniel C. Sobral fprintf(stderr, "end: regerror() test gave `%s' not `%s'\n", 1728ca5c256SDaniel C. Sobral erbuf, badpat); 1738ca5c256SDaniel C. Sobral status = 1; 1748ca5c256SDaniel C. Sobral } 1758ca5c256SDaniel C. Sobral ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, (size_t)SHORT); 1768ca5c256SDaniel C. Sobral if (strncmp(erbuf, badpat, SHORT-1) != 0 || erbuf[SHORT-1] != '\0' || 1778ca5c256SDaniel C. Sobral ne != strlen(badpat)+1) { 1788ca5c256SDaniel C. Sobral fprintf(stderr, "end: regerror() short test gave `%s' not `%.*s'\n", 1798ca5c256SDaniel C. Sobral erbuf, SHORT-1, badpat); 1808ca5c256SDaniel C. Sobral status = 1; 1818ca5c256SDaniel C. Sobral } 1828ca5c256SDaniel C. Sobral ne = regerror(REG_ITOA|REG_BADPAT, (regex_t *)NULL, erbuf, sizeof(erbuf)); 1838ca5c256SDaniel C. Sobral if (strcmp(erbuf, bpname) != 0 || ne != strlen(bpname)+1) { 1848ca5c256SDaniel C. Sobral fprintf(stderr, "end: regerror() ITOA test gave `%s' not `%s'\n", 1858ca5c256SDaniel C. Sobral erbuf, bpname); 1868ca5c256SDaniel C. Sobral status = 1; 1878ca5c256SDaniel C. Sobral } 1888ca5c256SDaniel C. Sobral re.re_endp = bpname; 1898ca5c256SDaniel C. Sobral ne = regerror(REG_ATOI, &re, erbuf, sizeof(erbuf)); 1908ca5c256SDaniel C. Sobral if (atoi(erbuf) != (int)REG_BADPAT) { 1918ca5c256SDaniel C. Sobral fprintf(stderr, "end: regerror() ATOI test gave `%s' not `%ld'\n", 1928ca5c256SDaniel C. Sobral erbuf, (long)REG_BADPAT); 1938ca5c256SDaniel C. Sobral status = 1; 1948ca5c256SDaniel C. Sobral } else if (ne != strlen(erbuf)+1) { 1958ca5c256SDaniel C. Sobral fprintf(stderr, "end: regerror() ATOI test len(`%s') = %ld\n", 1968ca5c256SDaniel C. Sobral erbuf, (long)REG_BADPAT); 1978ca5c256SDaniel C. Sobral status = 1; 1988ca5c256SDaniel C. Sobral } 1998ca5c256SDaniel C. Sobral } 2008ca5c256SDaniel C. Sobral 2018ca5c256SDaniel C. Sobral /* 2028ca5c256SDaniel C. Sobral - try - try it, and report on problems 2038ca5c256SDaniel C. Sobral == void try(char *f0, char *f1, char *f2, char *f3, char *f4, int opts); 204f76918a8SEnji Cooper - opts: may not match f1 2058ca5c256SDaniel C. Sobral */ 2068ca5c256SDaniel C. Sobral void 207f76918a8SEnji Cooper try(char *f0, char *f1, char *f2, char *f3, char *f4, int opts) 2088ca5c256SDaniel C. Sobral { 2098ca5c256SDaniel C. Sobral regex_t re; 2108ca5c256SDaniel C. Sobral # define NSUBS 10 2118ca5c256SDaniel C. Sobral regmatch_t subs[NSUBS]; 2128ca5c256SDaniel C. Sobral # define NSHOULD 15 2138ca5c256SDaniel C. Sobral char *should[NSHOULD]; 2148ca5c256SDaniel C. Sobral int nshould; 2158ca5c256SDaniel C. Sobral char erbuf[100]; 2168ca5c256SDaniel C. Sobral int err; 2178ca5c256SDaniel C. Sobral int len; 2188ca5c256SDaniel C. Sobral char *type = (opts & REG_EXTENDED) ? "ERE" : "BRE"; 2198fb3f3f6SDavid E. O'Brien int i; 2208ca5c256SDaniel C. Sobral char *grump; 2218ca5c256SDaniel C. Sobral char f0copy[1000]; 2228ca5c256SDaniel C. Sobral char f2copy[1000]; 2238ca5c256SDaniel C. Sobral 2248ca5c256SDaniel C. Sobral strcpy(f0copy, f0); 2258ca5c256SDaniel C. Sobral re.re_endp = (opts®_PEND) ? f0copy + strlen(f0copy) : NULL; 2268ca5c256SDaniel C. Sobral fixstr(f0copy); 2278ca5c256SDaniel C. Sobral err = regcomp(&re, f0copy, opts); 2288ca5c256SDaniel C. Sobral if (err != 0 && (!opt('C', f1) || err != efind(f2))) { 2298ca5c256SDaniel C. Sobral /* unexpected error or wrong error */ 2308ca5c256SDaniel C. Sobral len = regerror(err, &re, erbuf, sizeof(erbuf)); 2318ca5c256SDaniel C. Sobral fprintf(stderr, "%d: %s error %s, %d/%d `%s'\n", 2328ca5c256SDaniel C. Sobral line, type, eprint(err), len, 2338ca5c256SDaniel C. Sobral sizeof(erbuf), erbuf); 2348ca5c256SDaniel C. Sobral status = 1; 2358ca5c256SDaniel C. Sobral } else if (err == 0 && opt('C', f1)) { 2368ca5c256SDaniel C. Sobral /* unexpected success */ 2378ca5c256SDaniel C. Sobral fprintf(stderr, "%d: %s should have given REG_%s\n", 2388ca5c256SDaniel C. Sobral line, type, f2); 2398ca5c256SDaniel C. Sobral status = 1; 2408ca5c256SDaniel C. Sobral err = 1; /* so we won't try regexec */ 2418ca5c256SDaniel C. Sobral } 2428ca5c256SDaniel C. Sobral 2438ca5c256SDaniel C. Sobral if (err != 0) { 2448ca5c256SDaniel C. Sobral regfree(&re); 2458ca5c256SDaniel C. Sobral return; 2468ca5c256SDaniel C. Sobral } 2478ca5c256SDaniel C. Sobral 2488ca5c256SDaniel C. Sobral strcpy(f2copy, f2); 2498ca5c256SDaniel C. Sobral fixstr(f2copy); 2508ca5c256SDaniel C. Sobral 2518ca5c256SDaniel C. Sobral if (options('e', f1)®_STARTEND) { 2528ca5c256SDaniel C. Sobral if (strchr(f2, '(') == NULL || strchr(f2, ')') == NULL) 2538ca5c256SDaniel C. Sobral fprintf(stderr, "%d: bad STARTEND syntax\n", line); 2548ca5c256SDaniel C. Sobral subs[0].rm_so = strchr(f2, '(') - f2 + 1; 2558ca5c256SDaniel C. Sobral subs[0].rm_eo = strchr(f2, ')') - f2; 2568ca5c256SDaniel C. Sobral } 2578ca5c256SDaniel C. Sobral err = regexec(&re, f2copy, NSUBS, subs, options('e', f1)); 2588ca5c256SDaniel C. Sobral 2598ca5c256SDaniel C. Sobral if (err != 0 && (f3 != NULL || err != REG_NOMATCH)) { 2608ca5c256SDaniel C. Sobral /* unexpected error or wrong error */ 2618ca5c256SDaniel C. Sobral len = regerror(err, &re, erbuf, sizeof(erbuf)); 2628ca5c256SDaniel C. Sobral fprintf(stderr, "%d: %s exec error %s, %d/%d `%s'\n", 2638ca5c256SDaniel C. Sobral line, type, eprint(err), len, 2648ca5c256SDaniel C. Sobral sizeof(erbuf), erbuf); 2658ca5c256SDaniel C. Sobral status = 1; 2668ca5c256SDaniel C. Sobral } else if (err != 0) { 2678ca5c256SDaniel C. Sobral /* nothing more to check */ 2688ca5c256SDaniel C. Sobral } else if (f3 == NULL) { 2698ca5c256SDaniel C. Sobral /* unexpected success */ 2708ca5c256SDaniel C. Sobral fprintf(stderr, "%d: %s exec should have failed\n", 2718ca5c256SDaniel C. Sobral line, type); 2728ca5c256SDaniel C. Sobral status = 1; 2738ca5c256SDaniel C. Sobral err = 1; /* just on principle */ 2748ca5c256SDaniel C. Sobral } else if (opts®_NOSUB) { 2758ca5c256SDaniel C. Sobral /* nothing more to check */ 2768ca5c256SDaniel C. Sobral } else if ((grump = check(f2, subs[0], f3)) != NULL) { 2778ca5c256SDaniel C. Sobral fprintf(stderr, "%d: %s %s\n", line, type, grump); 2788ca5c256SDaniel C. Sobral status = 1; 2798ca5c256SDaniel C. Sobral err = 1; 2808ca5c256SDaniel C. Sobral } 2818ca5c256SDaniel C. Sobral 2828ca5c256SDaniel C. Sobral if (err != 0 || f4 == NULL) { 2838ca5c256SDaniel C. Sobral regfree(&re); 2848ca5c256SDaniel C. Sobral return; 2858ca5c256SDaniel C. Sobral } 2868ca5c256SDaniel C. Sobral 2878ca5c256SDaniel C. Sobral for (i = 1; i < NSHOULD; i++) 2888ca5c256SDaniel C. Sobral should[i] = NULL; 2898ca5c256SDaniel C. Sobral nshould = split(f4, should+1, NSHOULD-1, ","); 2908ca5c256SDaniel C. Sobral if (nshould == 0) { 2918ca5c256SDaniel C. Sobral nshould = 1; 2928ca5c256SDaniel C. Sobral should[1] = ""; 2938ca5c256SDaniel C. Sobral } 2948ca5c256SDaniel C. Sobral for (i = 1; i < NSUBS; i++) { 2958ca5c256SDaniel C. Sobral grump = check(f2, subs[i], should[i]); 2968ca5c256SDaniel C. Sobral if (grump != NULL) { 2978ca5c256SDaniel C. Sobral fprintf(stderr, "%d: %s $%d %s\n", line, 2988ca5c256SDaniel C. Sobral type, i, grump); 2998ca5c256SDaniel C. Sobral status = 1; 3008ca5c256SDaniel C. Sobral err = 1; 3018ca5c256SDaniel C. Sobral } 3028ca5c256SDaniel C. Sobral } 3038ca5c256SDaniel C. Sobral 3048ca5c256SDaniel C. Sobral regfree(&re); 3058ca5c256SDaniel C. Sobral } 3068ca5c256SDaniel C. Sobral 3078ca5c256SDaniel C. Sobral /* 3088ca5c256SDaniel C. Sobral - options - pick options out of a regression-test string 309f76918a8SEnji Cooper - type: 'c' - compile, 'e' - exec 3108ca5c256SDaniel C. Sobral == int options(int type, char *s); 3118ca5c256SDaniel C. Sobral */ 3128ca5c256SDaniel C. Sobral int 313f76918a8SEnji Cooper options(int type, char *s) 3148ca5c256SDaniel C. Sobral { 3158fb3f3f6SDavid E. O'Brien char *p; 3168fb3f3f6SDavid E. O'Brien int o = (type == 'c') ? copts : eopts; 3178fb3f3f6SDavid E. O'Brien char *legal = (type == 'c') ? "bisnmp" : "^$#tl"; 3188ca5c256SDaniel C. Sobral 3198ca5c256SDaniel C. Sobral for (p = s; *p != '\0'; p++) 3208ca5c256SDaniel C. Sobral if (strchr(legal, *p) != NULL) 3218ca5c256SDaniel C. Sobral switch (*p) { 3228ca5c256SDaniel C. Sobral case 'b': 3238ca5c256SDaniel C. Sobral o &= ~REG_EXTENDED; 3248ca5c256SDaniel C. Sobral break; 3258ca5c256SDaniel C. Sobral case 'i': 3268ca5c256SDaniel C. Sobral o |= REG_ICASE; 3278ca5c256SDaniel C. Sobral break; 3288ca5c256SDaniel C. Sobral case 's': 3298ca5c256SDaniel C. Sobral o |= REG_NOSUB; 3308ca5c256SDaniel C. Sobral break; 3318ca5c256SDaniel C. Sobral case 'n': 3328ca5c256SDaniel C. Sobral o |= REG_NEWLINE; 3338ca5c256SDaniel C. Sobral break; 3348ca5c256SDaniel C. Sobral case 'm': 3358ca5c256SDaniel C. Sobral o &= ~REG_EXTENDED; 3368ca5c256SDaniel C. Sobral o |= REG_NOSPEC; 3378ca5c256SDaniel C. Sobral break; 3388ca5c256SDaniel C. Sobral case 'p': 3398ca5c256SDaniel C. Sobral o |= REG_PEND; 3408ca5c256SDaniel C. Sobral break; 3418ca5c256SDaniel C. Sobral case '^': 3428ca5c256SDaniel C. Sobral o |= REG_NOTBOL; 3438ca5c256SDaniel C. Sobral break; 3448ca5c256SDaniel C. Sobral case '$': 3458ca5c256SDaniel C. Sobral o |= REG_NOTEOL; 3468ca5c256SDaniel C. Sobral break; 3478ca5c256SDaniel C. Sobral case '#': 3488ca5c256SDaniel C. Sobral o |= REG_STARTEND; 3498ca5c256SDaniel C. Sobral break; 3508ca5c256SDaniel C. Sobral case 't': /* trace */ 3518ca5c256SDaniel C. Sobral o |= REG_TRACE; 3528ca5c256SDaniel C. Sobral break; 3538ca5c256SDaniel C. Sobral case 'l': /* force long representation */ 3548ca5c256SDaniel C. Sobral o |= REG_LARGE; 3558ca5c256SDaniel C. Sobral break; 3568ca5c256SDaniel C. Sobral case 'r': /* force backref use */ 3578ca5c256SDaniel C. Sobral o |= REG_BACKR; 3588ca5c256SDaniel C. Sobral break; 3598ca5c256SDaniel C. Sobral } 3608ca5c256SDaniel C. Sobral return(o); 3618ca5c256SDaniel C. Sobral } 3628ca5c256SDaniel C. Sobral 3638ca5c256SDaniel C. Sobral /* 3648ca5c256SDaniel C. Sobral - opt - is a particular option in a regression string? 3658ca5c256SDaniel C. Sobral == int opt(int c, char *s); 3668ca5c256SDaniel C. Sobral */ 3678ca5c256SDaniel C. Sobral int /* predicate */ 368f76918a8SEnji Cooper opt(int c, char *s) 3698ca5c256SDaniel C. Sobral { 3708ca5c256SDaniel C. Sobral return(strchr(s, c) != NULL); 3718ca5c256SDaniel C. Sobral } 3728ca5c256SDaniel C. Sobral 3738ca5c256SDaniel C. Sobral /* 3748ca5c256SDaniel C. Sobral - fixstr - transform magic characters in strings 3758fb3f3f6SDavid E. O'Brien == void fixstr(char *p); 3768ca5c256SDaniel C. Sobral */ 3778ca5c256SDaniel C. Sobral void 378f76918a8SEnji Cooper fixstr(char *p) 3798ca5c256SDaniel C. Sobral { 3808ca5c256SDaniel C. Sobral if (p == NULL) 3818ca5c256SDaniel C. Sobral return; 3828ca5c256SDaniel C. Sobral 3838ca5c256SDaniel C. Sobral for (; *p != '\0'; p++) 3848ca5c256SDaniel C. Sobral if (*p == 'N') 3858ca5c256SDaniel C. Sobral *p = '\n'; 3868ca5c256SDaniel C. Sobral else if (*p == 'T') 3878ca5c256SDaniel C. Sobral *p = '\t'; 3888ca5c256SDaniel C. Sobral else if (*p == 'S') 3898ca5c256SDaniel C. Sobral *p = ' '; 3908ca5c256SDaniel C. Sobral else if (*p == 'Z') 3918ca5c256SDaniel C. Sobral *p = '\0'; 3928ca5c256SDaniel C. Sobral } 3938ca5c256SDaniel C. Sobral 3948ca5c256SDaniel C. Sobral /* 3958ca5c256SDaniel C. Sobral - check - check a substring match 3968ca5c256SDaniel C. Sobral == char *check(char *str, regmatch_t sub, char *should); 3978ca5c256SDaniel C. Sobral */ 3988ca5c256SDaniel C. Sobral char * /* NULL or complaint */ 399f76918a8SEnji Cooper check(char *str, regmatch_t sub, char *should) 4008ca5c256SDaniel C. Sobral { 4018fb3f3f6SDavid E. O'Brien int len; 4028fb3f3f6SDavid E. O'Brien int shlen; 4038fb3f3f6SDavid E. O'Brien char *p; 4048ca5c256SDaniel C. Sobral static char grump[500]; 4058fb3f3f6SDavid E. O'Brien char *at = NULL; 4068ca5c256SDaniel C. Sobral 4078ca5c256SDaniel C. Sobral if (should != NULL && strcmp(should, "-") == 0) 4088ca5c256SDaniel C. Sobral should = NULL; 4098ca5c256SDaniel C. Sobral if (should != NULL && should[0] == '@') { 4108ca5c256SDaniel C. Sobral at = should + 1; 4118ca5c256SDaniel C. Sobral should = ""; 4128ca5c256SDaniel C. Sobral } 4138ca5c256SDaniel C. Sobral 4148ca5c256SDaniel C. Sobral /* check rm_so and rm_eo for consistency */ 4158ca5c256SDaniel C. Sobral if (sub.rm_so > sub.rm_eo || (sub.rm_so == -1 && sub.rm_eo != -1) || 4168ca5c256SDaniel C. Sobral (sub.rm_so != -1 && sub.rm_eo == -1) || 4178ca5c256SDaniel C. Sobral (sub.rm_so != -1 && sub.rm_so < 0) || 4188ca5c256SDaniel C. Sobral (sub.rm_eo != -1 && sub.rm_eo < 0) ) { 4198ca5c256SDaniel C. Sobral sprintf(grump, "start %ld end %ld", (long)sub.rm_so, 4208ca5c256SDaniel C. Sobral (long)sub.rm_eo); 4218ca5c256SDaniel C. Sobral return(grump); 4228ca5c256SDaniel C. Sobral } 4238ca5c256SDaniel C. Sobral 4248ca5c256SDaniel C. Sobral /* check for no match */ 4258ca5c256SDaniel C. Sobral if (sub.rm_so == -1 && should == NULL) 4268ca5c256SDaniel C. Sobral return(NULL); 4278ca5c256SDaniel C. Sobral if (sub.rm_so == -1) 4288ca5c256SDaniel C. Sobral return("did not match"); 4298ca5c256SDaniel C. Sobral 4308ca5c256SDaniel C. Sobral /* check for in range */ 4318ca5c256SDaniel C. Sobral if (sub.rm_eo > strlen(str)) { 4328ca5c256SDaniel C. Sobral sprintf(grump, "start %ld end %ld, past end of string", 4338ca5c256SDaniel C. Sobral (long)sub.rm_so, (long)sub.rm_eo); 4348ca5c256SDaniel C. Sobral return(grump); 4358ca5c256SDaniel C. Sobral } 4368ca5c256SDaniel C. Sobral 4378ca5c256SDaniel C. Sobral len = (int)(sub.rm_eo - sub.rm_so); 4388ca5c256SDaniel C. Sobral shlen = (int)strlen(should); 4398ca5c256SDaniel C. Sobral p = str + sub.rm_so; 4408ca5c256SDaniel C. Sobral 4418ca5c256SDaniel C. Sobral /* check for not supposed to match */ 4428ca5c256SDaniel C. Sobral if (should == NULL) { 4438ca5c256SDaniel C. Sobral sprintf(grump, "matched `%.*s'", len, p); 4448ca5c256SDaniel C. Sobral return(grump); 4458ca5c256SDaniel C. Sobral } 4468ca5c256SDaniel C. Sobral 4478ca5c256SDaniel C. Sobral /* check for wrong match */ 4488ca5c256SDaniel C. Sobral if (len != shlen || strncmp(p, should, (size_t)shlen) != 0) { 4498ca5c256SDaniel C. Sobral sprintf(grump, "matched `%.*s' instead", len, p); 4508ca5c256SDaniel C. Sobral return(grump); 4518ca5c256SDaniel C. Sobral } 4528ca5c256SDaniel C. Sobral if (shlen > 0) 4538ca5c256SDaniel C. Sobral return(NULL); 4548ca5c256SDaniel C. Sobral 4558ca5c256SDaniel C. Sobral /* check null match in right place */ 4568ca5c256SDaniel C. Sobral if (at == NULL) 4578ca5c256SDaniel C. Sobral return(NULL); 4588ca5c256SDaniel C. Sobral shlen = strlen(at); 4598ca5c256SDaniel C. Sobral if (shlen == 0) 4608ca5c256SDaniel C. Sobral shlen = 1; /* force check for end-of-string */ 4618ca5c256SDaniel C. Sobral if (strncmp(p, at, shlen) != 0) { 4628ca5c256SDaniel C. Sobral sprintf(grump, "matched null at `%.20s'", p); 4638ca5c256SDaniel C. Sobral return(grump); 4648ca5c256SDaniel C. Sobral } 4658ca5c256SDaniel C. Sobral return(NULL); 4668ca5c256SDaniel C. Sobral } 4678ca5c256SDaniel C. Sobral 4688ca5c256SDaniel C. Sobral /* 4698ca5c256SDaniel C. Sobral - eprint - convert error number to name 4708ca5c256SDaniel C. Sobral == static char *eprint(int err); 4718ca5c256SDaniel C. Sobral */ 4728ca5c256SDaniel C. Sobral static char * 473f76918a8SEnji Cooper eprint(int err) 4748ca5c256SDaniel C. Sobral { 4758ca5c256SDaniel C. Sobral static char epbuf[100]; 4768ca5c256SDaniel C. Sobral size_t len; 4778ca5c256SDaniel C. Sobral 4788ca5c256SDaniel C. Sobral len = regerror(REG_ITOA|err, (regex_t *)NULL, epbuf, sizeof(epbuf)); 4798ca5c256SDaniel C. Sobral assert(len <= sizeof(epbuf)); 4808ca5c256SDaniel C. Sobral return(epbuf); 4818ca5c256SDaniel C. Sobral } 4828ca5c256SDaniel C. Sobral 4838ca5c256SDaniel C. Sobral /* 4848ca5c256SDaniel C. Sobral - efind - convert error name to number 4858ca5c256SDaniel C. Sobral == static int efind(char *name); 4868ca5c256SDaniel C. Sobral */ 4878ca5c256SDaniel C. Sobral static int 488f76918a8SEnji Cooper efind(char *name) 4898ca5c256SDaniel C. Sobral { 4908ca5c256SDaniel C. Sobral static char efbuf[100]; 4918ca5c256SDaniel C. Sobral size_t n; 4928ca5c256SDaniel C. Sobral regex_t re; 4938ca5c256SDaniel C. Sobral 4948ca5c256SDaniel C. Sobral sprintf(efbuf, "REG_%s", name); 4958ca5c256SDaniel C. Sobral assert(strlen(efbuf) < sizeof(efbuf)); 4968ca5c256SDaniel C. Sobral re.re_endp = efbuf; 4978ca5c256SDaniel C. Sobral (void) regerror(REG_ATOI, &re, efbuf, sizeof(efbuf)); 4988ca5c256SDaniel C. Sobral return(atoi(efbuf)); 4998ca5c256SDaniel C. Sobral } 500