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

Diff for /mandoc/eqn.c between version 1.60 and 1.67

version 1.60, 2016/01/07 20:19:01 version 1.67, 2017/06/22 00:30:20
Line 1 
Line 1 
 /*      $Id$ */  /*      $Id$
 /*  /*
  * Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>   * Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>   * Copyright (c) 2014, 2015, 2017 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 20 
Line 20 
 #include <sys/types.h>  #include <sys/types.h>
   
 #include <assert.h>  #include <assert.h>
   #include <ctype.h>
 #include <limits.h>  #include <limits.h>
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
Line 80  enum eqn_tok {
Line 81  enum eqn_tok {
         EQN_TOK_TDEFINE,          EQN_TOK_TDEFINE,
         EQN_TOK_NDEFINE,          EQN_TOK_NDEFINE,
         EQN_TOK_UNDEF,          EQN_TOK_UNDEF,
         EQN_TOK_EOF,  
         EQN_TOK_ABOVE,          EQN_TOK_ABOVE,
         EQN_TOK__MAX          EQN_TOK__MAX,
           EQN_TOK_FUNC,
           EQN_TOK_QUOTED,
           EQN_TOK_SYM,
           EQN_TOK_EOF
 };  };
   
 static  const char *eqn_toks[EQN_TOK__MAX] = {  static  const char *eqn_toks[EQN_TOK__MAX] = {
Line 130  static const char *eqn_toks[EQN_TOK__MAX] = {
Line 134  static const char *eqn_toks[EQN_TOK__MAX] = {
         "tdefine", /* EQN_TOK_TDEFINE */          "tdefine", /* EQN_TOK_TDEFINE */
         "ndefine", /* EQN_TOK_NDEFINE */          "ndefine", /* EQN_TOK_NDEFINE */
         "undef", /* EQN_TOK_UNDEF */          "undef", /* EQN_TOK_UNDEF */
         NULL, /* EQN_TOK_EOF */  
         "above", /* EQN_TOK_ABOVE */          "above", /* EQN_TOK_ABOVE */
 };  };
   
   static  const char *const eqn_func[] = {
           "acos", "acsc", "and",  "arc",  "asec", "asin", "atan",
           "cos",  "cosh", "coth", "csc",  "det",  "exp",  "for",
           "if",   "lim",  "ln",   "log",  "max",  "min",
           "sec",  "sin",  "sinh", "tan",  "tanh", "Im",   "Re",
   };
   
 enum    eqn_symt {  enum    eqn_symt {
         EQNSYM_alpha,          EQNSYM_alpha,
         EQNSYM_beta,          EQNSYM_beta,
Line 366  eqn_def_find(struct eqn_node *ep, const char *key, siz
Line 376  eqn_def_find(struct eqn_node *ep, const char *key, siz
 static const char *  static const char *
 eqn_next(struct eqn_node *ep, char quote, size_t *sz, int repl)  eqn_next(struct eqn_node *ep, char quote, size_t *sz, int repl)
 {  {
           static size_t    last_len;
           static int       lim;
   
         char            *start, *next;          char            *start, *next;
         int              q, diff, lim;          int              q, diff;
         size_t           ssz, dummy;          size_t           ssz, dummy;
         struct eqn_def  *def;          struct eqn_def  *def;
   
         if (NULL == sz)          if (NULL == sz)
                 sz = &dummy;                  sz = &dummy;
   
         lim = 0;          if (ep->cur >= last_len)
                   lim = 0;
         ep->rew = ep->cur;          ep->rew = ep->cur;
 again:  again:
         /* Prevent self-definitions. */          /* Prevent self-definitions. */
Line 448  again:
Line 462  again:
                 memmove(start + *sz + diff, start + *sz,                  memmove(start + *sz + diff, start + *sz,
                     (strlen(start) - *sz) + 1);                      (strlen(start) - *sz) + 1);
                 memcpy(start, def->val, def->valsz);                  memcpy(start, def->val, def->valsz);
                   last_len = start - ep->data + def->valsz;
                 lim++;                  lim++;
                 goto again;                  goto again;
         }          }
Line 493  eqn_tok_parse(struct eqn_node *ep, char **p)
Line 508  eqn_tok_parse(struct eqn_node *ep, char **p)
         size_t           i, sz;          size_t           i, sz;
         int              quoted;          int              quoted;
   
         if (NULL != p)          if (p != NULL)
                 *p = NULL;                  *p = NULL;
   
         quoted = ep->data[ep->cur] == '"';          quoted = ep->data[ep->cur] == '"';
   
         if (NULL == (start = eqn_nexttok(ep, &sz)))          if ((start = eqn_nexttok(ep, &sz)) == NULL)
                 return EQN_TOK_EOF;                  return EQN_TOK_EOF;
   
         if (quoted) {          if (quoted) {
                 if (p != NULL)                  if (p != NULL)
                         *p = mandoc_strndup(start, sz);                          *p = mandoc_strndup(start, sz);
                 return EQN_TOK__MAX;                  return EQN_TOK_QUOTED;
         }          }
   
         for (i = 0; i < EQN_TOK__MAX; i++) {          for (i = 0; i < EQN_TOK__MAX; i++)
                 if (NULL == eqn_toks[i])  
                         continue;  
                 if (STRNEQ(start, sz, eqn_toks[i], strlen(eqn_toks[i])))                  if (STRNEQ(start, sz, eqn_toks[i], strlen(eqn_toks[i])))
                         break;                          return i;
   
           for (i = 0; i < EQNSYM__MAX; i++) {
                   if (STRNEQ(start, sz,
                       eqnsyms[i].str, strlen(eqnsyms[i].str))) {
                           mandoc_asprintf(p, "\\[%s]", eqnsyms[i].sym);
                           return EQN_TOK_SYM;
                   }
         }          }
   
         if (i == EQN_TOK__MAX && NULL != p)          if (p != NULL)
                 *p = mandoc_strndup(start, sz);                  *p = mandoc_strndup(start, sz);
   
         return i;          for (i = 0; i < sizeof(eqn_func)/sizeof(*eqn_func); i++)
                   if (STRNEQ(start, sz, eqn_func[i], strlen(eqn_func[i])))
                           return EQN_TOK_FUNC;
   
           return EQN_TOK__MAX;
 }  }
   
 static void  static void
Line 697  static enum rofferr
Line 721  static enum rofferr
 eqn_parse(struct eqn_node *ep, struct eqn_box *parent)  eqn_parse(struct eqn_node *ep, struct eqn_box *parent)
 {  {
         char             sym[64];          char             sym[64];
         struct eqn_box  *cur;          struct eqn_box  *cur, *fontp, *nbox;
         const char      *start;          const char      *cp, *cpn, *start;
         char            *p;          char            *p;
         size_t           i, sz;          size_t           sz;
         enum eqn_tok     tok, subtok;          enum eqn_tok     tok, subtok;
         enum eqn_post    pos;          enum eqn_post    pos;
         int              size;          int              size;
Line 720  next_tok:
Line 744  next_tok:
   
 this_tok:  this_tok:
         switch (tok) {          switch (tok) {
         case (EQN_TOK_UNDEF):          case EQN_TOK_UNDEF:
                 eqn_undef(ep);                  eqn_undef(ep);
                 break;                  break;
         case (EQN_TOK_NDEFINE):          case EQN_TOK_NDEFINE:
         case (EQN_TOK_DEFINE):          case EQN_TOK_DEFINE:
                 eqn_def(ep);                  eqn_def(ep);
                 break;                  break;
         case (EQN_TOK_TDEFINE):          case EQN_TOK_TDEFINE:
                 if (eqn_nextrawtok(ep, NULL) == NULL ||                  if (eqn_nextrawtok(ep, NULL) == NULL ||
                     eqn_next(ep, ep->data[(int)ep->cur], NULL, 0) == NULL)                      eqn_next(ep, ep->data[(int)ep->cur], NULL, 0) == NULL)
                         mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,                          mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,
                             ep->eqn.ln, ep->eqn.pos, "tdefine");                              ep->eqn.ln, ep->eqn.pos, "tdefine");
                 break;                  break;
         case (EQN_TOK_DELIM):          case EQN_TOK_DELIM:
                 eqn_delim(ep);                  eqn_delim(ep);
                 break;                  break;
         case (EQN_TOK_GFONT):          case EQN_TOK_GFONT:
                 if (eqn_nextrawtok(ep, NULL) == NULL)                  if (eqn_nextrawtok(ep, NULL) == NULL)
                         mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,                          mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,
                             ep->eqn.ln, ep->eqn.pos, eqn_toks[tok]);                              ep->eqn.ln, ep->eqn.pos, eqn_toks[tok]);
                 break;                  break;
         case (EQN_TOK_MARK):          case EQN_TOK_MARK:
         case (EQN_TOK_LINEUP):          case EQN_TOK_LINEUP:
                 /* Ignore these. */                  /* Ignore these. */
                 break;                  break;
         case (EQN_TOK_DYAD):          case EQN_TOK_DYAD:
         case (EQN_TOK_VEC):          case EQN_TOK_VEC:
         case (EQN_TOK_UNDER):          case EQN_TOK_UNDER:
         case (EQN_TOK_BAR):          case EQN_TOK_BAR:
         case (EQN_TOK_TILDE):          case EQN_TOK_TILDE:
         case (EQN_TOK_HAT):          case EQN_TOK_HAT:
         case (EQN_TOK_DOT):          case EQN_TOK_DOT:
         case (EQN_TOK_DOTDOT):          case EQN_TOK_DOTDOT:
                 if (parent->last == NULL) {                  if (parent->last == NULL) {
                         mandoc_msg(MANDOCERR_EQN_NOBOX, ep->parse,                          mandoc_msg(MANDOCERR_EQN_NOBOX, ep->parse,
                             ep->eqn.ln, ep->eqn.pos, eqn_toks[tok]);                              ep->eqn.ln, ep->eqn.pos, eqn_toks[tok]);
Line 764  this_tok:
Line 788  this_tok:
                 parent->type = EQN_LISTONE;                  parent->type = EQN_LISTONE;
                 parent->expectargs = 1;                  parent->expectargs = 1;
                 switch (tok) {                  switch (tok) {
                 case (EQN_TOK_DOTDOT):                  case EQN_TOK_DOTDOT:
                         strlcpy(sym, "\\[ad]", sizeof(sym));                          strlcpy(sym, "\\[ad]", sizeof(sym));
                         break;                          break;
                 case (EQN_TOK_VEC):                  case EQN_TOK_VEC:
                         strlcpy(sym, "\\[->]", sizeof(sym));                          strlcpy(sym, "\\[->]", sizeof(sym));
                         break;                          break;
                 case (EQN_TOK_DYAD):                  case EQN_TOK_DYAD:
                         strlcpy(sym, "\\[<>]", sizeof(sym));                          strlcpy(sym, "\\[<>]", sizeof(sym));
                         break;                          break;
                 case (EQN_TOK_TILDE):                  case EQN_TOK_TILDE:
                         strlcpy(sym, "\\[a~]", sizeof(sym));                          strlcpy(sym, "\\[a~]", sizeof(sym));
                         break;                          break;
                 case (EQN_TOK_UNDER):                  case EQN_TOK_UNDER:
                         strlcpy(sym, "\\[ul]", sizeof(sym));                          strlcpy(sym, "\\[ul]", sizeof(sym));
                         break;                          break;
                 case (EQN_TOK_BAR):                  case EQN_TOK_BAR:
                         strlcpy(sym, "\\[rl]", sizeof(sym));                          strlcpy(sym, "\\[rl]", sizeof(sym));
                         break;                          break;
                 case (EQN_TOK_DOT):                  case EQN_TOK_DOT:
                         strlcpy(sym, "\\[a.]", sizeof(sym));                          strlcpy(sym, "\\[a.]", sizeof(sym));
                         break;                          break;
                 case (EQN_TOK_HAT):                  case EQN_TOK_HAT:
                         strlcpy(sym, "\\[ha]", sizeof(sym));                          strlcpy(sym, "\\[ha]", sizeof(sym));
                         break;                          break;
                 default:                  default:
Line 793  this_tok:
Line 817  this_tok:
                 }                  }
   
                 switch (tok) {                  switch (tok) {
                 case (EQN_TOK_DOTDOT):                  case EQN_TOK_DOTDOT:
                 case (EQN_TOK_VEC):                  case EQN_TOK_VEC:
                 case (EQN_TOK_DYAD):                  case EQN_TOK_DYAD:
                 case (EQN_TOK_TILDE):                  case EQN_TOK_TILDE:
                 case (EQN_TOK_BAR):                  case EQN_TOK_BAR:
                 case (EQN_TOK_DOT):                  case EQN_TOK_DOT:
                 case (EQN_TOK_HAT):                  case EQN_TOK_HAT:
                         parent->top = mandoc_strdup(sym);                          parent->top = mandoc_strdup(sym);
                         break;                          break;
                 case (EQN_TOK_UNDER):                  case EQN_TOK_UNDER:
                         parent->bottom = mandoc_strdup(sym);                          parent->bottom = mandoc_strdup(sym);
                         break;                          break;
                 default:                  default:
Line 810  this_tok:
Line 834  this_tok:
                 }                  }
                 parent = parent->parent;                  parent = parent->parent;
                 break;                  break;
         case (EQN_TOK_FWD):          case EQN_TOK_FWD:
         case (EQN_TOK_BACK):          case EQN_TOK_BACK:
         case (EQN_TOK_DOWN):          case EQN_TOK_DOWN:
         case (EQN_TOK_UP):          case EQN_TOK_UP:
                 subtok = eqn_tok_parse(ep, NULL);                  subtok = eqn_tok_parse(ep, NULL);
                 if (subtok != EQN_TOK__MAX) {                  if (subtok != EQN_TOK__MAX) {
                         mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,                          mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,
Line 822  this_tok:
Line 846  this_tok:
                         goto this_tok;                          goto this_tok;
                 }                  }
                 break;                  break;
         case (EQN_TOK_FAT):          case EQN_TOK_FAT:
         case (EQN_TOK_ROMAN):          case EQN_TOK_ROMAN:
         case (EQN_TOK_ITALIC):          case EQN_TOK_ITALIC:
         case (EQN_TOK_BOLD):          case EQN_TOK_BOLD:
                 while (parent->args == parent->expectargs)                  while (parent->args == parent->expectargs)
                         parent = parent->parent;                          parent = parent->parent;
                 /*                  /*
Line 837  this_tok:
Line 861  this_tok:
                 parent->type = EQN_LISTONE;                  parent->type = EQN_LISTONE;
                 parent->expectargs = 1;                  parent->expectargs = 1;
                 switch (tok) {                  switch (tok) {
                 case (EQN_TOK_FAT):                  case EQN_TOK_FAT:
                         parent->font = EQNFONT_FAT;                          parent->font = EQNFONT_FAT;
                         break;                          break;
                 case (EQN_TOK_ROMAN):                  case EQN_TOK_ROMAN:
                         parent->font = EQNFONT_ROMAN;                          parent->font = EQNFONT_ROMAN;
                         break;                          break;
                 case (EQN_TOK_ITALIC):                  case EQN_TOK_ITALIC:
                         parent->font = EQNFONT_ITALIC;                          parent->font = EQNFONT_ITALIC;
                         break;                          break;
                 case (EQN_TOK_BOLD):                  case EQN_TOK_BOLD:
                         parent->font = EQNFONT_BOLD;                          parent->font = EQNFONT_BOLD;
                         break;                          break;
                 default:                  default:
                         abort();                          abort();
                 }                  }
                 break;                  break;
         case (EQN_TOK_SIZE):          case EQN_TOK_SIZE:
         case (EQN_TOK_GSIZE):          case EQN_TOK_GSIZE:
                 /* Accept two values: integral size and a single. */                  /* Accept two values: integral size and a single. */
                 if (NULL == (start = eqn_nexttok(ep, &sz))) {                  if (NULL == (start = eqn_nexttok(ep, &sz))) {
                         mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,                          mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,
Line 876  this_tok:
Line 900  this_tok:
                 parent->expectargs = 1;                  parent->expectargs = 1;
                 parent->size = size;                  parent->size = size;
                 break;                  break;
         case (EQN_TOK_FROM):          case EQN_TOK_FROM:
         case (EQN_TOK_TO):          case EQN_TOK_TO:
         case (EQN_TOK_SUB):          case EQN_TOK_SUB:
         case (EQN_TOK_SUP):          case EQN_TOK_SUP:
                 /*                  /*
                  * We have a left-right-associative expression.                   * We have a left-right-associative expression.
                  * Repivot under a positional node, open a child scope                   * Repivot under a positional node, open a child scope
Line 904  this_tok:
Line 928  this_tok:
                         break;                          break;
                 }                  }
                 switch (tok) {                  switch (tok) {
                 case (EQN_TOK_FROM):                  case EQN_TOK_FROM:
                         pos = EQNPOS_FROM;                          pos = EQNPOS_FROM;
                         break;                          break;
                 case (EQN_TOK_TO):                  case EQN_TOK_TO:
                         pos = EQNPOS_TO;                          pos = EQNPOS_TO;
                         break;                          break;
                 case (EQN_TOK_SUP):                  case EQN_TOK_SUP:
                         pos = EQNPOS_SUP;                          pos = EQNPOS_SUP;
                         break;                          break;
                 case (EQN_TOK_SUB):                  case EQN_TOK_SUB:
                         pos = EQNPOS_SUB;                          pos = EQNPOS_SUB;
                         break;                          break;
                 default:                  default:
Line 921  this_tok:
Line 945  this_tok:
                 }                  }
                 parent = eqn_box_makebinary(ep, pos, parent);                  parent = eqn_box_makebinary(ep, pos, parent);
                 break;                  break;
         case (EQN_TOK_SQRT):          case EQN_TOK_SQRT:
                 while (parent->args == parent->expectargs)                  while (parent->args == parent->expectargs)
                         parent = parent->parent;                          parent = parent->parent;
                 /*                  /*
Line 934  this_tok:
Line 958  this_tok:
                 parent->pos = EQNPOS_SQRT;                  parent->pos = EQNPOS_SQRT;
                 parent->expectargs = 1;                  parent->expectargs = 1;
                 break;                  break;
         case (EQN_TOK_OVER):          case EQN_TOK_OVER:
                 /*                  /*
                  * We have a right-left-associative fraction.                   * We have a right-left-associative fraction.
                  * Close out anything that's currently open, then                   * Close out anything that's currently open, then
Line 951  this_tok:
Line 975  this_tok:
                         parent = parent->parent;                          parent = parent->parent;
                 parent = eqn_box_makebinary(ep, EQNPOS_OVER, parent);                  parent = eqn_box_makebinary(ep, EQNPOS_OVER, parent);
                 break;                  break;
         case (EQN_TOK_RIGHT):          case EQN_TOK_RIGHT:
         case (EQN_TOK_BRACE_CLOSE):          case EQN_TOK_BRACE_CLOSE:
                 /*                  /*
                  * Close out the existing brace.                   * Close out the existing brace.
                  * FIXME: this is a shitty sentinel: we should really                   * FIXME: this is a shitty sentinel: we should really
Line 987  this_tok:
Line 1011  this_tok:
                                 parent->right = mandoc_strndup(start, sz);                                  parent->right = mandoc_strndup(start, sz);
                 }                  }
                 parent = parent->parent;                  parent = parent->parent;
                 if (EQN_TOK_BRACE_CLOSE == tok && parent &&                  if (tok == EQN_TOK_BRACE_CLOSE &&
                     (parent->type == EQN_PILE ||                      (parent->type == EQN_PILE ||
                      parent->type == EQN_MATRIX))                       parent->type == EQN_MATRIX))
                         parent = parent->parent;                          parent = parent->parent;
Line 996  this_tok:
Line 1020  this_tok:
                     parent->args == parent->expectargs)                      parent->args == parent->expectargs)
                         parent = parent->parent;                          parent = parent->parent;
                 break;                  break;
         case (EQN_TOK_BRACE_OPEN):          case EQN_TOK_BRACE_OPEN:
         case (EQN_TOK_LEFT):          case EQN_TOK_LEFT:
                 /*                  /*
                  * If we already have something in the stack and we're                   * If we already have something in the stack and we're
                  * in an expression, then rewind til we're not any more                   * in an expression, then rewind til we're not any more
Line 1024  this_tok:
Line 1048  this_tok:
                                 parent->left = mandoc_strndup(start, sz);                                  parent->left = mandoc_strndup(start, sz);
                 }                  }
                 break;                  break;
         case (EQN_TOK_PILE):          case EQN_TOK_PILE:
         case (EQN_TOK_LPILE):          case EQN_TOK_LPILE:
         case (EQN_TOK_RPILE):          case EQN_TOK_RPILE:
         case (EQN_TOK_CPILE):          case EQN_TOK_CPILE:
         case (EQN_TOK_CCOL):          case EQN_TOK_CCOL:
         case (EQN_TOK_LCOL):          case EQN_TOK_LCOL:
         case (EQN_TOK_RCOL):          case EQN_TOK_RCOL:
                 while (parent->args == parent->expectargs)                  while (parent->args == parent->expectargs)
                         parent = parent->parent;                          parent = parent->parent;
                 parent = eqn_box_alloc(ep, parent);                  parent = eqn_box_alloc(ep, parent);
                 parent->type = EQN_PILE;                  parent->type = EQN_PILE;
                 parent->expectargs = 1;                  parent->expectargs = 1;
                 break;                  break;
         case (EQN_TOK_ABOVE):          case EQN_TOK_ABOVE:
                 for (cur = parent; cur != NULL; cur = cur->parent)                  for (cur = parent; cur != NULL; cur = cur->parent)
                         if (cur->type == EQN_PILE)                          if (cur->type == EQN_PILE)
                                 break;                                  break;
Line 1049  this_tok:
Line 1073  this_tok:
                 parent = eqn_box_alloc(ep, cur);                  parent = eqn_box_alloc(ep, cur);
                 parent->type = EQN_LIST;                  parent->type = EQN_LIST;
                 break;                  break;
         case (EQN_TOK_MATRIX):          case EQN_TOK_MATRIX:
                 while (parent->args == parent->expectargs)                  while (parent->args == parent->expectargs)
                         parent = parent->parent;                          parent = parent->parent;
                 parent = eqn_box_alloc(ep, parent);                  parent = eqn_box_alloc(ep, parent);
                 parent->type = EQN_MATRIX;                  parent->type = EQN_MATRIX;
                 parent->expectargs = 1;                  parent->expectargs = 1;
                 break;                  break;
         case (EQN_TOK_EOF):          case EQN_TOK_EOF:
                 /*                  /*
                  * End of file!                   * End of file!
                  * TODO: make sure we're not in an open subexpression.                   * TODO: make sure we're not in an open subexpression.
                  */                   */
                 return ROFF_EQN;                  return ROFF_EQN;
         default:          case EQN_TOK__MAX:
                 assert(tok == EQN_TOK__MAX);          case EQN_TOK_FUNC:
                 assert(NULL != p);          case EQN_TOK_QUOTED:
           case EQN_TOK_SYM:
                   assert(p != NULL);
                 /*                  /*
                  * If we already have something in the stack and we're                   * If we already have something in the stack and we're
                  * in an expression, then rewind til we're not any more.                   * in an expression, then rewind til we're not any more.
                  */                   */
                 while (parent->args == parent->expectargs)                  while (parent->args == parent->expectargs)
                         parent = parent->parent;                          parent = parent->parent;
                   /*
                    * Wrap well-known function names in a roman box,
                    * unless they already are in roman context.
                    */
                   for (fontp = parent; fontp != NULL; fontp = fontp->parent)
                           if (fontp->font != EQNFONT_NONE)
                                   break;
                   if (tok == EQN_TOK_FUNC &&
                       (fontp == NULL || fontp->font != EQNFONT_ROMAN)) {
                           parent = fontp = eqn_box_alloc(ep, parent);
                           parent->type = EQN_LISTONE;
                           parent->font = EQNFONT_ROMAN;
                           parent->expectargs = 1;
                   }
                 cur = eqn_box_alloc(ep, parent);                  cur = eqn_box_alloc(ep, parent);
                 cur->type = EQN_TEXT;                  cur->type = EQN_TEXT;
                 for (i = 0; i < EQNSYM__MAX; i++)                  cur->text = p;
                         if (0 == strcmp(eqnsyms[i].str, p)) {                  /*
                                 (void)snprintf(sym, sizeof(sym),                   * If not inside any explicit font context,
                                         "\\[%s]", eqnsyms[i].sym);                   * quoted strings become italic, and every letter
                                 cur->text = mandoc_strdup(sym);                   * of a bare string gets its own italic box.
                                 free(p);                   */
                   do {
                           if (fontp != NULL || *p == '\0' ||
                               tok == EQN_TOK_SYM)
                                 break;                                  break;
                           if (tok == EQN_TOK_QUOTED) {
                                   cur->font = EQNFONT_ITALIC;
                                   break;
                         }                          }
                           cp = p;
                 if (i == EQNSYM__MAX)                          for (;;) {
                         cur->text = p;                                  if (isalpha((unsigned char)*cp))
                                           cur->font = EQNFONT_ITALIC;
                                   cpn = cp + 1;
                                   if (*cp == '\\')
                                           mandoc_escape(&cpn, NULL, NULL);
                                   if (*cpn == '\0')
                                           break;
                                   if (cur->font != EQNFONT_ITALIC &&
                                       isalpha((unsigned char)*cpn) == 0) {
                                           cp = cpn;
                                           continue;
                                   }
                                   nbox = eqn_box_alloc(ep, parent);
                                   nbox->type = EQN_TEXT;
                                   nbox->text = mandoc_strdup(cpn);
                                   p = mandoc_strndup(cur->text,
                                       cpn - cur->text);
                                   free(cur->text);
                                   cur->text = p;
                                   cur = nbox;
                                   cp = nbox->text;
                           }
                   } while (0);
                 /*                  /*
                  * Post-process list status.                   * Post-process list status.
                  */                   */
Line 1091  this_tok:
Line 1159  this_tok:
                     parent->args == parent->expectargs)                      parent->args == parent->expectargs)
                         parent = parent->parent;                          parent = parent->parent;
                 break;                  break;
           default:
                   abort();
         }          }
         goto next_tok;          goto next_tok;
 }  }

Legend:
Removed from v.1.60  
changed lines
  Added in v.1.67

CVSweb