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

Diff for /mandoc/mdoc_macro.c between version 1.191 and 1.211

version 1.191, 2015/04/19 14:00:19 version 1.211, 2017/02/10 16:20:34
Line 1 
Line 1 
 /*      $Id$ */  /*      $Id$ */
 /*  /*
  * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>   * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010, 2012-2015 Ingo Schwarze <schwarze@openbsd.org>   * Copyright (c) 2010, 2012-2016 Ingo Schwarze <schwarze@openbsd.org>
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above   * purpose with or without fee is hereby granted, provided that the above
Line 210  const struct mdoc_macro * const mdoc_macros = __mdoc_m
Line 210  const struct mdoc_macro * const mdoc_macros = __mdoc_m
  * are errors.   * are errors.
  */   */
 void  void
 mdoc_macroend(struct roff_man *mdoc)  mdoc_endparse(struct roff_man *mdoc)
 {  {
         struct roff_node *n;          struct roff_node *n;
   
         /* Scan for open explicit scopes. */          /* Scan for open explicit scopes. */
   
         n = mdoc->last->flags & MDOC_VALID ?          n = mdoc->last->flags & NODE_VALID ?
             mdoc->last->parent : mdoc->last;              mdoc->last->parent : mdoc->last;
   
         for ( ; n; n = n->parent)          for ( ; n; n = n->parent)
Line 228  mdoc_macroend(struct roff_man *mdoc)
Line 228  mdoc_macroend(struct roff_man *mdoc)
         /* Rewind to the first. */          /* Rewind to the first. */
   
         rew_last(mdoc, mdoc->first);          rew_last(mdoc, mdoc->first);
           mdoc_state_reset(mdoc);
 }  }
   
 /*  /*
Line 239  lookup(struct roff_man *mdoc, int from, int line, int 
Line 240  lookup(struct roff_man *mdoc, int from, int line, int 
 {  {
         int      res;          int      res;
   
           if (mdoc->flags & MDOC_PHRASEQF) {
                   mdoc->flags &= ~MDOC_PHRASEQF;
                   return TOKEN_NONE;
           }
         if (from == TOKEN_NONE || mdoc_macros[from].flags & MDOC_PARSED) {          if (from == TOKEN_NONE || mdoc_macros[from].flags & MDOC_PARSED) {
                 res = mdoc_hash_find(p);                  res = mdoc_hash_find(p);
                 if (res != TOKEN_NONE) {                  if (res != TOKEN_NONE) {
                         if (mdoc_macros[res].flags & MDOC_CALLABLE)                          if (mdoc_macros[res].flags & MDOC_CALLABLE)
                                 return(res);                                  return res;
                         if (res != MDOC_br && res != MDOC_sp && res != MDOC_ll)                          if (res != MDOC_br && res != MDOC_sp && res != MDOC_ll)
                                 mandoc_msg(MANDOCERR_MACRO_CALL,                                  mandoc_msg(MANDOCERR_MACRO_CALL,
                                     mdoc->parse, line, ppos, p);                                      mdoc->parse, line, ppos, p);
                 }                  }
         }          }
         return(TOKEN_NONE);          return TOKEN_NONE;
 }  }
   
 /*  /*
Line 258  lookup(struct roff_man *mdoc, int from, int line, int 
Line 263  lookup(struct roff_man *mdoc, int from, int line, int 
 static void  static void
 rew_last(struct roff_man *mdoc, const struct roff_node *to)  rew_last(struct roff_man *mdoc, const struct roff_node *to)
 {  {
         struct roff_node *n, *np;  
   
         if (to->flags & MDOC_VALID)          if (to->flags & NODE_VALID)
                 return;                  return;
   
         mdoc->next = ROFF_NEXT_SIBLING;  
         while (mdoc->last != to) {          while (mdoc->last != to) {
                 /*                  mdoc_state(mdoc, mdoc->last);
                  * Save the parent here, because we may delete the                  mdoc->last->flags |= NODE_VALID | NODE_ENDED;
                  * mdoc->last node in the post-validation phase and reset                  mdoc->last = mdoc->last->parent;
                  * it to mdoc->last->parent, causing a step in the closing  
                  * out to be lost.  
                  */  
                 np = mdoc->last->parent;  
                 mdoc_valid_post(mdoc);  
                 n = mdoc->last;  
                 mdoc->last = np;  
                 assert(mdoc->last);  
                 mdoc->last->last = n;  
         }          }
         mdoc_valid_post(mdoc);          mdoc_state(mdoc, mdoc->last);
           mdoc->last->flags |= NODE_VALID | NODE_ENDED;
           mdoc->next = ROFF_NEXT_SIBLING;
 }  }
   
 /*  /*
Line 291  rew_pending(struct roff_man *mdoc, const struct roff_n
Line 287  rew_pending(struct roff_man *mdoc, const struct roff_n
         for (;;) {          for (;;) {
                 rew_last(mdoc, n);                  rew_last(mdoc, n);
   
                 switch (n->type) {                  if (mdoc->last == n) {
                 case ROFFT_HEAD:                          switch (n->type) {
                         roff_body_alloc(mdoc, n->line, n->pos, n->tok);                          case ROFFT_HEAD:
                         return;                                  roff_body_alloc(mdoc, n->line, n->pos,
                 case ROFFT_BLOCK:                                      n->tok);
                         break;                                  break;
                 default:                          case ROFFT_BLOCK:
                         return;                                  break;
                 }                          default:
                                   return;
                           }
                           if ( ! (n->flags & NODE_BROKEN))
                                   return;
                   } else
                           n = mdoc->last;
   
                 if ( ! (n->flags & MDOC_BROKEN))  
                         return;  
   
                 for (;;) {                  for (;;) {
                         if ((n = n->parent) == NULL)                          if ((n = n->parent) == NULL)
                                 return;                                  return;
   
                         if (n->type == ROFFT_BLOCK ||                          if (n->type == ROFFT_BLOCK ||
                             n->type == ROFFT_HEAD) {                              n->type == ROFFT_HEAD) {
                                 if (n->flags & MDOC_ENDED)                                  if (n->flags & NODE_ENDED)
                                         break;                                          break;
                                 else                                  else
                                         return;                                          return;
Line 328  rew_alt(int tok)
Line 327  rew_alt(int tok)
 {  {
         switch (tok) {          switch (tok) {
         case MDOC_Ac:          case MDOC_Ac:
                 return(MDOC_Ao);                  return MDOC_Ao;
         case MDOC_Bc:          case MDOC_Bc:
                 return(MDOC_Bo);                  return MDOC_Bo;
         case MDOC_Brc:          case MDOC_Brc:
                 return(MDOC_Bro);                  return MDOC_Bro;
         case MDOC_Dc:          case MDOC_Dc:
                 return(MDOC_Do);                  return MDOC_Do;
         case MDOC_Ec:          case MDOC_Ec:
                 return(MDOC_Eo);                  return MDOC_Eo;
         case MDOC_Ed:          case MDOC_Ed:
                 return(MDOC_Bd);                  return MDOC_Bd;
         case MDOC_Ef:          case MDOC_Ef:
                 return(MDOC_Bf);                  return MDOC_Bf;
         case MDOC_Ek:          case MDOC_Ek:
                 return(MDOC_Bk);                  return MDOC_Bk;
         case MDOC_El:          case MDOC_El:
                 return(MDOC_Bl);                  return MDOC_Bl;
         case MDOC_Fc:          case MDOC_Fc:
                 return(MDOC_Fo);                  return MDOC_Fo;
         case MDOC_Oc:          case MDOC_Oc:
                 return(MDOC_Oo);                  return MDOC_Oo;
         case MDOC_Pc:          case MDOC_Pc:
                 return(MDOC_Po);                  return MDOC_Po;
         case MDOC_Qc:          case MDOC_Qc:
                 return(MDOC_Qo);                  return MDOC_Qo;
         case MDOC_Re:          case MDOC_Re:
                 return(MDOC_Rs);                  return MDOC_Rs;
         case MDOC_Sc:          case MDOC_Sc:
                 return(MDOC_So);                  return MDOC_So;
         case MDOC_Xc:          case MDOC_Xc:
                 return(MDOC_Xo);                  return MDOC_Xo;
         default:          default:
                 return(tok);                  return tok;
         }          }
         /* NOTREACHED */  
 }  }
   
 static void  static void
