Print this page
Update to 1.12.3.

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/mandoc/mdoc.c
          +++ new/usr/src/cmd/mandoc/mdoc.c
   1      -/*      $Id: mdoc.c,v 1.196 2011/09/30 00:13:28 schwarze Exp $ */
        1 +/*      $Id: mdoc.c,v 1.206 2013/12/24 19:11:46 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 ↓ 82 lines elided ↑ open up ↑
  97   97                                  enum mdoct, enum mdoc_type);
  98   98  static  int               node_append(struct mdoc *, 
  99   99                                  struct mdoc_node *);
 100  100  #if 0
 101  101  static  int               mdoc_preptext(struct mdoc *, int, char *, int);
 102  102  #endif
 103  103  static  int               mdoc_ptext(struct mdoc *, int, char *, int);
 104  104  static  int               mdoc_pmacro(struct mdoc *, int, char *, int);
 105  105  
 106  106  const struct mdoc_node *
 107      -mdoc_node(const struct mdoc *m)
      107 +mdoc_node(const struct mdoc *mdoc)
 108  108  {
 109  109  
 110      -        assert( ! (MDOC_HALT & m->flags));
 111      -        return(m->first);
      110 +        assert( ! (MDOC_HALT & mdoc->flags));
      111 +        return(mdoc->first);
 112  112  }
 113  113  
 114  114  
 115  115  const struct mdoc_meta *
 116      -mdoc_meta(const struct mdoc *m)
      116 +mdoc_meta(const struct mdoc *mdoc)
 117  117  {
 118  118  
 119      -        assert( ! (MDOC_HALT & m->flags));
 120      -        return(&m->meta);
      119 +        assert( ! (MDOC_HALT & mdoc->flags));
      120 +        return(&mdoc->meta);
 121  121  }
 122  122  
 123  123  
 124  124  /*
 125  125   * Frees volatile resources (parse tree, meta-data, fields).
 126  126   */
 127  127  static void
 128  128  mdoc_free1(struct mdoc *mdoc)
 129  129  {
 130  130  
↓ open down ↓ 59 lines elided ↑ open up ↑
 190  190  
 191  191          mdoc_free1(mdoc);
 192  192          free(mdoc);
 193  193  }
 194  194  
 195  195  
 196  196  /*
 197  197   * Allocate volatile and non-volatile parse resources.  
 198  198   */
 199  199  struct mdoc *
 200      -mdoc_alloc(struct roff *roff, struct mparse *parse)
      200 +mdoc_alloc(struct roff *roff, struct mparse *parse, char *defos)
 201  201  {
 202  202          struct mdoc     *p;
 203  203  
 204  204          p = mandoc_calloc(1, sizeof(struct mdoc));
 205  205  
 206  206          p->parse = parse;
      207 +        p->defos = defos;
 207  208          p->roff = roff;
 208  209  
 209  210          mdoc_hash_init();
 210  211          mdoc_alloc1(p);
 211  212          return(p);
 212  213  }
 213  214  
 214  215  
 215  216  /*
 216  217   * Climb back up the parse tree, validating open scopes.  Mostly calls
 217  218   * through to macro_end() in macro.c.
 218  219   */
 219  220  int
 220      -mdoc_endparse(struct mdoc *m)
      221 +mdoc_endparse(struct mdoc *mdoc)
 221  222  {
 222  223  
 223      -        assert( ! (MDOC_HALT & m->flags));
 224      -        if (mdoc_macroend(m))
      224 +        assert( ! (MDOC_HALT & mdoc->flags));
      225 +        if (mdoc_macroend(mdoc))
 225  226                  return(1);
 226      -        m->flags |= MDOC_HALT;
      227 +        mdoc->flags |= MDOC_HALT;
 227  228          return(0);
 228  229  }
 229  230  
 230  231  int
 231      -mdoc_addeqn(struct mdoc *m, const struct eqn *ep)
      232 +mdoc_addeqn(struct mdoc *mdoc, const struct eqn *ep)
 232  233  {
 233  234          struct mdoc_node *n;
 234  235  
 235      -        assert( ! (MDOC_HALT & m->flags));
      236 +        assert( ! (MDOC_HALT & mdoc->flags));
 236  237  
 237  238          /* No text before an initial macro. */
 238  239  
 239      -        if (SEC_NONE == m->lastnamed) {
 240      -                mdoc_pmsg(m, ep->ln, ep->pos, MANDOCERR_NOTEXT);
      240 +        if (SEC_NONE == mdoc->lastnamed) {
      241 +                mdoc_pmsg(mdoc, ep->ln, ep->pos, MANDOCERR_NOTEXT);
 241  242                  return(1);
 242  243          }
 243  244  
 244      -        n = node_alloc(m, ep->ln, ep->pos, MDOC_MAX, MDOC_EQN);
      245 +        n = node_alloc(mdoc, ep->ln, ep->pos, MDOC_MAX, MDOC_EQN);
 245  246          n->eqn = ep;
 246  247  
 247      -        if ( ! node_append(m, n))
      248 +        if ( ! node_append(mdoc, n))
 248  249                  return(0);
 249  250  
 250      -        m->next = MDOC_NEXT_SIBLING;
      251 +        mdoc->next = MDOC_NEXT_SIBLING;
 251  252          return(1);
 252  253  }
 253  254  
 254  255  int
 255      -mdoc_addspan(struct mdoc *m, const struct tbl_span *sp)
      256 +mdoc_addspan(struct mdoc *mdoc, const struct tbl_span *sp)
 256  257  {
 257  258          struct mdoc_node *n;
 258  259  
 259      -        assert( ! (MDOC_HALT & m->flags));
      260 +        assert( ! (MDOC_HALT & mdoc->flags));
 260  261  
 261  262          /* No text before an initial macro. */
 262  263  
 263      -        if (SEC_NONE == m->lastnamed) {
 264      -                mdoc_pmsg(m, sp->line, 0, MANDOCERR_NOTEXT);
      264 +        if (SEC_NONE == mdoc->lastnamed) {
      265 +                mdoc_pmsg(mdoc, sp->line, 0, MANDOCERR_NOTEXT);
 265  266                  return(1);
 266  267          }
 267  268  
 268      -        n = node_alloc(m, sp->line, 0, MDOC_MAX, MDOC_TBL);
      269 +        n = node_alloc(mdoc, sp->line, 0, MDOC_MAX, MDOC_TBL);
 269  270          n->span = sp;
 270  271  
 271      -        if ( ! node_append(m, n))
      272 +        if ( ! node_append(mdoc, n))
 272  273                  return(0);
 273  274  
 274      -        m->next = MDOC_NEXT_SIBLING;
      275 +        mdoc->next = MDOC_NEXT_SIBLING;
 275  276          return(1);
 276  277  }
 277  278  
 278  279  
 279  280  /*
 280  281   * Main parse routine.  Parses a single line -- really just hands off to
 281  282   * the macro (mdoc_pmacro()) or text parser (mdoc_ptext()).
 282  283   */
 283  284  int
 284      -mdoc_parseln(struct mdoc *m, int ln, char *buf, int offs)
      285 +mdoc_parseln(struct mdoc *mdoc, int ln, char *buf, int offs)
 285  286  {
 286  287  
 287      -        assert( ! (MDOC_HALT & m->flags));
      288 +        assert( ! (MDOC_HALT & mdoc->flags));
 288  289  
 289      -        m->flags |= MDOC_NEWLINE;
      290 +        mdoc->flags |= MDOC_NEWLINE;
 290  291  
 291  292          /*
 292  293           * Let the roff nS register switch SYNOPSIS mode early,
 293  294           * such that the parser knows at all times
 294  295           * whether this mode is on or off.
 295  296           * Note that this mode is also switched by the Sh macro.
 296  297           */
 297      -        if (roff_regisset(m->roff, REG_nS)) {
 298      -                if (roff_regget(m->roff, REG_nS))
 299      -                        m->flags |= MDOC_SYNOPSIS;
 300      -                else
 301      -                        m->flags &= ~MDOC_SYNOPSIS;
 302      -        }
      298 +        if (roff_getreg(mdoc->roff, "nS"))
      299 +                mdoc->flags |= MDOC_SYNOPSIS;
      300 +        else
      301 +                mdoc->flags &= ~MDOC_SYNOPSIS;
 303  302  
 304      -        return(mandoc_getcontrol(buf, &offs) ?
 305      -                        mdoc_pmacro(m, ln, buf, offs) :
 306      -                        mdoc_ptext(m, ln, buf, offs));
      303 +        return(roff_getcontrol(mdoc->roff, buf, &offs) ?
      304 +                        mdoc_pmacro(mdoc, ln, buf, offs) :
      305 +                        mdoc_ptext(mdoc, ln, buf, offs));
 307  306  }
 308  307  
 309  308  int
 310  309  mdoc_macro(MACRO_PROT_ARGS)
 311  310  {
 312  311          assert(tok < MDOC_MAX);
 313  312  
 314  313          /* If we're in the body, deny prologue calls. */
 315  314  
 316  315          if (MDOC_PROLOGUE & mdoc_macros[tok].flags && 
 317      -                        MDOC_PBODY & m->flags) {
 318      -                mdoc_pmsg(m, line, ppos, MANDOCERR_BADBODY);
      316 +                        MDOC_PBODY & mdoc->flags) {
      317 +                mdoc_pmsg(mdoc, line, ppos, MANDOCERR_BADBODY);
 319  318                  return(1);
 320  319          }
 321  320  
 322  321          /* If we're in the prologue, deny "body" macros.  */
 323  322  
 324  323          if ( ! (MDOC_PROLOGUE & mdoc_macros[tok].flags) && 
 325      -                        ! (MDOC_PBODY & m->flags)) {
 326      -                mdoc_pmsg(m, line, ppos, MANDOCERR_BADPROLOG);
 327      -                if (NULL == m->meta.msec)
 328      -                        m->meta.msec = mandoc_strdup("1");
 329      -                if (NULL == m->meta.title)
 330      -                        m->meta.title = mandoc_strdup("UNKNOWN");
 331      -                if (NULL == m->meta.vol)
 332      -                        m->meta.vol = mandoc_strdup("LOCAL");
 333      -                if (NULL == m->meta.os)
 334      -                        m->meta.os = mandoc_strdup("LOCAL");
 335      -                if (NULL == m->meta.date)
 336      -                        m->meta.date = mandoc_normdate
 337      -                                (m->parse, NULL, line, ppos);
 338      -                m->flags |= MDOC_PBODY;
      324 +                        ! (MDOC_PBODY & mdoc->flags)) {
      325 +                mdoc_pmsg(mdoc, line, ppos, MANDOCERR_BADPROLOG);
      326 +                if (NULL == mdoc->meta.msec)
      327 +                        mdoc->meta.msec = mandoc_strdup("1");
      328 +                if (NULL == mdoc->meta.title)
      329 +                        mdoc->meta.title = mandoc_strdup("UNKNOWN");
      330 +                if (NULL == mdoc->meta.vol)
      331 +                        mdoc->meta.vol = mandoc_strdup("LOCAL");
      332 +                if (NULL == mdoc->meta.os)
      333 +                        mdoc->meta.os = mandoc_strdup("LOCAL");
      334 +                if (NULL == mdoc->meta.date)
      335 +                        mdoc->meta.date = mandoc_normdate
      336 +                                (mdoc->parse, NULL, line, ppos);
      337 +                mdoc->flags |= MDOC_PBODY;
 339  338          }
 340  339  
 341      -        return((*mdoc_macros[tok].fp)(m, tok, line, ppos, pos, buf));
      340 +        return((*mdoc_macros[tok].fp)(mdoc, tok, line, ppos, pos, buf));
 342  341  }
 343  342  
 344  343  
 345  344  static int
 346  345  node_append(struct mdoc *mdoc, struct mdoc_node *p)
 347  346  {
 348  347  
 349  348          assert(mdoc->last);
 350  349          assert(mdoc->first);
 351  350          assert(MDOC_ROOT != p->type);
↓ open down ↓ 15 lines elided ↑ open up ↑
 367  366  
 368  367          p->parent->nchild++;
 369  368  
 370  369          /*
 371  370           * Copy over the normalised-data pointer of our parent.  Not
 372  371           * everybody has one, but copying a null pointer is fine.
 373  372           */
 374  373  
 375  374          switch (p->type) {
 376  375          case (MDOC_BODY):
      376 +                if (ENDBODY_NOT != p->end)
      377 +                        break;
 377  378                  /* FALLTHROUGH */
 378  379          case (MDOC_TAIL):
 379  380                  /* FALLTHROUGH */
 380  381          case (MDOC_HEAD):
 381  382                  p->norm = p->parent->norm;
 382  383                  break;
 383  384          default:
 384  385                  break;
 385  386          }
 386  387  
↓ open down ↓ 30 lines elided ↑ open up ↑
 417  418                  break;
 418  419          default:
 419  420                  break;
 420  421          }
 421  422  
 422  423          return(1);
 423  424  }
 424  425  
 425  426  
 426  427  static struct mdoc_node *
 427      -node_alloc(struct mdoc *m, int line, int pos, 
      428 +node_alloc(struct mdoc *mdoc, int line, int pos, 
 428  429                  enum mdoct tok, enum mdoc_type type)
 429  430  {
 430  431          struct mdoc_node *p;
 431  432  
 432  433          p = mandoc_calloc(1, sizeof(struct mdoc_node));
 433      -        p->sec = m->lastsec;
      434 +        p->sec = mdoc->lastsec;
 434  435          p->line = line;
 435  436          p->pos = pos;
      437 +        p->lastline = line;
 436  438          p->tok = tok;
 437  439          p->type = type;
 438  440  
 439  441          /* Flag analysis. */
 440  442  
 441      -        if (MDOC_SYNOPSIS & m->flags)
      443 +        if (MDOC_SYNOPSIS & mdoc->flags)
 442  444                  p->flags |= MDOC_SYNPRETTY;
 443  445          else
 444  446                  p->flags &= ~MDOC_SYNPRETTY;
 445      -        if (MDOC_NEWLINE & m->flags)
      447 +        if (MDOC_NEWLINE & mdoc->flags)
 446  448                  p->flags |= MDOC_LINE;
 447      -        m->flags &= ~MDOC_NEWLINE;
      449 +        mdoc->flags &= ~MDOC_NEWLINE;
 448  450  
 449  451          return(p);
 450  452  }
 451  453  
 452  454  
 453  455  int
 454      -mdoc_tail_alloc(struct mdoc *m, int line, int pos, enum mdoct tok)
      456 +mdoc_tail_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok)
 455  457  {
 456  458          struct mdoc_node *p;
 457  459  
 458      -        p = node_alloc(m, line, pos, tok, MDOC_TAIL);
 459      -        if ( ! node_append(m, p))
      460 +        p = node_alloc(mdoc, line, pos, tok, MDOC_TAIL);
      461 +        if ( ! node_append(mdoc, p))
 460  462                  return(0);
 461      -        m->next = MDOC_NEXT_CHILD;
      463 +        mdoc->next = MDOC_NEXT_CHILD;
 462  464          return(1);
 463  465  }
 464  466  
 465  467  
 466  468  int
 467      -mdoc_head_alloc(struct mdoc *m, int line, int pos, enum mdoct tok)
      469 +mdoc_head_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok)
 468  470  {
 469  471          struct mdoc_node *p;
 470  472  
 471      -        assert(m->first);
 472      -        assert(m->last);
      473 +        assert(mdoc->first);
      474 +        assert(mdoc->last);
 473  475  
 474      -        p = node_alloc(m, line, pos, tok, MDOC_HEAD);
 475      -        if ( ! node_append(m, p))
      476 +        p = node_alloc(mdoc, line, pos, tok, MDOC_HEAD);
      477 +        if ( ! node_append(mdoc, p))
 476  478                  return(0);
 477      -        m->next = MDOC_NEXT_CHILD;
      479 +        mdoc->next = MDOC_NEXT_CHILD;
 478  480          return(1);
 479  481  }
 480  482  
 481  483  
 482  484  int
 483      -mdoc_body_alloc(struct mdoc *m, int line, int pos, enum mdoct tok)
      485 +mdoc_body_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok)
 484  486  {
 485  487          struct mdoc_node *p;
 486  488  
 487      -        p = node_alloc(m, line, pos, tok, MDOC_BODY);
 488      -        if ( ! node_append(m, p))
      489 +        p = node_alloc(mdoc, line, pos, tok, MDOC_BODY);
      490 +        if ( ! node_append(mdoc, p))
 489  491                  return(0);
 490      -        m->next = MDOC_NEXT_CHILD;
      492 +        mdoc->next = MDOC_NEXT_CHILD;
 491  493          return(1);
 492  494  }
 493  495  
 494  496  
 495  497  int
 496      -mdoc_endbody_alloc(struct mdoc *m, int line, int pos, enum mdoct tok,
      498 +mdoc_endbody_alloc(struct mdoc *mdoc, int line, int pos, enum mdoct tok,
 497  499                  struct mdoc_node *body, enum mdoc_endbody end)
 498  500  {
 499  501          struct mdoc_node *p;
 500  502  
 501      -        p = node_alloc(m, line, pos, tok, MDOC_BODY);
      503 +        p = node_alloc(mdoc, line, pos, tok, MDOC_BODY);
 502  504          p->pending = body;
      505 +        p->norm = body->norm;
 503  506          p->end = end;
 504      -        if ( ! node_append(m, p))
      507 +        if ( ! node_append(mdoc, p))
 505  508                  return(0);
 506      -        m->next = MDOC_NEXT_SIBLING;
      509 +        mdoc->next = MDOC_NEXT_SIBLING;
 507  510          return(1);
 508  511  }
 509  512  
 510  513  
 511  514  int
 512      -mdoc_block_alloc(struct mdoc *m, int line, int pos, 
      515 +mdoc_block_alloc(struct mdoc *mdoc, int line, int pos, 
 513  516                  enum mdoct tok, struct mdoc_arg *args)
 514  517  {
 515  518          struct mdoc_node *p;
 516  519  
 517      -        p = node_alloc(m, line, pos, tok, MDOC_BLOCK);
      520 +        p = node_alloc(mdoc, line, pos, tok, MDOC_BLOCK);
 518  521          p->args = args;
 519  522          if (p->args)
 520  523                  (args->refcnt)++;
 521  524  
 522  525          switch (tok) {
 523  526          case (MDOC_Bd):
 524  527                  /* FALLTHROUGH */
 525  528          case (MDOC_Bf):
 526  529                  /* FALLTHROUGH */
 527  530          case (MDOC_Bl):
 528  531                  /* FALLTHROUGH */
 529  532          case (MDOC_Rs):
 530  533                  p->norm = mandoc_calloc(1, sizeof(union mdoc_data));
 531  534                  break;
 532  535          default:
 533  536                  break;
 534  537          }
 535  538  
 536      -        if ( ! node_append(m, p))
      539 +        if ( ! node_append(mdoc, p))
 537  540                  return(0);
 538      -        m->next = MDOC_NEXT_CHILD;
      541 +        mdoc->next = MDOC_NEXT_CHILD;
 539  542          return(1);
 540  543  }
 541  544  
 542  545  
 543  546  int
 544      -mdoc_elem_alloc(struct mdoc *m, int line, int pos, 
      547 +mdoc_elem_alloc(struct mdoc *mdoc, int line, int pos, 
 545  548                  enum mdoct tok, struct mdoc_arg *args)
 546  549  {
 547  550          struct mdoc_node *p;
 548  551  
 549      -        p = node_alloc(m, line, pos, tok, MDOC_ELEM);
      552 +        p = node_alloc(mdoc, line, pos, tok, MDOC_ELEM);
 550  553          p->args = args;
 551  554          if (p->args)
 552  555                  (args->refcnt)++;
 553  556  
 554  557          switch (tok) {
 555  558          case (MDOC_An):
 556  559                  p->norm = mandoc_calloc(1, sizeof(union mdoc_data));
 557  560                  break;
 558  561          default:
 559  562                  break;
 560  563          }
 561  564  
 562      -        if ( ! node_append(m, p))
      565 +        if ( ! node_append(mdoc, p))
 563  566                  return(0);
 564      -        m->next = MDOC_NEXT_CHILD;
      567 +        mdoc->next = MDOC_NEXT_CHILD;
 565  568          return(1);
 566  569  }
 567  570  
 568  571  int
 569      -mdoc_word_alloc(struct mdoc *m, int line, int pos, const char *p)
      572 +mdoc_word_alloc(struct mdoc *mdoc, int line, int pos, const char *p)
 570  573  {
 571  574          struct mdoc_node *n;
 572  575  
 573      -        n = node_alloc(m, line, pos, MDOC_MAX, MDOC_TEXT);
 574      -        n->string = roff_strdup(m->roff, p);
      576 +        n = node_alloc(mdoc, line, pos, MDOC_MAX, MDOC_TEXT);
      577 +        n->string = roff_strdup(mdoc->roff, p);
 575  578  
 576      -        if ( ! node_append(m, n))
      579 +        if ( ! node_append(mdoc, n))
 577  580                  return(0);
 578  581  
 579      -        m->next = MDOC_NEXT_SIBLING;
      582 +        mdoc->next = MDOC_NEXT_SIBLING;
 580  583          return(1);
 581  584  }
 582  585  
      586 +void
      587 +mdoc_word_append(struct mdoc *mdoc, const char *p)
      588 +{
      589 +        struct mdoc_node        *n;
      590 +        char                    *addstr, *newstr;
 583  591  
      592 +        n = mdoc->last;
      593 +        addstr = roff_strdup(mdoc->roff, p);
      594 +        if (-1 == asprintf(&newstr, "%s %s", n->string, addstr)) {
      595 +                perror(NULL);
      596 +                exit((int)MANDOCLEVEL_SYSERR);
      597 +        }
      598 +        free(addstr);
      599 +        free(n->string);
      600 +        n->string = newstr;
      601 +        mdoc->next = MDOC_NEXT_SIBLING;
      602 +}
      603 +
 584  604  static void
 585  605  mdoc_node_free(struct mdoc_node *p)
 586  606  {
 587  607  
 588  608          if (MDOC_BLOCK == p->type || MDOC_ELEM == p->type)
 589  609                  free(p->norm);
 590  610          if (p->string)
 591  611                  free(p->string);
 592  612          if (p->args)
 593  613                  mdoc_argv_free(p->args);
 594  614          free(p);
 595  615  }
 596  616  
 597  617  
 598  618  static void
 599      -mdoc_node_unlink(struct mdoc *m, struct mdoc_node *n)
      619 +mdoc_node_unlink(struct mdoc *mdoc, struct mdoc_node *n)
 600  620  {
 601  621  
 602  622          /* Adjust siblings. */
 603  623  
 604  624          if (n->prev)
 605  625                  n->prev->next = n->next;
 606  626          if (n->next)
 607  627                  n->next->prev = n->prev;
 608  628  
 609  629          /* Adjust parent. */
↓ open down ↓ 1 lines elided ↑ open up ↑
 611  631          if (n->parent) {
 612  632                  n->parent->nchild--;
 613  633                  if (n->parent->child == n)
 614  634                          n->parent->child = n->prev ? n->prev : n->next;
 615  635                  if (n->parent->last == n)
 616  636                          n->parent->last = n->prev ? n->prev : NULL;
 617  637          }
 618  638  
 619  639          /* Adjust parse point, if applicable. */
 620  640  
 621      -        if (m && m->last == n) {
      641 +        if (mdoc && mdoc->last == n) {
 622  642                  if (n->prev) {
 623      -                        m->last = n->prev;
 624      -                        m->next = MDOC_NEXT_SIBLING;
      643 +                        mdoc->last = n->prev;
      644 +                        mdoc->next = MDOC_NEXT_SIBLING;
 625  645                  } else {
 626      -                        m->last = n->parent;
 627      -                        m->next = MDOC_NEXT_CHILD;
      646 +                        mdoc->last = n->parent;
      647 +                        mdoc->next = MDOC_NEXT_CHILD;
 628  648                  }
 629  649          }
 630  650  
 631      -        if (m && m->first == n)
 632      -                m->first = NULL;
      651 +        if (mdoc && mdoc->first == n)
      652 +                mdoc->first = NULL;
 633  653  }
 634  654  
 635  655  
 636  656  void
 637      -mdoc_node_delete(struct mdoc *m, struct mdoc_node *p)
      657 +mdoc_node_delete(struct mdoc *mdoc, struct mdoc_node *p)
 638  658  {
 639  659  
 640  660          while (p->child) {
 641  661                  assert(p->nchild);
 642      -                mdoc_node_delete(m, p->child);
      662 +                mdoc_node_delete(mdoc, p->child);
 643  663          }
 644  664          assert(0 == p->nchild);
 645  665  
 646      -        mdoc_node_unlink(m, p);
      666 +        mdoc_node_unlink(mdoc, p);
 647  667          mdoc_node_free(p);
 648  668  }
 649  669  
      670 +int
      671 +mdoc_node_relink(struct mdoc *mdoc, struct mdoc_node *p)
      672 +{
      673 +
      674 +        mdoc_node_unlink(mdoc, p);
      675 +        return(node_append(mdoc, p));
      676 +}
      677 +
 650  678  #if 0
 651  679  /*
 652  680   * Pre-treat a text line.
 653  681   * Text lines can consist of equations, which must be handled apart from
 654  682   * the regular text.
 655  683   * Thus, use this function to step through a line checking if it has any
 656  684   * equations embedded in it.
 657  685   * This must handle multiple equations AND equations that do not end at
 658  686   * the end-of-line, i.e., will re-enter in the next roff parse.
 659  687   */
 660  688  static int
 661      -mdoc_preptext(struct mdoc *m, int line, char *buf, int offs)
      689 +mdoc_preptext(struct mdoc *mdoc, int line, char *buf, int offs)
 662  690  {
 663  691          char            *start, *end;
 664  692          char             delim;
 665  693  
 666  694          while ('\0' != buf[offs]) {
 667  695                  /* Mark starting position if eqn is set. */
 668  696                  start = NULL;
 669      -                if ('\0' != (delim = roff_eqndelim(m->roff)))
      697 +                if ('\0' != (delim = roff_eqndelim(mdoc->roff)))
 670  698                          if (NULL != (start = strchr(buf + offs, delim)))
 671  699                                  *start++ = '\0';
 672  700  
 673  701                  /* Parse text as normal. */
 674      -                if ( ! mdoc_ptext(m, line, buf, offs))
      702 +                if ( ! mdoc_ptext(mdoc, line, buf, offs))
 675  703                          return(0);
 676  704  
 677  705                  /* Continue only if an equation exists. */
 678  706                  if (NULL == start)
 679  707                          break;
 680  708  
 681  709                  /* Read past the end of the equation. */
 682  710                  offs += start - (buf + offs);
 683  711                  assert(start == &buf[offs]);
 684  712                  if (NULL != (end = strchr(buf + offs, delim))) {
 685  713                          *end++ = '\0';
 686  714                          while (' ' == *end)
 687  715                                  end++;
 688  716                  }
 689  717  
 690  718                  /* Parse the equation itself. */
 691      -                roff_openeqn(m->roff, NULL, line, offs, buf);
      719 +                roff_openeqn(mdoc->roff, NULL, line, offs, buf);
 692  720  
 693  721                  /* Process a finished equation? */
 694      -                if (roff_closeeqn(m->roff))
 695      -                        if ( ! mdoc_addeqn(m, roff_eqn(m->roff)))
      722 +                if (roff_closeeqn(mdoc->roff))
      723 +                        if ( ! mdoc_addeqn(mdoc, roff_eqn(mdoc->roff)))
 696  724                                  return(0);
 697  725                  offs += (end - (buf + offs));
 698  726          } 
 699  727  
 700  728          return(1);
 701  729  }
 702  730  #endif
 703  731  
 704  732  /*
 705  733   * Parse free-form text, that is, a line that does not begin with the
 706  734   * control character.
 707  735   */
 708  736  static int
 709      -mdoc_ptext(struct mdoc *m, int line, char *buf, int offs)
      737 +mdoc_ptext(struct mdoc *mdoc, int line, char *buf, int offs)
 710  738  {
 711  739          char             *c, *ws, *end;
 712  740          struct mdoc_node *n;
 713  741  
 714  742          /* No text before an initial macro. */
 715  743  
 716      -        if (SEC_NONE == m->lastnamed) {
 717      -                mdoc_pmsg(m, line, offs, MANDOCERR_NOTEXT);
      744 +        if (SEC_NONE == mdoc->lastnamed) {
      745 +                mdoc_pmsg(mdoc, line, offs, MANDOCERR_NOTEXT);
 718  746                  return(1);
 719  747          }
 720  748  
 721      -        assert(m->last);
 722      -        n = m->last;
      749 +        assert(mdoc->last);
      750 +        n = mdoc->last;
 723  751  
 724  752          /*
 725  753           * Divert directly to list processing if we're encountering a
 726  754           * columnar MDOC_BLOCK with or without a prior MDOC_BLOCK entry
 727  755           * (a MDOC_BODY means it's already open, in which case we should
 728  756           * process within its context in the normal way).
 729  757           */
 730  758  
 731  759          if (MDOC_Bl == n->tok && MDOC_BODY == n->type &&
 732  760                          LIST_column == n->norm->Bl.type) {
 733  761                  /* `Bl' is open without any children. */
 734      -                m->flags |= MDOC_FREECOL;
 735      -                return(mdoc_macro(m, MDOC_It, line, offs, &offs, buf));
      762 +                mdoc->flags |= MDOC_FREECOL;
      763 +                return(mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf));
 736  764          }
 737  765  
 738  766          if (MDOC_It == n->tok && MDOC_BLOCK == n->type &&
 739  767                          NULL != n->parent &&
 740  768                          MDOC_Bl == n->parent->tok &&
 741  769                          LIST_column == n->parent->norm->Bl.type) {
 742  770                  /* `Bl' has block-level `It' children. */
 743      -                m->flags |= MDOC_FREECOL;
 744      -                return(mdoc_macro(m, MDOC_It, line, offs, &offs, buf));
      771 +                mdoc->flags |= MDOC_FREECOL;
      772 +                return(mdoc_macro(mdoc, MDOC_It, line, offs, &offs, buf));
 745  773          }
 746  774  
 747  775          /*
 748  776           * Search for the beginning of unescaped trailing whitespace (ws)
 749  777           * and for the first character not to be output (end).
 750  778           */
 751  779  
 752  780          /* FIXME: replace with strcspn(). */
 753  781          ws = NULL;
 754  782          for (c = end = buf + offs; *c; c++) {
↓ open down ↓ 7 lines elided ↑ open up ↑
 762  790                           * Always warn about trailing tabs,
 763  791                           * even outside literal context,
 764  792                           * where they should be put on the next line.
 765  793                           */
 766  794                          if (NULL == ws)
 767  795                                  ws = c;
 768  796                          /*
 769  797                           * Strip trailing tabs in literal context only;
 770  798                           * outside, they affect the next line.
 771  799                           */
 772      -                        if (MDOC_LITERAL & m->flags)
      800 +                        if (MDOC_LITERAL & mdoc->flags)
 773  801                                  continue;
 774  802                          break;
 775  803                  case '\\':
 776  804                          /* Skip the escaped character, too, if any. */
 777  805                          if (c[1])
 778  806                                  c++;
 779  807                          /* FALLTHROUGH */
 780  808                  default:
 781  809                          ws = NULL;
 782  810                          break;
 783  811                  }
 784  812                  end = c + 1;
 785  813          }
 786  814          *end = '\0';
 787  815  
 788  816          if (ws)
 789      -                mdoc_pmsg(m, line, (int)(ws-buf), MANDOCERR_EOLNSPACE);
      817 +                mdoc_pmsg(mdoc, line, (int)(ws-buf), MANDOCERR_EOLNSPACE);
 790  818  
 791      -        if ('\0' == buf[offs] && ! (MDOC_LITERAL & m->flags)) {
 792      -                mdoc_pmsg(m, line, (int)(c-buf), MANDOCERR_NOBLANKLN);
      819 +        if ('\0' == buf[offs] && ! (MDOC_LITERAL & mdoc->flags)) {
      820 +                mdoc_pmsg(mdoc, line, (int)(c-buf), MANDOCERR_NOBLANKLN);
 793  821  
 794  822                  /*
 795  823                   * Insert a `sp' in the case of a blank line.  Technically,
 796  824                   * blank lines aren't allowed, but enough manuals assume this
 797  825                   * behaviour that we want to work around it.
 798  826                   */
 799      -                if ( ! mdoc_elem_alloc(m, line, offs, MDOC_sp, NULL))
      827 +                if ( ! mdoc_elem_alloc(mdoc, line, offs, MDOC_sp, NULL))
 800  828                          return(0);
 801  829  
 802      -                m->next = MDOC_NEXT_SIBLING;
 803      -                return(1);
      830 +                mdoc->next = MDOC_NEXT_SIBLING;
      831 +
      832 +                return(mdoc_valid_post(mdoc));
 804  833          }
 805  834  
 806      -        if ( ! mdoc_word_alloc(m, line, offs, buf+offs))
      835 +        if ( ! mdoc_word_alloc(mdoc, line, offs, buf+offs))
 807  836                  return(0);
 808  837  
 809      -        if (MDOC_LITERAL & m->flags)
      838 +        if (MDOC_LITERAL & mdoc->flags)
 810  839                  return(1);
 811  840  
 812  841          /*
 813  842           * End-of-sentence check.  If the last character is an unescaped
 814  843           * EOS character, then flag the node as being the end of a
 815  844           * sentence.  The front-end will know how to interpret this.
 816  845           */
 817  846  
 818  847          assert(buf < end);
 819  848  
 820  849          if (mandoc_eos(buf+offs, (size_t)(end-buf-offs), 0))
 821      -                m->last->flags |= MDOC_EOS;
      850 +                mdoc->last->flags |= MDOC_EOS;
 822  851  
 823  852          return(1);
 824  853  }
 825  854  
 826  855  
 827  856  /*
 828  857   * Parse a macro line, that is, a line beginning with the control
 829  858   * character.
 830  859   */
 831  860  static int
 832      -mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs)
      861 +mdoc_pmacro(struct mdoc *mdoc, int ln, char *buf, int offs)
 833  862  {
 834  863          enum mdoct        tok;
 835  864          int               i, sv;
 836  865          char              mac[5];
 837  866          struct mdoc_node *n;
 838  867  
 839  868          /* Empty post-control lines are ignored. */
 840  869  
 841  870          if ('"' == buf[offs]) {
 842      -                mdoc_pmsg(m, ln, offs, MANDOCERR_BADCOMMENT);
      871 +                mdoc_pmsg(mdoc, ln, offs, MANDOCERR_BADCOMMENT);
 843  872                  return(1);
 844  873          } else if ('\0' == buf[offs])
 845  874                  return(1);
 846  875  
 847  876          sv = offs;
 848  877  
 849  878          /* 
 850  879           * Copy the first word into a nil-terminated buffer.
 851  880           * Stop copying when a tab, space, or eoln is encountered.
 852  881           */
↓ open down ↓ 1 lines elided ↑ open up ↑
 854  883          i = 0;
 855  884          while (i < 4 && '\0' != buf[offs] && 
 856  885                          ' ' != buf[offs] && '\t' != buf[offs])
 857  886                  mac[i++] = buf[offs++];
 858  887  
 859  888          mac[i] = '\0';
 860  889  
 861  890          tok = (i > 1 || i < 4) ? mdoc_hash_find(mac) : MDOC_MAX;
 862  891  
 863  892          if (MDOC_MAX == tok) {
 864      -                mandoc_vmsg(MANDOCERR_MACRO, m->parse, 
      893 +                mandoc_vmsg(MANDOCERR_MACRO, mdoc->parse, 
 865  894                                  ln, sv, "%s", buf + sv - 1);
 866  895                  return(1);
 867  896          }
 868  897  
 869  898          /* Disregard the first trailing tab, if applicable. */
 870  899  
 871  900          if ('\t' == buf[offs])
 872  901                  offs++;
 873  902  
 874  903          /* Jump to the next non-whitespace word. */
 875  904  
 876  905          while (buf[offs] && ' ' == buf[offs])
 877  906                  offs++;
 878  907  
 879  908          /* 
 880  909           * Trailing whitespace.  Note that tabs are allowed to be passed
 881  910           * into the parser as "text", so we only warn about spaces here.
 882  911           */
 883  912  
 884  913          if ('\0' == buf[offs] && ' ' == buf[offs - 1])
 885      -                mdoc_pmsg(m, ln, offs - 1, MANDOCERR_EOLNSPACE);
      914 +                mdoc_pmsg(mdoc, ln, offs - 1, MANDOCERR_EOLNSPACE);
 886  915  
 887  916          /*
 888  917           * If an initial macro or a list invocation, divert directly
 889  918           * into macro processing.
 890  919           */
 891  920  
 892      -        if (NULL == m->last || MDOC_It == tok || MDOC_El == tok) {
 893      -                if ( ! mdoc_macro(m, tok, ln, sv, &offs, buf)) 
      921 +        if (NULL == mdoc->last || MDOC_It == tok || MDOC_El == tok) {
      922 +                if ( ! mdoc_macro(mdoc, tok, ln, sv, &offs, buf)) 
 894  923                          goto err;
 895  924                  return(1);
 896  925          }
 897  926  
 898      -        n = m->last;
 899      -        assert(m->last);
      927 +        n = mdoc->last;
      928 +        assert(mdoc->last);
 900  929  
 901  930          /*
 902  931           * If the first macro of a `Bl -column', open an `It' block
 903  932           * context around the parsed macro.
 904  933           */
 905  934  
 906  935          if (MDOC_Bl == n->tok && MDOC_BODY == n->type &&
 907  936                          LIST_column == n->norm->Bl.type) {
 908      -                m->flags |= MDOC_FREECOL;
 909      -                if ( ! mdoc_macro(m, MDOC_It, ln, sv, &sv, buf))
      937 +                mdoc->flags |= MDOC_FREECOL;
      938 +                if ( ! mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf))
 910  939                          goto err;
 911  940                  return(1);
 912  941          }
 913  942  
 914  943          /*
 915  944           * If we're following a block-level `It' within a `Bl -column'
 916  945           * context (perhaps opened in the above block or in ptext()),
 917  946           * then open an `It' block context around the parsed macro.
 918  947           */
 919  948  
 920  949          if (MDOC_It == n->tok && MDOC_BLOCK == n->type &&
 921  950                          NULL != n->parent &&
 922  951                          MDOC_Bl == n->parent->tok &&
 923  952                          LIST_column == n->parent->norm->Bl.type) {
 924      -                m->flags |= MDOC_FREECOL;
 925      -                if ( ! mdoc_macro(m, MDOC_It, ln, sv, &sv, buf)) 
      953 +                mdoc->flags |= MDOC_FREECOL;
      954 +                if ( ! mdoc_macro(mdoc, MDOC_It, ln, sv, &sv, buf)) 
 926  955                          goto err;
 927  956                  return(1);
 928  957          }
 929  958  
 930  959          /* Normal processing of a macro. */
 931  960  
 932      -        if ( ! mdoc_macro(m, tok, ln, sv, &offs, buf)) 
      961 +        if ( ! mdoc_macro(mdoc, tok, ln, sv, &offs, buf)) 
 933  962                  goto err;
 934  963  
 935  964          return(1);
 936  965  
 937  966  err:    /* Error out. */
 938  967  
 939      -        m->flags |= MDOC_HALT;
      968 +        mdoc->flags |= MDOC_HALT;
 940  969          return(0);
 941  970  }
 942  971  
 943  972  enum mdelim
 944  973  mdoc_isdelim(const char *p)
 945  974  {
 946  975  
 947  976          if ('\0' == p[0])
 948  977                  return(DELIM_NONE);
 949  978  
↓ open down ↓ 23 lines elided ↑ open up ↑
 973 1002                          return(DELIM_CLOSE);
 974 1003                  default:
 975 1004                          return(DELIM_NONE);
 976 1005                  }
 977 1006  
 978 1007          if ('\\' != p[0])
 979 1008                  return(DELIM_NONE);
 980 1009  
 981 1010          if (0 == strcmp(p + 1, "."))
 982 1011                  return(DELIM_CLOSE);
 983      -        if (0 == strcmp(p + 1, "*(Ba"))
     1012 +        if (0 == strcmp(p + 1, "fR|\\fP"))
 984 1013                  return(DELIM_MIDDLE);
 985 1014  
 986 1015          return(DELIM_NONE);
 987 1016  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX