When checking the validity of cross references with -Tlint,
authorschwarze <schwarze@openbsd.org>
Sat, 1 Jul 2017 12:00:12 +0000 (12:00 +0000)
committerschwarze <schwarze@openbsd.org>
Sat, 1 Jul 2017 12:00:12 +0000 (12:00 +0000)
fall back from database search to file system search
just like man(1) does when looking up manuals.

This is not too expensive because on a system having up-to-date
mandoc.db(5) files, it only prolongs the time needed to check
*invalid* references - and you are supposed to have many of those,
right?  And on a system with missing or invalid mandoc.db(5) files,
spending a bit of time and warning loudly about the real problem
is also better than quickly issuing bogus warnings about cross
references that are actually valid.

usr.bin/mandoc/main.c

index 221b015..8d7ac02 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: main.c,v 1.197 2017/07/01 09:47:23 schwarze Exp $ */
+/*     $OpenBSD: main.c,v 1.198 2017/07/01 12:00:12 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2012, 2014-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -86,7 +86,7 @@ static        int               fs_lookup(const struct manpaths *,
                                size_t ipath, const char *,
                                const char *, const char *,
                                struct manpage **, size_t *);
-static void              fs_search(const struct mansearch *,
+static int               fs_search(const struct mansearch *,
                                const struct manpaths *, int, char**,
                                struct manpage **, size_t *);
 static int               koptions(int *, char *);
@@ -639,6 +639,8 @@ fs_lookup(const struct manpaths *paths, size_t ipath,
 found:
        warnx("outdated mandoc.db lacks %s(%s) entry, run makewhatis %s",
            name, sec, paths->paths[ipath]);
+       if (res == NULL)
+               return 1;
        *res = mandoc_reallocarray(*res, ++*ressz, sizeof(struct manpage));
        page = *res + (*ressz - 1);
        page->file = file;
@@ -651,7 +653,7 @@ found:
        return 1;
 }
 
-static void
+static int
 fs_search(const struct mansearch *cfg, const struct manpaths *paths,
        int argc, char **argv, struct manpage **res, size_t *ressz)
 {
@@ -663,7 +665,8 @@ fs_search(const struct mansearch *cfg, const struct manpaths *paths,
 
        assert(cfg->argmode == ARG_NAME);
 
-       *res = NULL;
+       if (res != NULL)
+               *res = NULL;
        *ressz = lastsz = 0;
        while (argc) {
                for (ipath = 0; ipath < paths->sz; ipath++) {
@@ -671,19 +674,20 @@ fs_search(const struct mansearch *cfg, const struct manpaths *paths,
                                if (fs_lookup(paths, ipath, cfg->sec,
                                    cfg->arch, *argv, res, ressz) &&
                                    cfg->firstmatch)
-                                       return;
+                                       return 1;
                        } else for (isec = 0; isec < nsec; isec++)
                                if (fs_lookup(paths, ipath, sections[isec],
                                    cfg->arch, *argv, res, ressz) &&
                                    cfg->firstmatch)
-                                       return;
+                                       return 1;
                }
-               if (*ressz == lastsz)
+               if (res != NULL && *ressz == lastsz)
                        warnx("No entry for %s in the manual.", *argv);
                lastsz = *ressz;
                argv++;
                argc--;
        }
+       return 0;
 }
 
 static void
@@ -797,6 +801,8 @@ check_xr(const char *file)
                search.firstmatch = 1;
                if (mansearch(&search, &paths, 1, &xr->name, NULL, &sz))
                        continue;
+               if (fs_search(&search, &paths, 1, &xr->name, NULL, &sz))
+                       continue;
                mandoc_asprintf(&cp, "Xr %s %s", xr->name, xr->sec);
                mmsg(MANDOCERR_XR_BAD, MANDOCLEVEL_STYLE,
                    file, xr->line, xr->pos + 1, cp);