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

Diff for /mandoc/Attic/mdocml.c between version 1.26 and 1.48

version 1.26, 2008/12/28 21:25:09 version 1.48, 2009/01/17 14:04:25
Line 30 
Line 30 
   
 #include "mdoc.h"  #include "mdoc.h"
   
 #define MD_LINE_SZ      (256)  #define xfprintf        (void)fprintf
   
   #define MD_LINE_SZ      (256)           /* Max input line size. */
   
   /*
    * Put this into a mdoctrans.h, which has:
    *
    * struct mdoc_trans; (opaque)
    *
    * struct mdoc_trans *mdoc_trans_alloc(const char *filter);
    *
    * mdoc_trans_free(struct mdoc_trans *);
    *
    * int mdoc_trans_getopt(struct mdoc_trans *, char *);
    *
    * int mdoc_trans_print(struct mdoc_trans *, const struct mdoc_node *);
    */
   
   typedef int             (*mdocprint)(const struct mdoc_node *);
   
   
 struct  md_parse {  struct  md_parse {
         int              warn;          int               warn;         /* Warning flags. */
 #define MD_WARN_ALL     (1 << 0)  #define MD_WARN_SYNTAX   (1 << 0)       /* Show syntax warnings. */
 #define MD_WARN_ERR     (1 << 1)  #define MD_WARN_COMPAT   (1 << 1)       /* Show compat warnings. */
         int              dbg;  #define MD_WARN_ALL      (0x03)         /* Show all warnings. */
         struct mdoc     *mdoc;  #define MD_WARN_ERR      (1 << 2)       /* Make warnings->errors. */
         char            *buf;          int               dbg;          /* Debug level. */
         u_long           bufsz;          struct mdoc      *mdoc;         /* Active parser. */
         char            *name;          char             *buf;          /* Input buffer. */
         int              fd;          u_long            bufsz;        /* Input buffer size. */
         int              lnn;          char             *name;         /* Input file name. */
         char            *line;          int               fd;           /* Input file desc. */
           mdocprint         print;        /* Node-print function. */
 };  };
   
 static  void             usage(void);  extern  char             *__progname;
   
 static  int              parse_begin(struct md_parse *);  extern  int               treeprint(const struct mdoc_node *);
 static  int              parse_leave(struct md_parse *, int);  
 static  int              io_begin(struct md_parse *);  
 static  int              io_leave(struct md_parse *, int);  
 static  int              buf_begin(struct md_parse *);  
 static  int              buf_leave(struct md_parse *, int);  
   
 static  int              msg_err(void *, int, int, enum mdoc_err);  static  void              usage(void);
 static  int              msg_warn(void *, int, int, enum mdoc_warn);  
 static  void             msg_msg(void *, int, const char *);  
   
   static  int               parse_begin(struct md_parse *);
   static  int               parse_leave(struct md_parse *, int);
   static  int               io_begin(struct md_parse *);
   static  int               io_leave(struct md_parse *, int);
   static  int               buf_begin(struct md_parse *);
   static  int               buf_leave(struct md_parse *, int);
   
   static  void              msg_msg(void *, int, int, const char *);
   static  int               msg_err(void *, int, int, const char *);
   static  int               msg_warn(void *, int, int,
                                   enum mdoc_warn, const char *);
   
 #ifdef __linux__  #ifdef __linux__
 extern  int              getsubopt(char **, char *const *, char **);  extern  int               getsubopt(char **, char *const *, char **);
 #endif  #endif
   
 int  int
