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