[BACK]Return to mdoc_validate.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Diff for /mandoc/mdoc_validate.c between version 1.333 and 1.334

version 1.333, 2017/06/10 01:48:53 version 1.334, 2017/06/10 16:54:16
Line 412  static void
Line 412  static void
 post_delim(POST_ARGS)  post_delim(POST_ARGS)
 {  {
         const struct roff_node  *nch;          const struct roff_node  *nch;
         const char              *lc;          const char              *lc, *cp;
           int                      nw;
         enum mdelim              delim;          enum mdelim              delim;
           enum roff_tok            tok;
   
           /*
            * Find candidates: at least two bytes,
            * the last one a closing or middle delimiter.
            */
   
           tok = mdoc->last->tok;
         nch = mdoc->last->last;          nch = mdoc->last->last;
         if (nch == NULL || nch->type != ROFFT_TEXT)          if (nch == NULL || nch->type != ROFFT_TEXT)
                 return;                  return;
Line 424  post_delim(POST_ARGS)
Line 432  post_delim(POST_ARGS)
         delim = mdoc_isdelim(lc);          delim = mdoc_isdelim(lc);
         if (delim == DELIM_NONE || delim == DELIM_OPEN)          if (delim == DELIM_NONE || delim == DELIM_OPEN)
                 return;                  return;
   
           /*
            * Reduce false positives by allowing various cases.
            */
   
           /* Escaped delimiters. */
           if (lc > nch->string + 1 && lc[-2] == '\\' &&
               (lc[-1] == '&' || lc[-1] == 'e'))
                   return;
   
           /* Specific byte sequences. */
           switch (*lc) {
           case ')':
                   for (cp = lc; cp >= nch->string; cp--)
                           if (*cp == '(')
                                   return;
                   break;
           case '.':
                   if (lc > nch->string + 1 && lc[-2] == '.' && lc[-1] == '.')
                           return;
                   if (lc[-1] == '.')
                           return;
                   break;
           case ';':
                   if (tok == MDOC_Vt)
                           return;
                   break;
           case '?':
                   if (lc[-1] == '?')
                           return;
                   break;
           case ']':
                   for (cp = lc; cp >= nch->string; cp--)
                           if (*cp == '[')
                                   return;
                   break;
           case '|':
                   if (lc == nch->string + 1 && lc[-1] == '|')
                           return;
           default:
                   break;
           }
   
           /* Exactly two non-alphanumeric bytes. */
           if (lc == nch->string + 1 && !isalnum((unsigned char)lc[-1]))
                   return;
   
           /* At least three alphabetic words with a sentence ending. */
           if (strchr("!.:?", *lc) != NULL && (tok == MDOC_Em ||
               tok == MDOC_Li || tok == MDOC_No || tok == MDOC_Po ||
               tok == MDOC_Pq || tok == MDOC_Sy)) {
                   nw = 0;
                   for (cp = lc - 1; cp >= nch->string; cp--) {
                           if (*cp == ' ') {
                                   nw++;
                                   if (cp > nch->string && cp[-1] == ',')
                                           cp--;
                           } else if (isalpha((unsigned int)*cp)) {
                                   if (nw > 1)
                                           return;
                           } else
                                   break;
                   }
           }
   
         mandoc_vmsg(MANDOCERR_DELIM, mdoc->parse,          mandoc_vmsg(MANDOCERR_DELIM, mdoc->parse,
             nch->line, nch->pos + (lc - nch->string),              nch->line, nch->pos + (lc - nch->string),
             "%s%s %s", roff_name[mdoc->last->tok],              "%s%s %s", roff_name[tok],
             nch == mdoc->last->child ? "" : " ...", nch->string);              nch == mdoc->last->child ? "" : " ...", nch->string);
 }  }
   

Legend:
Removed from v.1.333  
changed lines
  Added in v.1.334

CVSweb