main.c File Reference

#include <my_global.h>
#include <m_string.h>
#include <sys/types.h>
#include <regex.h>
#include <assert.h>
#include "main.ih"

Include dependency graph for main.c:

Include dependency graph

Defines

#define NS   10
#define MAXF   10
#define SHORT   10
#define NSUBS   10
#define NSHOULD   15

Functions

int split ()
void regprint ()
int main (int argc, argv)
void regress (FILE *in)
void rx_try (char *f0, char *f1, char *f2, char *f3, char *f4, int opts)
int options (int type, char *s)
int opt (int c, char *s)
void fixstr (char *p)
char * check (char *str, regmatch_t sub, char *should)
char * eprint (int err)
int efind (char *name)

Variables

char * progname
int debug = 0
int line = 0
int status = 0
int copts = REG_EXTENDED
int eopts = 0
regoff_t startoff = 0
regoff_t endoff = 0

Define Documentation

#define MAXF   10
 

#define NS   10
 

#define NSHOULD   15
 

#define NSUBS   10
 

#define SHORT   10
 


Function Documentation

char* check char *  str,
regmatch_t  sub,
char *  should
 

00409 {
00410         register int len;
00411         register int shlen;
00412         register char *p;
00413         static char grump[500];
00414         register char *at = NULL;
00415 
00416         if (should != NULL && strcmp(should, "-") == 0)
00417                 should = NULL;
00418         if (should != NULL && should[0] == '@') {
00419                 at = should + 1;
00420                 should = (char*) "";
00421         }
00422 
00423         /* check rm_so and rm_eo for consistency */
00424         if (sub.rm_so > sub.rm_eo || (sub.rm_so == -1 && sub.rm_eo != -1) ||
00425                                 (sub.rm_so != -1 && sub.rm_eo == -1) ||
00426                                 (sub.rm_so != -1 && sub.rm_so < 0) ||
00427                                 (sub.rm_eo != -1 && sub.rm_eo < 0) ) {
00428                 sprintf(grump, "start %ld end %ld", (long)sub.rm_so,
00429                                                         (long)sub.rm_eo);
00430                 return(grump);
00431         }
00432 
00433         /* check for no match */
00434         if (sub.rm_so == -1 && should == NULL)
00435                 return(NULL);
00436         if (sub.rm_so == -1)
00437                 return((char*) "did not match");
00438 
00439         /* check for in range */
00440         if ((int) sub.rm_eo > (int) strlen(str)) {
00441                 sprintf(grump, "start %ld end %ld, past end of string",
00442                                         (long)sub.rm_so, (long)sub.rm_eo);
00443                 return(grump);
00444         }
00445 
00446         len = (int)(sub.rm_eo - sub.rm_so);
00447         shlen = (int)strlen(should);
00448         p = str + sub.rm_so;
00449 
00450         /* check for not supposed to match */
00451         if (should == NULL) {
00452                 sprintf(grump, "matched `%.*s'", len, p);
00453                 return(grump);
00454         }
00455 
00456         /* check for wrong match */
00457         if (len != shlen || strncmp(p, should, (size_t)shlen) != 0) {
00458                 sprintf(grump, "matched `%.*s' instead", len, p);
00459                 return(grump);
00460         }
00461         if (shlen > 0)
00462                 return(NULL);
00463 
00464         /* check null match in right place */
00465         if (at == NULL)
00466                 return(NULL);
00467         shlen = strlen(at);
00468         if (shlen == 0)
00469                 shlen = 1;      /* force check for end-of-string */
00470         if (strncmp(p, at, shlen) != 0) {
00471                 sprintf(grump, "matched null at `%.20s'", p);
00472                 return(grump);
00473         }
00474         return(NULL);
00475 }

int efind char *  name  )  [static]
 

00500 {
00501         static char efbuf[100];
00502         regex_t re;
00503 
00504         sprintf(efbuf, "REG_%s", name);
00505         assert(strlen(efbuf) < sizeof(efbuf));
00506         re.re_endp = efbuf;
00507         (void) regerror(REG_ATOI, &re, efbuf, sizeof(efbuf));
00508         return(atoi(efbuf));
00509 }

char* eprint int  err  )  [static]
 

00484 {
00485         static char epbuf[100];
00486         size_t len;
00487 
00488         len = regerror(REG_ITOA|err, (regex_t *)NULL, epbuf, sizeof(epbuf));
00489         assert(len <= sizeof(epbuf));
00490         return(epbuf);
00491 }

void fixstr char *  p  ) 
 

