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

Diff for /texi2mdoc/main.c between version 1.1 and 1.2

version 1.1, 2015/02/16 22:24:43 version 1.2, 2015/02/17 10:27:18
Line 21 
Line 21 
 #include <ctype.h>  #include <ctype.h>
 #include <fcntl.h>  #include <fcntl.h>
 #include <getopt.h>  #include <getopt.h>
   #include <libgen.h>
   #include <limits.h>
 #include <stdarg.h>  #include <stdarg.h>
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
Line 32 
Line 34 
  * different story.   * different story.
  */   */
 enum    texicmd {  enum    texicmd {
           TEXICMD_ACRONYM,
         TEXICMD_A4PAPER,          TEXICMD_A4PAPER,
         TEXICMD_ANCHOR,          TEXICMD_ANCHOR,
           TEXICMD_APPENDIX,
           TEXICMD_APPENDIXSEC,
         TEXICMD_AT,          TEXICMD_AT,
         TEXICMD_BYE,          TEXICMD_BYE,
         TEXICMD_CHAPTER,          TEXICMD_CHAPTER,
Line 41  enum texicmd {
Line 46  enum texicmd {
         TEXICMD_CODE,          TEXICMD_CODE,
         TEXICMD_COMMAND,          TEXICMD_COMMAND,
         TEXICMD_COMMENT,          TEXICMD_COMMENT,
           TEXICMD_COMMENT_LONG,
         TEXICMD_CONTENTS,          TEXICMD_CONTENTS,
         TEXICMD_COPYING,          TEXICMD_COPYING,
         TEXICMD_COPYRIGHT,          TEXICMD_COPYRIGHT,
         TEXICMD_DETAILMENU,          TEXICMD_DETAILMENU,
         TEXICMD_DIRCATEGORY,          TEXICMD_DIRCATEGORY,
         TEXICMD_DIRENTRY,          TEXICMD_DIRENTRY,
           TEXICMD_DOTS,
         TEXICMD_EMAIL,          TEXICMD_EMAIL,
         TEXICMD_EMPH,          TEXICMD_EMPH,
         TEXICMD_END,          TEXICMD_END,
           TEXICMD_ENUMERATE,
         TEXICMD_EXAMPLE,          TEXICMD_EXAMPLE,
         TEXICMD_FILE,          TEXICMD_FILE,
           TEXICMD_HEADING,
         TEXICMD_I,          TEXICMD_I,
         TEXICMD_IFHTML,          TEXICMD_IFHTML,
         TEXICMD_IFNOTTEX,          TEXICMD_IFNOTTEX,
         TEXICMD_IFTEX,          TEXICMD_IFTEX,
         TEXICMD_IMAGE,          TEXICMD_IMAGE,
           TEXICMD_INCLUDE,
         TEXICMD_ITEM,          TEXICMD_ITEM,
         TEXICMD_ITEMIZE,          TEXICMD_ITEMIZE,
         TEXICMD_KBD,          TEXICMD_KBD,
Line 65  enum texicmd {
Line 75  enum texicmd {
         TEXICMD_NODE,          TEXICMD_NODE,
         TEXICMD_QUOTATION,          TEXICMD_QUOTATION,
         TEXICMD_PARINDENT,          TEXICMD_PARINDENT,
           TEXICMD_PRINTINDEX,
         TEXICMD_REF,          TEXICMD_REF,
         TEXICMD_SAMP,          TEXICMD_SAMP,
         TEXICMD_SECTION,          TEXICMD_SECTION,
Line 79  enum texicmd {
Line 90  enum texicmd {
         TEXICMD_TITLEPAGE,          TEXICMD_TITLEPAGE,
         TEXICMD_TOP,          TEXICMD_TOP,
         TEXICMD_UNNUMBERED,          TEXICMD_UNNUMBERED,
           TEXICMD_UNNUMBEREDSEC,
         TEXICMD_URL,          TEXICMD_URL,
         TEXICMD_VAR,          TEXICMD_VAR,
         TEXICMD__MAX          TEXICMD__MAX
Line 98  struct texifile {
Line 110  struct texifile {
   
 struct  texi;  struct  texi;
   
   /*
    * Callback for functions implementing texi commands.
    */
 typedef void (*texicmdfp)(struct texi *,  typedef void (*texicmdfp)(struct texi *,
         enum texicmd, const char *, size_t, size_t *);          enum texicmd, const char *, size_t, size_t *);
   
Line 124  struct texi {
Line 139  struct texi {
         size_t           outcol; /* column of output */          size_t           outcol; /* column of output */
         int              outmacro; /* whether output is in line macro */          int              outmacro; /* whether output is in line macro */
         int              seenws; /* whitespace has been ignored */          int              seenws; /* whitespace has been ignored */
           char            *dir; /* texi directory */
 };  };
   
   /* FIXME: don't use this crap. */
 #define ismpunct(_x) \  #define ismpunct(_x) \
         ('.' == (_x) || \          ('.' == (_x) || \
          ',' == (_x) || \           ',' == (_x) || \
          ';' == (_x))           ';' == (_x))
   #define isws(_x) \
           (' ' == (_x) || '\t' == (_x))
   
 static  void doarg1(struct texi *, enum texicmd, const char *, size_t, size_t *);  static  void doarg1(struct texi *, enum texicmd, const char *, size_t, size_t *);
 static  void dobracket(struct texi *, enum texicmd, const char *, size_t, size_t *);  static  void dobracket(struct texi *, enum texicmd, const char *, size_t, size_t *);
 static  void dobye(struct texi *, enum texicmd, const char *, size_t, size_t *);  static  void dobye(struct texi *, enum texicmd, const char *, size_t, size_t *);
 static  void docommand(struct texi *, enum texicmd, const char *, size_t, size_t *);  static  void docommand(struct texi *, enum texicmd, const char *, size_t, size_t *);
 static  void doemph(struct texi *, enum texicmd, const char *, size_t, size_t *);  static  void doemph(struct texi *, enum texicmd, const char *, size_t, size_t *);
   static  void doenumerate(struct texi *, enum texicmd, const char *, size_t, size_t *);
 static  void doexample(struct texi *, enum texicmd, const char *, size_t, size_t *);  static  void doexample(struct texi *, enum texicmd, const char *, size_t, size_t *);
 static  void dofile(struct texi *, enum texicmd, const char *, size_t, size_t *);  static  void dofile(struct texi *, enum texicmd, const char *, size_t, size_t *);
 static  void doifnottex(struct texi *, enum texicmd, const char *, size_t, size_t *);  static  void doifnottex(struct texi *, enum texicmd, const char *, size_t, size_t *);
 static  void doignblock(struct texi *, enum texicmd, const char *, size_t, size_t *);  static  void doignblock(struct texi *, enum texicmd, const char *, size_t, size_t *);
 static  void doignbracket(struct texi *, enum texicmd, const char *, size_t, size_t *);  static  void doignbracket(struct texi *, enum texicmd, const char *, size_t, size_t *);
 static  void doignline(struct texi *, enum texicmd, const char *, size_t, size_t *);  static  void doignline(struct texi *, enum texicmd, const char *, size_t, size_t *);
   static  void doinclude(struct texi *, enum texicmd, const char *, size_t, size_t *);
 static  void doitalic(struct texi *, enum texicmd, const char *, size_t, size_t *);  static  void doitalic(struct texi *, enum texicmd, const char *, size_t, size_t *);
 static  void doitem(struct texi *, enum texicmd, const char *, size_t, size_t *);  static  void doitem(struct texi *, enum texicmd, const char *, size_t, size_t *);
 static  void doitemize(struct texi *, enum texicmd, const char *, size_t, size_t *);  static  void doitemize(struct texi *, enum texicmd, const char *, size_t, size_t *);
Line 155  static void dosubsection(struct texi *, enum texicmd, 
Line 176  static void dosubsection(struct texi *, enum texicmd, 
 static  void dosymbol(struct texi *, enum texicmd, const char *, size_t, size_t *);  static  void dosymbol(struct texi *, enum texicmd, const char *, size_t, size_t *);
   
 static  const struct texitok texitoks[TEXICMD__MAX] = {  static  const struct texitok texitoks[TEXICMD__MAX] = {
           { doarg1, "acronym", 7 }, /* TEXICMD_ACRONYM */
         { doignline, "afourpaper", 10 }, /* TEXICMD_A4PAPER */          { doignline, "afourpaper", 10 }, /* TEXICMD_A4PAPER */
         { doignbracket, "anchor", 6 }, /* TEXICMD_ANCHOR */          { doignbracket, "anchor", 6 }, /* TEXICMD_ANCHOR */
           { dosh, "appendix", 8 }, /* TEXICMD_APPENDIX */
           { dosh, "appendixsec", 11 }, /* TEXICMD_APPENDIXSEC */
         { dosymbol, "@", 1 }, /* TEXICMD_AT */          { dosymbol, "@", 1 }, /* TEXICMD_AT */
         { dobye, "bye", 3 }, /* TEXICMD_BYE */          { dobye, "bye", 3 }, /* TEXICMD_BYE */
         { dosh, "chapter", 7 }, /* TEXICMD_CHAPTER */          { dosh, "chapter", 7 }, /* TEXICMD_CHAPTER */
Line 164  static const struct texitok texitoks[TEXICMD__MAX] = {
Line 188  static const struct texitok texitoks[TEXICMD__MAX] = {
         { doliteral, "code", 4 }, /* TEXICMD_CODE */          { doliteral, "code", 4 }, /* TEXICMD_CODE */
         { docommand, "command", 7 }, /* TEXICMD_COMMAND */          { docommand, "command", 7 }, /* TEXICMD_COMMAND */
         { doignline, "c", 1 }, /* TEXICMD_COMMENT */          { doignline, "c", 1 }, /* TEXICMD_COMMENT */
           { doignline, "comment", 7 }, /* TEXICMD_COMMENT_LONG */
         { doignline, "contents", 8 }, /* TEXICMD_CONTENTS */          { doignline, "contents", 8 }, /* TEXICMD_CONTENTS */
         { doignblock, "copying", 7 }, /* TEXICMD_COPYING */          { doignblock, "copying", 7 }, /* TEXICMD_COPYING */
         { dosymbol, "copyright", 9 }, /* TEXICMD_COPYRIGHT */          { dosymbol, "copyright", 9 }, /* TEXICMD_COPYRIGHT */
         { doignblock, "detailmenu", 10 }, /* TEXICMD_DETAILMENU */          { doignblock, "detailmenu", 10 }, /* TEXICMD_DETAILMENU */
         { doignline, "dircategory", 11 }, /* TEXICMD_DIRCATEGORY */          { doignline, "dircategory", 11 }, /* TEXICMD_DIRCATEGORY */
         { doignblock, "direntry", 8 }, /* TEXICMD_DIRENTRY */          { doignblock, "direntry", 8 }, /* TEXICMD_DIRENTRY */
           { dosymbol, "dots", 4 }, /* TEXICMD_DOTS */
         { doarg1, "email", 5 }, /* TEXICMD_EMAIL */          { doarg1, "email", 5 }, /* TEXICMD_EMAIL */
         { doemph, "emph", 4 }, /* TEXICMD_EMPH */          { doemph, "emph", 4 }, /* TEXICMD_EMPH */
         { NULL, "end", 3 }, /* TEXICMD_END */          { NULL, "end", 3 }, /* TEXICMD_END */
           { doenumerate, "enumerate", 9 }, /* TEXICMD_ENUMERATE */
         { doexample, "example", 7 }, /* TEXICMD_EXAMPLE */          { doexample, "example", 7 }, /* TEXICMD_EXAMPLE */
         { dofile, "file", 4 }, /* TEXICMD_FILE */          { dofile, "file", 4 }, /* TEXICMD_FILE */
           { dosection, "heading", 7 }, /* TEXICMD_HEADING */
         { doitalic, "i", 1 }, /* TEXICMD_I */          { doitalic, "i", 1 }, /* TEXICMD_I */
         { doignblock, "ifhtml", 6 }, /* TEXICMD_IFHTML */          { doignblock, "ifhtml", 6 }, /* TEXICMD_IFHTML */
         { doifnottex, "ifnottex", 8 }, /* TEXICMD_IFNOTTEX */          { doifnottex, "ifnottex", 8 }, /* TEXICMD_IFNOTTEX */
         { doignblock, "iftex", 5 }, /* TEXICMD_IFTEX */          { doignblock, "iftex", 5 }, /* TEXICMD_IFTEX */
         { doignbracket, "image", 5 }, /* TEXICMD_IMAGE */          { doignbracket, "image", 5 }, /* TEXICMD_IMAGE */
           { doinclude, "include", 7 }, /* TEXICMD_INCLUDE */
         { doitem, "item", 4 }, /* TEXICMD_ITEM */          { doitem, "item", 4 }, /* TEXICMD_ITEM */
         { doitemize, "itemize", 7 }, /* TEXICMD_ITEMIZE */          { doitemize, "itemize", 7 }, /* TEXICMD_ITEMIZE */
         { doliteral, "kbd", 3 }, /* TEXICMD_KBD */          { doliteral, "kbd", 3 }, /* TEXICMD_KBD */
Line 187  static const struct texitok texitoks[TEXICMD__MAX] = {
Line 216  static const struct texitok texitoks[TEXICMD__MAX] = {
         { doignblock, "menu", 4 }, /* TEXICMD_MENU */          { doignblock, "menu", 4 }, /* TEXICMD_MENU */
         { doignline, "node", 4 }, /* TEXICMD_NODE */          { doignline, "node", 4 }, /* TEXICMD_NODE */
         { doquotation, "quotation", 9 }, /* TEXICMD_QUOTATION */          { doquotation, "quotation", 9 }, /* TEXICMD_QUOTATION */
           { doignline, "printindex", 10 }, /* TEXICMD_PRINTINDEX */
         { doignline, "paragraphindent", 14 }, /* TEXICMD_PARINDENT */          { doignline, "paragraphindent", 14 }, /* TEXICMD_PARINDENT */
         { dobracket, "ref", 3 }, /* TEXICMD_REF */          { dobracket, "ref", 3 }, /* TEXICMD_REF */
         { doliteral, "samp", 4 }, /* TEXICMD_SAMP */          { doliteral, "samp", 4 }, /* TEXICMD_SAMP */
Line 202  static const struct texitok texitoks[TEXICMD__MAX] = {
Line 232  static const struct texitok texitoks[TEXICMD__MAX] = {
         { doignblock, "titlepage", 9 }, /* TEXICMD_TITLEPAGE */          { doignblock, "titlepage", 9 }, /* TEXICMD_TITLEPAGE */
         { dotop, "top", 3 }, /* TEXICMD_TOP */          { dotop, "top", 3 }, /* TEXICMD_TOP */
         { dosh, "unnumbered", 10 }, /* TEXICMD_UNNUMBERED */          { dosh, "unnumbered", 10 }, /* TEXICMD_UNNUMBERED */
           { dosection, "unnumberedsec", 13 }, /* TEXICMD_UNNUMBEREDSEC */
         { doarg1, "url", 3 }, /* TEXICMD_URL */          { doarg1, "url", 3 }, /* TEXICMD_URL */
         { doliteral, "var", 3 }, /* TEXICMD_VAR */          { doliteral, "var", 3 }, /* TEXICMD_VAR */
 };  };
   
   /*
    * Unmap the top-most file that we're using.
    */
 static void  static void
 texifilepop(struct texi *p)  texifilepop(struct texi *p)
 {  {
Line 216  texifilepop(struct texi *p)
Line 250  texifilepop(struct texi *p)
         munmap(f->map, f->mapsz);          munmap(f->map, f->mapsz);
 }  }
   
   /*
    * Unmap all files that we're currently using.
    * The utility should exit(...) after this is called.
    */
 static void  static void
 texiexit(struct texi *p)  texiexit(struct texi *p)
 {  {
   
         while (p->filepos > 0)          while (p->filepos > 0)
                 texifilepop(p);                  texifilepop(p);
           free(p->dir);
 }  }
   
   /*
    * Fatal error: unmap all files and exit.
    * The "errstring" is passed to perror(3).
    */
 static void  static void
 texifatal(struct texi *p, const char *errstring)  texiabort(struct texi *p, const char *errstring)
 {  {
   
         perror(errstring);          perror(errstring);
Line 242  texiwarn(const struct texi *p, const char *fmt, ...)
Line 285  texiwarn(const struct texi *p, const char *fmt, ...)
 {  {
         va_list  ap;          va_list  ap;
   
         fprintf(stderr, "%s:%zu:%zu: ",          fprintf(stderr, "%s:%zu:%zu: warning: ",
                 p->files[p->filepos - 1].name,                  p->files[p->filepos - 1].name,
                 p->files[p->filepos - 1].line + 1,                  p->files[p->filepos - 1].line + 1,
                 p->files[p->filepos - 1].col + 1);                  p->files[p->filepos - 1].col + 1);
Line 252  texiwarn(const struct texi *p, const char *fmt, ...)
Line 295  texiwarn(const struct texi *p, const char *fmt, ...)
         fputc('\n', stderr);          fputc('\n', stderr);
 }  }
   
   static void
   texierr(struct texi *p, const char *fmt, ...)
   {
           va_list  ap;
   
           fprintf(stderr, "%s:%zu:%zu: error: ",
                   p->files[p->filepos - 1].name,
                   p->files[p->filepos - 1].line + 1,
                   p->files[p->filepos - 1].col + 1);
           va_start(ap, fmt);
           vfprintf(stderr, fmt, ap);
           va_end(ap);
           fputc('\n', stderr);
           texiexit(p);
           exit(EXIT_FAILURE);
   }
   
 /*  /*
  * Put a single data character.   * Put a single data character.
  * This MUST NOT be a mdoc(7) command: it should be free text that's   * This MUST NOT be a mdoc(7) command: it should be free text that's
Line 442  texicmd(struct texi *p, const char *buf, 
Line 502  texicmd(struct texi *p, const char *buf, 
   
         assert('@' == buf[pos]);          assert('@' == buf[pos]);
         for (*end = ++pos; *end < sz && ! isspace(buf[*end]); (*end)++)          for (*end = ++pos; *end < sz && ! isspace(buf[*end]); (*end)++)
                 if ('@' == buf[*end] || '{' == buf[*end])                  if ((*end > pos && '@' == buf[*end]) || '{' == buf[*end])
                         break;                          break;
   
         len = *end - pos;          len = *end - pos;
Line 556  parseto(struct texi *p, const char *buf, 
Line 616  parseto(struct texi *p, const char *buf, 
                 cmd = texicmd(p, buf, *pos, sz, &end);                  cmd = texicmd(p, buf, *pos, sz, &end);
                 advanceto(p, buf, pos, end);                  advanceto(p, buf, pos, end);
                 if (TEXICMD_END == cmd) {                  if (TEXICMD_END == cmd) {
                         while (*pos < sz && ' ' == buf[*pos])                          while (*pos < sz && isws(buf[*pos]))
                                 advance(p, buf, pos);                                  advance(p, buf, pos);
                         /*                          /*
                          * FIXME: skip tabs and also check the full                           * FIXME: skip tabs and also check the full
Line 577  parseto(struct texi *p, const char *buf, 
Line 637  parseto(struct texi *p, const char *buf, 
 }  }
   
 static void  static void
   parsefile(struct texi *p, const char *fname)
   {
           struct texifile  *f;
           int               fd;
           struct stat       st;
   
           assert(p->filepos < 64);
           f = &p->files[p->filepos];
           memset(f, 0, sizeof(struct texifile));
   
           f->name = fname;
           if (-1 == (fd = open(fname, O_RDONLY, 0))) {
                   texiabort(p, fname);
           } else if (-1 == fstat(fd, &st)) {
                   close(fd);
                   texiabort(p, fname);
           }
   
           f->mapsz = st.st_size;
           f->map = mmap(NULL, f->mapsz,
                   PROT_READ, MAP_SHARED, fd, 0);
           close(fd);
   
           if (MAP_FAILED == f->map)
                   texiabort(p, fname);
   
           p->filepos++;
           parseeof(p, f->map, f->mapsz);
           texifilepop(p);
   }
   
   static void
 doignblock(struct texi *p, enum texicmd cmd,  doignblock(struct texi *p, enum texicmd cmd,
         const char *buf, size_t sz, size_t *pos)          const char *buf, size_t sz, size_t *pos)
 {  {
Line 649  doinline(struct texi *p, const char *buf, 
Line 741  doinline(struct texi *p, const char *buf, 
 }  }
   
 static void  static void
   doinclude(struct texi *p, enum texicmd cmd,
           const char *buf, size_t sz, size_t *pos)
   {
           char     fname[PATH_MAX], path[PATH_MAX];
           size_t   i;
           int      rc;
   
           while (*pos < sz && ' ' == buf[*pos])
                   advance(p, buf, pos);
   
           /* Read in the filename. */
           for (i = 0; *pos < sz && '\n' != buf[*pos]; i++) {
                   if (i == sizeof(fname) - 1)
                           break;
                   fname[i] = buf[*pos];
                   advance(p, buf, pos);
           }
   
           if (i == 0)
                   texierr(p, "path too short");
           else if ('\n' != buf[*pos])
                   texierr(p, "path too long");
           else if ('/' == fname[0])
                   texierr(p, "no absolute paths");
           fname[i] = '\0';
   
           if (strstr(fname, "../") || strstr(fname, "/.."))
                   texierr(p, "insecure path");
   
           /* Append filename to original name's directory. */
           rc = snprintf(path, sizeof(path), "%s/%s", p->dir, fname);
           if (rc < 0)
                   texierr(p, "couldn't format filename");
           else if ((size_t)rc >= sizeof(path))
                   texierr(p, "path too long");
   
           /* Pump through to parser. */
           parsefile(p, path);
   }
   
   static void
 doitalic(struct texi *p, enum texicmd cmd,  doitalic(struct texi *p, enum texicmd cmd,
         const char *buf, size_t sz, size_t *pos)          const char *buf, size_t sz, size_t *pos)
 {  {
Line 745  dosymbol(struct texi *p, enum texicmd cmd, 
Line 878  dosymbol(struct texi *p, enum texicmd cmd, 
         case (TEXICMD_COPYRIGHT):          case (TEXICMD_COPYRIGHT):
                 texiputchars(p, "\\(co");                  texiputchars(p, "\\(co");
                 break;                  break;
           case (TEXICMD_DOTS):
                   texiputchars(p, "...");
                   break;
         case (TEXICMD_LATEX):          case (TEXICMD_LATEX):
                 texiputchars(p, "LaTeX");                  texiputchars(p, "LaTeX");
                 break;                  break;
Line 835  dosection(struct texi *p, enum texicmd cmd, 
Line 971  dosection(struct texi *p, enum texicmd cmd, 
                 advanceeoln(p, buf, sz, pos);                  advanceeoln(p, buf, sz, pos);
                 return;                  return;
         }          }
         while (*pos < sz && ' ' == buf[*pos])          while (*pos < sz && isws(buf[*pos]) )
                 advance(p, buf, pos);                  advance(p, buf, pos);
         texifputs(p, ".Ss ");          texifputs(p, ".Ss ");
         while (*pos < sz && '\n' != buf[*pos]) {          while (*pos < sz && '\n' != buf[*pos]) {
Line 854  dosh(struct texi *p, enum texicmd cmd, 
Line 990  dosh(struct texi *p, enum texicmd cmd, 
                 advanceeoln(p, buf, sz, pos);                  advanceeoln(p, buf, sz, pos);
                 return;                  return;
         }          }
         while (*pos < sz && ' ' == buf[*pos])          while (*pos < sz && isws(buf[*pos]))
                 advance(p, buf, pos);                  advance(p, buf, pos);
         texifputs(p, ".Sh ");          texifputs(p, ".Sh ");
         while (*pos < sz && '\n' != buf[*pos]) {          while (*pos < sz && '\n' != buf[*pos]) {
Line 887  doitem(struct texi *p, enum texicmd cmd, 
Line 1023  doitem(struct texi *p, enum texicmd cmd, 
   
         /* See if we have arguments... */          /* See if we have arguments... */
         for (end = *pos; end < sz; end++)          for (end = *pos; end < sz; end++)
                 if (' ' != buf[end] && '\t' != buf[end])                  if ( ! isws(buf[end]))
                         break;                          break;
   
         /* If we have arguments, print them too. */          /* If we have arguments, print them too. */
Line 914  dotable(struct texi *p, enum texicmd cmd, 
Line 1050  dotable(struct texi *p, enum texicmd cmd, 
 }  }
   
 static void  static void
   doenumerate(struct texi *p, enum texicmd cmd,
           const char *buf, size_t sz, size_t *pos)
   {
   
           teximacro(p, ".Bl -enum");
           parseto(p, buf, sz, pos, "enumerate");
           teximacro(p, ".El");
   }
   
   static void
 doitemize(struct texi *p, enum texicmd cmd,  doitemize(struct texi *p, enum texicmd cmd,
         const char *buf, size_t sz, size_t *pos)          const char *buf, size_t sz, size_t *pos)
 {  {
Line 944  doignline(struct texi *p, enum texicmd cmd, 
Line 1090  doignline(struct texi *p, enum texicmd cmd, 
                 advance(p, buf, pos);                  advance(p, buf, pos);
 }  }
   
 static int  
 parsefile(struct texi *p, const char *fname)  
 {  
         struct texifile  *f;  
         int               fd;  
         struct stat       st;  
   
         assert(p->filepos < 64);  
         f = &p->files[p->filepos];  
         memset(f, 0, sizeof(struct texifile));  
   
         f->name = fname;  
         if (-1 == (fd = open(fname, O_RDONLY, 0))) {  
                 texifatal(p, fname);  
         } else if (-1 == fstat(fd, &st)) {  
                 close(fd);  
                 texifatal(p, fname);  
         }  
   
         f->mapsz = st.st_size;  
         f->map = mmap(NULL, f->mapsz,  
                 PROT_READ, MAP_SHARED, fd, 0);  
         close(fd);  
   
         if (MAP_FAILED == f->map) {  
                 texifatal(p, fname);  
                 return(0);  
         }  
   
         p->filepos++;  
         parseeof(p, f->map, f->mapsz);  
         texifilepop(p);  
         return(1);  
 }  
   
 int  int
 main(int argc, char *argv[])  main(int argc, char *argv[])
 {  {
         struct texi      texi;          struct texi      texi;
         int              c, rc;          int              c;
           char            *path, *dir;
         const char      *progname;          const char      *progname;
   
         progname = strrchr(argv[0], '/');          progname = strrchr(argv[0], '/');
Line 1002  main(int argc, char *argv[])
Line 1114  main(int argc, char *argv[])
         if (0 == (argc -= optind))          if (0 == (argc -= optind))
                 goto usage;                  goto usage;
   
           if (NULL == (path = strdup(argv[0]))) {
                   perror(NULL);
                   exit(EXIT_FAILURE);
           } else if (NULL == (dir = dirname(path))) {
                   perror(argv[0]);
                   free(path);
                   exit(EXIT_FAILURE);
           }
           free(path);
   
         memset(&texi, 0, sizeof(struct texi));          memset(&texi, 0, sizeof(struct texi));
         texi.flags = TEXI_HEADER;          texi.flags = TEXI_HEADER;
         rc = parsefile(&texi, argv[0]);          texi.dir = strdup(dir);
         return(rc ? EXIT_SUCCESS : EXIT_FAILURE);          parsefile(&texi, argv[0]);
           texiexit(&texi);
           return(EXIT_FAILURE);
 usage:  usage:
         fprintf(stderr, "usage: %s file\n", progname);          fprintf(stderr, "usage: %s file\n", progname);
         return(EXIT_FAILURE);          return(EXIT_FAILURE);

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

CVSweb