source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mdocml: Make apropos's lookup use a find(1)-like expression.
@ 2011-11-09 22:05 kristaps
  0 siblings, 0 replies; only message in thread
From: kristaps @ 2011-11-09 22:05 UTC (permalink / raw)
  To: source

Log Message:
-----------
Make apropos's lookup use a find(1)-like expression.  I'll write more on
this when it completes; this is to keep it in-tree.

Right now this uses prefix notation.  Ignore it.  I'll make this into
infix notation real soon.

The goal of this (exprcomp and exprexec) is to have arbitrary logical
expressions.

Modified Files:
--------------
    mdocml:
        apropos.c
        apropos.h
        cgi.c
        db.c

Revision Data
-------------
Index: cgi.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/cgi.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lcgi.c -Lcgi.c -u -p -r1.1 -r1.2
--- cgi.c
+++ cgi.c
@@ -47,13 +47,17 @@ struct	req {
 	enum page	 page;
 };
 
+#if 0
 static	void		 html_printtext(const char *);
+#endif
 static	int 		 kval_decode(char *);
 static	void		 kval_parse(struct kval **, size_t *, char *);
 static	void		 kval_free(struct kval *, size_t);
 static	void		 pg_index(const struct req *, char *);
 static	void		 pg_search(const struct req *, char *);
+#if 0
 static	void		 pg_searchres(struct rec *, size_t, void *);
+#endif
 
 static	const char * const pages[PAGE__MAX] = {
 	"index", /* PAGE_INDEX */ 
@@ -64,6 +68,7 @@ static	const char * const medias[MEDIA__
 	"html", /* MEDIA_HTML */
 };
 
+#if 0
 static void
 html_printtext(const char *p)
 {
@@ -88,6 +93,7 @@ html_printtext(const char *p)
 			break;
 		}
 }
+#endif
 
 static void
 kval_free(struct kval *p, size_t sz)
@@ -205,6 +211,7 @@ pg_index(const struct req *req, char *pa
 
 }
 
+#if 0
 static void
 pg_searchres(struct rec *recs, size_t sz, void *arg)
 {
@@ -223,6 +230,7 @@ pg_searchres(struct rec *recs, size_t sz
 		puts(")</A>");
 	}
 }
+#endif
 
 static void
 pg_search(const struct req *req, char *path)
@@ -238,8 +246,8 @@ pg_search(const struct req *req, char *p
 		return;
 
 	memset(&opt, 0, sizeof(struct opts));
-	opt.types = TYPE_NAME | TYPE_DESC;
-	apropos_search(&opt, req->fields[i].val, NULL, pg_searchres);
+	/*opt.types = TYPE_NAME | TYPE_DESC;
+	apropos_search(&opt, req->fields[i].val, NULL, pg_searchres);*/
 }
 
 int
