Print this page
Update to 1.12.3.

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/mandoc/man_validate.c
          +++ new/usr/src/cmd/mandoc/man_validate.c
   1      -/*      $Id: man_validate.c,v 1.80 2012/01/03 15:16:24 kristaps Exp $ */
        1 +/*      $Id: man_validate.c,v 1.86 2013/10/17 20:54:58 schwarze Exp $ */
   2    2  /*
   3    3   * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
   4      - * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
        4 + * Copyright (c) 2010, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
   5    5   *
   6    6   * Permission to use, copy, modify, and distribute this software for any
   7    7   * purpose with or without fee is hereby granted, provided that the above
   8    8   * copyright notice and this permission notice appear in all copies.
   9    9   *
  10   10   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11   11   * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12   12   * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13   13   * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14   14   * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
↓ open down ↓ 13 lines elided ↑ open up ↑
  28   28  #include <stdarg.h>
  29   29  #include <stdlib.h>
  30   30  #include <string.h>
  31   31  #include <time.h>
  32   32  
  33   33  #include "man.h"
  34   34  #include "mandoc.h"
  35   35  #include "libman.h"
  36   36  #include "libmandoc.h"
  37   37  
  38      -#define CHKARGS   struct man *m, struct man_node *n
       38 +#define CHKARGS   struct man *man, struct man_node *n
  39   39  
  40   40  typedef int     (*v_check)(CHKARGS);
  41   41  
  42   42  struct  man_valid {
  43   43          v_check  *pres;
  44   44          v_check  *posts;
  45   45  };
  46   46  
  47   47  static  int       check_eq0(CHKARGS);
  48   48  static  int       check_eq2(CHKARGS);
  49   49  static  int       check_le1(CHKARGS);
  50   50  static  int       check_ge2(CHKARGS);
  51   51  static  int       check_le5(CHKARGS);
       52 +static  int       check_head1(CHKARGS);
  52   53  static  int       check_par(CHKARGS);
  53   54  static  int       check_part(CHKARGS);
  54   55  static  int       check_root(CHKARGS);
  55   56  static  void      check_text(CHKARGS);
  56   57  
  57   58  static  int       post_AT(CHKARGS);
       59 +static  int       post_IP(CHKARGS);
  58   60  static  int       post_vs(CHKARGS);
  59   61  static  int       post_fi(CHKARGS);
  60   62  static  int       post_ft(CHKARGS);
  61   63  static  int       post_nf(CHKARGS);
  62   64  static  int       post_sec(CHKARGS);
  63   65  static  int       post_TH(CHKARGS);
  64   66  static  int       post_UC(CHKARGS);
  65   67  static  int       pre_sec(CHKARGS);
  66   68  
  67   69  static  v_check   posts_at[] = { post_AT, NULL };
  68   70  static  v_check   posts_br[] = { post_vs, check_eq0, NULL };
  69   71  static  v_check   posts_eq0[] = { check_eq0, NULL };
  70   72  static  v_check   posts_eq2[] = { check_eq2, NULL };
  71   73  static  v_check   posts_fi[] = { check_eq0, post_fi, NULL };
  72   74  static  v_check   posts_ft[] = { post_ft, NULL };
       75 +static  v_check   posts_ip[] = { post_IP, NULL };
       76 +static  v_check   posts_le1[] = { check_le1, NULL };
  73   77  static  v_check   posts_nf[] = { check_eq0, post_nf, NULL };
  74   78  static  v_check   posts_par[] = { check_par, NULL };
  75   79  static  v_check   posts_part[] = { check_part, NULL };
  76   80  static  v_check   posts_sec[] = { post_sec, NULL };
  77   81  static  v_check   posts_sp[] = { post_vs, check_le1, NULL };
  78   82  static  v_check   posts_th[] = { check_ge2, check_le5, post_TH, NULL };
  79   83  static  v_check   posts_uc[] = { post_UC, NULL };
       84 +static  v_check   posts_ur[] = { check_head1, check_part, NULL };
  80   85  static  v_check   pres_sec[] = { pre_sec, NULL };
  81   86  
  82   87  static  const struct man_valid man_valids[MAN_MAX] = {
  83   88          { NULL, posts_br }, /* br */
  84   89          { NULL, posts_th }, /* TH */
  85   90          { pres_sec, posts_sec }, /* SH */
  86   91          { pres_sec, posts_sec }, /* SS */
  87   92          { NULL, NULL }, /* TP */
  88   93          { NULL, posts_par }, /* LP */
  89   94          { NULL, posts_par }, /* PP */
  90   95          { NULL, posts_par }, /* P */
  91      -        { NULL, NULL }, /* IP */
       96 +        { NULL, posts_ip }, /* IP */
  92   97          { NULL, NULL }, /* HP */
  93   98          { NULL, NULL }, /* SM */
  94   99          { NULL, NULL }, /* SB */
  95  100          { NULL, NULL }, /* BI */
  96  101          { NULL, NULL }, /* IB */
  97  102          { NULL, NULL }, /* BR */
  98  103          { NULL, NULL }, /* RB */
  99  104          { NULL, NULL }, /* R */
 100  105          { NULL, NULL }, /* B */
 101  106          { NULL, NULL }, /* I */
 102  107          { NULL, NULL }, /* IR */
 103  108          { NULL, NULL }, /* RI */
 104  109          { NULL, posts_eq0 }, /* na */
 105  110          { NULL, posts_sp }, /* sp */
 106  111          { NULL, posts_nf }, /* nf */
 107  112          { NULL, posts_fi }, /* fi */
 108  113          { NULL, NULL }, /* RE */
 109  114          { NULL, posts_part }, /* RS */
 110  115          { NULL, NULL }, /* DT */
 111  116          { NULL, posts_uc }, /* UC */
 112      -        { NULL, NULL }, /* PD */
      117 +        { NULL, posts_le1 }, /* PD */
 113  118          { NULL, posts_at }, /* AT */
 114  119          { NULL, NULL }, /* in */
 115  120          { NULL, posts_ft }, /* ft */
 116  121          { NULL, posts_eq2 }, /* OP */
      122 +        { NULL, posts_nf }, /* EX */
      123 +        { NULL, posts_fi }, /* EE */
      124 +        { NULL, posts_ur }, /* UR */
      125 +        { NULL, NULL }, /* UE */
 117  126  };
 118  127  
 119  128  
 120  129  int
 121      -man_valid_pre(struct man *m, struct man_node *n)
      130 +man_valid_pre(struct man *man, struct man_node *n)
 122  131  {
 123  132          v_check         *cp;
 124  133  
 125  134          switch (n->type) {
 126  135          case (MAN_TEXT):
 127  136                  /* FALLTHROUGH */
 128  137          case (MAN_ROOT):
 129  138                  /* FALLTHROUGH */
 130  139          case (MAN_EQN):
 131  140                  /* FALLTHROUGH */
 132  141          case (MAN_TBL):
 133  142                  return(1);
 134  143          default:
 135  144                  break;
 136  145          }
 137  146  
 138  147          if (NULL == (cp = man_valids[n->tok].pres))
 139  148                  return(1);
 140  149          for ( ; *cp; cp++)
 141      -                if ( ! (*cp)(m, n)) 
      150 +                if ( ! (*cp)(man, n)) 
 142  151                          return(0);
 143  152          return(1);
 144  153  }
 145  154  
 146  155  
 147  156  int
 148      -man_valid_post(struct man *m)
      157 +man_valid_post(struct man *man)
 149  158  {
 150  159          v_check         *cp;
 151  160  
 152      -        if (MAN_VALID & m->last->flags)
      161 +        if (MAN_VALID & man->last->flags)
 153  162                  return(1);
 154      -        m->last->flags |= MAN_VALID;
      163 +        man->last->flags |= MAN_VALID;
 155  164  
 156      -        switch (m->last->type) {
      165 +        switch (man->last->type) {
 157  166          case (MAN_TEXT): 
 158      -                check_text(m, m->last);
      167 +                check_text(man, man->last);
 159  168                  return(1);
 160  169          case (MAN_ROOT):
 161      -                return(check_root(m, m->last));
      170 +                return(check_root(man, man->last));
 162  171          case (MAN_EQN):
 163  172                  /* FALLTHROUGH */
 164  173          case (MAN_TBL):
 165  174                  return(1);
 166  175          default:
 167  176                  break;
 168  177          }
 169  178  
 170      -        if (NULL == (cp = man_valids[m->last->tok].posts))
      179 +        if (NULL == (cp = man_valids[man->last->tok].posts))
 171  180                  return(1);
 172  181          for ( ; *cp; cp++)
 173      -                if ( ! (*cp)(m, m->last))
      182 +                if ( ! (*cp)(man, man->last))
 174  183                          return(0);
 175  184  
 176  185          return(1);
 177  186  }
 178  187  
 179  188  
 180  189  static int
 181  190  check_root(CHKARGS) 
 182  191  {
 183  192  
 184      -        if (MAN_BLINE & m->flags)
 185      -                man_nmsg(m, n, MANDOCERR_SCOPEEXIT);
 186      -        else if (MAN_ELINE & m->flags)
 187      -                man_nmsg(m, n, MANDOCERR_SCOPEEXIT);
      193 +        if (MAN_BLINE & man->flags)
      194 +                man_nmsg(man, n, MANDOCERR_SCOPEEXIT);
      195 +        else if (MAN_ELINE & man->flags)
      196 +                man_nmsg(man, n, MANDOCERR_SCOPEEXIT);
 188  197  
 189      -        m->flags &= ~MAN_BLINE;
 190      -        m->flags &= ~MAN_ELINE;
      198 +        man->flags &= ~MAN_BLINE;
      199 +        man->flags &= ~MAN_ELINE;
 191  200  
 192      -        if (NULL == m->first->child) {
 193      -                man_nmsg(m, n, MANDOCERR_NODOCBODY);
      201 +        if (NULL == man->first->child) {
      202 +                man_nmsg(man, n, MANDOCERR_NODOCBODY);
 194  203                  return(0);
 195      -        } else if (NULL == m->meta.title) {
 196      -                man_nmsg(m, n, MANDOCERR_NOTITLE);
      204 +        } else if (NULL == man->meta.title) {
      205 +                man_nmsg(man, n, MANDOCERR_NOTITLE);
 197  206  
 198  207                  /*
 199  208                   * If a title hasn't been set, do so now (by
 200  209                   * implication, date and section also aren't set).
 201  210                   */
 202  211  
 203      -                m->meta.title = mandoc_strdup("unknown");
 204      -                m->meta.msec = mandoc_strdup("1");
 205      -                m->meta.date = mandoc_normdate
 206      -                        (m->parse, NULL, n->line, n->pos);
      212 +                man->meta.title = mandoc_strdup("unknown");
      213 +                man->meta.msec = mandoc_strdup("1");
      214 +                man->meta.date = mandoc_normdate
      215 +                        (man->parse, NULL, n->line, n->pos);
 207  216          }
 208  217  
 209  218          return(1);
 210  219  }
 211  220  
 212  221  static void
 213  222  check_text(CHKARGS)
 214  223  {
 215  224          char            *cp, *p;
 216  225  
 217      -        if (MAN_LITERAL & m->flags)
      226 +        if (MAN_LITERAL & man->flags)
 218  227                  return;
 219  228  
 220  229          cp = n->string;
 221  230          for (p = cp; NULL != (p = strchr(p, '\t')); p++)
 222      -                man_pmsg(m, n->line, (int)(p - cp), MANDOCERR_BADTAB);
      231 +                man_pmsg(man, n->line, (int)(p - cp), MANDOCERR_BADTAB);
 223  232  }
 224  233  
 225  234  #define INEQ_DEFINE(x, ineq, name) \
 226  235  static int \
 227  236  check_##name(CHKARGS) \
 228  237  { \
 229  238          if (n->nchild ineq (x)) \
 230  239                  return(1); \
 231      -        mandoc_vmsg(MANDOCERR_ARGCOUNT, m->parse, n->line, n->pos, \
      240 +        mandoc_vmsg(MANDOCERR_ARGCOUNT, man->parse, n->line, n->pos, \
 232  241                          "line arguments %s %d (have %d)", \
 233  242                          #ineq, (x), n->nchild); \
 234  243          return(1); \
 235  244  }
 236  245  
 237  246  INEQ_DEFINE(0, ==, eq0)
 238  247  INEQ_DEFINE(2, ==, eq2)
 239  248  INEQ_DEFINE(1, <=, le1)
 240  249  INEQ_DEFINE(2, >=, ge2)
 241  250  INEQ_DEFINE(5, <=, le5)
 242  251  
 243  252  static int
      253 +check_head1(CHKARGS)
      254 +{
      255 +
      256 +        if (MAN_HEAD == n->type && 1 != n->nchild)
      257 +                mandoc_vmsg(MANDOCERR_ARGCOUNT, man->parse, n->line,
      258 +                    n->pos, "line arguments eq 1 (have %d)", n->nchild);
      259 +
      260 +        return(1);
      261 +}
      262 +
      263 +static int
 244  264  post_ft(CHKARGS)
 245  265  {
 246  266          char    *cp;
 247  267          int      ok;
 248  268  
 249  269          if (0 == n->nchild)
 250  270                  return(1);
 251  271  
 252  272          ok = 0;
 253  273          cp = n->child->string;
↓ open down ↓ 21 lines elided ↑ open up ↑
 275  295          case ('C'):
 276  296                  if ('W' == cp[1] && '\0' == cp[2])
 277  297                          ok = 1;
 278  298                  break;
 279  299          default:
 280  300                  break;
 281  301          }
 282  302  
 283  303          if (0 == ok) {
 284  304                  mandoc_vmsg
 285      -                        (MANDOCERR_BADFONT, m->parse,
      305 +                        (MANDOCERR_BADFONT, man->parse,
 286  306                           n->line, n->pos, "%s", cp);
 287  307                  *cp = '\0';
 288  308          }
 289  309  
 290  310          if (1 < n->nchild)
 291  311                  mandoc_vmsg
 292      -                        (MANDOCERR_ARGCOUNT, m->parse, n->line, 
      312 +                        (MANDOCERR_ARGCOUNT, man->parse, n->line, 
 293  313                           n->pos, "want one child (have %d)", 
 294  314                           n->nchild);
 295  315  
 296  316          return(1);
 297  317  }
 298  318  
 299  319  static int
 300  320  pre_sec(CHKARGS)
 301  321  {
 302  322  
 303  323          if (MAN_BLOCK == n->type)
 304      -                m->flags &= ~MAN_LITERAL;
      324 +                man->flags &= ~MAN_LITERAL;
 305  325          return(1);
 306  326  }
 307  327  
 308  328  static int
 309  329  post_sec(CHKARGS)
 310  330  {
 311  331  
 312  332          if ( ! (MAN_HEAD == n->type && 0 == n->nchild)) 
 313  333                  return(1);
 314  334  
 315      -        man_nmsg(m, n, MANDOCERR_SYNTARGCOUNT);
      335 +        man_nmsg(man, n, MANDOCERR_SYNTARGCOUNT);
 316  336          return(0);
 317  337  }
 318  338  
 319  339  static int
 320  340  check_part(CHKARGS)
 321  341  {
 322  342  
 323  343          if (MAN_BODY == n->type && 0 == n->nchild)
 324      -                mandoc_msg(MANDOCERR_ARGCWARN, m->parse, n->line, 
      344 +                mandoc_msg(MANDOCERR_ARGCWARN, man->parse, n->line, 
 325  345                                  n->pos, "want children (have none)");
 326  346  
 327  347          return(1);
 328  348  }
 329  349  
 330  350  
 331  351  static int
 332  352  check_par(CHKARGS)
 333  353  {
 334  354  
 335  355          switch (n->type) {
 336  356          case (MAN_BLOCK):
 337  357                  if (0 == n->body->nchild)
 338      -                        man_node_delete(m, n);
      358 +                        man_node_delete(man, n);
 339  359                  break;
 340  360          case (MAN_BODY):
 341  361                  if (0 == n->nchild)
 342      -                        man_nmsg(m, n, MANDOCERR_IGNPAR);
      362 +                        man_nmsg(man, n, MANDOCERR_IGNPAR);
 343  363                  break;
 344  364          case (MAN_HEAD):
 345  365                  if (n->nchild)
 346      -                        man_nmsg(m, n, MANDOCERR_ARGSLOST);
      366 +                        man_nmsg(man, n, MANDOCERR_ARGSLOST);
 347  367                  break;
 348  368          default:
 349  369                  break;
 350  370          }
 351  371  
 352  372          return(1);
 353  373  }
 354  374  
      375 +static int
      376 +post_IP(CHKARGS)
      377 +{
 355  378  
      379 +        switch (n->type) {
      380 +        case (MAN_BLOCK):
      381 +                if (0 == n->head->nchild && 0 == n->body->nchild)
      382 +                        man_node_delete(man, n);
      383 +                break;
      384 +        case (MAN_BODY):
      385 +                if (0 == n->parent->head->nchild && 0 == n->nchild)
      386 +                        man_nmsg(man, n, MANDOCERR_IGNPAR);
      387 +                break;
      388 +        default:
      389 +                break;
      390 +        }
      391 +        return(1);
      392 +}
      393 +
 356  394  static int
 357  395  post_TH(CHKARGS)
 358  396  {
 359  397          const char      *p;
 360  398          int              line, pos;
 361  399  
 362      -        if (m->meta.title)
 363      -                free(m->meta.title);
 364      -        if (m->meta.vol)
 365      -                free(m->meta.vol);
 366      -        if (m->meta.source)
 367      -                free(m->meta.source);
 368      -        if (m->meta.msec)
 369      -                free(m->meta.msec);
 370      -        if (m->meta.date)
 371      -                free(m->meta.date);
      400 +        free(man->meta.title);
      401 +        free(man->meta.vol);
      402 +        free(man->meta.source);
      403 +        free(man->meta.msec);
      404 +        free(man->meta.date);
 372  405  
 373  406          line = n->line;
 374  407          pos = n->pos;
 375      -        m->meta.title = m->meta.vol = m->meta.date =
 376      -                m->meta.msec = m->meta.source = NULL;
      408 +        man->meta.title = man->meta.vol = man->meta.date =
      409 +                man->meta.msec = man->meta.source = NULL;
 377  410  
 378  411          /* ->TITLE<- MSEC DATE SOURCE VOL */
 379  412  
 380  413          n = n->child;
 381  414          if (n && n->string) {
 382  415                  for (p = n->string; '\0' != *p; p++) {
 383  416                          /* Only warn about this once... */
 384  417                          if (isalpha((unsigned char)*p) && 
 385  418                                          ! isupper((unsigned char)*p)) {
 386      -                                man_nmsg(m, n, MANDOCERR_UPPERCASE);
      419 +                                man_nmsg(man, n, MANDOCERR_UPPERCASE);
 387  420                                  break;
 388  421                          }
 389  422                  }
 390      -                m->meta.title = mandoc_strdup(n->string);
      423 +                man->meta.title = mandoc_strdup(n->string);
 391  424          } else
 392      -                m->meta.title = mandoc_strdup("");
      425 +                man->meta.title = mandoc_strdup("");
 393  426  
 394  427          /* TITLE ->MSEC<- DATE SOURCE VOL */
 395  428  
 396  429          if (n)
 397  430                  n = n->next;
 398  431          if (n && n->string)
 399      -                m->meta.msec = mandoc_strdup(n->string);
      432 +                man->meta.msec = mandoc_strdup(n->string);
 400  433          else
 401      -                m->meta.msec = mandoc_strdup("");
      434 +                man->meta.msec = mandoc_strdup("");
 402  435  
 403  436          /* TITLE MSEC ->DATE<- SOURCE VOL */
 404  437  
 405  438          if (n)
 406  439                  n = n->next;
 407  440          if (n && n->string && '\0' != n->string[0]) {
 408  441                  pos = n->pos;
 409      -                m->meta.date = mandoc_normdate
 410      -                    (m->parse, n->string, line, pos);
      442 +                man->meta.date = mandoc_normdate
      443 +                    (man->parse, n->string, line, pos);
 411  444          } else
 412      -                m->meta.date = mandoc_strdup("");
      445 +                man->meta.date = mandoc_strdup("");
 413  446  
 414  447          /* TITLE MSEC DATE ->SOURCE<- VOL */
 415  448  
 416  449          if (n && (n = n->next))
 417      -                m->meta.source = mandoc_strdup(n->string);
      450 +                man->meta.source = mandoc_strdup(n->string);
 418  451  
 419  452          /* TITLE MSEC DATE SOURCE ->VOL<- */
 420  453          /* If missing, use the default VOL name for MSEC. */
 421  454  
 422  455          if (n && (n = n->next))
 423      -                m->meta.vol = mandoc_strdup(n->string);
 424      -        else if ('\0' != m->meta.msec[0] &&
 425      -            (NULL != (p = mandoc_a2msec(m->meta.msec))))
 426      -                m->meta.vol = mandoc_strdup(p);
      456 +                man->meta.vol = mandoc_strdup(n->string);
      457 +        else if ('\0' != man->meta.msec[0] &&
      458 +            (NULL != (p = mandoc_a2msec(man->meta.msec))))
      459 +                man->meta.vol = mandoc_strdup(p);
 427  460  
 428  461          /*
 429  462           * Remove the `TH' node after we've processed it for our
 430  463           * meta-data.
 431  464           */
 432      -        man_node_delete(m, m->last);
      465 +        man_node_delete(man, man->last);
 433  466          return(1);
 434  467  }
 435  468  
 436  469  static int
 437  470  post_nf(CHKARGS)
 438  471  {
 439  472  
 440      -        if (MAN_LITERAL & m->flags)
 441      -                man_nmsg(m, n, MANDOCERR_SCOPEREP);
      473 +        if (MAN_LITERAL & man->flags)
      474 +                man_nmsg(man, n, MANDOCERR_SCOPEREP);
 442  475  
 443      -        m->flags |= MAN_LITERAL;
      476 +        man->flags |= MAN_LITERAL;
 444  477          return(1);
 445  478  }
 446  479  
 447  480  static int
 448  481  post_fi(CHKARGS)
 449  482  {
 450  483  
 451      -        if ( ! (MAN_LITERAL & m->flags))
 452      -                man_nmsg(m, n, MANDOCERR_WNOSCOPE);
      484 +        if ( ! (MAN_LITERAL & man->flags))
      485 +                man_nmsg(man, n, MANDOCERR_WNOSCOPE);
 453  486  
 454      -        m->flags &= ~MAN_LITERAL;
      487 +        man->flags &= ~MAN_LITERAL;
 455  488          return(1);
 456  489  }
 457  490  
 458  491  static int
 459  492  post_UC(CHKARGS)
 460  493  {
 461  494          static const char * const bsd_versions[] = {
 462  495              "3rd Berkeley Distribution",
 463  496              "4th Berkeley Distribution",
 464  497              "4.2 Berkeley Distribution",
↓ open down ↓ 16 lines elided ↑ open up ↑
 481  514                  else if (0 == strcmp(s, "5"))
 482  515                          p = bsd_versions[2];
 483  516                  else if (0 == strcmp(s, "6"))
 484  517                          p = bsd_versions[3];
 485  518                  else if (0 == strcmp(s, "7"))
 486  519                          p = bsd_versions[4];
 487  520                  else
 488  521                          p = bsd_versions[0];
 489  522          }
 490  523  
 491      -        if (m->meta.source)
 492      -                free(m->meta.source);
 493      -
 494      -        m->meta.source = mandoc_strdup(p);
      524 +        free(man->meta.source);
      525 +        man->meta.source = mandoc_strdup(p);
 495  526          return(1);
 496  527  }
 497  528  
 498  529  static int
 499  530  post_AT(CHKARGS)
 500  531  {
 501  532          static const char * const unix_versions[] = {
 502  533              "7th Edition",
 503  534              "System III",
 504  535              "System V",
↓ open down ↓ 16 lines elided ↑ open up ↑
 521  552                  else if (0 == strcmp(s, "5")) {
 522  553                          nn = n->next;
 523  554                          if (nn && MAN_TEXT == nn->type && nn->string[0])
 524  555                                  p = unix_versions[3];
 525  556                          else
 526  557                                  p = unix_versions[2];
 527  558                  } else
 528  559                          p = unix_versions[0];
 529  560          }
 530  561  
 531      -        if (m->meta.source)
 532      -                free(m->meta.source);
 533      -
 534      -        m->meta.source = mandoc_strdup(p);
      562 +        free(man->meta.source);
      563 +        man->meta.source = mandoc_strdup(p);
 535  564          return(1);
 536  565  }
 537  566  
 538  567  static int
 539  568  post_vs(CHKARGS)
 540  569  {
 541  570  
 542      -        /* 
 543      -         * Don't warn about this because it occurs in pod2man and would
 544      -         * cause considerable (unfixable) warnage.
 545      -         */
 546      -        if (NULL == n->prev && MAN_ROOT == n->parent->type)
 547      -                man_node_delete(m, n);
      571 +        if (NULL != n->prev)
      572 +                return(1);
 548  573  
      574 +        switch (n->parent->tok) {
      575 +        case (MAN_SH):
      576 +                /* FALLTHROUGH */
      577 +        case (MAN_SS):
      578 +                man_nmsg(man, n, MANDOCERR_IGNPAR);
      579 +                /* FALLTHROUGH */
      580 +        case (MAN_MAX):
      581 +                /* 
      582 +                 * Don't warn about this because it occurs in pod2man
      583 +                 * and would cause considerable (unfixable) warnage.
      584 +                 */
      585 +                man_node_delete(man, n);
      586 +                break;
      587 +        default:
      588 +                break;
      589 +        }
      590 +
 549  591          return(1);
 550  592  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX