Hi Marcus,

Marcus MERIGHI wrote on Sun, Sep 14, 2014 at 12:28:43PM +0200:
> d-eberhd...@freenet.de (D. Eberhardt), 2014.09.14 (Sun) 11:14 (CEST):

>> with the question of network adapters naming I went stuck searching
>> for a 'supported hardware' list. On the path from

> I could get quite a list from the following command: 
> 
> $ apropos "network device" "ethernet device"

Actually,

  $ apropos -s 4 Nd=network Nd=ethernet

takes about half the time (50 instead of 100 milliseconds on my
notebook), doesn't suffer from the quoting problem, and finds two
additional devices, iec(4/sgi) and sq(4/sgi).

> I've checked a few I know of (bge, xl, em, wpi) to get the key words. 
> 
> The apropos search at http://www.openbsd.org/cgi-bin/man.cgi does not
> seem to work the same way, it doesn't like the quotes.

The quotes are a shell feature, and when you enter text into the search
box of the web interface, there is no shell involved in parsing it.

Anyway, there was no way to use whitespace characters in queries
in the web interface, which seems like a missing feature to me,
so i have fixed it.  You can now enter this into the search box

  network\ device ethernet\ device

to do the same as:

  $ apropos network\ device ethernet\ device

It is now documented here:

  http://www.openbsd.org/cgi-bin/man.cgi/mandoc/man8/man.cgi.8

  section "DESCRIPTION", subsection "HTML search interface",
  number 1, second paragraph.

Thanks for reporting!

Yours,
  Ingo


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+unsubscr...@mdocml.bsd.lv

Reply via email to