-/* $OpenBSD: mansearch.c,v 1.52 2017/03/03 13:10:55 schwarze Exp $ */
+/* $OpenBSD: mansearch.c,v 1.53 2017/04/17 20:04:26 schwarze Exp $ */
/*
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2013, 2014, 2015, 2016 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2013-2017 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
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 *);
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';
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';
/*
* 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;
if (cp[0] == '\0') {
if (cp[1] == '\0')
break;
- sz++;
+ sz += sep - 1;
} else if (cp[0] < ' ')
sz--;
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++;
}
/*
- * 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 = "";