=================================================================== RCS file: /cvs/mandoc/main.c,v retrieving revision 1.315 retrieving revision 1.327 diff -u -p -r1.315 -r1.327 --- mandoc/main.c 2018/12/30 00:49:55 1.315 +++ mandoc/main.c 2019/05/03 18:39:34 1.327 @@ -1,7 +1,7 @@ -/* $Id: main.c,v 1.315 2018/12/30 00:49:55 schwarze Exp $ */ +/* $Id: main.c,v 1.327 2019/05/03 18:39:34 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons - * Copyright (c) 2010-2012, 2014-2018 Ingo Schwarze + * Copyright (c) 2010-2012, 2014-2019 Ingo Schwarze * Copyright (c) 2010 Joerg Sonnenberger * * Permission to use, copy, modify, and distribute this software for any @@ -21,7 +21,7 @@ #include #include #include /* MACHINE */ -#include +#include #include #include @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -123,9 +124,9 @@ main(int argc, char *argv[]) struct manpage *res, *resp; const char *progname, *sec, *thisarg; char *conf_file, *defpaths, *auxpaths; - char *oarg; + char *oarg, *tagarg; unsigned char *uc; - size_t i, sz; + size_t i, sz, ssz; int prio, best_prio; enum outmode outmode; int fd, startdir; @@ -148,6 +149,7 @@ main(int argc, char *argv[]) setprogname(progname); #endif + mandoc_msg_setoutfile(stderr); if (strncmp(progname, "mandocdb", 8) == 0 || strcmp(progname, BINM_MAKEWHATIS) == 0) return mandocdb(argc, argv); @@ -298,12 +300,9 @@ main(int argc, char *argv[]) search.outkey = oarg; else { while (oarg != NULL) { - thisarg = oarg; if (manconf_output(&conf.output, - strsep(&oarg, ","), 0) == 0) - continue; - warnx("-O %s: Bad argument", thisarg); - return (int)MANDOCLEVEL_BADARG; + strsep(&oarg, ","), 0) == -1) + return (int)MANDOCLEVEL_BADARG; } } } @@ -354,7 +353,7 @@ main(int argc, char *argv[]) } else if (argc > 1 && ((uc = (unsigned char *)argv[0]) != NULL) && ((isdigit(uc[0]) && (uc[1] == '\0' || - (isalpha(uc[1]) && uc[2] == '\0'))) || + isalpha(uc[1]))) || (uc[0] == 'n' && uc[1] == '\0'))) { search.sec = (char *)uc; argv++; @@ -368,6 +367,17 @@ main(int argc, char *argv[]) #endif } + /* + * Use the first argument for -O tag in addition to + * using it as a search term for man(1) or apropos(1). + */ + + if (conf.output.tag != NULL && *conf.output.tag == '\0') { + tagarg = argc > 0 && search.argmode == ARG_EXPR ? + strchr(*argv, '=') : NULL; + conf.output.tag = tagarg == NULL ? *argv : tagarg + 1; + } + /* man(1), whatis(1), apropos(1) */ if (search.argmode != ARG_FILE) { @@ -399,6 +409,7 @@ main(int argc, char *argv[]) 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; @@ -421,7 +432,7 @@ main(int argc, char *argv[]) if (outmode == OUTMODE_ONE) { argc = 1; - best_prio = 20; + best_prio = 40; } else if (outmode == OUTMODE_ALL) argc = (int)sz; @@ -440,10 +451,21 @@ main(int argc, char *argv[]) sec = res[i].file; sec += strcspn(sec, "123456789"); if (sec[0] == '\0') - continue; + continue; /* No section at all. */ prio = sec_prios[sec[0] - '1']; - if (sec[1] != '/') - prio += 10; + if (search.sec != NULL) { + ssz = strlen(search.sec); + if (strncmp(sec, search.sec, ssz) == 0) + sec += ssz; + } else + sec++; /* Prefer without suffix. */ + if (*sec != '/') + prio += 10; /* Wrong dir name. */ + if (search.sec != NULL && + (strlen(sec) <= ssz + 3 || + strcmp(sec + strlen(sec) - ssz, + search.sec) != 0)) + prio += 20; /* Wrong file ext. */ if (prio >= best_prio) continue; best_prio = prio; @@ -480,8 +502,10 @@ main(int argc, char *argv[]) curp.mp = mparse_alloc(options, curp.os_e, curp.os_s); if (argc < 1) { - if (use_pager) + if (use_pager) { tag_files = tag_init(); + tag_files->tagname = conf.output.tag; + } thisarg = ""; mandoc_msg_setinfilename(thisarg); parse(&curp, STDIN_FILENO, thisarg); @@ -518,11 +542,7 @@ main(int argc, char *argv[]) if (use_pager) { use_pager = 0; tag_files = tag_init(); - if (conf.output.tag != NULL && - tag_files->tagname == NULL) - tag_files->tagname = - *conf.output.tag != '\0' ? - conf.output.tag : *argv; + tag_files->tagname = conf.output.tag; } mandoc_msg_setinfilename(thisarg); @@ -551,7 +571,7 @@ main(int argc, char *argv[]) } } else mandoc_msg(MANDOCERR_FILE, 0, 0, - "%s", strerror(errno)); + "%s: %s", thisarg, strerror(errno)); if (curp.wstop && mandoc_msg_getrc() != MANDOCLEVEL_OK) break; @@ -691,6 +711,7 @@ fs_lookup(const struct manpaths *paths, size_t ipath, const char *sec, const char *arch, const char *name, struct manpage **res, size_t *ressz) { + struct stat sb; glob_t globinfo; struct manpage *page; char *file; @@ -700,13 +721,13 @@ fs_lookup(const struct manpaths *paths, size_t ipath, form = FORM_SRC; mandoc_asprintf(&file, "%s/man%s/%s.%s", paths->paths[ipath], sec, name, sec); - if (access(file, R_OK) != -1) + if (stat(file, &sb) != -1) goto found; free(file); mandoc_asprintf(&file, "%s/cat%s/%s.0", paths->paths[ipath], sec, name); - if (access(file, R_OK) != -1) { + if (stat(file, &sb) != -1) { form = FORM_CAT; goto found; } @@ -715,7 +736,7 @@ fs_lookup(const struct manpaths *paths, size_t ipath, if (arch != NULL) { mandoc_asprintf(&file, "%s/man%s/%s/%s.%s", paths->paths[ipath], sec, arch, name, sec); - if (access(file, R_OK) != -1) + if (stat(file, &sb) != -1) goto found; free(file); } @@ -729,13 +750,16 @@ fs_lookup(const struct manpaths *paths, size_t ipath, if (globres == 0) file = mandoc_strdup(*globinfo.gl_pathv); globfree(&globinfo); - if (globres == 0) - goto found; + if (globres == 0) { + if (stat(file, &sb) != -1) + goto found; + free(file); + } if (res != NULL || ipath + 1 != paths->sz) return 0; mandoc_asprintf(&file, "%s.%s", name, sec); - globres = access(file, R_OK); + globres = stat(file, &sb); free(file); return globres != -1; @@ -751,6 +775,7 @@ found: page->file = file; page->names = NULL; page->output = NULL; + page->bits = NAME_FILE & NAME_MASK; page->ipath = ipath; page->sec = (*sec >= '1' && *sec <= '9') ? *sec - '1' + 1 : 10; page->form = form; @@ -787,7 +812,11 @@ fs_search(const struct mansearch *cfg, const struct ma } if (res != NULL && *ressz == lastsz && strchr(*argv, '/') == NULL) { - if (cfg->sec == NULL) + if (cfg->arch != NULL && + arch_valid(cfg->arch, OSENUM) == 0) + warnx("Unknown architecture \"%s\".", + cfg->arch); + else if (cfg->sec == NULL) warnx("No entry for %s in the manual.", *argv); else @@ -825,6 +854,8 @@ parse(struct curparse *curp, int fd, const char *file) if (curp->outdata == NULL) outdata_alloc(curp); + else if (curp->outtype == OUTT_HTML) + html_reset(curp); mandoc_xr_reset(); meta = mparse_result(curp->mp); @@ -1145,7 +1176,9 @@ spawn_pager(struct tag_files *tag_files) char *argv[MAX_PAGER_ARGS]; const char *pager; char *cp; +#if HAVE_LESS_T size_t cmdlen; +#endif int argc, use_ofn; pid_t pager_pid; @@ -1177,6 +1210,7 @@ spawn_pager(struct tag_files *tag_files) /* For less(1), use the tag file. */ use_ofn = 1; +#if HAVE_LESS_T if ((cmdlen = strlen(argv[0])) >= 4) { cp = argv[0] + cmdlen - 4; if (strcmp(cp, "less") == 0) { @@ -1189,6 +1223,7 @@ spawn_pager(struct tag_files *tag_files) } } } +#endif if (use_ofn) argv[argc++] = tag_files->ofn; argv[argc] = NULL;