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

Diff for /mandoc/Attic/mdocml.c between version 1.3 and 1.4

version 1.3, 2008/11/22 17:14:32 version 1.4, 2008/11/22 18:34:06
Line 32 
Line 32 
   
 #define BUFFER_IN_DEF   BUFSIZ  #define BUFFER_IN_DEF   BUFSIZ
 #define BUFFER_OUT_DEF  BUFSIZ  #define BUFFER_OUT_DEF  BUFSIZ
 #define BUFFER_LINE     BUFSIZ  
   
 struct md_rbuf {  
         int              fd;  
         const char      *name;  
         char            *buf;  
         size_t           bufsz;  
         size_t           line;  
 };  
   
 struct md_mbuf {  
         int              fd;  
         const char      *name;  
         char            *buf;  
         size_t           bufsz;  
         size_t           pos;  
 };  
   
 static void              usage(void);  static void              usage(void);
   static int               begin_io(const char *, const char *);
   static int               leave_io(const struct md_mbuf *,
                                   const struct md_rbuf *, int);
   static int               begin_bufs(struct md_mbuf *, struct md_rbuf *);
   static int               leave_bufs(const struct md_mbuf *,
                                   const struct md_rbuf *, 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_mbuf *, struct md_rbuf *);  
 static int               md_run(struct md_mbuf *, struct md_rbuf *);  
 static int               md_line(struct md_mbuf *, const struct md_rbuf *,  
                                 const char *, size_t);  
   
 static ssize_t           md_buf_fill(struct md_rbuf *);  
 static int               md_buf_flush(struct md_mbuf *);  
   
 static int               md_buf_putchar(struct md_mbuf *, char);  
 static int               md_buf_puts(struct md_mbuf *,  
                                 const char *, size_t);  
   
   
 int  int
 main(int argc, char *argv[])  main(int argc, char *argv[])
 {  {
Line 76  main(int argc, char *argv[])
Line 50  main(int argc, char *argv[])
         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 89  main(int argc, char *argv[])
Line 63  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));          return(begin_io(out ? out : "-", in ? in : "-"));
 }  }
   
   
 static int  static int
 md_begin(const char *out, const char *in)  leave_io(const struct md_mbuf *out,
                   const struct md_rbuf *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 char *out, const char *in)
 {  {
         int              c;          struct md_rbuf   fi;
         struct md_rbuf   fin;          struct md_mbuf   fo;
         struct md_mbuf   fout;  
   
   #define FI_FL   O_RDONLY
   #define FO_FL   O_WRONLY|O_CREAT|O_TRUNC
   
         assert(out);          assert(out);
         assert(in);          assert(in);
   
         /* TODO: accept "-" as both input and output. */          bzero(&fi, sizeof(struct md_rbuf));
           bzero(&fo, sizeof(struct md_mbuf));
   
         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_TRUNC, 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(&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_mbuf *out,
                   const struct md_rbuf *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_mbuf *out, struct md_rbuf *in)  begin_bufs(struct md_mbuf *out, struct md_rbuf *in)
 {  {
         struct stat      stin, stout;          struct stat      stin, stout;
         int              c;  
   
         assert(in);          assert(in);
         assert(out);          assert(out);
Line 183  md_begin_bufs(struct md_mbuf *out, struct md_rbuf *in)
Line 163  md_begin_bufs(struct md_mbuf *out, struct md_rbuf *in)
         }          }
   
         in->bufsz = MAX(stin.st_blksize, BUFFER_IN_DEF);          in->bufsz = MAX(stin.st_blksize, BUFFER_IN_DEF);
   
         out->bufsz = MAX(stout.st_blksize, BUFFER_OUT_DEF);          out->bufsz = MAX(stout.st_blksize, BUFFER_OUT_DEF);
   
         if (NULL == (in->buf = malloc(in->bufsz))) {          if (NULL == (in->buf = malloc(in->bufsz))) {
                 warn("malloc");                  warn("malloc");
                 return(1);                  return(leave_bufs(out, in, 1));
         } else if (NULL == (out->buf = malloc(out->bufsz))) {          } else if (NULL == (out->buf = malloc(out->bufsz))) {
                 warn("malloc");                  warn("malloc");
                 free(in->buf);                  return(leave_bufs(out, in, 1));
                 return(1);  
         }          }
   
         c = md_run(out, in);          return(leave_bufs(out, in, md_run(MD_DUMMY, out, in)));
   
         free(in->buf);  
         free(out->buf);  
   
         return(c);  
 }  }
   
   
 static ssize_t  
 md_buf_fill(struct md_rbuf *in)  
 {  
         ssize_t          ssz;  
   
         assert(in);  
         assert(in->buf);  
         assert(in->bufsz > 0);  
         assert(in->name);  
   
         if (-1 == (ssz = read(in->fd, in->buf, in->bufsz)))  
                 warn("%s", in->name);  
   
         return(ssz);  
 }  
   
   
 static int  
 md_run(struct md_mbuf *out, struct md_rbuf *in)  
 {  
         ssize_t          sz, i;  
         char             line[BUFFER_LINE];  
         size_t           pos;  
   
         assert(in);  
         assert(out);  
   
         out->pos = 0;  
         in->line = 1;  
   
         /* 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 < BUFFER_LINE) {  
                                 /* LINTED */  
                                 line[pos++] = in->buf[i];  
                                 continue;  
                         }  
   
                         warnx("%s: line %zu too long",  
                                         in->name, in->line);  
                         return(1);  
                 }  
         }  
   
         if (0 != pos && md_line(out, in, line, pos))  
                 return(1);  
   
         return(md_buf_flush(out) ? 0 : 1);  
 }  
   
   
 static int  
 md_buf_flush(struct md_mbuf *buf)  
 {  
         ssize_t          sz;  
   
         assert(buf);  
         assert(buf->buf);  
         assert(buf->name);  
   
         if (0 == buf->pos)  
                 return(1);  
   
         sz = write(buf->fd, buf->buf, buf->pos);  
   
         if (-1 == sz) {  
                 warn("%s", buf->name);  
                 return(0);  
         } else if ((size_t)sz != buf->pos) {  
                 warnx("%s: short write", buf->name);  
                 return(0);  
         }  
   
         buf->pos = 0;  
         return(1);  
 }  
   
   
 static int  
 md_buf_putchar(struct md_mbuf *buf, char c)  
 {  
         return(md_buf_puts(buf, &c, 1));  
 }  
   
   
 static int  
 md_buf_puts(struct md_mbuf *buf, const char *p, size_t sz)  
 {  
         size_t           ssz;  
   
         assert(p);  
         assert(buf);  
         assert(buf->buf);  
   
         while (buf->pos + sz > buf->bufsz) {  
                 ssz = buf->bufsz - buf->pos;  
                 (void)memcpy(buf->buf + buf->pos, p, ssz);  
                 p += ssz;  
                 sz -= ssz;  
                 buf->pos += ssz;  
   
                 if ( ! md_buf_flush(buf))  
                         return(0);  
         }  
   
         (void)memcpy(buf->buf + buf->pos, p, sz);  
         buf->pos += sz;  
         return(1);  
 }  
   
   
 static int  
 md_line(struct md_mbuf *out, const struct md_rbuf *in,  
                 const char *buf, size_t sz)  
 {  
   
         /* FIXME: this is just a placeholder function. */  
   
         assert(buf);  
         assert(out);  
         assert(in);  
   
         if ( ! md_buf_puts(out, buf, sz))  
                 return(1);  
         if ( ! md_buf_putchar(out, '\n'))  
                 return(1);  
   
         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.3  
changed lines
  Added in v.1.4

CVSweb