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

Diff for /mandoc/tbl_opts.c between version 1.2 and 1.22

version 1.2, 2010/12/28 13:47:38 version 1.22, 2018/12/12 21:54:35
Line 1 
Line 1 
 /*      $Id$ */  /*      $Id$ */
 /*  /*
  * Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>   * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
    * Copyright (c) 2015 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 14 
Line 15 
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */   */
   #include "config.h"
   
   #include <sys/types.h>
   
   #include <ctype.h>
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
   
   #include "mandoc.h"
   #include "tbl.h"
   #include "libmandoc.h"
 #include "libroff.h"  #include "libroff.h"
   
 enum    tbl_ident {  #define KEY_DPOINT      0
         KEY_CENTRE = 0,  #define KEY_DELIM       1
         KEY_DELIM,  #define KEY_LINESIZE    2
         KEY_EXPAND,  #define KEY_TAB         3
         KEY_BOX,  
         KEY_DBOX,  
         KEY_ALLBOX,  
         KEY_TAB,  
         KEY_LINESIZE,  
         KEY_NOKEEP,  
         KEY_DPOINT,  
         KEY_NOSPACE,  
         KEY_FRAME,  
         KEY_DFRAME,  
         KEY_MAX  
 };  
   
 struct  tbl_phrase {  struct  tbl_phrase {
         const char      *name;          const char      *name;
         int              key;          int              key;
         enum tbl_ident   ident;  
 };  };
   
 /* Handle Commonwealth/American spellings. */  static  const struct tbl_phrase keys[] = {
 #define KEY_MAXKEYS      14          {"decimalpoint", 0},
           {"delim",        0},
 static  const struct tbl_phrase keys[KEY_MAXKEYS] = {          {"linesize",     0},
         { "center",      TBL_OPT_CENTRE,        KEY_CENTRE},          {"tab",          0},
         { "centre",      TBL_OPT_CENTRE,        KEY_CENTRE},          {"allbox",       TBL_OPT_ALLBOX | TBL_OPT_BOX},
         { "delim",       0,                     KEY_DELIM},          {"box",          TBL_OPT_BOX},
         { "expand",      TBL_OPT_EXPAND,        KEY_EXPAND},          {"frame",        TBL_OPT_BOX},
         { "box",         TBL_OPT_BOX,           KEY_BOX},          {"center",       TBL_OPT_CENTRE},
         { "doublebox",   TBL_OPT_DBOX,          KEY_DBOX},          {"centre",       TBL_OPT_CENTRE},
         { "allbox",      TBL_OPT_ALLBOX,        KEY_ALLBOX},          {"doublebox",    TBL_OPT_DBOX},
         { "frame",       TBL_OPT_BOX,           KEY_FRAME},          {"doubleframe",  TBL_OPT_DBOX},
         { "doubleframe", TBL_OPT_DBOX,          KEY_DFRAME},          {"expand",       TBL_OPT_EXPAND},
         { "tab",         0,                     KEY_TAB},          {"nokeep",       TBL_OPT_NOKEEP},
         { "linesize",    0,                     KEY_LINESIZE},          {"nospaces",     TBL_OPT_NOSPACE},
         { "nokeep",      TBL_OPT_NOKEEP,        KEY_NOKEEP},          {"nowarn",       TBL_OPT_NOWARN},
         { "decimalpoint", 0,                    KEY_DPOINT},  
         { "nospaces",    TBL_OPT_NOSPACE,       KEY_NOSPACE},  
 };  };
   
 static  int              arg(struct tbl *, int, const char *, int *, int);  #define KEY_MAXKEYS ((int)(sizeof(keys)/sizeof(keys[0])))
 static  int              opt(struct tbl *, int, const char *, int *);  
   
 static int  static  void     arg(struct tbl_node *, int, const char *, int *, int);
 arg(struct tbl *tbl, int ln, const char *p, int *pos, int key)  
 {  
         int              sv;  
   
 again:  
         sv = *pos;  
   
         switch (tbl_next(tbl, p, pos)) {  static void
         case (TBL_TOK_OPENPAREN):  arg(struct tbl_node *tbl, int ln, const char *p, int *pos, int key)
                 break;  {
         case (TBL_TOK_SPACE):          int              len, want;
                 /* FALLTHROUGH */  
         case (TBL_TOK_TAB):  
                 goto again;  
         default:  
                 return(0);  
         }  
   
         sv = *pos;          while (p[*pos] == ' ' || p[*pos] == '\t')
                   (*pos)++;
   
         switch (tbl_next(tbl, p, pos)) {          /* Arguments are enclosed in parentheses. */
         case (TBL_TOK__MAX):  
                 break;          len = 0;
         default:          if (p[*pos] == '(') {
                 return(0);                  (*pos)++;
                   while (p[*pos + len] != ')')
                           len++;
         }          }
   
         switch (key) {          switch (key) {
         case (KEY_DELIM):          case KEY_DELIM:
                 /* FIXME: cache this value. */                  mandoc_vmsg(MANDOCERR_TBLOPT_EQN, tbl->parse,
                 if (2 != strlen(tbl->buf))                      ln, *pos, "%.*s", len, p + *pos);
                         return(0);                  want = 2;
                 tbl->delims[0] = tbl->buf[0];  
                 tbl->delims[1] = tbl->buf[1];  
                 break;                  break;
         case (KEY_TAB):          case KEY_TAB:
                 /* FIXME: cache this value. */                  want = 1;
                 if (1 != strlen(tbl->buf))                  if (len == want)
                         return(0);                          tbl->opts.tab = p[*pos];
                 tbl->tab = tbl->buf[0];  
                 break;                  break;
         case (KEY_LINESIZE):          case KEY_LINESIZE:
                 if ((tbl->linesize = atoi(tbl->buf)) <= 0)                  want = 0;
                         return(0);  
                 break;                  break;
         case (KEY_DPOINT):          case KEY_DPOINT:
                 /* FIXME: cache this value. */                  want = 1;
                 if (1 != strlen(tbl->buf))                  if (len == want)
                         return(0);                          tbl->opts.decimal = p[*pos];
                 tbl->decimal = tbl->buf[0];  
                 break;                  break;
         default:          default:
                 abort();                  abort();
         }          }
   
         sv = *pos;          if (len == 0)
                   mandoc_msg(MANDOCERR_TBLOPT_NOARG,
                       tbl->parse, ln, *pos, keys[key].name);
           else if (want && len != want)
                   mandoc_vmsg(MANDOCERR_TBLOPT_ARGSZ,
                       tbl->parse, ln, *pos, "%s want %d have %d",
                       keys[key].name, want, len);
   
         switch (tbl_next(tbl, p, pos)) {          *pos += len;
         case (TBL_TOK_CLOSEPAREN):          if (p[*pos] == ')')
                 break;                  (*pos)++;
         default:  
                 return(0);  
         }  
   
         return(1);  
 }  }
   
   /*
 static int   * Parse one line of options up to the semicolon.
 opt(struct tbl *tbl, int ln, const char *p, int *pos)   * Each option can be preceded by blanks and/or commas,
    * and some options are followed by arguments.
    */
   void
   tbl_option(struct tbl_node *tbl, int ln, const char *p, int *offs)
 {  {
         int              i, sv;          int              i, pos, len;
   
 again:          pos = *offs;
         sv = *pos;          for (;;) {
                   while (p[pos] == ' ' || p[pos] == '\t' || p[pos] == ',')
                           pos++;
   
         /*                  if (p[pos] == ';') {
          * EBNF describing this section:                          *offs = pos + 1;
          *                          return;
          * options      ::= option_list [:space:]* [;][\n]                  }
          * option_list  ::= option option_tail  
          * option_tail  ::= [:space:]+ option_list |  
          *              ::= epsilon  
          * option       ::= [:alpha:]+ args  
          * args         ::= [:space:]* [(] [:alpha:]+ [)]  
          */  
   
         switch (tbl_next(tbl, p, pos)) {                  /* Parse one option name. */
         case (TBL_TOK__MAX):  
                 break;  
         case (TBL_TOK_SPACE):  
                 /* FALLTHROUGH */  
         case (TBL_TOK_TAB):  
                 goto again;  
         case (TBL_TOK_SEMICOLON):  
                 tbl->part = TBL_PART_LAYOUT;  
                 return(1);  
         default:  
                 return(0);  
         }  
   
         for (i = 0; i < KEY_MAXKEYS; i++) {                  len = 0;
                 /* FIXME: hashtable this? */                  while (isalpha((unsigned char)p[pos + len]))
                 if (strcasecmp(tbl->buf, keys[i].name))                          len++;
   
                   if (len == 0) {
                           mandoc_vmsg(MANDOCERR_TBLOPT_ALPHA,
                               tbl->parse, ln, pos, "%c", p[pos]);
                           pos++;
                         continue;                          continue;
                 if (keys[i].key)                  }
                         tbl->opts |= keys[i].key;  
                 else if ( ! arg(tbl, ln, p, pos, keys[i].ident))  
                         return(0);  
   
                 break;                  /* Look up the option name. */
         }  
   
         if (KEY_MAXKEYS == i)                  i = 0;
                 return(0);                  while (i < KEY_MAXKEYS &&
                       (strncasecmp(p + pos, keys[i].name, len) ||
                        keys[i].name[len] != '\0'))
                           i++;
   
         return(opt(tbl, ln, p, pos));                  if (i == KEY_MAXKEYS) {
 }                          mandoc_vmsg(MANDOCERR_TBLOPT_BAD, tbl->parse,
                               ln, pos, "%.*s", len, p + pos);
                           pos += len;
                           continue;
                   }
   
 int                  /* Handle the option. */
 tbl_option(struct tbl *tbl, int ln, const char *p)  
 {  
         int              pos;  
   
         pos = 0;                  pos += len;
         return(opt(tbl, ln, p, &pos));                  if (keys[i].key)
                           tbl->opts.opts |= keys[i].key;
                   else
                           arg(tbl, ln, p, &pos, i);
           }
 }  }

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.22

CVSweb