Line 392  find_pending(struct roff_man *mdoc, int tok, int line,
Line 390  find_pending(struct roff_man *mdoc, int tok, int line,
   
         irc = 0;          irc = 0;
         for (n = mdoc->last; n != NULL && n != target; n = n->parent) {          for (n = mdoc->last; n != NULL && n != target; n = n->parent) {
                 if (n->flags & MDOC_ENDED) {                  if (n->flags & NODE_ENDED) {
                         if ( ! (n->flags & MDOC_VALID))                          if ( ! (n->flags & NODE_VALID))
                                 n->flags |= MDOC_BROKEN;                                  n->flags |= NODE_BROKEN;
                         continue;                          continue;
                 }                  }
                 if (n->type == ROFFT_BLOCK &&                  if (n->type == ROFFT_BLOCK &&
                     mdoc_macros[n->tok].flags & MDOC_EXPLICIT) {                      mdoc_macros[n->tok].flags & MDOC_EXPLICIT) {
                         irc = 1;                          irc = 1;
                         n->flags = MDOC_BROKEN;                          n->flags = NODE_BROKEN;
                         if (target->type == ROFFT_HEAD)                          if (target->type == ROFFT_HEAD)
                                 target->flags = MDOC_ENDED;                                  target->flags = NODE_ENDED;
                         else if ( ! (target->flags & MDOC_ENDED)) {                          else if ( ! (target->flags & NODE_ENDED)) {
                                 mandoc_vmsg(MANDOCERR_BLK_NEST,                                  mandoc_vmsg(MANDOCERR_BLK_NEST,
                                     mdoc->parse, line, ppos,                                      mdoc->parse, line, ppos,
                                     "%s breaks %s", mdoc_macronames[tok],                                      "%s breaks %s", mdoc_macronames[tok],
Line 413  find_pending(struct roff_man *mdoc, int tok, int line,
Line 411  find_pending(struct roff_man *mdoc, int tok, int line,
                         }                          }
                 }                  }
         }          }
         return(irc);          return irc;
 }  }
   
 /*  /*
Line 432  dword(struct roff_man *mdoc, int line, int col, const 
Line 430  dword(struct roff_man *mdoc, int line, int col, const 
             ! (mdoc->flags & (MDOC_SYNOPSIS | MDOC_KEEP | MDOC_SMOFF)) &&              ! (mdoc->flags & (MDOC_SYNOPSIS | MDOC_KEEP | MDOC_SMOFF)) &&
             d == DELIM_NONE && mdoc->last->type == ROFFT_TEXT &&              d == DELIM_NONE && mdoc->last->type == ROFFT_TEXT &&
             mdoc_isdelim(mdoc->last->string) == DELIM_NONE) {              mdoc_isdelim(mdoc->last->string) == DELIM_NONE) {
                 mdoc_word_append(mdoc, p);                  roff_word_append(mdoc, p);
                 return;                  return;
         }          }
   
         mdoc_word_alloc(mdoc, line, col, p);          roff_word_alloc(mdoc, line, col, p);
   
         /*          /*
          * If the word consists of a bare delimiter,           * If the word consists of a bare delimiter,
Line 446  dword(struct roff_man *mdoc, int line, int col, const 
Line 444  dword(struct roff_man *mdoc, int line, int col, const 
          */           */
   
         if (d == DELIM_OPEN)          if (d == DELIM_OPEN)
                 mdoc->last->flags |= MDOC_DELIMO;                  mdoc->last->flags |= NODE_DELIMO;
         else if (d == DELIM_CLOSE &&          else if (d == DELIM_CLOSE &&
             ! (mdoc->flags & MDOC_NODELIMC) &&              ! (mdoc->flags & MDOC_NODELIMC) &&
             mdoc->last->parent->tok != MDOC_Fd)              mdoc->last->parent->tok != MDOC_Fd)
                 mdoc->last->flags |= MDOC_DELIMC;                  mdoc->last->flags |= NODE_DELIMC;
         mdoc->flags &= ~MDOC_NODELIMC;          mdoc->flags &= ~MDOC_NODELIMC;
 }  }
   
Line 483  append_delims(struct roff_man *mdoc, int line, int *po
Line 481  append_delims(struct roff_man *mdoc, int line, int *po
                  */                   */
   
                 if (mandoc_eos(p, strlen(p)))                  if (mandoc_eos(p, strlen(p)))
                         mdoc->last->flags |= MDOC_EOS;                          mdoc->last->flags |= NODE_EOS;
         }          }
 }  }
   
