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

Diff for /docbook2mdoc/docbook2mdoc.c between version 1.6 and 1.8

version 1.6, 2014/03/28 10:08:24 version 1.8, 2014/03/28 12:11:18
Line 24 
Line 24 
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
   #include <unistd.h>
   
 /*  /*
  * All recognised node types.   * All recognised node types.
Line 58  enum nodeid {
Line 59  enum nodeid {
         NODE_REFPURPOSE,          NODE_REFPURPOSE,
         NODE_REFSECT1,          NODE_REFSECT1,
         NODE_REFSYNOPSISDIV,          NODE_REFSYNOPSISDIV,
           NODE_STRUCTNAME,
         NODE_SYNOPSIS,          NODE_SYNOPSIS,
         NODE_TEXT,          NODE_TEXT,
         NODE_TITLE,          NODE_TITLE,
Line 73  struct parse {
Line 75  struct parse {
         int              stop; /* should we stop now? */          int              stop; /* should we stop now? */
         struct pnode    *root; /* root of parse tree */          struct pnode    *root; /* root of parse tree */
         struct pnode    *cur; /* current node in tree */          struct pnode    *cur; /* current node in tree */
         unsigned int     flags;          char            *b; /* nil-terminated buffer for pre-print */
 #define PARSE_HAS_META   1          size_t           bsz; /* current length of b */
         char            *b;          size_t           mbsz; /* max bsz allocation */
         size_t           bsz;  
         size_t           mbsz;  
 };  };
   
 struct  node {  struct  node {
         const char      *name;          const char      *name; /* docbook element name */
         unsigned int     flags;          unsigned int     flags;
 #define NODE_IGNTEXT     1 /* ignore all contained text */  #define NODE_IGNTEXT     1 /* ignore all contained text */
 };  };
