=================================================================== RCS file: /cvs/mandoc/mansearch.c,v retrieving revision 1.69 retrieving revision 1.70 diff -u -p -r1.69 -r1.70 --- mandoc/mansearch.c 2017/03/03 13:11:21 1.69 +++ mandoc/mansearch.c 2017/04/17 20:05:08 1.70 @@ -1,7 +1,7 @@ -/* $OpenBSD: mansearch.c,v 1.69 2017/03/03 13:11:21 schwarze Exp $ */ +/* $OpenBSD: mansearch.c,v 1.70 2017/04/17 20:05:08 schwarze Exp $ */ /* * Copyright (c) 2012 Kristaps Dzonsons - * Copyright (c) 2013, 2014, 2015, 2016 Ingo Schwarze + * Copyright (c) 2013-2017 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -67,9 +67,9 @@ static struct ohash *manmerge_term(struct expr *, stru static struct ohash *manmerge_or(struct expr *, struct ohash *); static struct ohash *manmerge_and(struct expr *, struct ohash *); static char *buildnames(const struct dbm_page *); -static char *buildoutput(size_t, int32_t); -static size_t lstlen(const char *); -static void lstcat(char *, size_t *, const char *); +static char *buildoutput(size_t, struct dbm_page *); +static size_t lstlen(const char *, size_t); +static void lstcat(char *, size_t *, const char *, const char *); static int lstmatch(const char *, const char *); static struct expr *exprcomp(const struct mansearch *, int, char *[], int *); @@ -181,9 +181,7 @@ mansearch(const struct mansearch *search, mandoc_asprintf(&mpage->file, "%s/%s", paths->paths[i], page->file + 1); mpage->names = buildnames(page); - mpage->output = (int)outkey == KEY_Nd ? - mandoc_strdup(page->desc) : - buildoutput(outkey, page->addr); + mpage->output = buildoutput(outkey, page); mpage->ipath = i; mpage->bits = rp->bits; mpage->sec = *page->sect - '0'; @@ -404,16 +402,16 @@ buildnames(const struct dbm_page *page) char *buf; size_t i, sz; - sz = lstlen(page->name) + 1 + lstlen(page->sect) + - (page->arch == NULL ? 0 : 1 + lstlen(page->arch)) + 2; + sz = lstlen(page->name, 2) + 1 + lstlen(page->sect, 2) + + (page->arch == NULL ? 0 : 1 + lstlen(page->arch, 2)) + 2; buf = mandoc_malloc(sz); i = 0; - lstcat(buf, &i, page->name); + lstcat(buf, &i, page->name, ", "); buf[i++] = '('; - lstcat(buf, &i, page->sect); + lstcat(buf, &i, page->sect, ", "); if (page->arch != NULL) { buf[i++] = '/'; - lstcat(buf, &i, page->arch); + lstcat(buf, &i, page->arch, ", "); } buf[i++] = ')'; buf[i++] = '\0'; @@ -423,11 +421,11 @@ buildnames(const struct dbm_page *page) /* * Count the buffer space needed to print the NUL-terminated - * list of NUL-terminated strings, when printing two separator + * list of NUL-terminated strings, when printing sep separator * characters between strings. */ static size_t -lstlen(const char *cp) +lstlen(const char *cp, size_t sep) { size_t sz; @@ -435,7 +433,7 @@ lstlen(const char *cp) if (cp[0] == '\0') { if (cp[1] == '\0') break; - sz++; + sz += sep - 1; } else if (cp[0] < ' ') sz--; cp++; @@ -445,17 +443,20 @@ lstlen(const char *cp) /* * Print the NUL-terminated list of NUL-terminated strings - * into the buffer, seperating strings with a comma and a blank. + * into the buffer, seperating strings with sep. */ static void -lstcat(char *buf, size_t *i, const char *cp) +lstcat(char *buf, size_t *i, const char *cp, const char *sep) { + const char *s; + for (;;) { if (cp[0] == '\0') { if (cp[1] == '\0') break; - buf[(*i)++] = ','; - buf[(*i)++] = ' '; + s = sep; + while (*s != '\0') + buf[(*i)++] = *s++; } else if (cp[0] >= ' ') buf[(*i)++] = cp[0]; cp++; @@ -482,17 +483,44 @@ lstmatch(const char *want, const char *have) } /* - * Build a list of values taken by the macro im - * in the manual page with big-endian address addr. + * Build a list of values taken by the macro im in the manual page. */ static char * -buildoutput(size_t im, int32_t addr) +buildoutput(size_t im, struct dbm_page *page) { - const char *oldoutput, *sep; + const char *oldoutput, *sep, *input; char *output, *newoutput, *value; + size_t sz, i; + switch (im) { + case KEY_Nd: + return mandoc_strdup(page->desc); + case KEY_Nm: + input = page->name; + break; + case KEY_sec: + input = page->sect; + break; + case KEY_arch: + input = page->arch; + if (input == NULL) + input = "all\0"; + break; + default: + input = NULL; + break; + } + + if (input != NULL) { + sz = lstlen(input, 3) + 1; + output = mandoc_malloc(sz); + i = 0; + lstcat(output, &i, input, " # "); + return output; + } + output = NULL; - dbm_macro_bypage(im - 2, addr); + dbm_macro_bypage(im - 2, page->addr); while ((value = dbm_macro_next()) != NULL) { if (output == NULL) { oldoutput = "";