aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/cgi.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2014-09-14 19:44:28 +0000
committerIngo Schwarze <schwarze@openbsd.org>2014-09-14 19:44:28 +0000
commitc99d0805237ab16252befd6defffabebde81d74b (patch)
tree77429737b5e960b5729c27a1f0d64020204c8dd9 /cgi.c
parent2a37145b398147deef315887314495f6a9b9637e (diff)
downloadmandoc-c99d0805237ab16252befd6defffabebde81d74b.tar.gz
mandoc-c99d0805237ab16252befd6defffabebde81d74b.tar.zst
mandoc-c99d0805237ab16252befd6defffabebde81d74b.zip
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@.
Diffstat (limited to 'cgi.c')
-rw-r--r--cgi.c67
1 files changed, 33 insertions, 34 deletions
diff --git a/cgi.c b/cgi.c
index cbef30ef..81503081 100644
--- a/cgi.c
+++ b/cgi.c
@@ -1,4 +1,4 @@
-/* $Id: cgi.c,v 1.96 2014/08/26 11:21:40 schwarze Exp $ */
+/* $Id: cgi.c,v 1.97 2014/09/14 19:44:28 schwarze Exp $ */
/*
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014 Ingo Schwarze <schwarze@usta.de>
@@ -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);
}