00385 {
00386         if (p == NULL)
00387                 return;
00388 
00389         for (; *p != '\0'; p++)
00390                 if (*p == 'N')
00391                         *p = '\n';
00392                 else if (*p == 'T')
00393                         *p = '\t';
00394                 else if (*p == 'S')
00395                         *p = ' ';
00396                 else if (*p == 'Z')
00397                         *p = '\0';
00398 }

int main int  argc,
argv 
 

00029 {
00030         regex_t re;
00031 #       define  NS      10
00032         regmatch_t subs[NS];
00033         char erbuf[100];
00034         int err;
00035         size_t len;
00036         int c;
00037         int errflg = 0;
00038         register int i;
00039         extern int optind;
00040         extern char *optarg;
00041 
00042         progname = argv[0];
00043 
00044         while ((c = getopt(argc, argv, "c:e:S:E:x")) != EOF)
00045                 switch (c) {
00046                 case 'c':       /* compile options */
00047                         copts = options('c', optarg);
00048                         break;
00049                 case 'e':       /* execute options */
00050                         eopts = options('e', optarg);
00051                         break;
00052                 case 'S':       /* start offset */
00053                         startoff = (regoff_t)atoi(optarg);
00054                         break;
00055                 case 'E':       /* end offset */
00056                         endoff = (regoff_t)atoi(optarg);
00057                         break;
00058                 case 'x':       /* Debugging. */
00059                         debug++;
00060                         break;
00061                 case '?':
00062                 default:
00063                         errflg++;
00064                         break;
00065                 }
00066         if (errflg) {
00067                 fprintf(stderr, "usage: %s ", progname);
00068                 fprintf(stderr, "[-c copt][-C][-d] [re]\n");
00069                 exit(2);
00070         }
00071 
00072         if (optind >= argc) {
00073                 regress(stdin);
00074                 exit(status);
00075         }
00076 
00077         err = regcomp(&re, argv[optind++], copts, &my_charset_latin1);
00078         if (err) {
00079                 len = regerror(err, &re, erbuf, sizeof(erbuf));
00080                 fprintf(stderr, "error %s, %d/%d `%s'\n",
00081                         eprint(err), len, (int) sizeof(erbuf), erbuf);
00082                 exit(status);
00083         }
00084         regprint(&re, stdout);
00085 
00086         if (optind >= argc) {
00087                 regfree(&re);
00088                 exit(status);
00089         }
00090 
00091         if (eopts&REG_STARTEND) {
00092                 subs[0].rm_so = startoff;
00093                 subs[0].rm_eo = strlen(argv[optind]) - endoff;
00094         }
00095         err = regexec(&re, argv[optind], (size_t)NS, subs, eopts);
00096         if (err) {
00097                 len = regerror(err, &re, erbuf, sizeof(erbuf));
00098                 fprintf(stderr, "error %s, %d/%d `%s'\n",
00099                         eprint(err), (int) len, (int) sizeof(erbuf), erbuf);
00100                 exit(status);
00101         }
00102         if (!(copts&REG_NOSUB)) {
00103                 len = (int)(subs[0].rm_eo - subs[0].rm_so);
00104                 if (subs[0].rm_so != -1) {
00105                         if (len != 0)
00106                                 printf("match `%.*s'\n", (int)len,
00107                                         argv[optind] + subs[0].rm_so);
00108                         else
00109                                 printf("match `'@%.1s\n",
00110                                         argv[optind] + subs[0].rm_so);
00111                 }
00112                 for (i = 1; i < NS; i++)
00113                         if (subs[i].rm_so != -1)
00114                                 printf("(%d) `%.*s'\n", i,
00115                                         (int)(subs[i].rm_eo - subs[i].rm_so),
00116                                         argv[optind] + subs[i].rm_so);
00117         }
00118         exit(status);
00119 }

int opt int  c,
char *  s
 

00374 {
00375         return(strchr(s, c) != NULL);
00376 }

int options int  type,
char *  s
 

