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

Diff for /mandoc/mdoc_argv.c between version 1.1 and 1.10

version 1.1, 2009/03/27 15:00:15 version 1.10, 2009/07/06 11:21:34
Line 1 
Line 1 
 /* $Id$ */  /*      $Id$ */
 /*  /*
  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@openbsd.org>   * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
  *   *
  * 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   * purpose with or without fee is hereby granted, provided that the above
  * above copyright notice and this permission notice appear in all   * copyright notice and this permission notice appear in all copies.
  * copies.  
  *   *
  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED   * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE   * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL   * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR   * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  * PERFORMANCE OF THIS SOFTWARE.  
  */   */
 #include <sys/types.h>  #include <sys/types.h>
   
 #include <assert.h>  #include <assert.h>
 #include <ctype.h>  #include <ctype.h>
 #include <err.h>  
 #include <stdlib.h>  #include <stdlib.h>
 #include <stdio.h>  #include <stdio.h>
 #include <string.h>  #include <string.h>
Line 35 
Line 32 
  * There's no limit to the number or arguments that may be allocated.   * There's no limit to the number or arguments that may be allocated.
  */   */
   
   /* FIXME .Bf Li raises "macro-like parameter". */
   /* FIXME .Bl -column should deprecate old-groff syntax. */
   
 #define ARGS_QUOTED     (1 << 0)  #define ARGS_QUOTED     (1 << 0)
 #define ARGS_DELIM      (1 << 1)  #define ARGS_DELIM      (1 << 1)
 #define ARGS_TABSEP     (1 << 2)  #define ARGS_TABSEP     (1 << 2)
Line 47 
Line 47 
   
 #define MULTI_STEP       5  #define MULTI_STEP       5
   
 enum    mwarn {  
         WQUOTPARM,  
         WARGVPARM,  
         WCOLEMPTY,  
         WTAILWS  
 };  
   
 enum    merr {  enum    merr {
           ETAILWS,
           ECOLEMPTY,
           EARGVPARM,
           EQUOTPARM,
         EQUOTTERM,          EQUOTTERM,
           EMALLOC,
         EARGVAL          EARGVAL
 };  };
   
