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

Diff for /mandoc/Attic/mdocml.c between version 1.50 and 1.51

version 1.50, 2009/01/20 12:51:28 version 1.51, 2009/02/20 07:43:15
Line 30 
Line 30 
   
 #include "mdoc.h"  #include "mdoc.h"
   
 #define xfprintf        (void)fprintf  
   
 #define MD_LINE_SZ      (256)           /* Max input line size. */  #define MD_LINE_SZ      (256)           /* Max input line size. */
   
 /* TODO: have a struct for each transformer. */  
   
 typedef int             (*mdocprint)(const struct mdoc_node *);  
   
   
 struct  md_parse {  struct  md_parse {
         int               warn;         /* Warning flags. */          int               warn;         /* Warning flags. */
 #define MD_WARN_SYNTAX   (1 << 0)       /* Show syntax warnings. */  #define MD_WARN_SYNTAX   (1 << 0)       /* Show syntax warnings. */
Line 49  struct md_parse {
Line 42  struct md_parse {
         struct mdoc      *mdoc;         /* Active parser. */          struct mdoc      *mdoc;         /* Active parser. */
         char             *buf;          /* Input buffer. */          char             *buf;          /* Input buffer. */
         u_long            bufsz;        /* Input buffer size. */          u_long            bufsz;        /* Input buffer size. */
         char             *name;         /* Input file name. */          char             *in;           /* Input file name. */
         int               fd;           /* Input file desc. */          int               fdin;         /* Input file desc. */
         mdocprint         print;        /* Node-print function. */  
 };  };
   
 extern  char             *__progname;  extern  char             *__progname;
   
 extern  int               treeprint(const struct mdoc_node *);  
   
 static  void              usage(void);  static  void              usage(void);
   
   static  int               parse_opts(struct md_parse *, int, char *[]);
   static  int               parse_subopts(struct md_parse *, char *);
   
 static  int               parse_begin(struct md_parse *);  static  int               parse_begin(struct md_parse *);
 static  int               parse_leave(struct md_parse *, int);  static  int               parse_leave(struct md_parse *, int);
 static  int               io_begin(struct md_parse *);  static  int               io_begin(struct md_parse *);
Line 79  extern int    getsubopt(char **, char *const *, char *
Line 72  extern int    getsubopt(char **, char *const *, char *
 int  int
 main(int argc, char *argv[])  main(int argc, char *argv[])
 {  {
         int              c;  
         struct md_parse  parser;          struct md_parse  parser;
         char            *opts, *v, *filter;  
 #define ALL              0  
 #define COMPAT           1  
 #define SYNTAX           2  
 #define ERROR            3  
         char            *toks[] = { "all", "compat", "syntax",  
                                     "error", NULL };  
   
         extern char     *optarg;  
         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, "f:vW:")))          if ( ! parse_opts(&parser, argc, argv))
                 switch (c) {                  return(EXIT_FAILURE);
                 case ('f'):  
                         filter = optarg;  
                         break;  
                 case ('v'):  
                         parser.dbg++;  
                         break;  
                 case ('W'):  
                         opts = optarg;  
                         while (*opts)  
                                 switch (getsubopt(&opts, toks, &v)) {  
                                 case (ALL):  
                                         parser.warn |= MD_WARN_ALL;  
                                         break;  
                                 case (COMPAT):  
                                         parser.warn |= MD_WARN_COMPAT;  
                                         break;  
                                 case (SYNTAX):  
                                         parser.warn |= MD_WARN_SYNTAX;  
                                         break;  
                                 case (ERROR):  
                                         parser.warn |= MD_WARN_ERR;  
                                         break;  
                                 default:  
                                         usage();  
                                         return(1);  
                                 }  
                         break;  
                 default:  
                         usage();  
                         return(1);  
                 }  
   
         argv += optind;  
         argc -= optind;  
   
         parser.name = "-";  
         if (1 == argc)  
                 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 153  static int
Line 89  static int
 io_leave(struct md_parse *p, int code)  io_leave(struct md_parse *p, int code)
 {  {
   
         if (-1 == p->fd || STDIN_FILENO == p->fd)          if (-1 == p->fdin || STDIN_FILENO == p->fdin)
                 return(code);                  return(code);
   
         if (-1 == close(p->fd)) {          if (-1 == close(p->fdin)) {
                 warn("%s", p->name);                  warn("%s", p->in);
                 code = 0;                  code = 0;
         }          }
         return(code);          return(code);
Line 165  io_leave(struct md_parse *p, int code)
Line 101  io_leave(struct md_parse *p, int code)
   
   
 static int  static int
   parse_subopts(struct md_parse *p, char *arg)
   {
           char            *v;
           char            *toks[] = { "all", "compat",
                                   "syntax", "error", NULL };
   
           /*
            * Future -Wxxx levels and so on should be here.  For now we
            * only recognise syntax and compat warnings as categories,
            * beyond the usually "all" and "error" (make warn error out).
            */
   
           while (*arg)
                   switch (getsubopt(&arg, toks, &v)) {
                   case (0):
                           p->warn |= MD_WARN_ALL;
                           break;
                   case (1):
                           p->warn |= MD_WARN_COMPAT;
                           break;
                   case (2):
                           p->warn |= MD_WARN_SYNTAX;
                           break;
                   case (3):
                           p->warn |= MD_WARN_ERR;
                           break;
                   default:
                           usage();
                           return(0);
                   }
   
           return(1);
   }
   
   
   static int
   parse_opts(struct md_parse *p, int argc, char *argv[])
   {
           int              c;
   
           extern char     *optarg;
           extern int       optind;
   
           p->in = "-";
   
           while (-1 != (c = getopt(argc, argv, "vW:")))
                   switch (c) {
                   case ('v'):
                           p->dbg++;
                           break;
                   case ('W'):
                           if ( ! parse_subopts(p, optarg))
                                   return(0);
                           break;
                   default:
                           usage();
                           return(0);
                   }
   
           argv += optind;
           if (0 == (argc -= optind))
                   return(1);
   
           p->in = *argv++;
           return(1);
   }
   
   
   static int
 io_begin(struct md_parse *p)  io_begin(struct md_parse *p)
 {  {
   
         p->fd = STDIN_FILENO;          p->fdin = STDIN_FILENO;
         if (0 != strncmp(p->name, "-", 1))          if (0 != strncmp(p->in, "-", 1))
                 if (-1 == (p->fd = open(p->name, O_RDONLY, 0))) {                  if (-1 == (p->fdin = open(p->in, O_RDONLY, 0))) {
                         warn("%s", p->name);                          warn("%s", p->in);
                         return(io_leave(p, 0));                          return(io_leave(p, 0));
                 }                  }
   
Line 194  buf_begin(struct md_parse *p)
Line 199  buf_begin(struct md_parse *p)
 {  {
         struct stat      st;          struct stat      st;
   
         if (-1 == fstat(p->fd, &st)) {          if (-1 == fstat(p->fdin, &st)) {
                 warn("%s", p->name);                  warn("%s", p->in);
                 return(1);                  return(0);
         }          }
   
           /*
            * Try to intuit the fastest way of sucking down buffered data
            * by using either the block buffer size or the hard-coded one.
            * This is inspired by bin/cat.c.
            */
   
         p->bufsz = MAX(st.st_blksize, BUFSIZ);          p->bufsz = MAX(st.st_blksize, BUFSIZ);
   
         if (NULL == (p->buf = malloc(p->bufsz))) {          if (NULL == (p->buf = malloc(p->bufsz))) {
Line 213  buf_begin(struct md_parse *p)
Line 224  buf_begin(struct md_parse *p)
 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;  
   
         if (NULL == p->mdoc)          if (NULL == p->mdoc)
                 return(code);                  return(code);
   
         if ( ! mdoc_endparse(p->mdoc))          if ( ! mdoc_endparse(p->mdoc))
                 code = 0;                  code = 0;
         if (p->print && (n = mdoc_node(p->mdoc)))  
                 (*p->print)(n);  
   
         mdoc_free(p->mdoc);  #if 0
           /* TODO */
           if (code && ! mdoc_write(p->out, mdoc_node(p->mdoc))) {
                   warnx("%s: write error", p->out);
                   code = 0;
           }
   #endif
   
           mdoc_free(p->mdoc);
         return(code);          return(code);
 }  }
   
Line 245  parse_begin(struct md_parse *p)
Line 260  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));
   
           /*
            * This is a little more complicated than fgets.  TODO: have
            * some benchmarks that show it's faster (note that I want to
            * check many, many manuals simultaneously, so speed is
            * important).  Fill a buffer (sized to the block size) with a
            * single read, then parse \n-terminated lines into a line
            * buffer, which is passed to the parser.  Hard-code the line
            * buffer to a particular size -- a reasonable assumption.
            */
   
         for (lnn = 1, pos = 0; ; ) {          for (lnn = 1, pos = 0; ; ) {
                 if (-1 == (sz = read(p->fd, p->buf, p->bufsz))) {                  if (-1 == (sz = read(p->fdin, p->buf, p->bufsz))) {
                         warn("%s", p->name);                          warn("%s", p->in);
                         return(parse_leave(p, 0));                          return(parse_leave(p, 0));
                 } else if (0 == sz)                  } else if (0 == sz)
                         break;                          break;
Line 258  parse_begin(struct md_parse *p)
Line 283  parse_begin(struct md_parse *p)
                                         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->in, lnn);
                                                 p->name, lnn);  
                                 return(parse_leave(p, 0));                                  return(parse_leave(p, 0));
                         }                          }
   
Line 283  msg_err(void *arg, int line, int col, const char *msg)
Line 307  msg_err(void *arg, int line, int col, const char *msg)
   
         p = (struct md_parse *)arg;          p = (struct md_parse *)arg;
   
         xfprintf(stderr, "%s:%d: error: %s (column %d)\n",          warnx("%s:%d: error: %s (column %d)",
                         p->name, line, msg, col);                          p->in, line, msg, col);
         return(0);          return(0);
 }  }
   
Line 299  msg_msg(void *arg, int line, int col, const char *msg)
Line 323  msg_msg(void *arg, int line, int col, const char *msg)
         if (0 == p->dbg)          if (0 == p->dbg)
                 return;                  return;
   
         xfprintf(stderr, "%s:%d: debug: %s (column %d)\n",          warnx("%s:%d: debug: %s (column %d)",
                         p->name, line, msg, col);                          p->in, line, msg, col);
 }  }
   
   
Line 323  msg_warn(void *arg, int line, int col, 
Line 347  msg_warn(void *arg, int line, int col, 
                 return(1);                  return(1);
         }          }
   
         xfprintf(stderr, "%s:%d: warning: %s (column %d)\n",          warnx("%s:%d: warning: %s (column %d)",
                         p->name, line, msg, col);                          p->in, line, msg, col);
   
         if ( ! (p->warn & MD_WARN_ERR))          if ( ! (p->warn & MD_WARN_ERR))
                 return(1);                  return(1);
   
         xfprintf(stderr, "%s: considering warnings as errors\n",          warnx("%s: considering warnings as errors", __progname);
                         __progname);  
         return(0);          return(0);
 }  }
   
Line 339  static void
Line 362  static void
 usage(void)  usage(void)
 {  {
   
         xfprintf(stderr, "usage: %s [-v] [-Wwarn...] [-ffilter] "          warnx("usage: %s [-v] [-Wwarn...] [infile]", __progname);
                         "[infile]\n", __progname);  
 }  }
   

Legend:
Removed from v.1.50  
changed lines
  Added in v.1.51

CVSweb