[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.1 and 1.17

version 1.1, 2010/12/28 13:46:07 version 1.17, 2015/01/26 00:57:22
Line 1 
Line 1 
 /*      $Id$ */  /*      $Id$ */
 /*  /*
  * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>   * 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 "libmandoc.h"
 #include "libroff.h"  #include "libroff.h"
   
 enum    tbl_ident {  enum    tbl_ident {
Line 49  struct tbl_phrase {
Line 57  struct tbl_phrase {
 static  const struct tbl_phrase keys[KEY_MAXKEYS] = {  static  const struct tbl_phrase keys[KEY_MAXKEYS] = {
         { "center",      TBL_OPT_CENTRE,        KEY_CENTRE},          { "center",      TBL_OPT_CENTRE,        KEY_CENTRE},
         { "centre",      TBL_OPT_CENTRE,        KEY_CENTRE},          { "centre",      TBL_OPT_CENTRE,        KEY_CENTRE},
         { "delim",       0,                     KEY_DELIM},          { "delim",       0,                     KEY_DELIM},
         { "expand",      TBL_OPT_EXPAND,        KEY_EXPAND},          { "expand",      TBL_OPT_EXPAND,        KEY_EXPAND},
         { "box",         TBL_OPT_BOX,           KEY_BOX},          { "box",         TBL_OPT_BOX,           KEY_BOX},
         { "doublebox",   TBL_OPT_DBOX,          KEY_DBOX},          { "doublebox",   TBL_OPT_DBOX,          KEY_DBOX},
         { "allbox",      TBL_OPT_ALLBOX,        KEY_ALLBOX},          { "allbox",      TBL_OPT_ALLBOX,        KEY_ALLBOX},
         { "frame",       TBL_OPT_BOX,           KEY_FRAME},          { "frame",       TBL_OPT_BOX,           KEY_FRAME},
         { "doubleframe", TBL_OPT_DBOX,          KEY_DFRAME},          { "doubleframe", TBL_OPT_DBOX,          KEY_DFRAME},
Line 63  static const struct tbl_phrase keys[KEY_MAXKEYS] = {
Line 71  static const struct tbl_phrase keys[KEY_MAXKEYS] = {
         { "nospaces",    TBL_OPT_NOSPACE,       KEY_NOSPACE},          { "nospaces",    TBL_OPT_NOSPACE,       KEY_NOSPACE},
 };  };
   
 static  int              arg(struct tbl *, int, const char *, int *, int);  static  void             arg(struct tbl_node *, int,
 static  int              opt(struct tbl *, int, const char *, int *);                                  const char *, int *, enum tbl_ident);
   
 static int  
 arg(struct tbl *tbl, int ln, const char *p, int *pos, int key)  static void
   arg(struct tbl_node *tbl, int ln, const char *p, int *pos, enum tbl_ident key)
 {  {
         int              sv;          const char      *optname;
           int              len, want;
   
 again:          while (isspace((unsigned char)p[*pos]))
         sv = *pos;                  (*pos)++;
   
         switch (tbl_next(tbl, p, pos)) {          /* Arguments are enclosed in parentheses. */
         case (TBL_TOK_OPENPAREN):  
                 break;  
         case (TBL_TOK_SPACE):  
                 /* FALLTHROUGH */  
         case (TBL_TOK_TAB):  
                 goto again;  
         default:  
                 return(0);  
         }  
   
         sv = *pos;          len = 0;
           if (p[*pos] == '(') {
         switch (tbl_next(tbl, p, pos)) {                  (*pos)++;
         case (TBL_TOK__MAX):                  while (p[*pos + len] != ')')
                 break;                          len++;
         default:  
                 return(0);  
         }          }
   
         switch (key) {          switch (key) {
         case (KEY_DELIM):          case KEY_DELIM:
                 /* FIXME: cache this value. */                  optname = "delim";
                 if (2 != strlen(tbl->buf))                  want = 2;
                         return(0);  
                 tbl->delims[0] = tbl->buf[0];  
                 tbl->delims[1] = tbl->buf[1];  
                 break;                  break;
         case (KEY_TAB):          case KEY_TAB:
                 /* FIXME: cache this value. */                  optname = "tab";
                 if (1 != strlen(tbl->buf))                  want = 1;
                         return(0);                  if (len == want)
                 tbl->tab = tbl->buf[0];                          tbl->opts.tab = p[*pos];
                 break;                  break;
         case (KEY_LINESIZE):          case KEY_LINESIZE:
                 if ((tbl->linesize = atoi(tbl->buf)) <= 0)                  optname = "linesize";
                         return(0);                  want = 0;
                 break;                  break;
         case (KEY_DPOINT):          case KEY_DPOINT:
                 /* FIXME: cache this value. */                  optname = "decimalpoint";
                 if (1 != strlen(tbl->buf))                  want = 1;
                         return(0);                  if (len == want)
                 tbl->decimal = tbl->buf[0];                          tbl->opts.decimal = p[*pos];
                 break;                  break;
         default:          default:
                 abort();                  abort();
                   /* NOTREACHED */
         }          }
   
         sv = *pos;          if (len == 0)
                   mandoc_msg(MANDOCERR_TBLOPT_NOARG,
                       tbl->parse, ln, *pos, optname);
           else if (want && len != want)
                   mandoc_vmsg(MANDOCERR_TBLOPT_ARGSZ,
                       tbl->parse, ln, *pos,
                       "%s want %d have %d", optname, 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              i, sv;          int              i, pos, len;
   
 again:          pos = 0;
         sv = *pos;          for (;;) {
                   while (isspace((unsigned char)p[pos]) || p[pos] == ',')
                           pos++;
   
         /*                  if (p[pos] == ';')
          * EBNF describing this section:                          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, keys[i].ident);
           }
 }  }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.17

CVSweb