Line 70  static int   argv_opt_single(struct mdoc *, int, 
Line 68  static int   argv_opt_single(struct mdoc *, int, 
                                 struct mdoc_argv *, int *, char *);                                  struct mdoc_argv *, int *, char *);
 static  int              argv_multi(struct mdoc *, int,  static  int              argv_multi(struct mdoc *, int,
                                 struct mdoc_argv *, int *, char *);                                  struct mdoc_argv *, int *, char *);
 static  int              pwarn(struct mdoc *, int, int, enum mwarn);  static  int              perr(struct mdoc *, int, int, enum merr, int);
 static  int              perr(struct mdoc *, int, int, enum merr);  
   
   #define pwarn(m, l, p, t) perr((m), (l), (p), (t), 0)
   #define verr(m, t) perr((m), (m)->last->line, (m)->last->pos, (t), 1)
   
 /* Per-argument flags. */  /* Per-argument flags. */
   
 static  int mdoc_argvflags[MDOC_ARG_MAX] = {  static  int mdoc_argvflags[MDOC_ARG_MAX] = {
Line 105  static int mdoc_argvflags[MDOC_ARG_MAX] = {
Line 105  static int mdoc_argvflags[MDOC_ARG_MAX] = {
 };  };
   
 static  int mdoc_argflags[MDOC_MAX] = {  static  int mdoc_argflags[MDOC_MAX] = {
         0, /* \" */          0, /* Ap */
         0, /* Dd */          0, /* Dd */
         0, /* Dt */          0, /* Dt */
         0, /* Os */          0, /* Os */
Line 116  static int mdoc_argflags[MDOC_MAX] = {
Line 116  static int mdoc_argflags[MDOC_MAX] = {
         ARGS_DELIM | ARGS_QUOTED, /* Dl */          ARGS_DELIM | ARGS_QUOTED, /* Dl */
         0, /* Bd */          0, /* Bd */
         0, /* Ed */          0, /* Ed */
         0, /* Bl */          ARGS_QUOTED, /* Bl */
         0, /* El */          0, /* El */
         0, /* It */          0, /* It */
         ARGS_DELIM, /* Ad */          ARGS_DELIM, /* Ad */
Line 212  static int mdoc_argflags[MDOC_MAX] = {
Line 212  static int mdoc_argflags[MDOC_MAX] = {
         0, /* Fr */          0, /* Fr */
         0, /* Ud */          0, /* Ud */
         0, /* Lb */          0, /* Lb */
         0, /* Ap */  
         ARGS_DELIM, /* Lp */          ARGS_DELIM, /* Lp */
         ARGS_DELIM | ARGS_QUOTED, /* Lk */          ARGS_DELIM | ARGS_QUOTED, /* Lk */
         ARGS_DELIM | ARGS_QUOTED, /* Mt */          ARGS_DELIM | ARGS_QUOTED, /* Mt */
Line 282  mdoc_argv(struct mdoc *mdoc, int line, int tok,
Line 281  mdoc_argv(struct mdoc *mdoc, int line, int tok,
                 /* XXX - restore saved zeroed byte. */                  /* XXX - restore saved zeroed byte. */
                 if (sv)                  if (sv)
                         buf[*pos - 1] = sv;                          buf[*pos - 1] = sv;
                 if ( ! pwarn(mdoc, line, i, WARGVPARM))                  if ( ! pwarn(mdoc, line, i, EARGVPARM))
                         return(ARGV_ERROR);                          return(ARGV_ERROR);
                 return(ARGV_WORD);                  return(ARGV_WORD);
         }          }
Line 294  mdoc_argv(struct mdoc *mdoc, int line, int tok,
Line 293  mdoc_argv(struct mdoc *mdoc, int line, int tok,
                 return(ARGV_ERROR);                  return(ARGV_ERROR);
   
         if (NULL == (arg = *v)) {          if (NULL == (arg = *v)) {
                 if (NULL == (*v = calloc(1, sizeof(struct mdoc_arg))))                  *v = calloc(1, sizeof(struct mdoc_arg));
                         err(1, "calloc");                  if (NULL == *v) {
                           (void)verr(mdoc, EMALLOC);
                           return(ARGV_ERROR);
                   }
                 arg = *v;                  arg = *v;
         }          }
   
         arg->argc++;          arg->argc++;
         arg->argv = xrealloc(arg->argv, arg->argc *          arg->argv = realloc(arg->argv, arg->argc *
                         sizeof(struct mdoc_argv));                          sizeof(struct mdoc_argv));
   
           if (NULL == arg->argv) {
                   (void)verr(mdoc, EMALLOC);
                   return(ARGV_ERROR);
           }
   
         (void)memcpy(&arg->argv[(int)arg->argc - 1],          (void)memcpy(&arg->argv[(int)arg->argc - 1],
                         &tmp, sizeof(struct mdoc_argv));                          &tmp, sizeof(struct mdoc_argv));
   
Line 323  mdoc_argv_free(struct mdoc_arg *p)
Line 330  mdoc_argv_free(struct mdoc_arg *p)
                 if (p->refcnt)                  if (p->refcnt)
                         return;                          return;
         }          }
   
         assert(p->argc);          assert(p->argc);
   
         /* LINTED */          /* LINTED */
Line 344  mdoc_argv_free(struct mdoc_arg *p)
Line 350  mdoc_argv_free(struct mdoc_arg *p)
   
   
 static int  static int
 perr(struct mdoc *mdoc, int line, int pos, enum merr code)  perr(struct mdoc *mdoc, int line, int pos, enum merr code, int iserr)
 {  {
         char            *p;          char            *p;
   
         p = NULL;          p = NULL;
   
         switch (code) {          switch (code) {
           case (EMALLOC):
                   p = "memory exhausted";
                   break;
         case (EQUOTTERM):          case (EQUOTTERM):
                 p = "unterminated quoted parameter";                  p = "unterminated quoted parameter";
                 break;                  break;
         case (EARGVAL):          case (EARGVAL):
                 p = "argument requires a value";                  p = "argument requires a value";
                 break;                  break;
         }          case (EQUOTPARM):
   
         assert(p);  
         return(mdoc_perr(mdoc, line, pos, p));  
 }  
   
   
 static int  
 pwarn(struct mdoc *mdoc, int line, int pos, enum mwarn code)  
 {  
         char            *p;  
         int              c;  
   
         p = NULL;  
         c = WARN_SYNTAX;  
   
         switch (code) {  
         case (WQUOTPARM):  
                 p = "unexpected quoted parameter";                  p = "unexpected quoted parameter";
                 break;                  break;
         case (WARGVPARM):          case (EARGVPARM):
                 p = "argument-like parameter";                  p = "argument-like parameter";
                 break;                  break;
         case (WCOLEMPTY):          case (ECOLEMPTY):
                 p = "last list column is empty";                  p = "last list column is empty";
                 c = WARN_COMPAT;  
                 break;                  break;
         case (WTAILWS):          case (ETAILWS):
                 p = "trailing whitespace";                  p = "trailing whitespace";
                 c = WARN_COMPAT;  
                 break;                  break;
         }          }
   
         assert(p);          assert(p);
         return(mdoc_pwarn(mdoc, line, pos, c, p));          if (iserr)
                   return(mdoc_perr(mdoc, line, pos, p));
   
           return(mdoc_pwarn(mdoc, line, pos, p));
 }  }
   
   
Line 464  args(struct mdoc *mdoc, int line, 
Line 457  args(struct mdoc *mdoc, int line, 
                 return(ARGS_EOLN);                  return(ARGS_EOLN);
   
         if ('\"' == buf[*pos] && ! (fl & ARGS_QUOTED))          if ('\"' == buf[*pos] && ! (fl & ARGS_QUOTED))
                 if ( ! pwarn(mdoc, line, *pos, WQUOTPARM))                  if ( ! pwarn(mdoc, line, *pos, EQUOTPARM))
                         return(ARGS_ERROR);                          return(ARGS_ERROR);
   
         if ( ! (fl & ARGS_ARGVLIKE) && '-' == buf[*pos])          if ( ! (fl & ARGS_ARGVLIKE) && '-' == buf[*pos])
                 if ( ! pwarn(mdoc, line, *pos, WARGVPARM))                  if ( ! pwarn(mdoc, line, *pos, EARGVPARM))
                         return(ARGS_ERROR);                          return(ARGS_ERROR);
   
         /*          /*
Line 560  args(struct mdoc *mdoc, int line, 
Line 553  args(struct mdoc *mdoc, int line, 
                         }                          }
   
                         if (p && 0 == *p)                          if (p && 0 == *p)
                                 if ( ! pwarn(mdoc, line, *pos, WCOLEMPTY))                                  if ( ! pwarn(mdoc, line, *pos, ECOLEMPTY))
                                         return(0);                                          return(0);
                         if (p && 0 == *p && p > *v && ' ' == *(p - 1))                          if (p && 0 == *p && p > *v && ' ' == *(p - 1))
                                 if ( ! pwarn(mdoc, line, *pos, WTAILWS))                                  if ( ! pwarn(mdoc, line, *pos, ETAILWS))
                                         return(0);                                          return(0);
   
                         if (p)                          if (p)
Line 575  args(struct mdoc *mdoc, int line, 
Line 568  args(struct mdoc *mdoc, int line, 
                         assert(p);                          assert(p);
   
                         if (p > *v && ' ' == *(p - 1))                          if (p > *v && ' ' == *(p - 1))
                                 if ( ! pwarn(mdoc, line, *pos, WTAILWS))                                  if ( ! pwarn(mdoc, line, *pos, ETAILWS))
                                         return(0);                                          return(0);
                         *pos += (int)(p - *v);                          *pos += (int)(p - *v);
   
Line 607  args(struct mdoc *mdoc, int line, 
Line 600  args(struct mdoc *mdoc, int line, 
                 if (buf[*pos])                  if (buf[*pos])
                         return(ARGS_WORD);                          return(ARGS_WORD);
   
                 if ( ! pwarn(mdoc, line, *pos, WTAILWS))                  if ( ! pwarn(mdoc, line, *pos, ETAILWS))
                         return(ARGS_ERROR);                          return(ARGS_ERROR);
   
                 return(ARGS_WORD);                  return(ARGS_WORD);
Line 625  args(struct mdoc *mdoc, int line, 
Line 618  args(struct mdoc *mdoc, int line, 
                 (*pos)++;                  (*pos)++;
   
         if (0 == buf[*pos]) {          if (0 == buf[*pos]) {
                 (void)perr(mdoc, line, *pos, EQUOTTERM);                  (void)perr(mdoc, line, *pos, EQUOTTERM, 1);
                 return(ARGS_ERROR);                  return(ARGS_ERROR);
         }          }
   
Line 639  args(struct mdoc *mdoc, int line, 
Line 632  args(struct mdoc *mdoc, int line, 
         if (buf[*pos])          if (buf[*pos])
                 return(ARGS_QWORD);                  return(ARGS_QWORD);
   
         if ( ! pwarn(mdoc, line, *pos, WTAILWS))          if ( ! pwarn(mdoc, line, *pos, ETAILWS))
                 return(ARGS_ERROR);                  return(ARGS_ERROR);
   
         return(ARGS_QWORD);          return(ARGS_QWORD);
Line 660  argv_a2arg(int tok, const char *argv)
Line 653  argv_a2arg(int tok, const char *argv)
   
         switch (tok) {          switch (tok) {
         case (MDOC_An):          case (MDOC_An):
                 if (xstrcmp(argv, "split"))                  if (0 == strcmp(argv, "split"))
                         return(MDOC_Split);                          return(MDOC_Split);
                 else if (xstrcmp(argv, "nosplit"))                  else if (0 == strcmp(argv, "nosplit"))
                         return(MDOC_Nosplit);                          return(MDOC_Nosplit);
                 break;                  break;
   
         case (MDOC_Bd):          case (MDOC_Bd):
                 if (xstrcmp(argv, "ragged"))                  if (0 == strcmp(argv, "ragged"))
                         return(MDOC_Ragged);                          return(MDOC_Ragged);
                 else if (xstrcmp(argv, "unfilled"))                  else if (0 == strcmp(argv, "unfilled"))
                         return(MDOC_Unfilled);                          return(MDOC_Unfilled);
                 else if (xstrcmp(argv, "filled"))                  else if (0 == strcmp(argv, "filled"))
                         return(MDOC_Filled);                          return(MDOC_Filled);
                 else if (xstrcmp(argv, "literal"))                  else if (0 == strcmp(argv, "literal"))
                         return(MDOC_Literal);                          return(MDOC_Literal);
                 else if (xstrcmp(argv, "file"))                  else if (0 == strcmp(argv, "file"))
                         return(MDOC_File);                          return(MDOC_File);
                 else if (xstrcmp(argv, "offset"))                  else if (0 == strcmp(argv, "offset"))
                         return(MDOC_Offset);                          return(MDOC_Offset);
                 else if (xstrcmp(argv, "compact"))                  else if (0 == strcmp(argv, "compact"))
                         return(MDOC_Compact);                          return(MDOC_Compact);
                 break;                  break;
   
         case (MDOC_Bf):          case (MDOC_Bf):
                 if (xstrcmp(argv, "emphasis"))                  if (0 == strcmp(argv, "emphasis"))
                         return(MDOC_Emphasis);                          return(MDOC_Emphasis);
                 else if (xstrcmp(argv, "literal"))                  else if (0 == strcmp(argv, "literal"))
                         return(MDOC_Literal);                          return(MDOC_Literal);
                 else if (xstrcmp(argv, "symbolic"))                  else if (0 == strcmp(argv, "symbolic"))
                         return(MDOC_Symbolic);                          return(MDOC_Symbolic);
                 break;                  break;
   
         case (MDOC_Bk):          case (MDOC_Bk):
                 if (xstrcmp(argv, "words"))                  if (0 == strcmp(argv, "words"))
                         return(MDOC_Words);                          return(MDOC_Words);
                 break;                  break;
   
         case (MDOC_Bl):          case (MDOC_Bl):
                 if (xstrcmp(argv, "bullet"))                  if (0 == strcmp(argv, "bullet"))
                         return(MDOC_Bullet);                          return(MDOC_Bullet);
                 else if (xstrcmp(argv, "dash"))                  else if (0 == strcmp(argv, "dash"))
                         return(MDOC_Dash);                          return(MDOC_Dash);
                 else if (xstrcmp(argv, "hyphen"))                  else if (0 == strcmp(argv, "hyphen"))
                         return(MDOC_Hyphen);                          return(MDOC_Hyphen);
                 else if (xstrcmp(argv, "item"))                  else if (0 == strcmp(argv, "item"))
                         return(MDOC_Item);                          return(MDOC_Item);
                 else if (xstrcmp(argv, "enum"))                  else if (0 == strcmp(argv, "enum"))
                         return(MDOC_Enum);                          return(MDOC_Enum);
                 else if (xstrcmp(argv, "tag"))                  else if (0 == strcmp(argv, "tag"))
                         return(MDOC_Tag);                          return(MDOC_Tag);
                 else if (xstrcmp(argv, "diag"))                  else if (0 == strcmp(argv, "diag"))
                         return(MDOC_Diag);                          return(MDOC_Diag);
                 else if (xstrcmp(argv, "hang"))                  else if (0 == strcmp(argv, "hang"))
                         return(MDOC_Hang);                          return(MDOC_Hang);
                 else if (xstrcmp(argv, "ohang"))                  else if (0 == strcmp(argv, "ohang"))
                         return(MDOC_Ohang);                          return(MDOC_Ohang);
                 else if (xstrcmp(argv, "inset"))                  else if (0 == strcmp(argv, "inset"))
                         return(MDOC_Inset);                          return(MDOC_Inset);
                 else if (xstrcmp(argv, "column"))                  else if (0 == strcmp(argv, "column"))
                         return(MDOC_Column);                          return(MDOC_Column);
                 else if (xstrcmp(argv, "width"))                  else if (0 == strcmp(argv, "width"))
                         return(MDOC_Width);                          return(MDOC_Width);
                 else if (xstrcmp(argv, "offset"))                  else if (0 == strcmp(argv, "offset"))
                         return(MDOC_Offset);                          return(MDOC_Offset);
                 else if (xstrcmp(argv, "compact"))                  else if (0 == strcmp(argv, "compact"))
                         return(MDOC_Compact);                          return(MDOC_Compact);
                 else if (xstrcmp(argv, "nested"))                  else if (0 == strcmp(argv, "nested"))
                         return(MDOC_Nested);                          return(MDOC_Nested);
                 break;                  break;
   
         case (MDOC_Rv):          case (MDOC_Rv):
                 /* FALLTHROUGH */                  /* FALLTHROUGH */
         case (MDOC_Ex):          case (MDOC_Ex):
                 if (xstrcmp(argv, "std"))                  if (0 == strcmp(argv, "std"))
                         return(MDOC_Std);                          return(MDOC_Std);
                 break;                  break;
         default:          default:
Line 748  static int
Line 741  static int
 argv_multi(struct mdoc *mdoc, int line,  argv_multi(struct mdoc *mdoc, int line,
                 struct mdoc_argv *v, int *pos, char *buf)                  struct mdoc_argv *v, int *pos, char *buf)
 {  {
         int              c, ppos;          int              c;
         char            *p;          char            *p;
   
         ppos = *pos;  
   
         for (v->sz = 0; ; v->sz++) {          for (v->sz = 0; ; v->sz++) {
                 if ('-' == buf[*pos])                  if ('-' == buf[*pos])
                         break;                          break;
Line 762  argv_multi(struct mdoc *mdoc, int line, 
Line 753  argv_multi(struct mdoc *mdoc, int line, 
                 else if (ARGS_EOLN == c)                  else if (ARGS_EOLN == c)
                         break;                          break;
   
                 if (0 == v->sz % MULTI_STEP)                  if (0 == v->sz % MULTI_STEP) {
                         v->value = xrealloc(v->value,                          v->value = realloc(v->value,
                                 (v->sz + MULTI_STEP) * sizeof(char *));                                  (v->sz + MULTI_STEP) * sizeof(char *));
                           if (NULL == v->value) {
                                   (void)verr(mdoc, EMALLOC);
                                   return(ARGV_ERROR);
                           }
                   }
                 if (NULL == (v->value[(int)v->sz] = strdup(p)))                  if (NULL == (v->value[(int)v->sz] = strdup(p)))
                         err(1, "strdup");                          return(verr(mdoc, EMALLOC));
         }          }
   
         if (v->sz)          return(1);
                 return(1);  
   
         return(perr(mdoc, line, ppos, EARGVAL));  
 }  }
   
   
Line 794  argv_opt_single(struct mdoc *mdoc, int line, 
Line 787  argv_opt_single(struct mdoc *mdoc, int line, 
   
         v->sz = 1;          v->sz = 1;
         if (NULL == (v->value = calloc(1, sizeof(char *))))          if (NULL == (v->value = calloc(1, sizeof(char *))))
                 err(1, "calloc");                  return(verr(mdoc, EMALLOC));
         if (NULL == (v->value[0] = strdup(p)))          if (NULL == (v->value[0] = strdup(p)))
                 err(1, "strdup");                  return(verr(mdoc, EMALLOC));
   
         return(1);          return(1);
 }  }
   
Line 817  argv_single(struct mdoc *mdoc, int line, 
Line 811  argv_single(struct mdoc *mdoc, int line, 
         if (ARGS_ERROR == c)          if (ARGS_ERROR == c)
                 return(0);                  return(0);
         if (ARGS_EOLN == c)          if (ARGS_EOLN == c)
                 return(perr(mdoc, line, ppos, EARGVAL));                  return(perr(mdoc, line, ppos, EARGVAL, 1));
   
         v->sz = 1;          v->sz = 1;
         if (NULL == (v->value = calloc(1, sizeof(char *))))          if (NULL == (v->value = calloc(1, sizeof(char *))))
                 err(1, "calloc");                  return(verr(mdoc, EMALLOC));
         if (NULL == (v->value[0] = strdup(p)))          if (NULL == (v->value[0] = strdup(p)))
                 err(1, "strdup");                  return(verr(mdoc, EMALLOC));
   
         return(1);          return(1);
 }  }
   

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

CVSweb