]> git.cameronkatri.com Git - mandoc.git/blobdiff - mansearch.c
Issue a STYLE message when normalizing the date format in .Dd/.TH.
[mandoc.git] / mansearch.c
index ddfe2f5dccb861ab5b5a8cf49b944ecbdc197d5f..784c17bee714759682bb4092a9100d8c665f2c1f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mansearch.c,v 1.50 2016/07/09 15:23:36 schwarze Exp $ */
+/*     $Id: mansearch.c,v 1.77 2017/08/22 17:50:11 schwarze Exp $ */
 /*
  * Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2013-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -171,7 +171,9 @@ mansearch(const struct mansearch *search,
                        page = dbm_page_get(rp->page);
 
                        if (lstmatch(search->sec, page->sect) == 0 ||
-                           lstmatch(search->arch, page->arch) == 0)
+                           lstmatch(search->arch, page->arch) == 0 ||
+                           (search->argmode == ARG_NAME &&
+                            rp->bits <= (int32_t)(NAME_SYN & NAME_MASK)))
                                continue;
 
                        if (res == NULL) {
@@ -186,6 +188,16 @@ mansearch(const struct mansearch *search,
                        mpage = *res + cur;
                        mandoc_asprintf(&mpage->file, "%s/%s",
                            paths->paths[i], page->file + 1);
+                       if (access(chdir_status ? page->file + 1 :
+                           mpage->file, R_OK) == -1) {
+                               warn("%s", mpage->file);
+                               warnx("outdated mandoc.db contains "
+                                   "bogus %s entry, run makewhatis %s", 
+                                   page->file + 1, paths->paths[i]);
+                               free(mpage->file);
+                               free(rp);
+                               continue;
+                       }
                        mpage->names = buildnames(page);
                        mpage->output = buildoutput(outkey, page);
                        mpage->ipath = i;
@@ -394,13 +406,29 @@ static int
 manpage_compare(const void *vp1, const void *vp2)
 {
        const struct manpage    *mp1, *mp2;
+       const char              *cp1, *cp2;
+       size_t                   sz1, sz2;
        int                      diff;
 
        mp1 = vp1;
        mp2 = vp2;
-       return (diff = mp2->bits - mp1->bits) ? diff :
-           (diff = mp1->sec - mp2->sec) ? diff :
-           strcasecmp(mp1->names, mp2->names);
+       if ((diff = mp2->bits - mp1->bits) ||
+           (diff = mp1->sec - mp2->sec))
+               return diff;
+
+       /* Fall back to alphabetic ordering of names. */
+       sz1 = strcspn(mp1->names, "(");
+       sz2 = strcspn(mp2->names, "(");
+       if (sz1 < sz2)
+               sz1 = sz2;
+       if ((diff = strncasecmp(mp1->names, mp2->names, sz1)))
+               return diff;
+
+       /* For identical names and sections, prefer arch-dependent. */
+       cp1 = strchr(mp1->names + sz1, '/');
+       cp2 = strchr(mp2->names + sz2, '/');
+       return cp1 != NULL && cp2 != NULL ? strcasecmp(cp1, cp2) :
+           cp1 != NULL ? -1 : cp2 != NULL ? 1 : 0;
 }
 
 static char *
@@ -436,14 +464,28 @@ lstlen(const char *cp, size_t sep)
 {
        size_t   sz;
 
-       for (sz = 0;; sz++) {
-               if (cp[0] == '\0') {
-                       if (cp[1] == '\0')
-                               break;
-                       sz += sep - 1;
-               } else if (cp[0] < ' ')
-                       sz--;
-               cp++;
+       for (sz = 0; *cp != '\0'; cp++) {
+
+               /* Skip names appearing only in the SYNOPSIS. */
+               if (*cp <= (char)(NAME_SYN & NAME_MASK)) {
+                       while (*cp != '\0')
+                               cp++;
+                       continue;
+               }
+
+               /* Skip name class markers. */
+               if (*cp < ' ')
+                       cp++;
+
+               /* Print a separator before each but the first string. */
+               if (sz)
+                       sz += sep;
+
+               /* Copy one string. */
+               while (*cp != '\0') {
+                       sz++;
+                       cp++;
+               }
        }
        return sz;
 }
@@ -455,19 +497,34 @@ lstlen(const char *cp, size_t sep)
 static void
 lstcat(char *buf, size_t *i, const char *cp, const char *sep)
 {
-       const char *s;
+       const char      *s;
+       size_t           i_start;
 
-       for (;;) {
-               if (cp[0] == '\0') {
-                       if (cp[1] == '\0')
-                               break;
+       for (i_start = *i; *cp != '\0'; cp++) {
+
+               /* Skip names appearing only in the SYNOPSIS. */
+               if (*cp <= (char)(NAME_SYN & NAME_MASK)) {
+                       while (*cp != '\0')
+                               cp++;
+                       continue;
+               }
+
+               /* Skip name class markers. */
+               if (*cp < ' ')
+                       cp++;
+
+               /* Print a separator before each but the first string. */
+               if (*i > i_start) {
                        s = sep;
                        while (*s != '\0')
                                buf[(*i)++] = *s++;
-               } else if (cp[0] >= ' ')
-                       buf[(*i)++] = cp[0];
-               cp++;
+               }
+
+               /* Copy one string. */
+               while (*cp != '\0')
+                       buf[(*i)++] = *cp++;
        }
+
 }
 
 /*