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

Diff for /mandoc/Attic/mdocml.c between version 1.1 and 1.6

version 1.1, 2008/11/22 14:53:29 version 1.6, 2008/11/23 11:05:25
Line 30 
Line 30 
   
 #include "libmdocml.h"  #include "libmdocml.h"
   
 struct md_file {  #define BUFFER_IN_DEF   BUFSIZ
         int              fd;  #define BUFFER_OUT_DEF  BUFSIZ
         const char      *name;  
 };  
   
 struct md_buf {  
         struct md_file  *file;  
         char            *buf;  
         size_t           bufsz;  
         size_t           line;  
 };  
   
 static void              usage(void);  static void              usage(void);
   static int               begin_io(const struct md_args *,
                                   char *, char *);
   static int               leave_io(const struct md_buf *,
                                   const struct md_buf *, int);
   static int               begin_bufs(const struct md_args *,
                                   struct md_buf *, struct md_buf *);
   static int               leave_bufs(const struct md_buf *,
                                   const struct md_buf *, int);
   
 static int               md_begin(const char *, const char *);  
 static int               md_begin_io(const char *, const char *);  
 static int               md_begin_bufs(struct md_file *, struct md_file *);  
 static int               md_run(struct md_buf *, struct md_buf *);  
 static int               md_line(struct md_buf *, const struct md_buf *,  
                                 const char *, size_t);  
   
 static ssize_t           md_buf_fill(struct md_buf *);  
   
   
 int  int
 main(int argc, char *argv[])  main(int argc, char *argv[])
 {  {
         int              c;          int              c;
         char            *out, *in;          char            *out, *in;
           struct md_args   args;
   
         extern char     *optarg;          extern char     *optarg;
         extern int       optind;          extern int       optind;
   
         out = NULL;          out = in = NULL;
   
         while (-1 != (c = getopt(argc, argv, "o:")))          while (-1 != (c = getopt(argc, argv, "o:")))
                 switch (c) {                  switch (c) {
Line 76  main(int argc, char *argv[])
Line 66  main(int argc, char *argv[])
                 }                  }
   
         argv += optind;          argv += optind;
         if (1 != (argc -= optind)) {          argc -= optind;
                 usage();  
                 return(1);  
         }  
   
         argc--;          if (1 == argc)
         in = *argv++;                  in = *argv++;
   
         return(md_begin(out, in));          args.type = MD_HTML4_STRICT;
   
           return(begin_io(&args, out ? out : "-", in ? in : "-"));
 }  }
   
   
 static int  static int
 md_begin(const char *out, const char *in)  leave_io(const struct md_buf *out,
                   const struct md_buf *in, int c)
 {  {
         char             buf[MAXPATHLEN];          assert(out);
   
         assert(in);          assert(in);
         if (out)  
                 return(md_begin_io(out, in));  
   
         if (strlcpy(buf, in, MAXPATHLEN) >= MAXPATHLEN)          if (-1 != in->fd && -1 == close(in->fd)) {
                 warnx("output filename too long");                  assert(in->name);
         else if (strlcat(buf, ".html", MAXPATHLEN) >= MAXPATHLEN)                  warn("%s", in->name);
                 warnx("output filename too long");                  c = 1;
         else          }
                 return(md_begin_io(buf, in));          if (-1 != out->fd && STDOUT_FILENO != out->fd &&
                           -1 == close(out->fd)) {
                   assert(out->name);
                   warn("%s", out->name);
                   c = 1;
           }
   
         return(1);          return(c);
 }  }
   
   
 static int  static int
 md_begin_io(const char *out, const char *in)  begin_io(const struct md_args *args, char *out, char *in)
 {  {
         int              c;          struct md_buf    fi;
         struct md_file   fin, fout;          struct md_buf    fo;
   
   #define FI_FL   O_RDONLY
   #define FO_FL   O_WRONLY|O_CREAT|O_TRUNC
   
           assert(args);
         assert(out);          assert(out);
         assert(in);          assert(in);
   
         /* XXX: put an output file in TMPDIR and switch it out when the          bzero(&fi, sizeof(struct md_buf));
          * true file is ready to be written.          bzero(&fo, sizeof(struct md_buf));
          */  
   
         fin.name = in;          fi.fd = STDIN_FILENO;
           fo.fd = STDOUT_FILENO;
   
         if (-1 == (fin.fd = open(fin.name, O_RDONLY, 0))) {          fi.name = in;
                 warn("%s", fin.name);          fo.name = out;
                 return(1);  
         }  
   
         fout.name = out;          if (0 != strncmp(fi.name, "-", 1))
                   if (-1 == (fi.fd = open(fi.name, FI_FL, 0))) {
                           warn("%s", fi.name);
                           return(leave_io(&fo, &fi, 1));
                   }
   
         fout.fd = open(fout.name, O_WRONLY | O_CREAT | O_EXCL, 0644);          if (0 != strncmp(fo.name, "-", 1))
         if (-1 == fout.fd) {                  if (-1 == (fo.fd = open(fo.name, FO_FL, 0644))) {
                 warn("%s", fout.name);                          warn("%s", fo.name);
                 if (-1 == close(fin.fd))                          return(leave_io(&fo, &fi, 1));
                         warn("%s", fin.name);                  }
                 return(1);  
         }  
   
         c = md_begin_bufs(&fout, &fin);          return(leave_io(&fo, &fi, begin_bufs(args, &fo, &fi)));
   }
   
         if (-1 == close(fin.fd)) {  
                 warn("%s", in);  
                 c = 1;  
         }  
         if (-1 == close(fout.fd)) {  
                 warn("%s", out);  
                 c = 1;  
         }  
   
   static int
   leave_bufs(const struct md_buf *out,
                   const struct md_buf *in, int c)
   {
           assert(out);
           assert(in);
           if (out->buf)
                   free(out->buf);
           if (in->buf)
                   free(in->buf);
         return(c);          return(c);
 }  }
   
   
 static int  static int
 md_begin_bufs(struct md_file *out, struct md_file *in)  begin_bufs(const struct md_args *args,
                   struct md_buf *out, struct md_buf *in)
 {  {
         struct stat      stin, stout;          struct stat      stin, stout;
         struct md_buf    inbuf, outbuf;  
         int              c;          int              c;
   
           assert(args);
         assert(in);          assert(in);
         assert(out);          assert(out);
   
         if (-1 == fstat(in->fd, &stin)) {          if (-1 == fstat(in->fd, &stin)) {
                 warn("fstat: %s", in->name);                  warn("%s", in->name);
                 return(1);                  return(1);
         } else if (-1 == fstat(out->fd, &stout)) {          } else if (-1 == fstat(out->fd, &stout)) {
                 warn("fstat: %s", out->name);                  warn("%s", out->name);
                 return(1);                  return(1);
         }          }
   
         inbuf.file = in;          in->bufsz = MAX(stin.st_blksize, BUFFER_IN_DEF);
         inbuf.line = 1;          out->bufsz = MAX(stout.st_blksize, BUFFER_OUT_DEF);
         inbuf.bufsz = MAX(stin.st_blksize, BUFSIZ);  
   
         outbuf.file = out;          if (NULL == (in->buf = malloc(in->bufsz))) {
         outbuf.line = 1;  
         outbuf.bufsz = MAX(stout.st_blksize, BUFSIZ);  
   
         if (NULL == (inbuf.buf = malloc(inbuf.bufsz))) {  
                 warn("malloc");                  warn("malloc");
                 return(1);                  return(leave_bufs(out, in, 1));
         } else if (NULL == (outbuf.buf = malloc(outbuf.bufsz))) {          } else if (NULL == (out->buf = malloc(out->bufsz))) {
                 warn("malloc");                  warn("malloc");
                 free(inbuf.buf);                  return(leave_bufs(out, in, 1));
                 return(1);  
         }          }
   
         c = md_run(&outbuf, &inbuf);          c = md_run(args, out, in);
           return(leave_bufs(out, in, -1 == c ? 1 : 0));
         free(inbuf.buf);  
         free(outbuf.buf);  
   
         return(c);  
 }  }
   
   
 static ssize_t  
 md_buf_fill(struct md_buf *in)  
 {  
         ssize_t          ssz;  
   
         assert(in);  
         assert(in->file);  
         assert(in->buf);  
         assert(in->bufsz > 0);  
         assert(in->file->name);  
   
         if (-1 == (ssz = read(in->file->fd, in->buf, in->bufsz)))  
                 warn("%s", in->file->name);  
   
         return(ssz);  
 }  
   
   
 static int  
 md_run(struct md_buf *out, struct md_buf *in)  
 {  
         ssize_t          sz, i;  
         char             line[BUFSIZ];  
         size_t           pos;  
   
         assert(in);  
         assert(out);  
   
         /* LINTED */  
         for (pos = 0; ; ) {  
                 if (-1 == (sz = md_buf_fill(in)))  
                         return(1);  
                 else if (0 == sz)  
                         break;  
   
                 for (i = 0; i < sz; i++) {  
                         if ('\n' == in->buf[i]) {  
                                 if (md_line(out, in, line, pos))  
                                         return(1);  
                                 in->line++;  
                                 pos = 0;  
                                 continue;  
                         }  
   
                         if (pos < BUFSIZ) {  
                                 /* LINTED */  
                                 line[pos++] = in->buf[i];  
                                 continue;  
                         }  
   
                         warnx("%s: line %zu too long",  
                                         in->file->name, in->line);  
                         return(1);  
                 }  
         }  
   
         if (0 != pos)  
                 return(md_line(out, in, line, pos));  
   
         return(0);  
 }  
   
   
 static int  
 md_line(struct md_buf *out, const struct md_buf *in,  
                 const char *buf, size_t sz)  
 {  
         size_t           i;  
   
         assert(buf);  
         assert(out);  
         assert(in);  
   
         for (i = 0; i < sz; i++)  
                 (void)putchar(buf[i]);  
   
         (void)putchar('\n');  
         return(0);  
 }  
   
   
 static void  static void
 usage(void)  usage(void)
 {  {
         extern char     *__progname;          extern char     *__progname;
   
         (void)printf("usage: %s [-o outfile] infile\n", __progname);          (void)printf("usage: %s [-o outfile] [infile]\n", __progname);
 }  }

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

CVSweb