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.5/8.14.5) with ESMTP id s8EJiVFY002431 for ; Sun, 14 Sep 2014 15:44:31 -0400 (EDT) Received: (from schwarze@localhost) by krisdoz.my.domain (8.14.5/8.14.3/Submit) id s8EJiSv1025521; Sun, 14 Sep 2014 15:44:28 -0400 (EDT) Date: Sun, 14 Sep 2014 15:44:28 -0400 (EDT) Message-Id: <201409141944.s8EJiSv1025521@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: Support backslash-escaping of white space in the query X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 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 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