00317 {
00318         register char *p;
00319         register int o = (type == 'c') ? copts : eopts;
00320         register const char *legal = (type == 'c') ? "bisnmp" : "^$#tl";
00321 
00322         for (p = s; *p != '\0'; p++)
00323                 if (strchr(legal, *p) != NULL)
00324                         switch (*p) {
00325                         case 'b':
00326                                 o &= ~REG_EXTENDED;
00327                                 break;
00328                         case 'i':
00329                                 o |= REG_ICASE;
00330                                 break;
00331                         case 's':
00332                                 o |= REG_NOSUB;
00333                                 break;
00334                         case 'n':
00335                                 o |= REG_NEWLINE;
00336                                 break;
00337                         case 'm':
00338                                 o &= ~REG_EXTENDED;
00339                                 o |= REG_NOSPEC;
00340                                 break;
00341                         case 'p':
00342                                 o |= REG_PEND;
00343                                 break;
00344                         case '^':
00345                                 o |= REG_NOTBOL;
00346                                 break;
00347                         case '$':
00348                                 o |= REG_NOTEOL;
00349                                 break;
00350                         case '#':
00351                                 o |= REG_STARTEND;
00352                                 break;
00353                         case 't':       /* trace */
00354                                 o |= REG_TRACE;
00355                                 break;
00356                         case 'l':       /* force long representation */
00357                                 o |= REG_LARGE;
00358                                 break;
00359                         case 'r':       /* force backref use */
00360                                 o |= REG_BACKR;
00361                                 break;
00362                         }
00363         return(o);
00364 }

void regprint  ) 
 

void regress FILE *  in  ) 
 

00128 {
00129         char inbuf[1000];
00130 #       define  MAXF    10
00131         char *f[MAXF];
00132         int nf;
00133         int i;
00134         char erbuf[100];
00135         size_t ne;
00136         const char *badpat = "invalid regular expression";
00137 #       define  SHORT   10
00138         const char *bpname = "REG_BADPAT";
00139         regex_t re;
00140 
00141         while (fgets(inbuf, sizeof(inbuf), in) != NULL) {
00142                 line++;
00143                 if (inbuf[0] == '#' || inbuf[0] == '\n')
00144                         continue;                       /* NOTE CONTINUE */
00145                 inbuf[strlen(inbuf)-1] = '\0';  /* get rid of stupid \n */
00146                 if (debug)
00147                         fprintf(stdout, "%d:\n", line);
00148                 nf = split(inbuf, f, MAXF, "\t\t");
00149                 if (nf < 3) {
00150                         fprintf(stderr, "bad input, line %d\n", line);
00151                         exit(1);
00152                 }
00153                 for (i = 0; i < nf; i++)
00154                         if (strcmp(f[i], "\"\"") == 0)
00155                                 f[i] = (char*) "";
00156                 if (nf <= 3)
00157                         f[3] = NULL;
00158                 if (nf <= 4)
00159                         f[4] = NULL;
00160                 rx_try(f[0], f[1], f[2], f[3], f[4], options('c', f[1]));
00161                 if (opt('&', f[1]))     /* try with either type of RE */
00162                         rx_try(f[0], f[1], f[2], f[3], f[4],
00163                                         options('c', f[1]) &~ REG_EXTENDED);
00164         }
00165 
00166         ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, sizeof(erbuf));
00167         if (strcmp(erbuf, badpat) != 0 || ne != strlen(badpat)+1) {
00168                 fprintf(stderr, "end: regerror() test gave `%s' not `%s'\n",
00169                                                         erbuf, badpat);
00170                 status = 1;
00171         }
00172         ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, (size_t)SHORT);
00173         if (strncmp(erbuf, badpat, SHORT-1) != 0 || erbuf[SHORT-1] != '\0' ||
00174                                                 ne != strlen(badpat)+1) {
00175                 fprintf(stderr, "end: regerror() short test gave `%s' not `%.*s'\n",
00176                                                 erbuf, SHORT-1, badpat);
00177                 status = 1;
00178         }
00179         ne = regerror(REG_ITOA|REG_BADPAT, (regex_t *)NULL, erbuf, sizeof(erbuf));
00180         if (strcmp(erbuf, bpname) != 0 || ne != strlen(bpname)+1) {
00181                 fprintf(stderr, "end: regerror() ITOA test gave `%s' not `%s'\n",
00182                                                 erbuf, bpname);
00183                 status = 1;
00184         }
00185         re.re_endp = bpname;
00186         ne = regerror(REG_ATOI, &re, erbuf, sizeof(erbuf));
00187         if (atoi(erbuf) != (int)REG_BADPAT) {
00188                 fprintf(stderr, "end: regerror() ATOI test gave `%s' not `%ld'\n",
00189                                                 erbuf, (long)REG_BADPAT);
00190                 status = 1;
00191         } else if (ne != strlen(erbuf)+1) {
00192                 fprintf(stderr, "end: regerror() ATOI test len(`%s') = %ld\n",
00193                                                 erbuf, (long)REG_BADPAT);
00194                 status = 1;
00195         }
00196 }