Line 508  macro_or_word(MACRO_PROT_ARGS, int parsed)
Line 506  macro_or_word(MACRO_PROT_ARGS, int parsed)
         if (ntok == TOKEN_NONE) {          if (ntok == TOKEN_NONE) {
                 dword(mdoc, line, ppos, p, DELIM_MAX, tok == TOKEN_NONE ||                  dword(mdoc, line, ppos, p, DELIM_MAX, tok == TOKEN_NONE ||
                     mdoc_macros[tok].flags & MDOC_JOIN);                      mdoc_macros[tok].flags & MDOC_JOIN);
                 return(0);                  return 0;
         } else {          } else {
                 if (mdoc_macros[tok].fp == in_line_eoln)                  if (mdoc_macros[tok].fp == in_line_eoln)
                         rew_elem(mdoc, tok);                          rew_elem(mdoc, tok);
                 mdoc_macro(mdoc, ntok, line, ppos, pos, buf);                  mdoc_macro(mdoc, ntok, line, ppos, pos, buf);
                 if (tok == TOKEN_NONE)                  if (tok == TOKEN_NONE)
                         append_delims(mdoc, line, pos, buf);                          append_delims(mdoc, line, pos, buf);
                 return(1);                  return 1;
         }          }
 }  }
   
Line 551  blk_exp_close(MACRO_PROT_ARGS)
Line 549  blk_exp_close(MACRO_PROT_ARGS)
                 break;                  break;
         }          }
   
           /* Search backwards for the beginning of our own body. */
   
           atok = rew_alt(tok);
           body = NULL;
           for (n = mdoc->last; n; n = n->parent) {
                   if (n->flags & NODE_ENDED || n->tok != atok ||
                       n->type != ROFFT_BODY || n->end != ENDBODY_NOT)
                           continue;
                   body = n;
                   break;
           }
   
         /*          /*
          * Search backwards for beginnings of blocks,           * Search backwards for beginnings of blocks,
          * both of our own and of pending sub-blocks.           * both of our own and of pending sub-blocks.
          */           */
   
         atok = rew_alt(tok);          endbody = itblk = later = NULL;
         body = endbody = itblk = later = NULL;  
         for (n = mdoc->last; n; n = n->parent) {          for (n = mdoc->last; n; n = n->parent) {
                 if (n->flags & MDOC_ENDED) {                  if (n->flags & NODE_ENDED) {
                         if ( ! (n->flags & MDOC_VALID))                          if ( ! (n->flags & NODE_VALID))
                                 n->flags |= MDOC_BROKEN;                                  n->flags |= NODE_BROKEN;
                         continue;                          continue;
                 }                  }
   
                 /* Remember the start of our own body. */                  /*
                    * Mismatching end macros can never break anything
                    * and we only care about the breaking of BLOCKs.
                    */
   
                 if (n->type == ROFFT_BODY && atok == n->tok) {                  if (body == NULL || n->type != ROFFT_BLOCK)
                         if (n->end == ENDBODY_NOT)  
                                 body = n;  
                         continue;                          continue;
                 }  
   
                 if (n->type != ROFFT_BLOCK || n->tok == MDOC_Nm)                  /*
                    * SYNOPSIS name blocks can not be broken themselves,
                    * but they do get broken together with a broken child.
                    */
   
                   if (n->tok == MDOC_Nm) {
                           if (later != NULL)
                                   n->flags |= NODE_BROKEN | NODE_ENDED;
                         continue;                          continue;
                   }
   
                 if (n->tok == MDOC_It) {                  if (n->tok == MDOC_It) {
                         itblk = n;                          itblk = n;
Line 611  blk_exp_close(MACRO_PROT_ARGS)
Line 628  blk_exp_close(MACRO_PROT_ARGS)
                             atok, body, ENDBODY_SPACE);                              atok, body, ENDBODY_SPACE);
   
                         if (tok == MDOC_El)                          if (tok == MDOC_El)
                                 itblk->flags |= MDOC_ENDED | MDOC_BROKEN;                                  itblk->flags |= NODE_ENDED | NODE_BROKEN;
   
                         /*                          /*
                          * If a block closing macro taking arguments                           * If a block closing macro taking arguments
Line 633  blk_exp_close(MACRO_PROT_ARGS)
Line 650  blk_exp_close(MACRO_PROT_ARGS)
   
                 /* Breaking an open sub block. */                  /* Breaking an open sub block. */
   
                 n->flags |= MDOC_BROKEN;                  n->flags |= NODE_BROKEN;
                 if (later == NULL)                  if (later == NULL)
                         later = n;                          later = n;
         }          }
