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

Diff for /mandoc/eqn.c between version 1.80 and 1.84

version 1.80, 2018/12/13 03:40:13 version 1.84, 2020/01/08 12:16:24
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, 2017 Ingo Schwarze <schwarze@openbsd.org>   * Copyright (c) 2014,2015,2017,2018,2020 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 30 
Line 30 
 #include "mandoc_aux.h"  #include "mandoc_aux.h"
 #include "mandoc.h"  #include "mandoc.h"
 #include "roff.h"  #include "roff.h"
   #include "eqn.h"
 #include "libmandoc.h"  #include "libmandoc.h"
 #include "eqn_parse.h"  #include "eqn_parse.h"
   
Line 302  static void   eqn_undef(struct eqn_node *);
Line 303  static void   eqn_undef(struct eqn_node *);
   
   
 struct eqn_node *  struct eqn_node *
 eqn_alloc(struct mparse *parse)  eqn_alloc(void)
 {  {
         struct eqn_node *ep;          struct eqn_node *ep;
   
         ep = mandoc_calloc(1, sizeof(*ep));          ep = mandoc_calloc(1, sizeof(*ep));
         ep->parse = parse;  
         ep->gsize = EQN_DEFSIZE;          ep->gsize = EQN_DEFSIZE;
         return ep;          return ep;
 }  }
Line 399  eqn_next(struct eqn_node *ep, enum parse_mode mode)
Line 399  eqn_next(struct eqn_node *ep, enum parse_mode mode)
                 case '"':                  case '"':
                         quoted = 1;                          quoted = 1;
                         break;                          break;
                   case ' ':
                   case '\t':
                   case '~':
                   case '^':
                           if (quoted)
                                   break;
                           ep->start++;
                           continue;
                 default:                  default:
                         break;                          break;
                 }                  }
Line 406  eqn_next(struct eqn_node *ep, enum parse_mode mode)
Line 414  eqn_next(struct eqn_node *ep, enum parse_mode mode)
                         ep->end = strchr(ep->start + 1, *ep->start);                          ep->end = strchr(ep->start + 1, *ep->start);
                         ep->start++;  /* Skip opening quote. */                          ep->start++;  /* Skip opening quote. */
                         if (ep->end == NULL) {                          if (ep->end == NULL) {
                                 mandoc_msg(MANDOCERR_ARG_QUOTE, ep->parse,                                  mandoc_msg(MANDOCERR_ARG_QUOTE,
                                     ep->node->line, ep->node->pos, NULL);                                      ep->node->line, ep->node->pos, NULL);
                                 ep->end = strchr(ep->start, '\0');                                  ep->end = strchr(ep->start, '\0');
                         }                          }
Line 427  eqn_next(struct eqn_node *ep, enum parse_mode mode)
Line 435  eqn_next(struct eqn_node *ep, enum parse_mode mode)
                 if ((def = eqn_def_find(ep)) == NULL)                  if ((def = eqn_def_find(ep)) == NULL)
                         break;                          break;
                 if (++lim > EQN_NEST_MAX) {                  if (++lim > EQN_NEST_MAX) {
                         mandoc_msg(MANDOCERR_ROFFLOOP, ep->parse,                          mandoc_msg(MANDOCERR_ROFFLOOP,
                             ep->node->line, ep->node->pos, NULL);                              ep->node->line, ep->node->pos, NULL);
                         return EQN_TOK_EOF;                          return EQN_TOK_EOF;
                 }                  }
Line 491  eqn_box_free(struct eqn_box *bp)
Line 499  eqn_box_free(struct eqn_box *bp)
         free(bp);          free(bp);
 }  }
   
   struct eqn_box *
   eqn_box_new(void)
   {
           struct eqn_box  *bp;
   
           bp = mandoc_calloc(1, sizeof(*bp));
           bp->expectargs = UINT_MAX;
           return bp;
   }
   
 /*  /*
  * Allocate a box as the last child of the parent node.   * Allocate a box as the last child of the parent node.
  */   */
