From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from localhost (mandoc.bsd.lv [local]) by mandoc.bsd.lv (OpenSMTPD) with ESMTPA id e8aaede3 for ; Sun, 28 Jul 2019 13:23:47 -0500 (EST) Date: Sun, 28 Jul 2019 13:23:47 -0500 (EST) X-Mailinglist: mandoc-source Reply-To: source@mandoc.bsd.lv MIME-Version: 1.0 From: schwarze@mandoc.bsd.lv To: source@mandoc.bsd.lv Subject: mandoc: In man(1) mode, do the search for each name independently, and X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Message-ID: <862a41bf6316999b@mandoc.bsd.lv> Log Message: ----------- In man(1) mode, do the search for each name independently, and show the results in the order of the command line arguments. Implemented by separating the code for man(1) and apropos(1) in the main() program. Surprisingly, the number of lines of code remains unchanged. Issue reported by deraadt@, additional input from millert@. Modified Files: -------------- mandoc: main.c Revision Data ------------- Index: main.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/main.c,v retrieving revision 1.337 retrieving revision 1.338 diff -Lmain.c -Lmain.c -u -p -r1.337 -r1.338 --- main.c +++ main.c @@ -120,7 +120,8 @@ main(int argc, char *argv[]) struct outstate outst; /* Output state. */ struct winsize ws; /* Result of ioctl(TIOCGWINSZ). */ struct mansearch search; /* Search options. */ - struct manpage *res, *resp; /* Search results. */ + struct manpage *res; /* Complete list of search results. */ + struct manpage *resn; /* Search results for one name. */ struct mparse *mp; /* Opaque parser object. */ const char *conf_file; /* -C: alternate config file. */ const char *os_s; /* -I: Operating system for display. */ @@ -130,8 +131,9 @@ main(int argc, char *argv[]) char *oarg; /* -O: output option string. */ char *tagarg; /* -O tag: default value. */ unsigned char *uc; - size_t sz; /* Number of elements in res[]. */ - size_t i, ssz; + size_t ressz; /* Number of elements in res[]. */ + size_t resnsz; /* Number of elements in resn[]. */ + size_t i, ib, ssz; int options; /* Parser options. */ int show_usage; /* Invalid argument: give up. */ int prio, best_prio; @@ -384,11 +386,10 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; } - resp = NULL; /* - * Quirks for help(1) - * and for a man(1) section argument without -s. + * Quirks for help(1) and man(1), + * in particular for a section argument without -s. */ if (search.argmode == ARG_NAME) { @@ -412,6 +413,8 @@ main(int argc, char *argv[]) if (search.arch == NULL) search.arch = MACHINE; #endif + if (outmode == OUTMODE_ONE) + search.firstmatch = 1; } /* @@ -425,80 +428,54 @@ main(int argc, char *argv[]) conf.output.tag = tagarg == NULL ? *argv : tagarg + 1; } - /* man(1), whatis(1), apropos(1) */ - - if (search.argmode != ARG_FILE) { - if (search.argmode == ARG_NAME && - outmode == OUTMODE_ONE) - search.firstmatch = 1; - - /* Access the mandoc database. */ + /* Read the configuration file. */ + if (search.argmode != ARG_FILE) manconf_parse(&conf, conf_file, defpaths, auxpaths); - if ( ! mansearch(&search, &conf.manpath, - argc, argv, &res, &sz)) - usage(search.argmode); - if (sz == 0 && search.argmode == ARG_NAME) - (void)fs_search(&search, &conf.manpath, - argc, argv, &res, &sz); - - if (search.argmode == ARG_NAME) { - for (c = 0; c < argc; c++) { - if (strchr(argv[c], '/') == NULL) + /* man(1): Resolve each name individually. */ + + if (search.argmode == ARG_NAME) { + if (argc < 1) + usage(ARG_NAME); + for (res = NULL, ressz = 0; argc > 0; argc--, argv++) { + (void)mansearch(&search, &conf.manpath, + 1, argv, &resn, &resnsz); + if (resnsz == 0) + (void)fs_search(&search, &conf.manpath, + 1, argv, &resn, &resnsz); + if (resnsz == 0) { + if (strchr(*argv, '/') == NULL) { + mandoc_msg_setrc(MANDOCLEVEL_BADARG); continue; - if (access(argv[c], R_OK) == -1) { - mandoc_msg_setinfilename(argv[c]); + } + if (access(*argv, R_OK) == -1) { + mandoc_msg_setinfilename(*argv); mandoc_msg(MANDOCERR_BADARG_BAD, 0, 0, "%s", strerror(errno)); mandoc_msg_setinfilename(NULL); continue; } + resnsz = 1; + resn = mandoc_calloc(resnsz, sizeof(*res)); + resn->file = mandoc_strdup(*argv); + resn->ipath = SIZE_MAX; + resn->form = FORM_SRC; + } + if (outmode != OUTMODE_ONE || resnsz == 1) { res = mandoc_reallocarray(res, - sz + 1, sizeof(*res)); - res[sz].file = mandoc_strdup(argv[c]); - res[sz].names = NULL; - res[sz].output = NULL; - res[sz].bits = 0; - res[sz].ipath = SIZE_MAX; - res[sz].sec = 10; - res[sz].form = FORM_SRC; - sz++; + ressz + resnsz, sizeof(*res)); + memcpy(res + ressz, resn, + sizeof(*resn) * resnsz); + ressz += resnsz; + continue; } - } - if (sz == 0) { - if (search.argmode != ARG_NAME) - warnx("nothing appropriate"); - mandoc_msg_setrc(MANDOCLEVEL_BADARG); - goto out; - } - - /* - * For standard man(1) and -a output mode, - * prepare for copying filename pointers - * into the program parameter array. - */ + /* Search for the best section. */ - if (outmode == OUTMODE_ONE) { - argc = 1; best_prio = 40; - } else if (outmode == OUTMODE_ALL) - argc = (int)sz; - - /* Iterate all matching manuals. */ - - resp = res; - for (i = 0; i < sz; i++) { - if (outmode == OUTMODE_FLN) - puts(res[i].file); - else if (outmode == OUTMODE_LST) - printf("%s - %s\n", res[i].names, - res[i].output == NULL ? "" : - res[i].output); - else if (outmode == OUTMODE_ONE) { - /* Search for the best section. */ - sec = res[i].file; + for (ib = i = 0; i < resnsz; i++) { + sec = resn[i].file; sec += strcspn(sec, "123456789"); if (sec[0] == '\0') continue; /* No section at all. */ @@ -519,32 +496,53 @@ main(int argc, char *argv[]) if (prio >= best_prio) continue; best_prio = prio; - resp = res + i; + ib = i; } + res = mandoc_reallocarray(res, ressz + 1, + sizeof(*res)); + memcpy(res + ressz++, resn + ib, sizeof(*resn)); } - /* - * For man(1), -a and -i output mode, fall through - * to the main mandoc(1) code iterating files - * and running the parsers on each of them. - */ + /* apropos(1), whatis(1): Process the full search expression. */ + + } else if (search.argmode != ARG_FILE) { + if (mansearch(&search, &conf.manpath, + argc, argv, &res, &ressz) == 0) + usage(search.argmode); - if (outmode == OUTMODE_FLN || outmode == OUTMODE_LST) + if (ressz == 0) { + warnx("nothing appropriate"); + mandoc_msg_setrc(MANDOCLEVEL_BADARG); goto out; + } + + /* mandoc(1): Take command line arguments as file names. */ + } else { - sz = argc > 0 ? argc : 1; - resp = res = mandoc_recallocarray(NULL, 0, sz, sizeof(*res)); - for (i = 0; i < sz; i++) { + ressz = argc > 0 ? argc : 1; + res = mandoc_calloc(ressz, sizeof(*res)); + for (i = 0; i < ressz; i++) { if (argc > 0) res[i].file = mandoc_strdup(argv[i]); res[i].ipath = SIZE_MAX; res[i].form = FORM_SRC; } - if (argc < 1) - argc = 1; } - /* mandoc(1) */ + switch (outmode) { + case OUTMODE_FLN: + for (i = 0; i < ressz; i++) + puts(res[i].file); + goto out; + case OUTMODE_LST: + for (i = 0; i < ressz; i++) + printf("%s - %s\n", res[i].names, + res[i].output == NULL ? "" : + res[i].output); + goto out; + default: + break; + } #if HAVE_PLEDGE if (outst.use_pager) { @@ -581,8 +579,8 @@ main(int argc, char *argv[]) */ startdir = open(".", O_RDONLY | O_DIRECTORY); - while (argc-- > 0) { - process_onefile(mp, resp++, startdir, &outst, &conf); + for (i = 0; i < ressz; i++) { + process_onefile(mp, res + i, startdir, &outst, &conf); if (outst.wstop && mandoc_msg_getrc() != MANDOCLEVEL_OK) break; } @@ -614,7 +612,7 @@ main(int argc, char *argv[]) mchars_free(); out: - mansearch_free(res, sz); + mansearch_free(res, ressz); if (search.argmode != ARG_FILE) manconf_free(&conf); -- To unsubscribe send an email to source+unsubscribe@mandoc.bsd.lv