18ca5c256SDaniel C. Sobral /* $FreeBSD$ 28ca5c256SDaniel C. Sobral */ 38ca5c256SDaniel C. Sobral #include <stdio.h> 48ca5c256SDaniel C. Sobral #include <string.h> 58ca5c256SDaniel C. Sobral #include <sys/types.h> 68ca5c256SDaniel C. Sobral #include <regex.h> 78ca5c256SDaniel C. Sobral #include <assert.h> 88ca5c256SDaniel C. Sobral 98ca5c256SDaniel C. Sobral #include "main.ih" 108ca5c256SDaniel C. Sobral 118ca5c256SDaniel C. Sobral char *progname; 128ca5c256SDaniel C. Sobral int debug = 0; 138ca5c256SDaniel C. Sobral int line = 0; 148ca5c256SDaniel C. Sobral int status = 0; 158ca5c256SDaniel C. Sobral 168ca5c256SDaniel C. Sobral int copts = REG_EXTENDED; 178ca5c256SDaniel C. Sobral int eopts = 0; 188ca5c256SDaniel C. Sobral regoff_t startoff = 0; 198ca5c256SDaniel C. Sobral regoff_t endoff = 0; 208ca5c256SDaniel C. Sobral 218ca5c256SDaniel C. Sobral 228ca5c256SDaniel C. Sobral extern int split(); 238ca5c256SDaniel C. Sobral extern void regprint(); 248ca5c256SDaniel C. Sobral 258ca5c256SDaniel C. Sobral /* 268ca5c256SDaniel C. Sobral - main - do the simple case, hand off to regress() for regression 278ca5c256SDaniel C. Sobral */ 288ca5c256SDaniel C. Sobral main(argc, argv) 298ca5c256SDaniel C. Sobral int argc; 308ca5c256SDaniel C. Sobral char *argv[]; 318ca5c256SDaniel C. Sobral { 328ca5c256SDaniel C. Sobral regex_t re; 338ca5c256SDaniel C. Sobral # define NS 10 348ca5c256SDaniel C. Sobral regmatch_t subs[NS]; 358ca5c256SDaniel C. Sobral char erbuf[100]; 368ca5c256SDaniel C. Sobral int err; 378ca5c256SDaniel C. Sobral size_t len; 388ca5c256SDaniel C. Sobral int c; 398ca5c256SDaniel C. Sobral int errflg = 0; 408ca5c256SDaniel C. Sobral register int i; 418ca5c256SDaniel C. Sobral extern int optind; 428ca5c256SDaniel C. Sobral extern char *optarg; 438ca5c256SDaniel C. Sobral 448ca5c256SDaniel C. Sobral progname = argv[0]; 458ca5c256SDaniel C. Sobral 468ca5c256SDaniel C. Sobral while ((c = getopt(argc, argv, "c:e:S:E:x")) != EOF) 478ca5c256SDaniel C. Sobral switch (c) { 488ca5c256SDaniel C. Sobral case 'c': /* compile options */ 498ca5c256SDaniel C. Sobral copts = options('c', optarg); 508ca5c256SDaniel C. Sobral break; 518ca5c256SDaniel C. Sobral case 'e': /* execute options */ 528ca5c256SDaniel C. Sobral eopts = options('e', optarg); 538ca5c256SDaniel C. Sobral break; 548ca5c256SDaniel C. Sobral case 'S': /* start offset */ 558ca5c256SDaniel C. Sobral startoff = (regoff_t)atoi(optarg); 568ca5c256SDaniel C. Sobral break; 578ca5c256SDaniel C. Sobral case 'E': /* end offset */ 588ca5c256SDaniel C. Sobral endoff = (regoff_t)atoi(optarg); 598ca5c256SDaniel C. Sobral break; 608ca5c256SDaniel C. Sobral case 'x': /* Debugging. */ 618ca5c256SDaniel C. Sobral debug++; 628ca5c256SDaniel C. Sobral break; 638ca5c256SDaniel C. Sobral case '?': 648ca5c256SDaniel C. Sobral default: 658ca5c256SDaniel C. Sobral errflg++; 668ca5c256SDaniel C. Sobral break; 678ca5c256SDaniel C. Sobral } 688ca5c256SDaniel C. Sobral if (errflg) { 698ca5c256SDaniel C. Sobral fprintf(stderr, "usage: %s ", progname); 708ca5c256SDaniel C. Sobral fprintf(stderr, "[-c copt][-C][-d] [re]\n"); 718ca5c256SDaniel C. Sobral exit(2); 728ca5c256SDaniel C. Sobral } 738ca5c256SDaniel C. Sobral 748ca5c256SDaniel C. Sobral if (optind >= argc) { 758ca5c256SDaniel C. Sobral regress(stdin); 768ca5c256SDaniel C. Sobral exit(status); 778ca5c256SDaniel C. Sobral } 788ca5c256SDaniel C. Sobral 798ca5c256SDaniel C. Sobral err = regcomp(&re, argv[optind++], copts); 808ca5c256SDaniel C. Sobral if (err) { 818ca5c256SDaniel C. Sobral len = regerror(err, &re, erbuf, sizeof(erbuf)); 828ca5c256SDaniel C. Sobral fprintf(stderr, "error %s, %d/%d `%s'\n", 838ca5c256SDaniel C. Sobral eprint(err), len, sizeof(erbuf), erbuf); 848ca5c256SDaniel C. Sobral exit(status); 858ca5c256SDaniel C. Sobral } 868ca5c256SDaniel C. Sobral regprint(&re, stdout); 878ca5c256SDaniel C. Sobral 888ca5c256SDaniel C. Sobral if (optind >= argc) { 898ca5c256SDaniel C. Sobral regfree(&re); 908ca5c256SDaniel C. Sobral exit(status); 918ca5c256SDaniel C. Sobral } 928ca5c256SDaniel C. Sobral 938ca5c256SDaniel C. Sobral if (eopts®_STARTEND) { 948ca5c256SDaniel C. Sobral subs[0].rm_so = startoff; 958ca5c256SDaniel C. Sobral subs[0].rm_eo = strlen(argv[optind]) - endoff; 968ca5c256SDaniel C. Sobral } 978ca5c256SDaniel C. Sobral err = regexec(&re, argv[optind], (size_t)NS, subs, eopts); 988ca5c256SDaniel C. Sobral if (err) { 998ca5c256SDaniel C. Sobral len = regerror(err, &re, erbuf, sizeof(erbuf)); 1008ca5c256SDaniel C. Sobral fprintf(stderr, "error %s, %d/%d `%s'\n", 1018ca5c256SDaniel C. Sobral eprint(err), len, sizeof(erbuf), erbuf); 1028ca5c256SDaniel C. Sobral exit(status); 1038ca5c256SDaniel C. Sobral } 1048ca5c256SDaniel C. Sobral if (!(copts®_NOSUB)) { 1058ca5c256SDaniel C. Sobral len = (int)(subs[0].rm_eo - subs[0].rm_so); 1068ca5c256SDaniel C. Sobral if (subs[0].rm_so != -1) { 1078ca5c256SDaniel C. Sobral if (len != 0) 1088ca5c256SDaniel C. Sobral printf("match `%.*s'\n", len, 1098ca5c256SDaniel C. Sobral argv[optind] + subs[0].rm_so); 1108ca5c256SDaniel C. Sobral else 1118ca5c256SDaniel C. Sobral printf("match `'@%.1s\n", 1128ca5c256SDaniel C. Sobral argv[optind] + subs[0].rm_so); 1138ca5c256SDaniel C. Sobral } 1148ca5c256SDaniel C. Sobral for (i = 1; i < NS; i++) 1158ca5c256SDaniel C. Sobral if (subs[i].rm_so != -1) 1168ca5c256SDaniel C. Sobral printf("(%d) `%.*s'\n", i, 1178ca5c256SDaniel C. Sobral (int)(subs[i].rm_eo - subs[i].rm_so), 1188ca5c256SDaniel C. Sobral argv[optind] + subs[i].rm_so); 1198ca5c256SDaniel C. Sobral } 1208ca5c256SDaniel C. Sobral exit(status); 1218ca5c256SDaniel C. Sobral } 1228ca5c256SDaniel C. Sobral 1238ca5c256SDaniel C. Sobral /* 1248ca5c256SDaniel C. Sobral - regress - main loop of regression test 1258ca5c256SDaniel C. Sobral == void regress(FILE *in); 1268ca5c256SDaniel C. Sobral */ 1278ca5c256SDaniel C. Sobral void 1288ca5c256SDaniel C. Sobral regress(in) 1298ca5c256SDaniel C. Sobral 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); 2038ca5c256SDaniel C. Sobral */ 2048ca5c256SDaniel C. Sobral void 2058ca5c256SDaniel C. Sobral try(f0, f1, f2, f3, f4, opts) 2068ca5c256SDaniel C. Sobral char *f0; 2078ca5c256SDaniel C. Sobral char *f1; 2088ca5c256SDaniel C. Sobral char *f2; 2098ca5c256SDaniel C. Sobral char *f3; 2108ca5c256SDaniel C. Sobral char *f4; 2118ca5c256SDaniel C. Sobral int opts; /* may not match f1 */ 2128ca5c256SDaniel C. Sobral { 2138ca5c256SDaniel C. Sobral regex_t re; 2148ca5c256SDaniel C. Sobral # define NSUBS 10 2158ca5c256SDaniel C. Sobral regmatch_t subs[NSUBS]; 2168ca5c256SDaniel C. Sobral # define NSHOULD 15 2178ca5c256SDaniel C. Sobral char *should[NSHOULD]; 2188ca5c256SDaniel C. Sobral int nshould; 2198ca5c256SDaniel C. Sobral char erbuf[100]; 2208ca5c256SDaniel C. Sobral int err; 2218ca5c256SDaniel C. Sobral int len; 2228ca5c256SDaniel C. Sobral char *type = (opts & REG_EXTENDED) ? "ERE" : "BRE"; 2238ca5c256SDaniel C. Sobral register int i; 2248ca5c256SDaniel C. Sobral char *grump; 2258ca5c256SDaniel C. Sobral char f0copy[1000]; 2268ca5c256SDaniel C. Sobral char f2copy[1000]; 2278ca5c256SDaniel C. Sobral 2288ca5c256SDaniel C. Sobral strcpy(f0copy, f0); 2298ca5c256SDaniel C. Sobral re.re_endp = (opts®_PEND) ? f0copy + strlen(f0copy) : NULL; 2308ca5c256SDaniel C. Sobral fixstr(f0copy); 2318ca5c256SDaniel C. Sobral err = regcomp(&re, f0copy, opts); 2328ca5c256SDaniel C. Sobral if (err != 0 && (!opt('C', f1) || err != efind(f2))) { 2338ca5c256SDaniel C. Sobral /* unexpected error or wrong error */ 2348ca5c256SDaniel C. Sobral len = regerror(err, &re, erbuf, sizeof(erbuf)); 2358ca5c256SDaniel C. Sobral fprintf(stderr, "%d: %s error %s, %d/%d `%s'\n", 2368ca5c256SDaniel C. Sobral line, type, eprint(err), len, 2378ca5c256SDaniel C. Sobral sizeof(erbuf), erbuf); 2388ca5c256SDaniel C. Sobral status = 1; 2398ca5c256SDaniel C. Sobral } else if (err == 0 && opt('C', f1)) { 2408ca5c256SDaniel C. Sobral /* unexpected success */ 2418ca5c256SDaniel C. Sobral fprintf(stderr, "%d: %s should have given REG_%s\n", 2428ca5c256SDaniel C. Sobral line, type, f2); 2438ca5c256SDaniel C. Sobral status = 1; 2448ca5c256SDaniel C. Sobral err = 1; /* so we won't try regexec */ 2458ca5c256SDaniel C. Sobral } 2468ca5c256SDaniel C. Sobral 2478ca5c256SDaniel C. Sobral if (err != 0) { 2488ca5c256SDaniel C. Sobral regfree(&re); 2498ca5c256SDaniel C. Sobral return; 2508ca5c256SDaniel C. Sobral } 2518ca5c256SDaniel C. Sobral 2528ca5c256SDaniel C. Sobral strcpy(f2copy, f2); 2538ca5c256SDaniel C. Sobral fixstr(f2copy); 2548ca5c256SDaniel C. Sobral 2558ca5c256SDaniel C. Sobral if (options('e', f1)®_STARTEND) { 2568ca5c256SDaniel C. Sobral if (strchr(f2, '(') == NULL || strchr(f2, ')') == NULL) 2578ca5c256SDaniel C. Sobral fprintf(stderr, "%d: bad STARTEND syntax\n", line); 2588ca5c256SDaniel C. Sobral subs[0].rm_so = strchr(f2, '(') - f2 + 1; 2598ca5c256SDaniel C. Sobral subs[0].rm_eo = strchr(f2, ')') - f2; 2608ca5c256SDaniel C. Sobral } 2618ca5c256SDaniel C. Sobral err = regexec(&re, f2copy, NSUBS, subs, options('e', f1)); 2628ca5c256SDaniel C. Sobral 2638ca5c256SDaniel C. Sobral if (err != 0 && (f3 != NULL || err != REG_NOMATCH)) { 2648ca5c256SDaniel C. Sobral /* unexpected error or wrong error */ 2658ca5c256SDaniel C. Sobral len = regerror(err, &re, erbuf, sizeof(erbuf)); 2668ca5c256SDaniel C. Sobral fprintf(stderr, "%d: %s exec error %s, %d/%d `%s'\n", 2678ca5c256SDaniel C. Sobral line, type, eprint(err), len, 2688ca5c256SDaniel C. Sobral sizeof(erbuf), erbuf); 2698ca5c256SDaniel C. Sobral status = 1; 2708ca5c256SDaniel C. Sobral } else if (err != 0) { 2718ca5c256SDaniel C. Sobral /* nothing more to check */ 2728ca5c256SDaniel C. Sobral } else if (f3 == NULL) { 2738ca5c256SDaniel C. Sobral /* unexpected success */ 2748ca5c256SDaniel C. Sobral fprintf(stderr, "%d: %s exec should have failed\n", 2758ca5c256SDaniel C. Sobral line, type); 2768ca5c256SDaniel C. Sobral status = 1; 2778ca5c256SDaniel C. Sobral err = 1; /* just on principle */ 2788ca5c256SDaniel C. Sobral } else if (opts®_NOSUB) { 2798ca5c256SDaniel C. Sobral /* nothing more to check */ 2808ca5c256SDaniel C. Sobral } else if ((grump = check(f2, subs[0], f3)) != NULL) { 2818ca5c256SDaniel C. Sobral fprintf(stderr, "%d: %s %s\n", line, type, grump); 2828ca5c256SDaniel C. Sobral status = 1; 2838ca5c256SDaniel C. Sobral err = 1; 2848ca5c256SDaniel C. Sobral } 2858ca5c256SDaniel C. Sobral 2868ca5c256SDaniel C. Sobral if (err != 0 || f4 == NULL) { 2878ca5c256SDaniel C. Sobral regfree(&re); 2888ca5c256SDaniel C. Sobral return; 2898ca5c256SDaniel C. Sobral } 2908ca5c256SDaniel C. Sobral 2918ca5c256SDaniel C. Sobral for (i = 1; i < NSHOULD; i++) 2928ca5c256SDaniel C. Sobral should[i] = NULL; 2938ca5c256SDaniel C. Sobral nshould = split(f4, should+1, NSHOULD-1, ","); 2948ca5c256SDaniel C. Sobral if (nshould == 0) { 2958ca5c256SDaniel C. Sobral nshould = 1; 2968ca5c256SDaniel C. Sobral should[1] = ""; 2978ca5c256SDaniel C. Sobral } 2988ca5c256SDaniel C. Sobral for (i = 1; i < NSUBS; i++) { 2998ca5c256SDaniel C. Sobral grump = check(f2, subs[i], should[i]); 3008ca5c256SDaniel C. Sobral if (grump != NULL) { 3018ca5c256SDaniel C. Sobral fprintf(stderr, "%d: %s $%d %s\n", line, 3028ca5c256SDaniel C. Sobral type, i, grump); 3038ca5c256SDaniel C. Sobral status = 1; 3048ca5c256SDaniel C. Sobral err = 1; 3058ca5c256SDaniel C. Sobral } 3068ca5c256SDaniel C. Sobral } 3078ca5c256SDaniel C. Sobral 3088ca5c256SDaniel C. Sobral regfree(&re); 3098ca5c256SDaniel C. Sobral } 3108ca5c256SDaniel C. Sobral 3118ca5c256SDaniel C. Sobral /* 3128ca5c256SDaniel C. Sobral - options - pick options out of a regression-test string 3138ca5c256SDaniel C. Sobral == int options(int type, char *s); 3148ca5c256SDaniel C. Sobral */ 3158ca5c256SDaniel C. Sobral int 3168ca5c256SDaniel C. Sobral options(type, s) 3178ca5c256SDaniel C. Sobral int type; /* 'c' compile, 'e' exec */ 3188ca5c256SDaniel C. Sobral char *s; 3198ca5c256SDaniel C. Sobral { 3208ca5c256SDaniel C. Sobral register char *p; 3218ca5c256SDaniel C. Sobral register int o = (type == 'c') ? copts : eopts; 3228ca5c256SDaniel C. Sobral register char *legal = (type == 'c') ? "bisnmp" : "^$#tl"; 3238ca5c256SDaniel C. Sobral 3248ca5c256SDaniel C. Sobral for (p = s; *p != '\0'; p++) 3258ca5c256SDaniel C. Sobral if (strchr(legal, *p) != NULL) 3268ca5c256SDaniel C. Sobral switch (*p) { 3278ca5c256SDaniel C. Sobral case 'b': 3288ca5c256SDaniel C. Sobral o &= ~REG_EXTENDED; 3298ca5c256SDaniel C. Sobral break; 3308ca5c256SDaniel C. Sobral case 'i': 3318ca5c256SDaniel C. Sobral o |= REG_ICASE; 3328ca5c256SDaniel C. Sobral break; 3338ca5c256SDaniel C. Sobral case 's': 3348ca5c256SDaniel C. Sobral o |= REG_NOSUB; 3358ca5c256SDaniel C. Sobral break; 3368ca5c256SDaniel C. Sobral case 'n': 3378ca5c256SDaniel C. Sobral o |= REG_NEWLINE; 3388ca5c256SDaniel C. Sobral break; 3398ca5c256SDaniel C. Sobral case 'm': 3408ca5c256SDaniel C. Sobral o &= ~REG_EXTENDED; 3418ca5c256SDaniel C. Sobral o |= REG_NOSPEC; 3428ca5c256SDaniel C. Sobral break; 3438ca5c256SDaniel C. Sobral case 'p': 3448ca5c256SDaniel C. Sobral o |= REG_PEND; 3458ca5c256SDaniel C. Sobral break; 3468ca5c256SDaniel C. Sobral case '^': 3478ca5c256SDaniel C. Sobral o |= REG_NOTBOL; 3488ca5c256SDaniel C. Sobral break; 3498ca5c256SDaniel C. Sobral case '$': 3508ca5c256SDaniel C. Sobral o |= REG_NOTEOL; 3518ca5c256SDaniel C. Sobral break; 3528ca5c256SDaniel C. Sobral case '#': 3538ca5c256SDaniel C. Sobral o |= REG_STARTEND; 3548ca5c256SDaniel C. Sobral break; 3558ca5c256SDaniel C. Sobral case 't': /* trace */ 3568ca5c256SDaniel C. Sobral o |= REG_TRACE; 3578ca5c256SDaniel C. Sobral break; 3588ca5c256SDaniel C. Sobral case 'l': /* force long representation */ 3598ca5c256SDaniel C. Sobral o |= REG_LARGE; 3608ca5c256SDaniel C. Sobral break; 3618ca5c256SDaniel C. Sobral case 'r': /* force backref use */ 3628ca5c256SDaniel C. Sobral o |= REG_BACKR; 3638ca5c256SDaniel C. Sobral break; 3648ca5c256SDaniel C. Sobral } 3658ca5c256SDaniel C. Sobral return(o); 3668ca5c256SDaniel C. Sobral } 3678ca5c256SDaniel C. Sobral 3688ca5c256SDaniel C. Sobral /* 3698ca5c256SDaniel C. Sobral - opt - is a particular option in a regression string? 3708ca5c256SDaniel C. Sobral == int opt(int c, char *s); 3718ca5c256SDaniel C. Sobral */ 3728ca5c256SDaniel C. Sobral int /* predicate */ 3738ca5c256SDaniel C. Sobral opt(c, s) 3748ca5c256SDaniel C. Sobral int c; 3758ca5c256SDaniel C. Sobral char *s; 3768ca5c256SDaniel C. Sobral { 3778ca5c256SDaniel C. Sobral return(strchr(s, c) != NULL); 3788ca5c256SDaniel C. Sobral } 3798ca5c256SDaniel C. Sobral 3808ca5c256SDaniel C. Sobral /* 3818ca5c256SDaniel C. Sobral - fixstr - transform magic characters in strings 3828ca5c256SDaniel C. Sobral == void fixstr(register char *p); 3838ca5c256SDaniel C. Sobral */ 3848ca5c256SDaniel C. Sobral void 3858ca5c256SDaniel C. Sobral fixstr(p) 3868ca5c256SDaniel C. Sobral register char *p; 3878ca5c256SDaniel C. Sobral { 3888ca5c256SDaniel C. Sobral if (p == NULL) 3898ca5c256SDaniel C. Sobral return; 3908ca5c256SDaniel C. Sobral 3918ca5c256SDaniel C. Sobral for (; *p != '\0'; p++) 3928ca5c256SDaniel C. Sobral if (*p == 'N') 3938ca5c256SDaniel C. Sobral *p = '\n'; 3948ca5c256SDaniel C. Sobral else if (*p == 'T') 3958ca5c256SDaniel C. Sobral *p = '\t'; 3968ca5c256SDaniel C. Sobral else if (*p == 'S') 3978ca5c256SDaniel C. Sobral *p = ' '; 3988ca5c256SDaniel C. Sobral else if (*p == 'Z') 3998ca5c256SDaniel C. Sobral *p = '\0'; 4008ca5c256SDaniel C. Sobral } 4018ca5c256SDaniel C. Sobral 4028ca5c256SDaniel C. Sobral /* 4038ca5c256SDaniel C. Sobral - check - check a substring match 4048ca5c256SDaniel C. Sobral == char *check(char *str, regmatch_t sub, char *should); 4058ca5c256SDaniel C. Sobral */ 4068ca5c256SDaniel C. Sobral char * /* NULL or complaint */ 4078ca5c256SDaniel C. Sobral check(str, sub, should) 4088ca5c256SDaniel C. Sobral char *str; 4098ca5c256SDaniel C. Sobral regmatch_t sub; 4108ca5c256SDaniel C. Sobral char *should; 4118ca5c256SDaniel C. Sobral { 4128ca5c256SDaniel C. Sobral register int len; 4138ca5c256SDaniel C. Sobral register int shlen; 4148ca5c256SDaniel C. Sobral register char *p; 4158ca5c256SDaniel C. Sobral static char grump[500]; 4168ca5c256SDaniel C. Sobral register char *at = NULL; 4178ca5c256SDaniel C. Sobral 4188ca5c256SDaniel C. Sobral if (should != NULL && strcmp(should, "-") == 0) 4198ca5c256SDaniel C. Sobral should = NULL; 4208ca5c256SDaniel C. Sobral if (should != NULL && should[0] == '@') { 4218ca5c256SDaniel C. Sobral at = should + 1; 4228ca5c256SDaniel C. Sobral should = ""; 4238ca5c256SDaniel C. Sobral } 4248ca5c256SDaniel C. Sobral 4258ca5c256SDaniel C. Sobral /* check rm_so and rm_eo for consistency */ 4268ca5c256SDaniel C. Sobral if (sub.rm_so > sub.rm_eo || (sub.rm_so == -1 && sub.rm_eo != -1) || 4278ca5c256SDaniel C. Sobral (sub.rm_so != -1 && sub.rm_eo == -1) || 4288ca5c256SDaniel C. Sobral (sub.rm_so != -1 && sub.rm_so < 0) || 4298ca5c256SDaniel C. Sobral (sub.rm_eo != -1 && sub.rm_eo < 0) ) { 4308ca5c256SDaniel C. Sobral sprintf(grump, "start %ld end %ld", (long)sub.rm_so, 4318ca5c256SDaniel C. Sobral (long)sub.rm_eo); 4328ca5c256SDaniel C. Sobral return(grump); 4338ca5c256SDaniel C. Sobral } 4348ca5c256SDaniel C. Sobral 4358ca5c256SDaniel C. Sobral /* check for no match */ 4368ca5c256SDaniel C. Sobral if (sub.rm_so == -1 && should == NULL) 4378ca5c256SDaniel C. Sobral return(NULL); 4388ca5c256SDaniel C. Sobral if (sub.rm_so == -1) 4398ca5c256SDaniel C. Sobral return("did not match"); 4408ca5c256SDaniel C. Sobral 4418ca5c256SDaniel C. Sobral /* check for in range */ 4428ca5c256SDaniel C. Sobral if (sub.rm_eo > strlen(str)) { 4438ca5c256SDaniel C. Sobral sprintf(grump, "start %ld end %ld, past end of string", 4448ca5c256SDaniel C. Sobral (long)sub.rm_so, (long)sub.rm_eo); 4458ca5c256SDaniel C. Sobral return(grump); 4468ca5c256SDaniel C. Sobral } 4478ca5c256SDaniel C. Sobral 4488ca5c256SDaniel C. Sobral len = (int)(sub.rm_eo - sub.rm_so); 4498ca5c256SDaniel C. Sobral shlen = (int)strlen(should); 4508ca5c256SDaniel C. Sobral p = str + sub.rm_so; 4518ca5c256SDaniel C. Sobral 4528ca5c256SDaniel C. Sobral /* check for not supposed to match */ 4538ca5c256SDaniel C. Sobral if (should == NULL) { 4548ca5c256SDaniel C. Sobral sprintf(grump, "matched `%.*s'", len, p); 4558ca5c256SDaniel C. Sobral return(grump); 4568ca5c256SDaniel C. Sobral } 4578ca5c256SDaniel C. Sobral 4588ca5c256SDaniel C. Sobral /* check for wrong match */ 4598ca5c256SDaniel C. Sobral if (len != shlen || strncmp(p, should, (size_t)shlen) != 0) { 4608ca5c256SDaniel C. Sobral sprintf(grump, "matched `%.*s' instead", len, p); 4618ca5c256SDaniel C. Sobral return(grump); 4628ca5c256SDaniel C. Sobral } 4638ca5c256SDaniel C. Sobral if (shlen > 0) 4648ca5c256SDaniel C. Sobral return(NULL); 4658ca5c256SDaniel C. Sobral 4668ca5c256SDaniel C. Sobral /* check null match in right place */ 4678ca5c256SDaniel C. Sobral if (at == NULL) 4688ca5c256SDaniel C. Sobral return(NULL); 4698ca5c256SDaniel C. Sobral shlen = strlen(at); 4708ca5c256SDaniel C. Sobral if (shlen == 0) 4718ca5c256SDaniel C. Sobral shlen = 1; /* force check for end-of-string */ 4728ca5c256SDaniel C. Sobral if (strncmp(p, at, shlen) != 0) { 4738ca5c256SDaniel C. Sobral sprintf(grump, "matched null at `%.20s'", p); 4748ca5c256SDaniel C. Sobral return(grump); 4758ca5c256SDaniel C. Sobral } 4768ca5c256SDaniel C. Sobral return(NULL); 4778ca5c256SDaniel C. Sobral } 4788ca5c256SDaniel C. Sobral 4798ca5c256SDaniel C. Sobral /* 4808ca5c256SDaniel C. Sobral - eprint - convert error number to name 4818ca5c256SDaniel C. Sobral == static char *eprint(int err); 4828ca5c256SDaniel C. Sobral */ 4838ca5c256SDaniel C. Sobral static char * 4848ca5c256SDaniel C. Sobral eprint(err) 4858ca5c256SDaniel C. Sobral int err; 4868ca5c256SDaniel C. Sobral { 4878ca5c256SDaniel C. Sobral static char epbuf[100]; 4888ca5c256SDaniel C. Sobral size_t len; 4898ca5c256SDaniel C. Sobral 4908ca5c256SDaniel C. Sobral len = regerror(REG_ITOA|err, (regex_t *)NULL, epbuf, sizeof(epbuf)); 4918ca5c256SDaniel C. Sobral assert(len <= sizeof(epbuf)); 4928ca5c256SDaniel C. Sobral return(epbuf); 4938ca5c256SDaniel C. Sobral } 4948ca5c256SDaniel C. Sobral 4958ca5c256SDaniel C. Sobral /* 4968ca5c256SDaniel C. Sobral - efind - convert error name to number 4978ca5c256SDaniel C. Sobral == static int efind(char *name); 4988ca5c256SDaniel C. Sobral */ 4998ca5c256SDaniel C. Sobral static int 5008ca5c256SDaniel C. Sobral efind(name) 5018ca5c256SDaniel C. Sobral char *name; 5028ca5c256SDaniel C. Sobral { 5038ca5c256SDaniel C. Sobral static char efbuf[100]; 5048ca5c256SDaniel C. Sobral size_t n; 5058ca5c256SDaniel C. Sobral regex_t re; 5068ca5c256SDaniel C. Sobral 5078ca5c256SDaniel C. Sobral sprintf(efbuf, "REG_%s", name); 5088ca5c256SDaniel C. Sobral assert(strlen(efbuf) < sizeof(efbuf)); 5098ca5c256SDaniel C. Sobral re.re_endp = efbuf; 5108ca5c256SDaniel C. Sobral (void) regerror(REG_ATOI, &re, efbuf, sizeof(efbuf)); 5118ca5c256SDaniel C. Sobral return(atoi(efbuf)); 5128ca5c256SDaniel C. Sobral } 513