Line 646  blk_exp_close(MACRO_PROT_ARGS)
Line 663  blk_exp_close(MACRO_PROT_ARGS)
                          * Stray .Ec without previous .Eo:                           * Stray .Ec without previous .Eo:
                          * Break the output line, keep the arguments.                           * Break the output line, keep the arguments.
                          */                           */
                         mdoc_elem_alloc(mdoc, line, ppos, MDOC_br, NULL);                          roff_elem_alloc(mdoc, line, ppos, MDOC_br);
                         rew_elem(mdoc, MDOC_br);                          rew_elem(mdoc, MDOC_br);
                 }                  }
         } else if (endbody == NULL) {          } else if (endbody == NULL) {
Line 668  blk_exp_close(MACRO_PROT_ARGS)
Line 685  blk_exp_close(MACRO_PROT_ARGS)
   
         if (endbody != NULL)          if (endbody != NULL)
                 n = endbody;                  n = endbody;
   
           ntok = TOKEN_NONE;
         for (j = 0; ; j++) {          for (j = 0; ; j++) {
                 lastarg = *pos;                  lastarg = *pos;
   
Line 695  blk_exp_close(MACRO_PROT_ARGS)
Line 714  blk_exp_close(MACRO_PROT_ARGS)
         }          }
   
         if (n != NULL) {          if (n != NULL) {
                 if (n != mdoc->last && n->flags & MDOC_BROKEN) {                  if (ntok != TOKEN_NONE && n->flags & NODE_BROKEN) {
                         target = n;                          target = n;
                         do                          do
                                 target = target->parent;                                  target = target->parent;
                         while ( ! (target->flags & MDOC_ENDED));                          while ( ! (target->flags & NODE_ENDED));
                         pending = find_pending(mdoc, ntok, line, ppos,                          pending = find_pending(mdoc, ntok, line, ppos,
                             target);                              target);
                 } else                  } else
Line 730  in_line(MACRO_PROT_ARGS)
Line 749  in_line(MACRO_PROT_ARGS)
   
         switch (tok) {          switch (tok) {
         case MDOC_An:          case MDOC_An:
                 /* FALLTHROUGH */  
         case MDOC_Ar:          case MDOC_Ar:
                 /* FALLTHROUGH */  
         case MDOC_Fl:          case MDOC_Fl:
                 /* FALLTHROUGH */  
         case MDOC_Mt:          case MDOC_Mt:
                 /* FALLTHROUGH */  
         case MDOC_Nm:          case MDOC_Nm:
                 /* FALLTHROUGH */  
         case MDOC_Pa:          case MDOC_Pa:
                 nc = 1;                  nc = 1;
                 break;                  break;
Line 763  in_line(MACRO_PROT_ARGS)
Line 777  in_line(MACRO_PROT_ARGS)
   
                 if (ac == ARGS_EOLN) {                  if (ac == ARGS_EOLN) {
                         if (d == DELIM_OPEN)                          if (d == DELIM_OPEN)
                                 mdoc->last->flags &= ~MDOC_DELIMO;                                  mdoc->last->flags &= ~NODE_DELIMO;
                         break;                          break;
                 }                  }
   
Line 857  in_line(MACRO_PROT_ARGS)
Line 871  in_line(MACRO_PROT_ARGS)
                  */                   */
   
                 if (firstarg && d == DELIM_CLOSE && !nc)                  if (firstarg && d == DELIM_CLOSE && !nc)
                         mdoc->last->flags &= ~MDOC_DELIMC;                          mdoc->last->flags &= ~NODE_DELIMC;
                 firstarg = 0;                  firstarg = 0;
   
                 /*                  /*
Line 920  blk_full(MACRO_PROT_ARGS)
Line 934  blk_full(MACRO_PROT_ARGS)
   
                 blk = NULL;                  blk = NULL;
                 for (n = mdoc->last; n != NULL; n = n->parent) {                  for (n = mdoc->last; n != NULL; n = n->parent) {
                         if (n->flags & MDOC_ENDED) {                          if (n->flags & NODE_ENDED) {
                                 if ( ! (n->flags & MDOC_VALID))                                  if ( ! (n->flags & NODE_VALID))
                                         n->flags |= MDOC_BROKEN;                                          n->flags |= NODE_BROKEN;
                                 continue;                                  continue;
                         }                          }
                         if (n->type != ROFFT_BLOCK)                          if (n->type != ROFFT_BLOCK)
Line 942  blk_full(MACRO_PROT_ARGS)
Line 956  blk_full(MACRO_PROT_ARGS)
                         if (mdoc_macros[n->tok].flags & MDOC_EXPLICIT) {                          if (mdoc_macros[n->tok].flags & MDOC_EXPLICIT) {
                                 switch (tok) {                                  switch (tok) {
                                 case MDOC_Sh:                                  case MDOC_Sh:
                                         /* FALLTHROUGH */  
                                 case MDOC_Ss:                                  case MDOC_Ss:
                                         mandoc_vmsg(MANDOCERR_BLK_BROKEN,                                          mandoc_vmsg(MANDOCERR_BLK_BROKEN,
                                             mdoc->parse, line, ppos,                                              mdoc->parse, line, ppos,
Line 982  blk_full(MACRO_PROT_ARGS)
Line 995  blk_full(MACRO_PROT_ARGS)
   
                         /* Close out prior implicit scopes. */                          /* Close out prior implicit scopes. */
   
                         rew_last(mdoc, n);                          rew_pending(mdoc, n);
                 }                  }
   
                 /* Skip items outside lists. */                  /* Skip items outside lists. */
Line 990  blk_full(MACRO_PROT_ARGS)
Line 1003  blk_full(MACRO_PROT_ARGS)
                 if (tok == MDOC_It && (n == NULL || n->tok != MDOC_Bl)) {                  if (tok == MDOC_It && (n == NULL || n->tok != MDOC_Bl)) {
                         mandoc_vmsg(MANDOCERR_IT_STRAY, mdoc->parse,                          mandoc_vmsg(MANDOCERR_IT_STRAY, mdoc->parse,
                             line, ppos, "It %s", buf + *pos);                              line, ppos, "It %s", buf + *pos);
                         mdoc_elem_alloc(mdoc, line, ppos, MDOC_br, NULL);                          roff_elem_alloc(mdoc, line, ppos, MDOC_br);
                         rew_elem(mdoc, MDOC_br);                          rew_elem(mdoc, MDOC_br);
                         return;                          return;
                 }                  }
Line 1032  blk_full(MACRO_PROT_ARGS)
Line 1045  blk_full(MACRO_PROT_ARGS)
         if (tok == MDOC_Bk)          if (tok == MDOC_Bk)
                 mdoc->flags |= MDOC_KEEP;                  mdoc->flags |= MDOC_KEEP;
   
         ac = ARGS_PEND;          ac = ARGS_EOLN;
         for (;;) {          for (;;) {
   
                   /*
                    * If we are right after a tab character,
                    * do not parse the first word for macros.
                    */
   
                   if (mdoc->flags & MDOC_PHRASEQN) {
                           mdoc->flags &= ~MDOC_PHRASEQN;
                           mdoc->flags |= MDOC_PHRASEQF;
                   }
   
                 la = *pos;                  la = *pos;
                 lac = ac;                  lac = ac;
                 ac = mdoc_args(mdoc, line, pos, buf, tok, &p);                  ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
                 if (ac == ARGS_EOLN) {                  if (ac == ARGS_EOLN) {
                         if (lac != ARGS_PPHRASE && lac != ARGS_PHRASE)                          if (lac != ARGS_PHRASE ||
                               ! (mdoc->flags & MDOC_PHRASEQF))
                                 break;                                  break;
   
                         /*                          /*
                          * This is necessary: if the last token on a                           * This line ends in a tab; start the next
                          * line is a `Ta' or tab, then we'll get                           * column now, with a leading blank.
                          * ARGS_EOLN, so we must be smart enough to  
                          * reopen our scope if the last parse was a  
                          * phrase or partial phrase.  
                          */                           */
   
                         if (body != NULL)                          if (body != NULL)
                                 rew_last(mdoc, body);                                  rew_last(mdoc, body);
                         body = roff_body_alloc(mdoc, line, ppos, tok);                          body = roff_body_alloc(mdoc, line, ppos, tok);
                           roff_word_alloc(mdoc, line, ppos, "\\&");
                         break;                          break;
                 }                  }
   
                 if (tok == MDOC_Bd || tok == MDOC_Bk) {                  if (tok == MDOC_Bd || tok == MDOC_Bk) {
                         mandoc_vmsg(MANDOCERR_ARG_EXCESS,                          mandoc_vmsg(MANDOCERR_ARG_EXCESS,
                             mdoc->parse, line, la, "%s ... %s",                              mdoc->parse, line, la, "%s ... %s",
Line 1072  blk_full(MACRO_PROT_ARGS)
Line 1098  blk_full(MACRO_PROT_ARGS)
                  */                   */
   
                 if (head == NULL &&                  if (head == NULL &&
                     ac != ARGS_PEND &&  
                     ac != ARGS_PHRASE &&                      ac != ARGS_PHRASE &&
                     ac != ARGS_PPHRASE &&  
                     ac != ARGS_QWORD &&                      ac != ARGS_QWORD &&
                     mdoc_isdelim(p) == DELIM_OPEN) {                      mdoc_isdelim(p) == DELIM_OPEN) {
                         dword(mdoc, line, la, p, DELIM_OPEN, 0);                          dword(mdoc, line, la, p, DELIM_OPEN, 0);
Line 1086  blk_full(MACRO_PROT_ARGS)
Line 1110  blk_full(MACRO_PROT_ARGS)
                 if (head == NULL)                  if (head == NULL)
                         head = roff_head_alloc(mdoc, line, ppos, tok);                          head = roff_head_alloc(mdoc, line, ppos, tok);
   
                 if (ac == ARGS_PHRASE ||                  if (ac == ARGS_PHRASE) {
                     ac == ARGS_PEND ||  
                     ac == ARGS_PPHRASE) {  
   
                         /*                          /*
                          * If we haven't opened a body yet, rewind the                           * If we haven't opened a body yet, rewind the
Line 1098  blk_full(MACRO_PROT_ARGS)
Line 1120  blk_full(MACRO_PROT_ARGS)
                         rew_last(mdoc, body == NULL ? head : body);                          rew_last(mdoc, body == NULL ? head : body);
                         body = roff_body_alloc(mdoc, line, ppos, tok);                          body = roff_body_alloc(mdoc, line, ppos, tok);
   
                         /*                          /* Process to the tab or to the end of the line. */
                          * Process phrases: set whether we're in a  
                          * partial-phrase (this effects line handling)  
                          * then call down into the phrase parser.  
                          */  
   
                         if (ac == ARGS_PPHRASE)                          mdoc->flags |= MDOC_PHRASE;
                                 mdoc->flags |= MDOC_PPHRASE;  
                         if (ac == ARGS_PEND && lac == ARGS_PPHRASE)  
                                 mdoc->flags |= MDOC_PPHRASE;  
                         parse_rest(mdoc, TOKEN_NONE, line, &la, buf);                          parse_rest(mdoc, TOKEN_NONE, line, &la, buf);
                         mdoc->flags &= ~MDOC_PPHRASE;                          mdoc->flags &= ~MDOC_PHRASE;
   
                           /* There may have been `Ta' macros. */
   
                           while (body->next != NULL)
                                   body = body->next;
                         continue;                          continue;
                 }                  }
   
Line 1117  blk_full(MACRO_PROT_ARGS)
Line 1137  blk_full(MACRO_PROT_ARGS)
                         break;                          break;
         }          }
   
         if (blk->flags & MDOC_VALID)          if (blk->flags & NODE_VALID)
                 return;                  return;
         if (head == NULL)          if (head == NULL)
                 head = roff_head_alloc(mdoc, line, ppos, tok);                  head = roff_head_alloc(mdoc, line, ppos, tok);
Line 1223  blk_part_exp(MACRO_PROT_ARGS)
Line 1243  blk_part_exp(MACRO_PROT_ARGS)
          * case of `Eo'); and a body that may be empty.           * case of `Eo'); and a body that may be empty.
          */           */
   
         mdoc_block_alloc(mdoc, line, ppos, tok, NULL);          roff_block_alloc(mdoc, line, ppos, tok);
         head = NULL;          head = NULL;
         for (;;) {          for (;;) {
                 la = *pos;                  la = *pos;
Line 1285  in_line_argn(MACRO_PROT_ARGS)
Line 1305  in_line_argn(MACRO_PROT_ARGS)
   
         switch (tok) {          switch (tok) {
         case MDOC_Ap:          case MDOC_Ap:
                 /* FALLTHROUGH */  
         case MDOC_Ns:          case MDOC_Ns:
                 /* FALLTHROUGH */  
         case MDOC_Ux:          case MDOC_Ux:
                 maxargs = 0;                  maxargs = 0;
                 break;                  break;
         case MDOC_Bx:          case MDOC_Bx:
                 /* FALLTHROUGH */  
         case MDOC_Es:          case MDOC_Es:
                 /* FALLTHROUGH */  
         case MDOC_Xr:          case MDOC_Xr:
                 maxargs = 2;                  maxargs = 2;
                 break;                  break;
Line 1392  in_line_eoln(MACRO_PROT_ARGS)
Line 1408  in_line_eoln(MACRO_PROT_ARGS)
                 if (mdoc->next == ROFF_NEXT_SIBLING)                  if (mdoc->next == ROFF_NEXT_SIBLING)
                         n = n->parent;                          n = n->parent;
                 if (n->tok == MDOC_Nm)                  if (n->tok == MDOC_Nm)
                         rew_last(mdoc, mdoc->last->parent);                          rew_last(mdoc, n->parent);
         }          }
   
         if (buf[*pos] == '\0' &&          if (buf[*pos] == '\0' &&
Line 1422  parse_rest(struct roff_man *mdoc, int tok, int line, i
Line 1438  parse_rest(struct roff_man *mdoc, int tok, int line, i
         for (;;) {          for (;;) {
                 la = *pos;                  la = *pos;
                 if (mdoc_args(mdoc, line, pos, buf, tok, NULL) == ARGS_EOLN)                  if (mdoc_args(mdoc, line, pos, buf, tok, NULL) == ARGS_EOLN)
                         return(0);                          return 0;
                 if (macro_or_word(mdoc, tok, line, la, pos, buf, 1))                  if (macro_or_word(mdoc, tok, line, la, pos, buf, 1))
                         return(1);                          return 1;
         }          }
 }  }
   
Line 1456  phrase_ta(MACRO_PROT_ARGS)
Line 1472  phrase_ta(MACRO_PROT_ARGS)
   
         body = NULL;          body = NULL;
         for (n = mdoc->last; n != NULL; n = n->parent) {          for (n = mdoc->last; n != NULL; n = n->parent) {
                 if (n->flags & MDOC_ENDED)                  if (n->flags & NODE_ENDED)
                         continue;                          continue;
                 if (n->tok == MDOC_It && n->type == ROFFT_BODY)                  if (n->tok == MDOC_It && n->type == ROFFT_BODY)
                         body = n;                          body = n;
                 if (n->tok == MDOC_Bl)                  if (n->tok == MDOC_Bl && n->end == ENDBODY_NOT)
                         break;                          break;
         }          }
   

Legend:
Removed from v.1.191  
changed lines
  Added in v.1.211

CVSweb