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

Diff for /docbook2mdoc/parse.c between version 1.23 and 1.28

version 1.23, 2019/04/08 14:37:31 version 1.28, 2019/04/09 13:35:29
Line 17 
Line 17 
  */   */
 #include <assert.h>  #include <assert.h>
 #include <ctype.h>  #include <ctype.h>
   #include <errno.h>
   #include <fcntl.h>
   #include <libgen.h>
 #include <stdarg.h>  #include <stdarg.h>
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
Line 210  static const struct element elements[] = {
Line 213  static const struct element elements[] = {
         { "varname",            NODE_VARNAME },          { "varname",            NODE_VARNAME },
         { "warning",            NODE_WARNING },          { "warning",            NODE_WARNING },
         { "wordasword",         NODE_WORDASWORD },          { "wordasword",         NODE_WORDASWORD },
         { "xi:include",         NODE_DELETE_WARN },          { "xi:include",         NODE_INCLUDE },
         { "year",               NODE_YEAR },          { "year",               NODE_YEAR },
         { NULL,                 NODE_IGNORE }          { NULL,                 NODE_IGNORE }
 };  };
Line 273  static const struct entity entities[] = {
Line 276  static const struct entity entities[] = {
   
 static size_t    parse_string(struct parse *, char *, size_t,  static size_t    parse_string(struct parse *, char *, size_t,
                          enum pstate *, int);                           enum pstate *, int);
   static void      parse_fd(struct parse *, int);
   
   
 static void  static void
Line 405  xml_entity(struct parse *p, const char *name)
Line 409  xml_entity(struct parse *p, const char *name)
                         TAILQ_FOREACH(dat, &p->doctype->childq, child) {                          TAILQ_FOREACH(dat, &p->doctype->childq, child) {
                                 if ((ccp = pnode_getattr_raw(dat,                                  if ((ccp = pnode_getattr_raw(dat,
                                      ATTRKEY_NAME, NULL)) == NULL ||                                       ATTRKEY_NAME, NULL)) == NULL ||
                                     strcmp(ccp, name) != 0 ||                                      strcmp(ccp, name) != 0)
                                     (ccp = pnode_getattr_raw(dat,                                          continue;
                                   if ((ccp = pnode_getattr_raw(dat,
                                       ATTRKEY_SYSTEM, NULL)) != NULL) {
                                           parse_file(p, -1, ccp);
                                           p->flags &= ~PFLAG_SPC;
                                           return;
                                   }
                                   if ((ccp = pnode_getattr_raw(dat,
                                      ATTRKEY_DEFINITION, NULL)) == NULL)                                       ATTRKEY_DEFINITION, NULL)) == NULL)
                                         continue;                                          continue;
                                 if ((cp = strdup(ccp)) == NULL) {                                  if ((cp = strdup(ccp)) == NULL) {
Line 620  xml_attrval(struct parse *ps, const char *name)
Line 631  xml_attrval(struct parse *ps, const char *name)
                 perror(NULL);                  perror(NULL);
                 exit(1);                  exit(1);
         }          }
           ps->flags &= ~PFLAG_ATTR;
 }  }
   
 /*  /*
Line 630  static void
Line 642  static void
 xml_elem_end(struct parse *ps, const char *name)  xml_elem_end(struct parse *ps, const char *name)
 {  {
         const struct element    *elem;          const struct element    *elem;
           struct pnode            *n;
           const char              *cp;
         enum nodeid              node;          enum nodeid              node;
   
         /*          /*
Line 660  xml_elem_end(struct parse *ps, const char *name)
Line 674  xml_elem_end(struct parse *ps, const char *name)
                 break;                  break;
         case NODE_IGNORE:          case NODE_IGNORE:
                 break;                  break;
           case NODE_INCLUDE:
                   n = ps->cur;
                   ps->cur = ps->cur->parent;
                   cp = pnode_getattr_raw(n, ATTRKEY_HREF, NULL);
                   if (cp == NULL)
                           error_msg(ps, "<xi:include> element "
                               "without href attribute");
                   else
                           parse_file(ps, -1, cp);
                   pnode_unlink(n);
                   ps->flags &= ~PFLAG_SPC;
                   break;
         case NODE_DOCTYPE:          case NODE_DOCTYPE:
                 ps->flags &= ~PFLAG_EEND;                  ps->flags &= ~PFLAG_EEND;
                 /* FALLTHROUGH */                  /* FALLTHROUGH */
Line 950  parse_string(struct parse *p, char *b, size_t rlen,
Line 976  parse_string(struct parse *p, char *b, size_t rlen,
                 /* Process text up to the next tag, entity, or EOL. */                  /* Process text up to the next tag, entity, or EOL. */
   
                 } else {                  } else {
                         advance(p, b, rlen, &pend, "<&", refill);                          advance(p, b, rlen, &pend,
                               p->ncur == NODE_DOCTYPE ? "<&]" : "<&",
                               refill);
                         xml_char(p, b + poff, pend - poff);                          xml_char(p, b + poff, pend - poff);
                 }                  }
         }          }
         return poff;          return poff;
 }  }
   
 struct ptree *  
 parse_file(struct parse *p, int fd, const char *fname)  /*
    * The read loop.
    * If the previous token was incomplete and asked for more input,
    * we have to enter the read loop once more even on EOF.
    * Once rsz is 0, incomplete tokens will no longer ask for more input
    * but instead use whatever there is, and then exit the read loop.
    * The minus one on the size limit for read(2) is needed such that
    * advance() can set b[rlen] to NUL when needed.
    */
   static void
   parse_fd(struct parse *p, int fd)
 {  {
         char             b[4096];          char             b[4096];
         ssize_t          rsz;   /* Return value from read(2). */          ssize_t          rsz;   /* Return value from read(2). */
Line 966  parse_file(struct parse *p, int fd, const char *fname)
Line 1004  parse_file(struct parse *p, int fd, const char *fname)
         size_t           poff;  /* Parse offset in b[]. */          size_t           poff;  /* Parse offset in b[]. */
         enum pstate      pstate;          enum pstate      pstate;
   
         p->fname = fname;  
         p->nline = 1;  
         p->ncol = 1;  
         pstate = PARSE_ELEM;  
         rlen = 0;          rlen = 0;
           pstate = PARSE_ELEM;
         /*  
          * Read loop.  
          *  
          * If the previous token was incomplete and asked for more  
          * input, we have to enter the read loop once more even on EOF.  
          * Once rsz is 0, incomplete tokens will no longer ask  
          * for more input but instead use whatever there is,  
          * and then exit the read loop.  
          * The minus one on the size limit for read(2) is needed  
          * such that advance() can set b[rlen] to NUL when needed.  
          */  
   
         while ((rsz = read(fd, b + rlen, sizeof(b) - rlen - 1)) >= 0 &&          while ((rsz = read(fd, b + rlen, sizeof(b) - rlen - 1)) >= 0 &&
             (rlen += rsz) > 0) {              (rlen += rsz) > 0) {
                 poff = parse_string(p, b, rlen, &pstate, rsz > 0);                  poff = parse_string(p, b, rlen, &pstate, rsz > 0);
Line 992  parse_file(struct parse *p, int fd, const char *fname)
Line 1014  parse_file(struct parse *p, int fd, const char *fname)
                 rlen -= poff;                  rlen -= poff;
                 memmove(b, b + poff, rlen);                  memmove(b, b + poff, rlen);
         }          }
         if (rsz < 0) {          if (rsz < 0)
                 perror(fname);                  error_msg(p, "read: %s", strerror(errno));
                 p->tree->flags |= TREE_FAIL;  }
   
   /*
    * Open and parse a file.
    */
   struct ptree *
   parse_file(struct parse *p, int fd, const char *fname)
   {
           const char      *save_fname;
           int              save_line, save_col;
   
           /* Save and initialize reporting data. */
   
           save_fname = p->fname;
           save_line = p->nline;
           save_col = p->ncol;
           p->fname = fname;
           p->line = 0;
           p->col = 0;
   
           /* Open the file, unless it is already open. */
   
           if (fd == -1 && (fd = open(fname, O_RDONLY, 0)) == -1) {
                   error_msg(p, "open: %s", strerror(errno));
                   p->fname = save_fname;
                   return p->tree;
         }          }
         pnode_closetext(p);  
         if ((p->tree->flags & TREE_CLOSED) == 0)          /*
                 warn_msg(p, "document not closed");           * After opening the starting file, change to the directory it
         pnode_unlink(p->doctype);           * is located in, in case it wants to include any further files,
            * which are typically given with relative paths in DocBook.
            * Do this on a best-effort basis; don't complain about failure.
            */
   
           if (save_fname == NULL && (fname = dirname(fname)) != NULL &&
               strcmp(fname, ".") != 0)
                   (void)chdir(fname);
   
           /* Run the read loop. */
   
           p->nline = 1;
           p->ncol = 1;
           parse_fd(p, fd);
   
           /* On the top level, finalize the parse tree. */
   
           if (save_fname == NULL) {
                   pnode_closetext(p);
                   if (p->tree->root == NULL)
                           error_msg(p, "empty document");
                   else if ((p->tree->flags & TREE_CLOSED) == 0)
                           warn_msg(p, "document not closed");
                   pnode_unlink(p->doctype);
           }
   
           /* Clean up. */
   
           if (fd != STDIN_FILENO)
                   close(fd);
           p->fname = save_fname;
           p->nline = save_line;
           p->ncol = save_col;
         return p->tree;          return p->tree;
 }  }

Legend:
Removed from v.1.23  
changed lines
  Added in v.1.28

CVSweb