From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from krisdoz.my.domain (schwarze@localhost [127.0.0.1]) by krisdoz.my.domain (8.14.3/8.14.3) with ESMTP id pADBAS5G019562 for ; Sun, 13 Nov 2011 06:10:28 -0500 (EST) Received: (from schwarze@localhost) by krisdoz.my.domain (8.14.3/8.14.3/Submit) id pADBASx8000944; Sun, 13 Nov 2011 06:10:28 -0500 (EST) Date: Sun, 13 Nov 2011 06:10:28 -0500 (EST) Message-Id: <201111131110.pADBASx8000944@krisdoz.my.domain> X-Mailinglist: mdocml-source Reply-To: source@mdocml.bsd.lv MIME-Version: 1.0 From: schwarze@mdocml.bsd.lv To: source@mdocml.bsd.lv Subject: mdocml: Rewrite the expression parser for a more concise syntax: X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Log Message: ----------- Rewrite the expression parser for a more concise syntax: apropos [search_type[,...]=]substring apropos search_type[,...][,i]~regex ... and expression evaluation must take the search type into account. This allows to: * drop the global -I option and * drop the enum match, just using a boolean int. "go ahead" kristaps@ Modified Files: -------------- mdocml: apropos.c apropos_db.c apropos_db.h Revision Data ------------- Index: apropos_db.c =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/apropos_db.c,v retrieving revision 1.2 retrieving revision 1.3 diff -Lapropos_db.c -Lapropos_db.c -u -p -r1.2 -r1.3 --- apropos_db.c +++ apropos_db.c @@ -1,6 +1,7 @@ /* $Id$ */ /* * Copyright (c) 2011 Kristaps Dzonsons + * Copyright (c) 2011 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -31,15 +32,8 @@ #include "apropos_db.h" #include "mandoc.h" -enum match { - MATCH_REGEX, - MATCH_REGEXCASE, - MATCH_STR, - MATCH_STRCASE -}; - struct expr { - enum match match; + int regex; int mask; char *v; regex_t re; @@ -71,7 +65,7 @@ static const struct type types[] = { static DB *btree_open(void); static int btree_read(const DBT *, const struct mchars *, char **); -static int exprexec(const struct expr *, char *); +static int exprexec(const struct expr *, char *, int); static DB *index_open(void); static int index_read(const DBT *, const DBT *, const struct mchars *, struct rec *); @@ -368,7 +362,7 @@ apropos_search(const struct opts *opts, if ( ! btree_read(&key, mc, &buf)) break; - if ( ! exprexec(expr, buf)) + if ( ! exprexec(expr, buf, *(int *)val.data)) continue; memcpy(&rec, val.data + 4, sizeof(recno_t)); @@ -460,55 +454,55 @@ out: } struct expr * -exprcomp(int cs, char *argv[], int argc) +exprcomp(int argc, char *argv[]) { struct expr *p; struct expr e; - int i, pos, ch; - - pos = 0; - - if (pos > argc) - return(NULL); - - for (i = 0; 0 != types[i].mask; i++) - if (0 == strcmp(types[i].name, argv[pos])) - break; - - if (0 == (e.mask = types[i].mask)) - return(NULL); + char *key; + int i, icase; - if (++pos > argc--) + if (0 >= argc) return(NULL); - if ('-' != *argv[pos]) - e.match = cs ? MATCH_STRCASE : MATCH_STR; - else if (0 == strcmp("-eq", argv[pos])) - e.match = cs ? MATCH_STRCASE : MATCH_STR; - else if (0 == strcmp("-ieq", argv[pos])) - e.match = MATCH_STRCASE; - else if (0 == strcmp("-re", argv[pos])) - e.match = cs ? MATCH_REGEXCASE : MATCH_REGEX; - else if (0 == strcmp("-ire", argv[pos])) - e.match = MATCH_REGEXCASE; - else - return(NULL); + /* + * Choose regex or substring match. + */ + + if (NULL == (e.v = strpbrk(*argv, "=~"))) { + e.regex = 0; + e.v = *argv; + } else { + e.regex = '~' == *e.v; + *e.v++ = '\0'; + } - if ('-' == *argv[pos]) - pos++; + /* + * Determine the record types to search for. + */ + + icase = 0; + e.mask = 0; + if (*argv < e.v) { + while (NULL != (key = strsep(argv, ","))) { + if ('i' == key[0] && '\0' == key[1]) { + icase = REG_ICASE; + continue; + } + i = 0; + while (types[i].mask && + strcmp(types[i].name, key)) + i++; + e.mask |= types[i].mask; + } + } + if (0 == e.mask) + e.mask = TYPE_Nm | TYPE_Nd; - if (pos > argc--) + if (e.regex && + regcomp(&e.re, e.v, REG_EXTENDED | REG_NOSUB | icase)) return(NULL); - e.v = mandoc_strdup(argv[pos]); - - if (MATCH_REGEX == e.match || MATCH_REGEXCASE == e.match) { - ch = REG_EXTENDED | REG_NOSUB; - if (MATCH_REGEXCASE == e.match) - ch |= REG_ICASE; - if (regcomp(&e.re, e.v, ch)) - return(NULL); - } + e.v = mandoc_strdup(e.v); p = mandoc_calloc(1, sizeof(struct expr)); memcpy(p, &e, sizeof(struct expr)); @@ -522,7 +516,7 @@ exprfree(struct expr *p) if (NULL == p) return; - if (MATCH_REGEX == p->match) + if (p->regex) regfree(&p->re); free(p->v); @@ -530,14 +524,14 @@ exprfree(struct expr *p) } static int -exprexec(const struct expr *p, char *cp) +exprexec(const struct expr *p, char *cp, int mask) { - if (MATCH_STR == p->match) - return(0 == strcmp(p->v, cp)); - else if (MATCH_STRCASE == p->match) - return(0 == strcasecmp(p->v, cp)); + if ( ! (mask & p->mask)) + return(0); - assert(MATCH_REGEX == p->match); - return(0 == regexec(&p->re, cp, 0, NULL, 0)); + if (p->regex) + return(0 == regexec(&p->re, cp, 0, NULL, 0)); + else + return(NULL != strcasestr(cp, p->v)); } Index: apropos_db.h =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/apropos_db.h,v retrieving revision 1.2 retrieving revision 1.3 diff -Lapropos_db.h -Lapropos_db.h -u -p -r1.2 -r1.3 --- apropos_db.h +++ apropos_db.h @@ -49,7 +49,7 @@ void apropos_search(const struct opts const struct expr *, void *, void (*)(struct rec *, size_t, void *)); -struct expr *exprcomp(int, char *[], int); +struct expr *exprcomp(int, char *[]); void exprfree(struct expr *); __END_DECLS Index: apropos.c =================================================================== RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/apropos.c,v retrieving revision 1.11 retrieving revision 1.12 diff -Lapropos.c -Lapropos.c -u -p -r1.11 -r1.12 --- apropos.c +++ apropos.c @@ -33,7 +33,7 @@ static char *progname; int main(int argc, char *argv[]) { - int ch, cs; + int ch; struct opts opts; struct expr *e; extern int optind; @@ -47,9 +47,7 @@ main(int argc, char *argv[]) else ++progname; - cs = 0; - - while (-1 != (ch = getopt(argc, argv, "S:s:I"))) + while (-1 != (ch = getopt(argc, argv, "S:s:"))) switch (ch) { case ('S'): opts.arch = optarg; @@ -57,9 +55,6 @@ main(int argc, char *argv[]) case ('s'): opts.cat = optarg; break; - case ('I'): - cs = 1; - break; default: usage(); return(EXIT_FAILURE); @@ -71,7 +66,7 @@ main(int argc, char *argv[]) if (0 == argc) return(EXIT_SUCCESS); - if (NULL == (e = exprcomp(cs, argv, argc))) { + if (NULL == (e = exprcomp(argc, argv))) { fprintf(stderr, "Bad expression\n"); return(EXIT_FAILURE); } -- To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv