source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mdocml: Support backslash-escaping of white space in the query
@ 2014-09-14 19:44 schwarze
  0 siblings, 0 replies; only message in thread
From: schwarze @ 2014-09-14 19:44 UTC (permalink / raw)
  To: source

Log Message:
-----------
Support backslash-escaping of white space in the query expression,
to be more similar to apropos(1) called from the shell.
Missing feature reported by Marcus MERIGHI <mcmer dash openbsd at 
tor dot at> on misc@.

Modified Files:
--------------
    mdocml:
        cgi.c
        man.cgi.8

Revision Data
-------------
Index: man.cgi.8
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/man.cgi.8,v
retrieving revision 1.10
retrieving revision 1.11
diff -Lman.cgi.8 -Lman.cgi.8 -u -p -r1.10 -r1.11
--- man.cgi.8
+++ man.cgi.8
@@ -43,6 +43,12 @@ either a name of a manual page or an
 using the syntax described in the
 .Xr apropos 1
 manual; filling this in is required for each search.
+.Pp
+The expression is broken into words at whitespace.
+Whitespace characters and backslashes can be escaped
+by prepending a backslash.
+The effect of prepending a backslash to another character is undefined;
+in the current implementation, it has no effect.
 .It
 A
 .Dq Submit
Index: cgi.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/cgi.c,v
retrieving revision 1.96
retrieving revision 1.97
diff -Lcgi.c -Lcgi.c -u -p -r1.96 -r1.97
--- cgi.c
+++ cgi.c
@@ -954,10 +954,10 @@ pg_search(const struct req *req)
 	struct mansearch	  search;
 	struct manpaths		  paths;
 	struct manpage		 *res;
-	char			**cp;
-	const char		 *ep, *start;
+	char			**argv;
+	char			 *query, *rp, *wp;
 	size_t			  ressz;
-	int			  i, sz;
+	int			  argc;
 
 	/*
 	 * Begin by chdir()ing into the root of the manpath.
@@ -982,46 +982,45 @@ pg_search(const struct req *req)
 	paths.paths[0] = mandoc_strdup(".");
 
 	/*
-	 * Poor man's tokenisation: just break apart by spaces.
-	 * Yes, this is half-ass.  But it works for now.
+	 * Break apart at spaces with backslash-escaping.
 	 */
 
-	ep = req->q.query;
-	while (ep && isspace((unsigned char)*ep))
-		ep++;
-
-	sz = 0;
-	cp = NULL;
-	while (ep && '\0' != *ep) {
-		cp = mandoc_reallocarray(cp, sz + 1, sizeof(char *));
-		start = ep;
-		while ('\0' != *ep && ! isspace((unsigned char)*ep))
-			ep++;
-		cp[sz] = mandoc_malloc((ep - start) + 1);
-		memcpy(cp[sz], start, ep - start);
-		cp[sz++][ep - start] = '\0';
-		while (isspace((unsigned char)*ep))
-			ep++;
+	argc = 0;
+	argv = NULL;
+	rp = query = mandoc_strdup(req->q.query);
+	for (;;) {
+		while (isspace((unsigned char)*rp))
+			rp++;
+		if (*rp == '\0')
+			break;
+		argv = mandoc_reallocarray(argv, argc + 1, sizeof(char *));
+		argv[argc++] = wp = rp;
+		for (;;) {
+			if (isspace((unsigned char)*rp)) {
+				*wp = '\0';
+				rp++;
+				break;
+			}
+			if (rp[0] == '\\' && rp[1] != '\0')
+				rp++;
+			if (wp != rp)
+				*wp = *rp;
+			if (*rp == '\0')
+				break;
+			wp++;
+			rp++;
+		}
 	}
 
-	if (0 == mansearch(&search, &paths, sz, cp, &res, &ressz))
+	if (0 == mansearch(&search, &paths, argc, argv, &res, &ressz))
 		pg_noresult(req, "You entered an invalid query.");
 	else if (0 == ressz)
 		pg_noresult(req, "No results found.");
 	else
 		pg_searchres(req, res, ressz);
 
-	for (i = 0; i < sz; i++)
-		free(cp[i]);
-	free(cp);
-
-	for (i = 0; i < (int)ressz; i++) {
-		free(res[i].file);
-		free(res[i].names);
-		free(res[i].output);
-	}
-	free(res);
-
+	free(query);
+	mansearch_free(res, ressz);
 	free(paths.paths[0]);
 	free(paths.paths);
 }
--
 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:[~2014-09-14 19:44 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-14 19:44 mdocml: Support backslash-escaping of white space in the query schwarze

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).