Index: apropos.h
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/apropos.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lapropos.h -Lapropos.h -u -p -r1.1 -r1.2
--- apropos.h
+++ apropos.h
@@ -53,15 +53,18 @@ struct	rec {
 struct	opts {
 	const char	*arch; /* restrict to architecture */
 	const char	*cat; /* restrict to manual section */
-	int		 types; /* only types in bitmask */
-	int		 flags;
-#define	OPTS_INSENS	(0x01) /* case-insensitive match */
 };
 
 __BEGIN_DECLS
 
-void	 apropos_search(const struct opts *, const char *, 
-		void *, void (*)(struct rec *, size_t, void *));
+struct	expr;
+
+void	 	 apropos_search(const struct opts *, 
+			const struct expr *, void *, 
+			void (*)(struct rec *, size_t, void *));
+
+struct	expr	*exprcomp(int, char *[], int);
+void		 exprfree(struct expr *);
 
 __END_DECLS
 
Index: apropos.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/apropos.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -Lapropos.c -Lapropos.c -u -p -r1.9 -r1.10
--- apropos.c
+++ apropos.c
@@ -24,29 +24,6 @@
 #include "apropos.h"
 #include "mandoc.h"
 
-struct	type {
-	int		 mask;
-	const char	*name; /* command-line type name */
-};
-
-static	const struct type types[] = {
-	{ TYPE_NAME, "name" },
-	{ TYPE_FUNCTION, "func" },
-	{ TYPE_UTILITY, "utility" },
-	{ TYPE_INCLUDES, "incl" },
-	{ TYPE_VARIABLE, "var" },
-	{ TYPE_STANDARD, "stand" },
-	{ TYPE_AUTHOR, "auth" },
-	{ TYPE_CONFIG, "conf" },
-	{ TYPE_DESC, "desc" },
-	{ TYPE_XREF, "xref" },
-	{ TYPE_PATH, "path" },
-	{ TYPE_ENV, "env" },
-	{ TYPE_ERR, "err" },
-	{ INT_MAX, "all" },
-	{ 0, NULL }
-};
-
 static	int	 cmp(const void *, const void *);
 static	void	 list(struct rec *, size_t, void *);
 static	void	 usage(void);
@@ -56,23 +33,23 @@ static	char	*progname;
 int
 main(int argc, char *argv[])
 {
-	int		 ch, i;
-	char		*q, *v;
+	int		 ch, cs;
 	struct opts	 opts;
+	struct expr	*e;
 	extern int	 optind;
 	extern char	*optarg;
 
 	memset(&opts, 0, sizeof(struct opts));
 
-	q = NULL;
-
 	progname = strrchr(argv[0], '/');
 	if (progname == NULL)
 		progname = argv[0];
 	else
 		++progname;
 
-	while (-1 != (ch = getopt(argc, argv, "S:s:It:"))) 
+	cs = 0;
+
+	while (-1 != (ch = getopt(argc, argv, "S:s:I"))) 
 		switch (ch) {
 		case ('S'):
 			opts.arch = optarg;
@@ -81,26 +58,8 @@ main(int argc, char *argv[])
 			opts.cat = optarg;
 			break;
 		case ('I'):
-			opts.flags |= OPTS_INSENS;
+			cs = 1;
 			break;
-		case ('t'):
-			while (NULL != (v = strsep(&optarg, ","))) {
-				if ('\0' == *v)
-					continue;
-				for (i = 0; types[i].mask; i++) {
-					if (strcmp(types[i].name, v))
-						continue;
-					break;
-				}
-				if (0 == types[i].mask)
-					break;
-				opts.types |= types[i].mask;
-			}
-			if (NULL == v)
-				break;
-			
-			fprintf(stderr, "%s: Bad type\n", v);
-			return(EXIT_FAILURE);
 		default:
 			usage();
 			return(EXIT_FAILURE);
@@ -109,14 +68,13 @@ main(int argc, char *argv[])
 	argc -= optind;
 	argv += optind;
 
-	if (0 == argc || '\0' == **argv) {
-		usage();
+	if (0 == argc) 
 		return(EXIT_SUCCESS);
-	} else
-		q = *argv;
 
-	if (0 == opts.types)
-		opts.types = TYPE_NAME | TYPE_DESC;
+	if (NULL == (e = exprcomp(cs, argv, argc))) {
+		fprintf(stderr, "Bad expression\n");
+		return(EXIT_FAILURE);
+	}
 
 	/*
 	 * Configure databases.
@@ -125,7 +83,8 @@ main(int argc, char *argv[])
 	 * The index database is a recno.
 	 */
 
-	apropos_search(&opts, q, NULL, list);
+	apropos_search(&opts, e, NULL, list);
+	exprfree(e);
 	return(EXIT_SUCCESS);
 }
 
@@ -161,6 +120,6 @@ usage(void)
 			"[-I] "
 			"[-S arch] "
 			"[-s section] "
-			"[-t type[,...]] "
-			"key\n", progname);
+			"EXPR\n", 
+			progname);
 }
Index: db.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/db.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -Ldb.c -Ldb.c -u -p -r1.1 -r1.2
--- db.c
+++ db.c
@@ -30,8 +30,46 @@
 #include "apropos.h"
 #include "mandoc.h"
 
+enum	match {
+	MATCH_REGEX,
+	MATCH_REGEXCASE,
+	MATCH_STR,
+	MATCH_STRCASE
+};
+
+struct	expr {
+	enum match	 match;
+	int	 	 mask;
+	char		*v;
+	regex_t	 	 re;
+};
+
+struct	type {
+	int		 mask;
+	const char	*name;
+};
+
+static	const struct type types[] = {
+	{ TYPE_NAME, "name" },
+	{ TYPE_FUNCTION, "func" },
+	{ TYPE_UTILITY, "utility" },
+	{ TYPE_INCLUDES, "incl" },
+	{ TYPE_VARIABLE, "var" },
+	{ TYPE_STANDARD, "stand" },
+	{ TYPE_AUTHOR, "auth" },
+	{ TYPE_CONFIG, "conf" },
+	{ TYPE_DESC, "desc" },
+	{ TYPE_XREF, "xref" },
+	{ TYPE_PATH, "path" },
+	{ TYPE_ENV, "env" },
+	{ TYPE_ERR, "err" },
+	{ INT_MAX, "all" },
+	{ 0, NULL }
+};
+
 static	DB	*btree_open(void);
 static	int	 btree_read(const DBT *, const struct mchars *, char **);
