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

Diff for /mandoc/eqn.c between version 1.32 and 1.40

version 1.32, 2011/07/23 12:01:54 version 1.40, 2014/04/20 16:46:04
Line 26 
Line 26 
 #include <time.h>  #include <time.h>
   
 #include "mandoc.h"  #include "mandoc.h"
   #include "mandoc_aux.h"
 #include "libmandoc.h"  #include "libmandoc.h"
 #include "libroff.h"  #include "libroff.h"
   
Line 102  enum eqn_symt {
Line 103  enum eqn_symt {
         EQNSYM__MAX          EQNSYM__MAX
 };  };
   
   enum    eqnpartt {
           EQN_DEFINE = 0,
           EQN_NDEFINE,
           EQN_TDEFINE,
           EQN_SET,
           EQN_UNDEF,
           EQN_GFONT,
           EQN_GSIZE,
           EQN_BACK,
           EQN_FWD,
           EQN_UP,
           EQN_DOWN,
           EQN__MAX
   };
   
 struct  eqnstr {  struct  eqnstr {
         const char      *name;          const char      *name;
         size_t           sz;          size_t           sz;
Line 122  struct eqnsym {
Line 138  struct eqnsym {
         const char      *sym;          const char      *sym;
 };  };
   
 enum    eqnpartt {  
         EQN_DEFINE = 0,  
         EQN_SET,  
         EQN_UNDEF,  
         EQN_GFONT,  
         EQN_GSIZE,  
         EQN__MAX  
 };  
   
 static  enum eqn_rest    eqn_box(struct eqn_node *, struct eqn_box *);  static  enum eqn_rest    eqn_box(struct eqn_node *, struct eqn_box *);
 static  struct eqn_box  *eqn_box_alloc(struct eqn_node *,  static  struct eqn_box  *eqn_box_alloc(struct eqn_node *,
                                 struct eqn_box *);                                  struct eqn_box *);
 static  void             eqn_box_free(struct eqn_box *);  static  void             eqn_box_free(struct eqn_box *);
 static  struct eqn_def  *eqn_def_find(struct eqn_node *,  static  struct eqn_def  *eqn_def_find(struct eqn_node *,
                                 const char *, size_t);                                  const char *, size_t);
 static  int              eqn_do_gfont(struct eqn_node *);  static  int              eqn_do_gfont(struct eqn_node *);
 static  int              eqn_do_gsize(struct eqn_node *);  static  int              eqn_do_gsize(struct eqn_node *);
 static  int              eqn_do_define(struct eqn_node *);  static  int              eqn_do_define(struct eqn_node *);
 static  int              eqn_do_set(struct eqn_node *);  static  int              eqn_do_ign1(struct eqn_node *);
   static  int              eqn_do_ign2(struct eqn_node *);
   static  int              eqn_do_tdefine(struct eqn_node *);
 static  int              eqn_do_undef(struct eqn_node *);  static  int              eqn_do_undef(struct eqn_node *);
 static  enum eqn_rest    eqn_eqn(struct eqn_node *, struct eqn_box *);  static  enum eqn_rest    eqn_eqn(struct eqn_node *, struct eqn_box *);
 static  enum eqn_rest    eqn_list(struct eqn_node *, struct eqn_box *);  static  enum eqn_rest    eqn_list(struct eqn_node *, struct eqn_box *);
 static  enum eqn_rest    eqn_matrix(struct eqn_node *, struct eqn_box *);  static  enum eqn_rest    eqn_matrix(struct eqn_node *, struct eqn_box *);
 static  const char      *eqn_nexttok(struct eqn_node *, size_t *);  static  const char      *eqn_nexttok(struct eqn_node *, size_t *);
 static  const char      *eqn_nextrawtok(struct eqn_node *, size_t *);  static  const char      *eqn_nextrawtok(struct eqn_node *, size_t *);
 static  const char      *eqn_next(struct eqn_node *,  static  const char      *eqn_next(struct eqn_node *,
                                 char, size_t *, int);                                  char, size_t *, int);
 static  void             eqn_rewind(struct eqn_node *);  static  void             eqn_rewind(struct eqn_node *);
   
 static  const struct eqnpart eqnparts[EQN__MAX] = {  static  const struct eqnpart eqnparts[EQN__MAX] = {
         { { "define", 6 }, eqn_do_define }, /* EQN_DEFINE */          { { "define", 6 }, eqn_do_define }, /* EQN_DEFINE */
         { { "set", 3 }, eqn_do_set }, /* EQN_SET */          { { "ndefine", 7 }, eqn_do_define }, /* EQN_NDEFINE */
           { { "tdefine", 7 }, eqn_do_tdefine }, /* EQN_TDEFINE */
           { { "set", 3 }, eqn_do_ign2 }, /* EQN_SET */
         { { "undef", 5 }, eqn_do_undef }, /* EQN_UNDEF */          { { "undef", 5 }, eqn_do_undef }, /* EQN_UNDEF */
         { { "gfont", 5 }, eqn_do_gfont }, /* EQN_GFONT */          { { "gfont", 5 }, eqn_do_gfont }, /* EQN_GFONT */
         { { "gsize", 5 }, eqn_do_gsize }, /* EQN_GSIZE */          { { "gsize", 5 }, eqn_do_gsize }, /* EQN_GSIZE */
           { { "back", 4 }, eqn_do_ign1 }, /* EQN_BACK */
           { { "fwd", 3 }, eqn_do_ign1 }, /* EQN_FWD */
           { { "up", 2 }, eqn_do_ign1 }, /* EQN_UP */
           { { "down", 4 }, eqn_do_ign1 }, /* EQN_DOWN */
 };  };
   
 static  const struct eqnstr eqnmarks[EQNMARK__MAX] = {  static  const struct eqnstr eqnmarks[EQNMARK__MAX] = {
Line 175  static const struct eqnstr eqnfonts[EQNFONT__MAX] = {
Line 190  static const struct eqnstr eqnfonts[EQNFONT__MAX] = {
         { "", 0 }, /* EQNFONT_NONE */          { "", 0 }, /* EQNFONT_NONE */
         { "roman", 5 }, /* EQNFONT_ROMAN */          { "roman", 5 }, /* EQNFONT_ROMAN */
         { "bold", 4 }, /* EQNFONT_BOLD */          { "bold", 4 }, /* EQNFONT_BOLD */
           { "fat", 3 }, /* EQNFONT_FAT */
         { "italic", 6 }, /* EQNFONT_ITALIC */          { "italic", 6 }, /* EQNFONT_ITALIC */
 };  };
   
Line 189  static const struct eqnstr eqnposs[EQNPOS__MAX] = {
Line 205  static const struct eqnstr eqnposs[EQNPOS__MAX] = {
   
 static  const struct eqnstr eqnpiles[EQNPILE__MAX] = {  static  const struct eqnstr eqnpiles[EQNPILE__MAX] = {
         { "", 0 }, /* EQNPILE_NONE */          { "", 0 }, /* EQNPILE_NONE */
           { "pile", 4 }, /* EQNPILE_PILE */
         { "cpile", 5 }, /* EQNPILE_CPILE */          { "cpile", 5 }, /* EQNPILE_CPILE */
         { "rpile", 5 }, /* EQNPILE_RPILE */          { "rpile", 5 }, /* EQNPILE_RPILE */
         { "lpile", 5 }, /* EQNPILE_LPILE */          { "lpile", 5 }, /* EQNPILE_LPILE */
           { "col", 3 }, /* EQNPILE_COL */
         { "ccol", 4 }, /* EQNPILE_CCOL */          { "ccol", 4 }, /* EQNPILE_CCOL */
         { "rcol", 4 }, /* EQNPILE_RCOL */          { "rcol", 4 }, /* EQNPILE_RCOL */
         { "lcol", 4 }, /* EQNPILE_LCOL */          { "lcol", 4 }, /* EQNPILE_LCOL */
Line 259  static const struct eqnsym eqnsyms[EQNSYM__MAX] = {
Line 277  static const struct eqnsym eqnsyms[EQNSYM__MAX] = {
         { { ">=", 2 }, ">=" }, /* EQNSYM_moreequal */          { { ">=", 2 }, ">=" }, /* EQNSYM_moreequal */
 };  };
   
 /* ARGSUSED */  
 enum rofferr  enum rofferr
 eqn_read(struct eqn_node **epp, int ln,  eqn_read(struct eqn_node **epp, int ln,
                 const char *p, int pos, int *offs)                  const char *p, int pos, int *offs)
 {  {
         size_t           sz;          size_t           sz;
Line 275  eqn_read(struct eqn_node **epp, int ln, 
Line 293  eqn_read(struct eqn_node **epp, int ln, 
          * validate the full equation.           * validate the full equation.
          */           */
   
         if (0 == strcmp(p, ".EN")) {          if (0 == strncmp(p, ".EN", 3)) {
                 er = eqn_end(ep);                  er = eqn_end(epp);
                 *epp = NULL;                  p += 3;
                   while (' ' == *p || '\t' == *p)
                           p++;
                   if ('\0' == *p)
                           return(er);
                   mandoc_msg(MANDOCERR_ARGSLOST, ep->parse, ln, pos, NULL);
                 return(er);                  return(er);
         }          }
   
Line 301  eqn_read(struct eqn_node **epp, int ln, 
Line 324  eqn_read(struct eqn_node **epp, int ln, 
 }  }
   
 struct eqn_node *  struct eqn_node *
 eqn_alloc(int pos, int line, struct mparse *parse)  eqn_alloc(const char *name, int pos, int line, struct mparse *parse)
 {  {
         struct eqn_node *p;          struct eqn_node *p;
           size_t           sz;
           const char      *end;
   
         p = mandoc_calloc(1, sizeof(struct eqn_node));          p = mandoc_calloc(1, sizeof(struct eqn_node));
   
           if (name && '\0' != *name) {
                   sz = strlen(name);
                   assert(sz);
                   do {
                           sz--;
                           end = name + (int)sz;
                   } while (' ' == *end || '\t' == *end);
                   p->eqn.name = mandoc_strndup(name, sz + 1);
           }
   
         p->parse = parse;          p->parse = parse;
         p->eqn.ln = line;          p->eqn.ln = line;
         p->eqn.pos = pos;          p->eqn.pos = pos;
Line 315  eqn_alloc(int pos, int line, struct mparse *parse)
Line 351  eqn_alloc(int pos, int line, struct mparse *parse)
 }  }
   
 enum rofferr  enum rofferr
 eqn_end(struct eqn_node *ep)  eqn_end(struct eqn_node **epp)
 {  {
           struct eqn_node *ep;
         struct eqn_box  *root;          struct eqn_box  *root;
         enum eqn_rest    c;          enum eqn_rest    c;
   
           ep = *epp;
           *epp = NULL;
   
         ep->eqn.root = mandoc_calloc(1, sizeof(struct eqn_box));          ep->eqn.root = mandoc_calloc(1, sizeof(struct eqn_box));
   
         root = ep->eqn.root;          root = ep->eqn.root;
Line 373  eqn_matrix(struct eqn_node *ep, struct eqn_box *last)
Line 413  eqn_matrix(struct eqn_node *ep, struct eqn_box *last)
   
         while (EQN_OK == (c = eqn_box(ep, bp)))          while (EQN_OK == (c = eqn_box(ep, bp)))
                 switch (bp->last->pile) {                  switch (bp->last->pile) {
                 case (EQNPILE_LCOL):                  case EQNPILE_LCOL:
                         /* FALLTHROUGH */                          /* FALLTHROUGH */
                 case (EQNPILE_CCOL):                  case EQNPILE_CCOL:
                         /* FALLTHROUGH */                          /* FALLTHROUGH */
                 case (EQNPILE_RCOL):                  case EQNPILE_RCOL:
                         continue;                          continue;
                 default:                  default:
                         EQN_MSG(MANDOCERR_EQNSYNT, ep);                          EQN_MSG(MANDOCERR_EQNSYNT, ep);
Line 464  eqn_box(struct eqn_node *ep, struct eqn_box *last)
Line 504  eqn_box(struct eqn_node *ep, struct eqn_box *last)
                 return(EQN_DESCOPE);                  return(EQN_DESCOPE);
         else if (STRNEQ(start, sz, "above", 5))          else if (STRNEQ(start, sz, "above", 5))
                 return(EQN_DESCOPE);                  return(EQN_DESCOPE);
           else if (STRNEQ(start, sz, "mark", 4))
                   return(EQN_OK);
           else if (STRNEQ(start, sz, "lineup", 6))
                   return(EQN_OK);
   
         for (i = 0; i < (int)EQN__MAX; i++) {          for (i = 0; i < (int)EQN__MAX; i++) {
                 if ( ! EQNSTREQ(&eqnparts[i].str, start, sz))                  if ( ! EQNSTREQ(&eqnparts[i].str, start, sz))
                         continue;                          continue;
                 return((*eqnparts[i].fp)(ep) ? EQN_OK : EQN_ERR);                  return((*eqnparts[i].fp)(ep) ? EQN_OK : EQN_ERR);
         }          }
   
         if (STRNEQ(start, sz, "{", 1)) {          if (STRNEQ(start, sz, "{", 1)) {
                 if (EQN_DESCOPE != (c = eqn_eqn(ep, last))) {                  if (EQN_DESCOPE != (c = eqn_eqn(ep, last))) {
Line 484  eqn_box(struct eqn_node *ep, struct eqn_box *last)
Line 528  eqn_box(struct eqn_node *ep, struct eqn_box *last)
                         return(EQN_OK);                          return(EQN_OK);
                 EQN_MSG(MANDOCERR_EQNBADSCOPE, ep);                  EQN_MSG(MANDOCERR_EQNBADSCOPE, ep);
                 return(EQN_ERR);                  return(EQN_ERR);
         }          }
   
         for (i = 0; i < (int)EQNPILE__MAX; i++) {          for (i = 0; i < (int)EQNPILE__MAX; i++) {
                 if ( ! EQNSTREQ(&eqnpiles[i], start, sz))                  if ( ! EQNSTREQ(&eqnpiles[i], start, sz))
Line 530  eqn_box(struct eqn_node *ep, struct eqn_box *last)
Line 574  eqn_box(struct eqn_node *ep, struct eqn_box *last)
                 if (NULL == last->last) {                  if (NULL == last->last) {
                         EQN_MSG(MANDOCERR_EQNSYNT, ep);                          EQN_MSG(MANDOCERR_EQNSYNT, ep);
                         return(EQN_ERR);                          return(EQN_ERR);
                 }                  }
                 last->last->pos = (enum eqn_post)i;                  last->last->pos = (enum eqn_post)i;
                 if (EQN_EOF == (c = eqn_box(ep, last))) {                  if (EQN_EOF == (c = eqn_box(ep, last))) {
                         EQN_MSG(MANDOCERR_EQNEOF, ep);                          EQN_MSG(MANDOCERR_EQNEOF, ep);
Line 545  eqn_box(struct eqn_node *ep, struct eqn_box *last)
Line 589  eqn_box(struct eqn_node *ep, struct eqn_box *last)
                 if (NULL == last->last) {                  if (NULL == last->last) {
                         EQN_MSG(MANDOCERR_EQNSYNT, ep);                          EQN_MSG(MANDOCERR_EQNSYNT, ep);
                         return(EQN_ERR);                          return(EQN_ERR);
                 }                  }
                 last->last->mark = (enum eqn_markt)i;                  last->last->mark = (enum eqn_markt)i;
                 if (EQN_EOF == (c = eqn_box(ep, last))) {                  if (EQN_EOF == (c = eqn_box(ep, last))) {
                         EQN_MSG(MANDOCERR_EQNEOF, ep);                          EQN_MSG(MANDOCERR_EQNEOF, ep);
Line 605  eqn_free(struct eqn_node *p)
Line 649  eqn_free(struct eqn_node *p)
                 free(p->defs[i].val);                  free(p->defs[i].val);
         }          }
   
           free(p->eqn.name);
         free(p->data);          free(p->data);
         free(p->defs);          free(p->defs);
         free(p);          free(p);
Line 681  again:
Line 726  again:
         /* Prevent self-definitions. */          /* Prevent self-definitions. */
   
         if (lim >= EQN_NEST_MAX) {          if (lim >= EQN_NEST_MAX) {
                 EQN_MSG(MANDOCERR_EQNNEST, ep);                  EQN_MSG(MANDOCERR_ROFFLOOP, ep);
                 return(NULL);                  return(NULL);
         }          }
   
Line 716  again:
Line 761  again:
                 if (q)                  if (q)
                         ep->cur++;                          ep->cur++;
                 while (' ' == ep->data[(int)ep->cur] ||                  while (' ' == ep->data[(int)ep->cur] ||
                                 '\t' == ep->data[(int)ep->cur] ||                      '\t' == ep->data[(int)ep->cur] ||
                                 '^' == ep->data[(int)ep->cur] ||                      '^' == ep->data[(int)ep->cur] ||
                                 '~' == ep->data[(int)ep->cur])                      '~' == ep->data[(int)ep->cur])
                         ep->cur++;                          ep->cur++;
         } else {          } else {
                 if (q)                  if (q)
Line 744  again:
Line 789  again:
                 }                  }
   
                 diff = def->valsz - *sz;                  diff = def->valsz - *sz;
                 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);
                 goto again;                  goto again;
         }          }
Line 754  again:
Line 799  again:
 }  }
   
 static int  static int
 eqn_do_set(struct eqn_node *ep)  eqn_do_ign1(struct eqn_node *ep)
 {  {
         const char      *start;  
   
         if (NULL == (start = eqn_nextrawtok(ep, NULL)))          if (NULL == eqn_nextrawtok(ep, NULL))
                 EQN_MSG(MANDOCERR_EQNEOF, ep);                  EQN_MSG(MANDOCERR_EQNEOF, ep);
         else if (NULL == (start = eqn_nextrawtok(ep, NULL)))          else
                   return(1);
   
           return(0);
   }
   
   static int
   eqn_do_ign2(struct eqn_node *ep)
   {
   
           if (NULL == eqn_nextrawtok(ep, NULL))
                 EQN_MSG(MANDOCERR_EQNEOF, ep);                  EQN_MSG(MANDOCERR_EQNEOF, ep);
           else if (NULL == eqn_nextrawtok(ep, NULL))
                   EQN_MSG(MANDOCERR_EQNEOF, ep);
         else          else
                 return(1);                  return(1);
   
Line 769  eqn_do_set(struct eqn_node *ep)
Line 825  eqn_do_set(struct eqn_node *ep)
 }  }
   
 static int  static int
   eqn_do_tdefine(struct eqn_node *ep)
   {
   
           if (NULL == eqn_nextrawtok(ep, NULL))
                   EQN_MSG(MANDOCERR_EQNEOF, ep);
           else if (NULL == eqn_next(ep, ep->data[(int)ep->cur], NULL, 0))
                   EQN_MSG(MANDOCERR_EQNEOF, ep);
           else
                   return(1);
   
           return(0);
   }
   
   static int
 eqn_do_define(struct eqn_node *ep)  eqn_do_define(struct eqn_node *ep)
 {  {
         const char      *start;          const char      *start;
Line 781  eqn_do_define(struct eqn_node *ep)
Line 851  eqn_do_define(struct eqn_node *ep)
                 return(0);                  return(0);
         }          }
   
         /*          /*
          * Search for a key that already exists.           * Search for a key that already exists.
          * Create a new key if none is found.           * Create a new key if none is found.
          */           */
   
Line 794  eqn_do_define(struct eqn_node *ep)
Line 864  eqn_do_define(struct eqn_node *ep)
   
                 if (i == (int)ep->defsz) {                  if (i == (int)ep->defsz) {
                         ep->defsz++;                          ep->defsz++;
                         ep->defs = mandoc_realloc                          ep->defs = mandoc_realloc(ep->defs,
                                 (ep->defs, ep->defsz *                              ep->defsz * sizeof(struct eqn_def));
                                  sizeof(struct eqn_def));  
                         ep->defs[i].key = ep->defs[i].val = NULL;                          ep->defs[i].key = ep->defs[i].val = NULL;
                 }                  }
   
                 ep->defs[i].keysz = sz;                  ep->defs[i].keysz = sz;
                 ep->defs[i].key = mandoc_realloc                  ep->defs[i].key = mandoc_realloc(
                         (ep->defs[i].key, sz + 1);                      ep->defs[i].key, sz + 1);
   
                 memcpy(ep->defs[i].key, start, sz);                  memcpy(ep->defs[i].key, start, sz);
                 ep->defs[i].key[(int)sz] = '\0';                  ep->defs[i].key[(int)sz] = '\0';
Line 826  eqn_do_define(struct eqn_node *ep)
Line 895  eqn_do_define(struct eqn_node *ep)
 static int  static int
 eqn_do_gfont(struct eqn_node *ep)  eqn_do_gfont(struct eqn_node *ep)
 {  {
         const char      *start;  
   
         if (NULL == (start = eqn_nextrawtok(ep, NULL))) {          if (NULL == eqn_nextrawtok(ep, NULL)) {
                 EQN_MSG(MANDOCERR_EQNEOF, ep);                  EQN_MSG(MANDOCERR_EQNEOF, ep);
                 return(0);                  return(0);
         }          }
         return(1);          return(1);
 }  }
   
Line 844  eqn_do_gsize(struct eqn_node *ep)
Line 912  eqn_do_gsize(struct eqn_node *ep)
         if (NULL == (start = eqn_nextrawtok(ep, &sz))) {          if (NULL == (start = eqn_nextrawtok(ep, &sz))) {
                 EQN_MSG(MANDOCERR_EQNEOF, ep);                  EQN_MSG(MANDOCERR_EQNEOF, ep);
                 return(0);                  return(0);
         }          }
   
         ep->gsize = mandoc_strntoi(start, sz, 10);          ep->gsize = mandoc_strntoi(start, sz, 10);
         return(1);          return(1);
 }  }
Line 871  eqn_def_find(struct eqn_node *ep, const char *key, siz
Line 938  eqn_def_find(struct eqn_node *ep, const char *key, siz
 {  {
         int              i;          int              i;
   
         for (i = 0; i < (int)ep->defsz; i++)          for (i = 0; i < (int)ep->defsz; i++)
                 if (ep->defs[i].keysz && STRNEQ(ep->defs[i].key,                  if (ep->defs[i].keysz && STRNEQ(ep->defs[i].key,
                                         ep->defs[i].keysz, key, sz))                      ep->defs[i].keysz, key, sz))
                         return(&ep->defs[i]);                          return(&ep->defs[i]);
   
         return(NULL);          return(NULL);

Legend:
Removed from v.1.32  
changed lines
  Added in v.1.40

CVSweb