Line 68  main(int argc, char *argv[])
Line 93  main(int argc, char *argv[])
 {  {
         int              c;          int              c;
         struct md_parse  parser;          struct md_parse  parser;
         char            *opts, *v;          char            *opts, *v, *filter;
 #define ALL              0  #define ALL              0
 #define ERROR            1  #define COMPAT           1
         char            *toks[] = { "all", "error", NULL };  #define SYNTAX           2
   #define ERROR            3
           char            *toks[] = { "all", "compat", "syntax",
                                       "error", NULL };
   
         extern char     *optarg;          extern char     *optarg;
         extern int       optind;          extern int       optind;
   
           filter = NULL;
   
         (void)memset(&parser, 0, sizeof(struct md_parse));          (void)memset(&parser, 0, sizeof(struct md_parse));
   
         while (-1 != (c = getopt(argc, argv, "vW:")))          while (-1 != (c = getopt(argc, argv, "f:vW:")))
                 switch (c) {                  switch (c) {
                   case ('f'):
                           filter = optarg;
                           break;
                 case ('v'):                  case ('v'):
                         parser.dbg++;                          parser.dbg++;
                         break;                          break;
Line 90  main(int argc, char *argv[])
Line 123  main(int argc, char *argv[])
                                 case (ALL):                                  case (ALL):
                                         parser.warn |= MD_WARN_ALL;                                          parser.warn |= MD_WARN_ALL;
                                         break;                                          break;
                                   case (COMPAT):
                                           parser.warn |= MD_WARN_COMPAT;
                                           break;
                                   case (SYNTAX):
                                           parser.warn |= MD_WARN_SYNTAX;
                                           break;
                                 case (ERROR):                                  case (ERROR):
                                         parser.warn |= MD_WARN_ERR;                                          parser.warn |= MD_WARN_ERR;
                                         break;                                          break;
Line 110  main(int argc, char *argv[])
Line 149  main(int argc, char *argv[])
         if (1 == argc)          if (1 == argc)
                 parser.name = *argv++;                  parser.name = *argv++;
   
           if (filter) {
                   if (0 == strcmp(filter, "tree"))
                           parser.print = treeprint;
           }
   
         if ( ! io_begin(&parser))          if ( ! io_begin(&parser))
                 return(EXIT_FAILURE);                  return(EXIT_FAILURE);
   
Line 178  buf_begin(struct md_parse *p)
Line 222  buf_begin(struct md_parse *p)
 }  }
   
   
 static void  
 print_node(const struct mdoc_node *n, int indent)  
 {  
         const char       *p, *t;  
         int               i, j;  
         size_t            argc, sz;  
         char            **params;  
         struct mdoc_arg  *argv;  
   
         argv = NULL;  
         argc = 0;  
         params = NULL;  
         sz = 0;  
   
         switch (n->type) {  
         case (MDOC_TEXT):  
                 assert(NULL == n->child);  
                 p = n->data.text.string;  
                 t = "text";  
                 break;  
         case (MDOC_BODY):  
                 p = mdoc_macronames[n->data.body.tok];  
                 t = "block-body";  
                 break;  
         case (MDOC_HEAD):  
                 p = mdoc_macronames[n->data.head.tok];  
                 t = "block-head";  
                 params = n->data.head.args;  
                 sz = n->data.head.sz;  
                 break;  
         case (MDOC_ELEM):  
                 assert(NULL == n->child);  
                 p = mdoc_macronames[n->data.elem.tok];  
                 t = "element";  
                 argv = n->data.elem.argv;  
                 argc = n->data.elem.argc;  
                 params = n->data.elem.args;  
                 sz = n->data.elem.sz;  
                 break;  
         case (MDOC_BLOCK):  
                 p = mdoc_macronames[n->data.block.tok];  
                 t = "block";  
                 argv = n->data.block.argv;  
                 argc = n->data.block.argc;  
                 break;  
         default:  
                 abort();  
                 /* NOTREACHED */  
         }  
   
         for (i = 0; i < indent; i++)  
                 (void)printf("    ");  
         (void)printf("%s (%s)", p, t);  
   
         for (i = 0; i < (int)argc; i++) {  
                 (void)printf(" -%s", mdoc_argnames[argv[i].arg]);  
                 for (j = 0; j < (int)argv[i].sz; j++)  
                         (void)printf(" \"%s\"", argv[i].value[j]);  
         }  
   
         for (i = 0; i < (int)sz; i++)  
                 (void)printf(" \"%s\"", params[i]);  
   
         (void)printf("\n");  
   
         if (n->child)  
                 print_node(n->child, indent + 1);  
         if (n->next)  
                 print_node(n->next, indent);  
 }  
   
   
 static int  static int
 parse_leave(struct md_parse *p, int code)  parse_leave(struct md_parse *p, int code)
 {  {
         const struct mdoc_node *n;          const struct mdoc_node *n;
   
         if (p->mdoc) {          if (NULL == p->mdoc)
                 if ((n = mdoc_result(p->mdoc)))                  return(code);
                         print_node(n, 0);  
                 mdoc_free(p->mdoc);          if ( ! mdoc_endparse(p->mdoc))
         }                  code = 0;
           if (p->print && (n = mdoc_result(p->mdoc)))
                   (*p->print)(n);
   
           mdoc_free(p->mdoc);
   
         return(code);          return(code);
 }  }
   
Line 269  parse_begin(struct md_parse *p)
Line 246  parse_begin(struct md_parse *p)
 {  {
         ssize_t          sz, i;          ssize_t          sz, i;
         size_t           pos;          size_t           pos;
         char             line[256], sv[256];          char             line[MD_LINE_SZ];
         struct mdoc_cb   cb;          struct mdoc_cb   cb;
           int              lnn;
   
         cb.mdoc_err = msg_err;          cb.mdoc_err = msg_err;
         cb.mdoc_warn = msg_warn;          cb.mdoc_warn = msg_warn;
Line 279  parse_begin(struct md_parse *p)
Line 257  parse_begin(struct md_parse *p)
         if (NULL == (p->mdoc = mdoc_alloc(p, &cb)))          if (NULL == (p->mdoc = mdoc_alloc(p, &cb)))
                 return(parse_leave(p, 0));                  return(parse_leave(p, 0));
   
         p->lnn = 1;          for (lnn = 1, pos = 0; ; ) {
         p->line = sv;  
   
         for (pos = 0; ; ) {  
                 if (-1 == (sz = read(p->fd, p->buf, p->bufsz))) {                  if (-1 == (sz = read(p->fd, p->buf, p->bufsz))) {
                         warn("%s", p->name);                          warn("%s", p->name);
                         return(parse_leave(p, 0));                          return(parse_leave(p, 0));
Line 292  parse_begin(struct md_parse *p)
Line 267  parse_begin(struct md_parse *p)
                 for (i = 0; i < sz; i++) {                  for (i = 0; i < sz; i++) {
                         if ('\n' != p->buf[i]) {                          if ('\n' != p->buf[i]) {
                                 if (pos < sizeof(line)) {                                  if (pos < sizeof(line)) {
                                         sv[(int)pos] = p->buf[(int)i];                                          line[(int)pos++] = p->buf[(int)i];
                                         line[(int)pos++] =  
                                                 p->buf[(int)i];  
                                         continue;                                          continue;
                                 }                                  }
                                 warnx("%s: line %d too long",                                  warnx("%s: line %d too long",
                                                 p->name, p->lnn);                                                  p->name, lnn);
                                 return(parse_leave(p, 0));                                  return(parse_leave(p, 0));
                         }                          }
   
                         line[(int)pos] = sv[(int)pos] = 0;                          line[(int)pos] = 0;
                         if ( ! mdoc_parseln(p->mdoc, line))                          if ( ! mdoc_parseln(p->mdoc, lnn, line))
                                 return(parse_leave(p, 0));                                  return(parse_leave(p, 0));
   
                         p->lnn++;                          lnn++;
                         pos = 0;                          pos = 0;
                 }                  }
         }          }
Line 316  parse_begin(struct md_parse *p)
Line 289  parse_begin(struct md_parse *p)
   
   
 static int  static int
 msg_err(void *arg, int tok, int col, enum mdoc_err type)  msg_err(void *arg, int line, int col, const char *msg)
 {  {
         char             *fmt, *lit;  
         struct md_parse  *p;          struct md_parse  *p;
         int               i;  
   
         p = (struct md_parse *)arg;          p = (struct md_parse *)arg;
   
         fmt = lit = NULL;          xfprintf(stderr, "%s:%d: error: %s (column %d)\n",
                           p->name, line, msg, col);
         switch (type) {  
         case (ERR_SYNTAX_QUOTE):  
                 lit = "syntax: disallowed argument quotation";  
                 break;  
         case (ERR_SYNTAX_UNQUOTE):  
                 lit = "syntax: unterminated quotation";  
                 break;  
         case (ERR_SYNTAX_WS):  
                 lit = "syntax: whitespace in argument";  
                 break;  
         case (ERR_SYNTAX_ARGFORM):  
                 fmt = "syntax: macro `%s' arguments malformed";  
                 break;  
         case (ERR_SYNTAX_ARG):  
                 fmt = "syntax: unknown argument for macro `%s'";  
                 break;  
         case (ERR_SCOPE_BREAK):  
                 /* Which scope is broken? */  
                 fmt = "scope: macro `%s' breaks prior explicit scope";  
                 break;  
         case (ERR_SCOPE_NOCTX):  
                 fmt = "scope: closure macro `%s' has no context";  
                 break;  
         case (ERR_SCOPE_NONEST):  
                 fmt = "scope: macro `%s' may not be nested in the current context";  
                 break;  
         case (ERR_MACRO_NOTSUP):  
                 fmt = "macro `%s' not supported";  
                 break;  
         case (ERR_MACRO_NOTCALL):  
                 fmt = "macro `%s' not callable";  
                 break;  
         case (ERR_SEC_PROLOGUE):  
                 fmt = "macro `%s' cannot be called in the prologue";  
                 break;  
         case (ERR_SEC_NPROLOGUE):  
                 fmt = "macro `%s' called outside of prologue";  
                 break;  
         case (ERR_ARGS_GE1):  
                 fmt = "macro `%s' expects one or more arguments";  
                 break;  
         case (ERR_ARGS_MANY):  
                 fmt = "macro `%s' has too many arguments";  
                 break;  
         case (ERR_SEC_PROLOGUE_OO):  
                 fmt = "prologue macro `%s' is out-of-order";  
                 break;  
         case (ERR_SEC_PROLOGUE_REP):  
                 fmt = "prologue macro `%s' repeated";  
                 break;  
         case (ERR_SEC_NAME):  
                 lit = "`NAME' section must be first";  
                 break;  
         case (ERR_SYNTAX_ARGVAL):  
                 lit = "syntax: expected value for macro argument";  
                 break;  
         case (ERR_SYNTAX_ARGBAD):  
                 lit = "syntax: invalid value for macro argument";  
                 break;  
         case (ERR_SYNTAX_ARGMANY):  
                 lit = "syntax: too many values for macro argument";  
                 break;  
         default:  
                 abort();  
                 /* NOTREACHED */  
         }  
   
         if (fmt) {  
                 (void)fprintf(stderr, "%s:%d: error: ",  
                                 p->name, p->lnn);  
                 (void)fprintf(stderr, fmt, mdoc_macronames[tok]);  
         } else  
                 (void)fprintf(stderr, "%s:%d: error: %s",  
                                 p->name, p->lnn, lit);  
   
         if (p->dbg < 1) {  
                 if (-1 != col)  
                         (void)fprintf(stderr, " (column %d)\n", col);  
                 return(0);  
         } else if (-1 == col) {  
                 (void)fprintf(stderr, "\nFrom: %s", p->line);  
                 return(0);  
         }  
   
         (void)fprintf(stderr, "\nFrom: %s\n      ", p->line);  
         for (i = 0; i < col; i++)  
                 (void)fprintf(stderr, " ");  
         (void)fprintf(stderr, "^\n");  
   
         return(0);          return(0);
 }  }
   
   
 static void  static void
 msg_msg(void *arg, int col, const char *msg)  msg_msg(void *arg, int line, int col, const char *msg)
 {  {
         struct md_parse  *p;          struct md_parse  *p;
         int               i;  
   
         p = (struct md_parse *)arg;          p = (struct md_parse *)arg;
   
         if (p->dbg < 2)          if (0 == p->dbg)
                 return;                  return;
   
         (void)printf("%s:%d: %s", p->name, p->lnn, msg);          xfprintf(stderr, "%s:%d: debug: %s (column %d)\n",
                           p->name, line, msg, col);
         if (p->dbg < 3) {  
                 if (-1 != col)  
                         (void)printf(" (column %d)\n", col);  
                 return;  
         } else if (-1 == col) {  
                 (void)printf("\nFrom %s\n", p->line);  
                 return;  
         }  
   
         (void)printf("\nFrom: %s\n      ", p->line);  
         for (i = 0; i < col; i++)  
                 (void)printf(" ");  
         (void)printf("^\n");  
 }  }
   
   
 static int  static int
 msg_warn(void *arg, int tok, int col, enum mdoc_warn type)  msg_warn(void *arg, int line, int col,
                   enum mdoc_warn type, const char *msg)
 {  {
         char             *fmt, *lit;  
         struct md_parse  *p;          struct md_parse  *p;
         int               i;  
         extern char      *__progname;  
   
         p = (struct md_parse *)arg;          p = (struct md_parse *)arg;
   
         if ( ! (p->warn & MD_WARN_ALL))  
                 return(1);  
   
         fmt = lit = NULL;  
   
         switch (type) {          switch (type) {
         case (WARN_SYNTAX_WS_EOLN):          case (WARN_COMPAT):
                 lit = "syntax: whitespace at end-of-line";                  if (p->warn & MD_WARN_COMPAT)
                 break;                          break;
         case (WARN_SYNTAX_QUOTED):                  return(1);
                 lit = "syntax: quotation mark starting string";          case (WARN_SYNTAX):
                 break;                  if (p->warn & MD_WARN_SYNTAX)
         case (WARN_SYNTAX_MACLIKE):                          break;
                 lit = "syntax: macro-like argument";                  return(1);
                 break;  
         case (WARN_SYNTAX_ARGLIKE):  
                 lit = "syntax: argument-like value";  
                 break;  
         case (WARN_SEC_OO):  
                 lit = "section is out of conventional order";  
                 break;  
         case (WARN_ARGS_GE1):  
                 fmt = "macro `%s' suggests one or more arguments";  
                 break;  
         case (WARN_ARGS_EQ0):  
                 fmt = "macro `%s' suggests zero arguments";  
                 break;  
         case (WARN_IGN_AFTER_BLK):  
                 fmt = "ignore: macro `%s' ignored after block macro";  
                 break;  
         case (WARN_IGN_BEFORE_BLK):  
                 fmt = "ignore: macro before block macro `%s' ignored";  
                 break;  
         default:  
                 abort();  
                 /* NOTREACHED */  
         }          }
   
         if (fmt) {          xfprintf(stderr, "%s:%d: warning: %s (column %d)\n",
                 (void)fprintf(stderr, "%s:%d: warning: ",                          p->name, line, msg, col);
                                 p->name, p->lnn);  
                 (void)fprintf(stderr, fmt, mdoc_macronames[tok]);  
         } else  
                 (void)fprintf(stderr, "%s:%d: warning: %s",  
                                 p->name, p->lnn, lit);  
   
         if (p->dbg >= 1) {          if ( ! (p->warn & MD_WARN_ERR))
                 (void)fprintf(stderr, "\nFrom: %s\n      ", p->line);                  return(1);
                 for (i = 0; i < col; i++)  
                         (void)fprintf(stderr, " ");  
                 (void)fprintf(stderr, "^\n");  
         } else  
                 (void)fprintf(stderr, " (column %d)\n", col);  
   
         if (p->warn & MD_WARN_ERR) {          xfprintf(stderr, "%s: considering warnings as errors\n",
                 (void)fprintf(stderr, "%s: considering warnings as "                          __progname);
                                 "errors\n", __progname);          return(0);
                 return(0);  
         }  
   
         return(1);  
 }  }
   
   
 static void  static void
 usage(void)  usage(void)
 {  {
         extern char     *__progname;  
   
         (void)fprintf(stderr, "usage: %s [-v] [-Wwarn...] [infile]\n",          xfprintf(stderr, "usage: %s [-v] [-Wwarn...] [-ffilter] "
                         __progname);                          "[infile]\n", __progname);
 }  }
   

Legend:
Removed from v.1.26  
changed lines
  Added in v.1.48

CVSweb