+static	int	 exprexec(const struct expr *, char *);
 static	DB	*index_open(void);
 static	int	 index_read(const DBT *, const DBT *, 
 			const struct mchars *, struct rec *);
@@ -277,16 +315,15 @@ index_read(const DBT *key, const DBT *va
 }
 
 /*
- * Search the mandocdb database for the regular expression "q".
+ * Search the mandocdb database for the expression "expr".
  * Filter out by "opts".
  * Call "res" with the results, which may be zero.
  */
 void
-apropos_search(const struct opts *opts, const char *q, void *arg, 
-		void (*res)(struct rec *, size_t, void *))
+apropos_search(const struct opts *opts, const struct expr *expr,
+		void *arg, void (*res)(struct rec *, size_t, void *))
 {
 	int		 i, len, root, leaf;
-	regex_t		 reg;
 	DBT		 key, val;
 	DB		*btree, *idx;
 	struct mchars	*mc;
@@ -307,19 +344,8 @@ apropos_search(const struct opts *opts, 
 
 	memset(&srec, 0, sizeof(struct rec));
 
-	if (NULL != q && '\0' == *q)
-		q = NULL;
-
-	ch = REG_EXTENDED | REG_NOSUB | 
-		(OPTS_INSENS & opts->flags ? REG_ICASE : 0);
-
 	/* XXX: error out with bad regexp? */
 
-	if (NULL == q || regcomp(&reg, q, ch)) {
-		(*res)(NULL, 0, arg);
-		return;
-	}
-
 	mc = mchars_alloc();
 
 	/* XXX: return fact that we've errored? */
@@ -337,13 +363,10 @@ apropos_search(const struct opts *opts, 
 		 */
 		if (key.size < 2 || 8 != val.size) 
 			break;
-
-		if ( ! (*(int32_t *)val.data & opts->types))
-			continue;
-
 		if ( ! btree_read(&key, mc, &buf))
 			break;
-		if (regexec(&reg, buf, 0, NULL, 0))
+
+		if ( ! exprexec(expr, buf))
 			continue;
 
 		memcpy(&rec, val.data + 4, sizeof(recno_t));
@@ -432,5 +455,74 @@ out:
 
 	free(buf);
 	free(recs);
-	regfree(&reg);
+}
+
+struct expr *
+exprcomp(int cs, char *argv[], int argc)
+{
+	struct expr	*p;
+	struct expr	 e;
+	int		 i, ch;
+
+	if (3 != argc)
+		return(NULL);
+
+	if (0 == strcmp("-eq", argv[0]))
+		e.match = cs ? MATCH_STRCASE : MATCH_STR;
+	else if (0 == strcmp("-ieq", argv[0]))
+		e.match = MATCH_STRCASE;
+	else if (0 == strcmp("-re", argv[0]))
+		e.match = cs ? MATCH_REGEXCASE : MATCH_REGEX;
+	else if (0 == strcmp("-ire", argv[0]))
+		e.match = MATCH_REGEXCASE;
+	else
+		return(NULL);
+
+	for (i = 0; 0 != types[i].mask; i++)
+		if (0 == strcmp(types[i].name, argv[1]))
+			break;
+
+	if (0 == (e.mask = types[i].mask))
+		return(NULL);
+
+	e.v = mandoc_strdup(argv[2]);
+
+	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);
+	}
+
+	p = mandoc_calloc(1, sizeof(struct expr));
+	memcpy(p, &e, sizeof(struct expr));
+	return(p);
+}
+
+void
+exprfree(struct expr *p)
+{
+
+	if (NULL == p)
+		return;
+
+	if (MATCH_REGEX == p->match)
+		regfree(&p->re);
+
+	free(p->v);
+	free(p);
+}
+
+static int
+exprexec(const struct expr *p, char *cp)
+{
+
+	if (MATCH_STR == p->match)
+		return(0 == strcmp(p->v, cp));
+	else if (MATCH_STRCASE == p->match)
+		return(0 == strcasecmp(p->v, cp));
+
+	assert(MATCH_REGEX == p->match);
+	return(0 == regexec(&p->re, cp, 0, NULL, 0));
 }
--
 To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2011-11-09 22:05 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-09 22:05 mdocml: Make apropos's lookup use a find(1)-like expression kristaps

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).