Line 126  static const struct node nodes[NODE__MAX] = {
Line 126  static const struct node nodes[NODE__MAX] = {
         { "refpurpose", 0 },          { "refpurpose", 0 },
         { "refsect1", 0 },          { "refsect1", 0 },
         { "refsynopsisdiv", NODE_IGNTEXT },          { "refsynopsisdiv", NODE_IGNTEXT },
           { "structname", 0 },
         { "synopsis", 0 },          { "synopsis", 0 },
         { NULL, 0 },          { NULL, 0 },
         { "title", 0 },          { "title", 0 },
Line 133  static const struct node nodes[NODE__MAX] = {
Line 134  static const struct node nodes[NODE__MAX] = {
   
 /*  /*
  * Look up whether "parent" is a valid parent for "node".   * Look up whether "parent" is a valid parent for "node".
    * This is sucked directly from the DocBook specification: look at the
    * "children" and "parent" sections of each node.
  */   */
 static int  static int
 isparent(enum nodeid node, enum nodeid parent)  isparent(enum nodeid node, enum nodeid parent)
Line 336  isparent(enum nodeid node, enum nodeid parent)
Line 339  isparent(enum nodeid node, enum nodeid parent)
                 return(parent == NODE_REFENTRY);                  return(parent == NODE_REFENTRY);
         case (NODE_REFSYNOPSISDIV):          case (NODE_REFSYNOPSISDIV):
                 return(parent == NODE_REFENTRY);                  return(parent == NODE_REFENTRY);
           case (NODE_STRUCTNAME):
                   switch (parent) {
                   case (NODE_CODE):
                   case (NODE_FUNCSYNOPSISINFO):
                   case (NODE_FUNCTION):
                   case (NODE_OPTION):
                   case (NODE_PARA):
                   case (NODE_PARAMETER):
                   case (NODE_PROGRAMLISTING):
                   case (NODE_REFDESCRIPTOR):
                   case (NODE_REFENTRYTITLE):
                   case (NODE_REFNAME):
                   case (NODE_REFPURPOSE):
                   case (NODE_SYNOPSIS):
                   case (NODE_TITLE):
                           return(1);
                   default:
                           break;
                   }
                   return(0);
         case (NODE_SYNOPSIS):          case (NODE_SYNOPSIS):
                 switch (parent) {                  switch (parent) {
                 case (NODE_REFSYNOPSISDIV):                  case (NODE_REFSYNOPSISDIV):
Line 364  isparent(enum nodeid node, enum nodeid parent)
Line 387  isparent(enum nodeid node, enum nodeid parent)
         return(0);          return(0);
 }  }
   
   /*
    * Process a stream of characters.
    * We store text as nodes in and of themselves.
    * If a text node is already open, append to it.
    * If it's not open, open one under the current context.
    */
 static void  static void
 xml_char(void *arg, const XML_Char *p, int sz)  xml_char(void *arg, const XML_Char *p, int sz)
 {  {
Line 424  xml_char(void *arg, const XML_Char *p, int sz)
Line 453  xml_char(void *arg, const XML_Char *p, int sz)
  * Begin an element.   * Begin an element.
  * First, look for the element.   * First, look for the element.
  * If we don't find it and we're not parsing, keep going.   * If we don't find it and we're not parsing, keep going.
  * If we don't find it (and we're parsing), puke and exit.   * If we don't find it and we're parsing, puke and exit.
  * If we find it but we're not parsing yet (i.e., it's not a refentry   * If we find it but we're not parsing yet (i.e., it's not a refentry
  * and thus out of context), keep going.   * and thus out of context), keep going.
  * If we're at the root and already have a tree, puke and exit.   * If we find it and we're at the root and already have a tree, puke and
    * exit (FIXME: I don't think this is right?).
    * If we find it but we're parsing a text node, close out the text node,
    * return to its parent, and keep going.
  * Make sure that the element is in the right context.   * Make sure that the element is in the right context.
  * Lastly, put the node onto our parse tree and continue.   * Lastly, put the node onto our parse tree and continue.
  */   */
Line 455  xml_elem_start(void *arg, const XML_Char *name, const 
Line 487  xml_elem_start(void *arg, const XML_Char *name, const 
                 else if (0 == strcmp(nodes[node].name, name))                  else if (0 == strcmp(nodes[node].name, name))
                         break;                          break;
   
           /* FIXME: do more with these error messages... */
         if (NODE__MAX == node && NODE_ROOT == ps->node) {          if (NODE__MAX == node && NODE_ROOT == ps->node) {
                 fprintf(stderr, "%s: ignoring node\n", name);                  fprintf(stderr, "%s: ignoring node\n", name);
                 return;                  return;
Line 494  xml_elem_start(void *arg, const XML_Char *name, const 
Line 527  xml_elem_start(void *arg, const XML_Char *name, const 
   
 /*  /*
  * Roll up the parse tree.   * Roll up the parse tree.
  * Does nothing else special.   * If we're at a text node, roll that one up first.
  * If we hit the root, then assign ourselves as the NODE_ROOT.   * If we hit the root, then assign ourselves as the NODE_ROOT.
  */   */
 static void  static void
Line 519  xml_elem_end(void *arg, const XML_Char *name)
Line 552  xml_elem_end(void *arg, const XML_Char *name)
                 ps->node = ps->cur->node;                  ps->node = ps->cur->node;
 }  }
   
   /*
    * Recursively free a node (NULL is ok).
    */
 static void  static void
 pnode_free(struct pnode *pn)  pnode_free(struct pnode *pn)
 {  {
Line 536  pnode_free(struct pnode *pn)
Line 572  pnode_free(struct pnode *pn)
         free(pn);          free(pn);
 }  }
   
   /*
    * Unlink a node from its parent and pnode_free() it.
    */
 static void  static void
 pnode_unlink(struct pnode *pn)  pnode_unlink(struct pnode *pn)
 {  {
Line 545  pnode_unlink(struct pnode *pn)
Line 584  pnode_unlink(struct pnode *pn)
         pnode_free(pn);          pnode_free(pn);
 }  }
   
   /*
    * Unlink all children of a node and pnode_free() them.
    */
 static void  static void
 pnode_unlinksub(struct pnode *pn)  pnode_unlinksub(struct pnode *pn)
 {  {
Line 553  pnode_unlinksub(struct pnode *pn)
Line 595  pnode_unlinksub(struct pnode *pn)
                 pnode_unlink(TAILQ_FIRST(&pn->childq));                  pnode_unlink(TAILQ_FIRST(&pn->childq));
 }  }
   
   /*
    * Reset the lookaside buffer.
    */
 static void  static void
 bufclear(struct parse *p)  bufclear(struct parse *p)
 {  {
Line 560  bufclear(struct parse *p)
Line 605  bufclear(struct parse *p)
         p->b[p->bsz = 0] = '\0';          p->b[p->bsz = 0] = '\0';
 }  }
   
   /*
    * Append NODE_TEXT contents to the current buffer, reallocating its
    * size if necessary.
    * The buffer is ALWAYS nil-terminated.
    */
 static void  static void
 bufappend(struct parse *p, struct pnode *pn)  bufappend(struct parse *p, struct pnode *pn)
 {  {
Line 577  bufappend(struct parse *p, struct pnode *pn)
Line 627  bufappend(struct parse *p, struct pnode *pn)
         p->b[p->bsz] = '\0';          p->b[p->bsz] = '\0';
 }  }
   
   /*
    * Recursively append all NODE_TEXT nodes to the buffer.
    * This descends into non-text nodes, but doesn't do anything beyond
    * them.
    * In other words, this is a recursive text grok.
    */
 static void  static void
 bufappend_r(struct parse *p, struct pnode *pn)  bufappend_r(struct parse *p, struct pnode *pn)
 {  {
Line 589  bufappend_r(struct parse *p, struct pnode *pn)
Line 645  bufappend_r(struct parse *p, struct pnode *pn)
 }  }
   
 /*  /*
  * Print text presumably on a macro line.   * Recursively print text presumably on a macro line.
  * Ignore any child macros.  
  * Convert all whitespace to regular spaces.   * Convert all whitespace to regular spaces.
  */   */
 static void  static void
Line 639  pnode_printmacroline(struct parse *p, struct pnode *pn
Line 694  pnode_printmacroline(struct parse *p, struct pnode *pn
         putchar('\n');          putchar('\n');
 }  }
   
   /*
    * Start the SYNOPSIS macro, unlinking its [superfluous] title.
    */
 static void  static void
 pnode_printrefsynopsisdiv(struct parse *p, struct pnode *pn)  pnode_printrefsynopsisdiv(struct parse *p, struct pnode *pn)
 {  {
Line 653  pnode_printrefsynopsisdiv(struct parse *p, struct pnod
Line 711  pnode_printrefsynopsisdiv(struct parse *p, struct pnod
         puts(".Sh SYNOPSIS");          puts(".Sh SYNOPSIS");
 }  }
   
   /*
    * Start a hopefully-named `Sh' section.
    */
 static void  static void
 pnode_printrefsect(struct parse *p, struct pnode *pn)  pnode_printrefsect(struct parse *p, struct pnode *pn)
 {  {
Line 671  pnode_printrefsect(struct parse *p, struct pnode *pn)
Line 732  pnode_printrefsect(struct parse *p, struct pnode *pn)
                 puts("UNKNOWN");                  puts("UNKNOWN");
 }  }
   
   /*
    * Start a reference, extracting the title and volume.
    */
 static void  static void
 pnode_printciterefentry(struct parse *p, struct pnode *pn)  pnode_printciterefentry(struct parse *p, struct pnode *pn)
 {  {
Line 713  pnode_printrefmeta(struct parse *p, struct pnode *pn)
Line 777  pnode_printrefmeta(struct parse *p, struct pnode *pn)
         fputs(".Dt ", stdout);          fputs(".Dt ", stdout);
   
         if (NULL != title) {          if (NULL != title) {
                   /* FIXME: uppercase. */
                 pnode_printmacrolinepart(p, title);                  pnode_printmacrolinepart(p, title);
                 putchar(' ');                  putchar(' ');
         } else          } else
Line 821  pnode_printarg(struct parse *p, struct pnode *pn, int 
Line 886  pnode_printarg(struct parse *p, struct pnode *pn, int 
                 puts("");                  puts("");
 }  }
   
   /*
    * Recursively search and return the first instance of "node".
    */
   static struct pnode *
   pnode_findfirst(struct pnode *pn, enum nodeid node)
   {
           struct pnode    *pp, *res;
   
           res = NULL;
           TAILQ_FOREACH(pp, &pn->childq, child) {
                   res = pp->node == node ? pp :
                           pnode_findfirst(pp, node);
                   if (NULL != res)
                           break;
           }
   
           return(res);
   }
   
   static void
   pnode_printprologue(struct parse *p, struct pnode *pn)
   {
           struct pnode    *pp;
   
           if (NULL != (pp = pnode_findfirst(p->root, NODE_REFMETA))) {
                   pnode_printrefmeta(p, pp);
                   pnode_unlink(pp);
           } else {
                   puts(".\\\" Supplying bogus prologue...");
                   puts(".Dd $Mdocdate" "$");
                   puts(".Dt UNKNOWN 1");
                   puts(".Os");
           }
   }
   
 /*  /*
  * Print a parsed node (or ignore it--whatever).   * Print a parsed node (or ignore it--whatever).
  * This is a recursive function.   * This is a recursive function.
Line 886  pnode_print(struct parse *p, struct pnode *pn)
Line 986  pnode_print(struct parse *p, struct pnode *pn)
                 puts(".Bd -literal");                  puts(".Bd -literal");
                 break;                  break;
         case (NODE_REFMETA):          case (NODE_REFMETA):
                 pnode_printrefmeta(p, pn);                  abort();
                 pnode_unlinksub(pn);  
                 p->flags |= PARSE_HAS_META;  
                 break;                  break;
         case (NODE_REFNAME):          case (NODE_REFNAME):
                 fputs(".Nm ", stdout);                  fputs(".Nm ", stdout);
Line 896  pnode_print(struct parse *p, struct pnode *pn)
Line 994  pnode_print(struct parse *p, struct pnode *pn)
                 pnode_unlinksub(pn);                  pnode_unlinksub(pn);
                 return;                  return;
         case (NODE_REFNAMEDIV):          case (NODE_REFNAMEDIV):
                 if ( ! (PARSE_HAS_META & p->flags)) {  
                         puts(".Dd $Mdocdate" "$");  
                         puts(".Dt UNKNOWN 1");  
                         puts(".Os");  
                 }  
                 puts(".Sh NAME");                  puts(".Sh NAME");
                 break;                  break;
         case (NODE_REFPURPOSE):          case (NODE_REFPURPOSE):
Line 914  pnode_print(struct parse *p, struct pnode *pn)
Line 1007  pnode_print(struct parse *p, struct pnode *pn)
         case (NODE_REFSECT1):          case (NODE_REFSECT1):
                 pnode_printrefsect(p, pn);                  pnode_printrefsect(p, pn);
                 break;                  break;
           case (NODE_STRUCTNAME):
                   fputs(".Vt ", stdout);
                   pnode_printmacroline(p, pn);
                   pnode_unlinksub(pn);
                   return;
         case (NODE_TEXT):          case (NODE_TEXT):
                 bufclear(p);                  bufclear(p);
                 bufappend(p, pn);                  bufappend(p, pn);
Line 988  readfile(XML_Parser xp, int fd, 
Line 1086  readfile(XML_Parser xp, int fd, 
                  * Exit when we've read all or errors have occured                   * Exit when we've read all or errors have occured
                  * during the parse sequence.                   * during the parse sequence.
                  */                   */
                   pnode_printprologue(&p, p.root);
                 pnode_print(&p, p.root);                  pnode_print(&p, p.root);
                 pnode_free(p.root);                  pnode_free(p.root);
                 free(p.b);                  free(p.b);

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

CVSweb