void rx_try char *  f0,
char *  f1,
char *  f2,
char *  f3,
char *  f4,
int  opts
 

00210 {
00211         regex_t re;
00212 #       define  NSUBS   10
00213         regmatch_t subs[NSUBS];
00214 #       define  NSHOULD 15
00215         char *should[NSHOULD];
00216         int nshould;
00217         char erbuf[100];
00218         int err;
00219         int len;
00220         const char *type = (opts & REG_EXTENDED) ? "ERE" : "BRE";
00221         register int i;
00222         char *grump;
00223         char f0copy[1000];
00224         char f2copy[1000];
00225 
00226         strcpy(f0copy, f0);
00227         re.re_endp = (opts&REG_PEND) ? f0copy + strlen(f0copy) : NULL;
00228         fixstr(f0copy);
00229         err = regcomp(&re, f0copy, opts, &my_charset_latin1);
00230         if (err != 0 && (!opt('C', f1) || err != efind(f2))) {
00231                 /* unexpected error or wrong error */
00232                 len = regerror(err, &re, erbuf, sizeof(erbuf));
00233                 fprintf(stderr, "%d: %s error %s, %d/%d `%s'\n",
00234                                         line, type, eprint(err), len,
00235                                         (int) sizeof(erbuf), erbuf);
00236                 status = 1;
00237         } else if (err == 0 && opt('C', f1)) {
00238                 /* unexpected success */
00239                 fprintf(stderr, "%d: %s should have given REG_%s\n",
00240                                                 line, type, f2);
00241                 status = 1;
00242                 err = 1;        /* so we won't try regexec */
00243         }
00244 
00245         if (err != 0) {
00246                 regfree(&re);
00247                 return;
00248         }
00249 
00250         strcpy(f2copy, f2);
00251         fixstr(f2copy);
00252 
00253         if (options('e', f1)&REG_STARTEND) {
00254                 if (strchr(f2, '(') == NULL || strchr(f2, ')') == NULL)
00255                         fprintf(stderr, "%d: bad STARTEND syntax\n", line);
00256                 subs[0].rm_so = strchr(f2, '(') - f2 + 1;
00257                 subs[0].rm_eo = strchr(f2, ')') - f2;
00258         }
00259         err = regexec(&re, f2copy, NSUBS, subs, options('e', f1));
00260 
00261         if (err != 0 && (f3 != NULL || err != REG_NOMATCH)) {
00262                 /* unexpected error or wrong error */
00263                 len = regerror(err, &re, erbuf, sizeof(erbuf));
00264                 fprintf(stderr, "%d: %s exec error %s, %d/%d `%s'\n",
00265                                         line, type, eprint(err), len,
00266                                         (int) sizeof(erbuf), erbuf);
00267                 status = 1;
00268         } else if (err != 0) {
00269                 /* nothing more to check */
00270         } else if (f3 == NULL) {
00271                 /* unexpected success */
00272                 fprintf(stderr, "%d: %s exec should have failed\n",
00273                                                 line, type);
00274                 status = 1;
00275                 err = 1;                /* just on principle */
00276         } else if (opts&REG_NOSUB) {
00277                 /* nothing more to check */
00278         } else if ((grump = check(f2, subs[0], f3)) != NULL) {
00279                 fprintf(stderr, "%d: %s %s\n", line, type, grump);
00280                 status = 1;
00281                 err = 1;
00282         }
00283 
00284         if (err != 0 || f4 == NULL) {
00285                 regfree(&re);
00286                 return;
00287         }
00288 
00289         for (i = 1; i < NSHOULD; i++)
00290                 should[i] = NULL;
00291         nshould = split(f4, should+1, NSHOULD-1, ",");
00292         if (nshould == 0) {
00293                 nshould = 1;
00294                 should[1] = (char*) "";
00295         }
00296         for (i = 1; i < NSUBS; i++) {
00297                 grump = check(f2, subs[i], should[i]);
00298                 if (grump != NULL) {
00299                         fprintf(stderr, "%d: %s $%d %s\n", line,
00300                                                         type, i, grump);
00301                         status = 1;
00302                         err = 1;
00303                 }
00304         }
00305 
00306         regfree(&re);
00307 }

int split  ) 
 


Variable Documentation

int copts = REG_EXTENDED
 

int debug = 0
 

regoff_t endoff = 0
 

int eopts = 0
 

int line = 0
 

char* progname
 

regoff_t startoff = 0
 

int status = 0
 


Generated on Thu Feb 24 11:01:16 2005 for MySQL by  doxygen 1.3.9.1