Line 499  eqn_box_alloc(struct eqn_node *ep, struct eqn_box *par
Line 517  eqn_box_alloc(struct eqn_node *ep, struct eqn_box *par
 {  {
         struct eqn_box  *bp;          struct eqn_box  *bp;
   
         bp = mandoc_calloc(1, sizeof(struct eqn_box));          bp = eqn_box_new();
         bp->parent = parent;          bp->parent = parent;
         bp->parent->args++;          bp->parent->args++;
         bp->expectargs = UINT_MAX;  
         bp->font = bp->parent->font;          bp->font = bp->parent->font;
         bp->size = ep->gsize;          bp->size = ep->gsize;
   
Line 551  static void
Line 568  static void
 eqn_delim(struct eqn_node *ep)  eqn_delim(struct eqn_node *ep)
 {  {
         if (ep->end[0] == '\0' || ep->end[1] == '\0') {          if (ep->end[0] == '\0' || ep->end[1] == '\0') {
                 mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,                  mandoc_msg(MANDOCERR_REQ_EMPTY,
                     ep->node->line, ep->node->pos, "delim");                      ep->node->line, ep->node->pos, "delim");
                 if (ep->end[0] != '\0')                  if (ep->end[0] != '\0')
                         ep->end++;                          ep->end++;
Line 578  eqn_undef(struct eqn_node *ep)
Line 595  eqn_undef(struct eqn_node *ep)
         struct eqn_def  *def;          struct eqn_def  *def;
   
         if (eqn_next(ep, MODE_NOSUB) == EQN_TOK_EOF) {          if (eqn_next(ep, MODE_NOSUB) == EQN_TOK_EOF) {
                 mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,                  mandoc_msg(MANDOCERR_REQ_EMPTY,
                     ep->node->line, ep->node->pos, "undef");                      ep->node->line, ep->node->pos, "undef");
                 return;                  return;
         }          }
Line 597  eqn_def(struct eqn_node *ep)
Line 614  eqn_def(struct eqn_node *ep)
         int              i;          int              i;
   
         if (eqn_next(ep, MODE_NOSUB) == EQN_TOK_EOF) {          if (eqn_next(ep, MODE_NOSUB) == EQN_TOK_EOF) {
                 mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,                  mandoc_msg(MANDOCERR_REQ_EMPTY,
                     ep->node->line, ep->node->pos, "define");                      ep->node->line, ep->node->pos, "define");
                 return;                  return;
         }          }
Line 626  eqn_def(struct eqn_node *ep)
Line 643  eqn_def(struct eqn_node *ep)
         }          }
   
         if (eqn_next(ep, MODE_QUOTED) == EQN_TOK_EOF) {          if (eqn_next(ep, MODE_QUOTED) == EQN_TOK_EOF) {
                 mandoc_vmsg(MANDOCERR_REQ_EMPTY, ep->parse,                  mandoc_msg(MANDOCERR_REQ_EMPTY,
                     ep->node->line, ep->node->pos, "define %s", def->key);                      ep->node->line, ep->node->pos, "define %s", def->key);
                 free(def->key);                  free(def->key);
                 free(def->val);                  free(def->val);
Line 660  eqn_parse(struct eqn_node *ep)
Line 677  eqn_parse(struct eqn_node *ep)
         if (ep->data == NULL)          if (ep->data == NULL)
                 return;                  return;
   
         ep->start = ep->end = ep->data + strspn(ep->data, " ^~");          ep->start = ep->end = ep->data;
   
 next_tok:  next_tok:
         tok = eqn_next(ep, MODE_TOK);          tok = eqn_next(ep, MODE_TOK);
Line 675  next_tok:
Line 692  next_tok:
         case EQN_TOK_TDEFINE:          case EQN_TOK_TDEFINE:
                 if (eqn_next(ep, MODE_NOSUB) == EQN_TOK_EOF ||                  if (eqn_next(ep, MODE_NOSUB) == EQN_TOK_EOF ||
                     eqn_next(ep, MODE_QUOTED) == EQN_TOK_EOF)                      eqn_next(ep, MODE_QUOTED) == EQN_TOK_EOF)
                         mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,                          mandoc_msg(MANDOCERR_REQ_EMPTY,
                             ep->node->line, ep->node->pos, "tdefine");                              ep->node->line, ep->node->pos, "tdefine");
                 break;                  break;
         case EQN_TOK_DELIM:          case EQN_TOK_DELIM:
Line 683  next_tok:
Line 700  next_tok:
                 break;                  break;
         case EQN_TOK_GFONT:          case EQN_TOK_GFONT:
                 if (eqn_next(ep, MODE_SUB) == EQN_TOK_EOF)                  if (eqn_next(ep, MODE_SUB) == EQN_TOK_EOF)
                         mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,                          mandoc_msg(MANDOCERR_REQ_EMPTY, ep->node->line,
                             ep->node->line, ep->node->pos, eqn_toks[tok]);                              ep->node->pos, "%s", eqn_toks[tok]);
                 break;                  break;
         case EQN_TOK_MARK:          case EQN_TOK_MARK:
         case EQN_TOK_LINEUP:          case EQN_TOK_LINEUP:
Line 699  next_tok:
Line 716  next_tok:
         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->node->line,
                             ep->node->line, ep->node->pos, eqn_toks[tok]);                              ep->node->pos, "%s", eqn_toks[tok]);
                         cur = eqn_box_alloc(ep, parent);                          cur = eqn_box_alloc(ep, parent);
                         cur->type = EQN_TEXT;                          cur->type = EQN_TEXT;
                         cur->text = mandoc_strdup("");                          cur->text = mandoc_strdup("");
Line 744  next_tok:
Line 761  next_tok:
         case EQN_TOK_DOWN:          case EQN_TOK_DOWN:
         case EQN_TOK_UP:          case EQN_TOK_UP:
                 if (eqn_next(ep, MODE_SUB) == EQN_TOK_EOF)                  if (eqn_next(ep, MODE_SUB) == EQN_TOK_EOF)
                         mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,                          mandoc_msg(MANDOCERR_REQ_EMPTY, ep->node->line,
                             ep->node->line, ep->node->pos, eqn_toks[tok]);                              ep->node->pos, "%s", eqn_toks[tok]);
                 break;                  break;
         case EQN_TOK_FAT:          case EQN_TOK_FAT:
         case EQN_TOK_ROMAN:          case EQN_TOK_ROMAN:
Line 782  next_tok:
Line 799  next_tok:
         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 (eqn_next(ep, MODE_SUB) == EQN_TOK_EOF) {                  if (eqn_next(ep, MODE_SUB) == EQN_TOK_EOF) {
                         mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,                          mandoc_msg(MANDOCERR_REQ_EMPTY, ep->node->line,
                             ep->node->line, ep->node->pos, eqn_toks[tok]);                              ep->node->pos, "%s", eqn_toks[tok]);
                         break;                          break;
                 }                  }
                 size = mandoc_strntoi(ep->start, ep->toksz, 10);                  size = mandoc_strntoi(ep->start, ep->toksz, 10);
                 if (-1 == size) {                  if (-1 == size) {
                         mandoc_msg(MANDOCERR_IT_NONUM, ep->parse,                          mandoc_msg(MANDOCERR_IT_NONUM, ep->node->line,
                             ep->node->line, ep->node->pos, eqn_toks[tok]);                              ep->node->pos, "%s", eqn_toks[tok]);
                         break;                          break;
                 }                  }
                 if (EQN_TOK_GSIZE == tok) {                  if (EQN_TOK_GSIZE == tok) {
Line 813  next_tok:
Line 830  next_tok:
                  * and keep on reading.                   * and keep on reading.
                  */                   */
                 if (parent->last == NULL) {                  if (parent->last == NULL) {
                         mandoc_msg(MANDOCERR_EQN_NOBOX, ep->parse,                          mandoc_msg(MANDOCERR_EQN_NOBOX, ep->node->line,
                             ep->node->line, ep->node->pos, eqn_toks[tok]);                              ep->node->pos, "%s", eqn_toks[tok]);
                         cur = eqn_box_alloc(ep, parent);                          cur = eqn_box_alloc(ep, parent);
                         cur->type = EQN_TEXT;                          cur->type = EQN_TEXT;
                         cur->text = mandoc_strdup("");                          cur->text = mandoc_strdup("");
Line 880  next_tok:
Line 897  next_tok:
                  * rebalance and continue reading.                   * rebalance and continue reading.
                  */                   */
                 if (parent->last == NULL) {                  if (parent->last == NULL) {
                         mandoc_msg(MANDOCERR_EQN_NOBOX, ep->parse,                          mandoc_msg(MANDOCERR_EQN_NOBOX, ep->node->line,
                             ep->node->line, ep->node->pos, eqn_toks[tok]);                              ep->node->pos, "%s", eqn_toks[tok]);
                         cur = eqn_box_alloc(ep, parent);                          cur = eqn_box_alloc(ep, parent);
                         cur->type = EQN_TEXT;                          cur->type = EQN_TEXT;
                         cur->text = mandoc_strdup("");                          cur->text = mandoc_strdup("");
Line 907  next_tok:
Line 924  next_tok:
                              cur->left != NULL))                               cur->left != NULL))
                                 break;                                  break;
                 if (cur == NULL) {                  if (cur == NULL) {
                         mandoc_msg(MANDOCERR_BLK_NOTOPEN, ep->parse,                          mandoc_msg(MANDOCERR_BLK_NOTOPEN, ep->node->line,
                             ep->node->line, ep->node->pos, eqn_toks[tok]);                              ep->node->pos, "%s", eqn_toks[tok]);
                         break;                          break;
                 }                  }
                 parent = cur;                  parent = cur;
                 if (EQN_TOK_RIGHT == tok) {                  if (EQN_TOK_RIGHT == tok) {
                         if (eqn_next(ep, MODE_SUB) == EQN_TOK_EOF) {                          if (eqn_next(ep, MODE_SUB) == EQN_TOK_EOF) {
                                 mandoc_msg(MANDOCERR_REQ_EMPTY,                                  mandoc_msg(MANDOCERR_REQ_EMPTY,
                                     ep->parse, ep->node->line,                                      ep->node->line, ep->node->pos,
                                     ep->node->pos, eqn_toks[tok]);                                      "%s", eqn_toks[tok]);
                                 break;                                  break;
                         }                          }
                         /* Handling depends on right/left. */                          /* Handling depends on right/left. */
Line 950  next_tok:
Line 967  next_tok:
                         parent = parent->parent;                          parent = parent->parent;
                 if (EQN_TOK_LEFT == tok &&                  if (EQN_TOK_LEFT == tok &&
                     eqn_next(ep, MODE_SUB) == EQN_TOK_EOF) {                      eqn_next(ep, MODE_SUB) == EQN_TOK_EOF) {
                         mandoc_msg(MANDOCERR_REQ_EMPTY, ep->parse,                          mandoc_msg(MANDOCERR_REQ_EMPTY, ep->node->line,
                             ep->node->line, ep->node->pos, eqn_toks[tok]);                              ep->node->pos, "%s", eqn_toks[tok]);
                         break;                          break;
                 }                  }
                 parent = eqn_box_alloc(ep, parent);                  parent = eqn_box_alloc(ep, parent);
Line 984  next_tok:
Line 1001  next_tok:
                         if (cur->type == EQN_PILE)                          if (cur->type == EQN_PILE)
                                 break;                                  break;
                 if (cur == NULL) {                  if (cur == NULL) {
                         mandoc_msg(MANDOCERR_IT_STRAY, ep->parse,                          mandoc_msg(MANDOCERR_IT_STRAY, ep->node->line,
                             ep->node->line, ep->node->pos, eqn_toks[tok]);                              ep->node->pos, "%s", eqn_toks[tok]);
                         break;                          break;
                 }                  }
                 parent = eqn_box_alloc(ep, cur);                  parent = eqn_box_alloc(ep, cur);

Legend:
Removed from v.1.80  
changed lines
  Added in v.1.84

CVSweb