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

Diff for /mandoc/Attic/xml.c between version 1.9 and 1.10

version 1.9, 2008/12/02 18:26:57 version 1.10, 2008/12/03 14:39:59
Line 16 
Line 16 
  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR   * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.   * PERFORMANCE OF THIS SOFTWARE.
  */   */
 #include <sys/param.h>  
   
 #include <assert.h>  
 #include <ctype.h>  
 #include <err.h>  
 #include <stdio.h>  
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
   
 #include "libmdocml.h"  #include "libmdocml.h"
 #include "private.h"  #include "private.h"
   #include "ml.h"
   
 #define COLUMNS          72  
   
 enum    md_ns {  static  ssize_t         xml_endtag(struct md_mbuf *,
         MD_NS_BLOCK,                                  const struct md_args *,
         MD_NS_INLINE,                                  enum md_ns, int);
         MD_NS_DEFAULT  static  ssize_t         xml_begintag(struct md_mbuf *,
 };                                  const struct md_args *,
                                   enum md_ns, int,
                                   const int *, const char **);
   
 enum    md_tok {  static ssize_t
         MD_BLKIN,               /* Controls spacing. */  xml_begintag(struct md_mbuf *mbuf, const struct md_args *args,
         MD_BLKOUT,                  enum md_ns ns, int tok,
         MD_IN,                  const int *argc, const char **argv)
         MD_OUT,  
         MD_TEXT  
 };  
   
 struct  md_xml {  
         const struct md_args    *args;  
         const struct md_rbuf    *rbuf;  
   
         struct md_mbuf  *mbuf;  
         struct rofftree *tree;  
         size_t           indent;  
         size_t           pos;  
         enum md_tok      last;  
         int              flags;  
 #define MD_LITERAL      (1 << 0) /* TODO */  
 #define MD_OVERRIDE_ONE (1 << 1)  
 #define MD_OVERRIDE_ALL (1 << 2)  
 };  
   
 static  void             roffmsg(void *arg, enum roffmsg,  
                                 const char *, const char *, char *);  
 static  int              roffhead(void *);  
 static  int              rofftail(void *);  
 static  int              roffin(void *, int, int *, char **);  
 static  int              roffdata(void *, int, char *);  
 static  int              roffout(void *, int);  
 static  int              roffblkin(void *, int, int *, char **);  
 static  int              roffblkout(void *, int);  
 static  int              roffspecial(void *, int, int *, char **, char **);  
   
 static  void             mbuf_mode(struct md_xml *, enum md_ns);  
 static  int              mbuf_newline(struct md_xml *);  
 static  int              xml_indent(struct md_xml *);  
 static  int              mbuf_data(struct md_xml *, int, char *);  
 static  int              xml_nputstring(struct md_xml *,  
                                 const char *, size_t);  
 static  int              xml_puts(struct md_xml *, const char *);  
 static  int              xml_nputs(struct md_xml *,  
                                 const char *, size_t);  
 static  int              xml_begintag(struct md_xml *, const char *,  
                                 enum md_ns, int *, char **);  
 static  int              xml_endtag(struct md_xml *,  
                                 const char *, enum md_ns);  
   
 #ifdef __linux__ /* FIXME: remove */  
 static  size_t            strlcat(char *, const char *, size_t);  
 static  size_t            strlcpy(char *, const char *, size_t);  
 #endif  
   
   
 static void  
 mbuf_mode(struct md_xml *p, enum md_ns ns)  
 {  {
         p->flags &= ~MD_OVERRIDE_ONE;  
         p->last = ns;  
 }  
   
   
 static int  
 xml_begintag(struct md_xml *p, const char *name, enum md_ns ns,  
                 int *argc, char **argv)  
 {  
         char             buf[64];  
         ssize_t          sz;  
         size_t           res;          size_t           res;
   
           res = 0;
   
         switch (ns) {          switch (ns) {
         case (MD_NS_BLOCK):          case (MD_NS_BLOCK):
                 res = strlcpy(buf, "block:", sizeof(buf));                  if ( ! ml_nputs(mbuf, "block:", 6, &res))
                 assert(res < sizeof(buf));                          return(-1);
                 break;                  break;
         case (MD_NS_INLINE):          case (MD_NS_INLINE):
                 res = strlcpy(buf, "inline:", sizeof(buf));                  if ( ! ml_nputs(mbuf, "inline:", 7, &res))
                 assert(res < sizeof(buf));                          return(-1);
                 break;                  break;
         default:          default:
                 *buf = 0;                  if ( ! ml_nputs(mbuf, "mbuf", 4, &res))
                 break;                          return(-1);
                   return((ssize_t)res);
         }          }
   
         res = strlcat(buf, name, sizeof(buf));          if ( ! ml_nputs(mbuf, toknames[tok],
         assert(res < sizeof(buf));                                  strlen(toknames[tok]), &res))
                   return(-1);
   
         if (-1 == (sz = ml_begintag(p->mbuf, buf, argc, argv)))          return((ssize_t)res);
                 return(0);  
   
         p->pos += sz;  
         return(1);  
 }  }
   
   
 static int  static ssize_t
 xml_endtag(struct md_xml *p, const char *name, enum md_ns ns)  xml_endtag(struct md_mbuf *mbuf, const struct md_args *args,
                   enum md_ns ns, int tok)
 {  {
         char             buf[64];  
         ssize_t          sz;  
         size_t           res;          size_t           res;
   
           res = 0;
   
         switch (ns) {          switch (ns) {
         case (MD_NS_BLOCK):          case (MD_NS_BLOCK):
                 res = strlcpy(buf, "block:", sizeof(buf));                  if ( ! ml_nputs(mbuf, "block:", 6, &res))
                 assert(res < sizeof(buf));                          return(-1);
                 break;                  break;
         case (MD_NS_INLINE):          case (MD_NS_INLINE):
                 res = strlcpy(buf, "inline:", sizeof(buf));                  if ( ! ml_nputs(mbuf, "inline:", 7, &res))
                 assert(res < sizeof(buf));                          return(-1);
                 break;                  break;
         default:          default:
                 *buf = 0;                  if ( ! ml_nputs(mbuf, "mbuf", 4, &res))
                 break;                          return(-1);
                   return((ssize_t)res);
         }          }
   
         res = strlcat(buf, name, sizeof(buf));          if ( ! ml_nputs(mbuf, toknames[tok],
         assert(res < sizeof(buf));                                  strlen(toknames[tok]), &res))
                   return(-1);
   
         if (-1 == (sz = ml_endtag(p->mbuf, buf)))          return((ssize_t)res);
                 return(0);  
   
         p->pos += sz;  
         return(1);  
 }  }
   
   
 static int  
 xml_nputstring(struct md_xml *p, const char *buf, size_t sz)  
 {  
         ssize_t          res;  
   
         if (-1 == (res = ml_nputstring(p->mbuf, buf, sz)))  
                 return(0);  
         p->pos += res;  
         return(1);  
 }  
   
   
 static int  
 xml_nputs(struct md_xml *p, const char *buf, size_t sz)  
 {  
         ssize_t          res;  
   
         if (-1 == (res = ml_nputs(p->mbuf, buf, sz)))  
                 return(0);  
         p->pos += res;  
         return(1);  
 }  
   
   
 static int  
 xml_puts(struct md_xml *p, const char *buf)  
 {  
   
         return(xml_nputs(p, buf, strlen(buf)));  
 }  
   
   
 static int  
 xml_indent(struct md_xml *p)  
 {  
         ssize_t          res;  
   
         if (-1 == (res = ml_indent(p->mbuf, p->indent)))  
                 return(0);  
         p->pos += res;  
         return(1);  
 }  
   
   
 static int  
 mbuf_newline(struct md_xml *p)  
 {  
   
         if ( ! md_buf_putchar(p->mbuf, '\n'))  
                 return(0);  
   
         p->pos = 0;  
         return(1);  
 }  
   
   
 static int  
 mbuf_data(struct md_xml *p, int space, char *buf)  
 {  
         size_t           sz;  
         char            *bufp;  
   
         assert(p->mbuf);  
         assert(0 != p->indent);  
   
         if (MD_OVERRIDE_ONE & p->flags || MD_OVERRIDE_ALL & p->flags)  
                 space = 0;  
   
         if (MD_LITERAL & p->flags)  
                 return(xml_nputstring(p, buf, sizeof(buf)));  
   
         while (*buf) {  
                 while (*buf && isspace(*buf))  
                         buf++;  
   
                 if (0 == *buf)  
                         break;  
   
                 bufp = buf;  
                 while (*buf && ! isspace(*buf))  
                         buf++;  
   
                 if (0 != *buf)  
                         *buf++ = 0;  
   
                 sz = strlen(bufp);  
   
                 if (0 == p->pos) {  
                         if ( ! xml_indent(p))  
                                 return(0);  
                         if ( ! xml_nputstring(p, bufp, sz))  
                                 return(0);  
                         if (p->indent * MAXINDENT + sz >= COLUMNS)  
                                 if ( ! mbuf_newline(p))  
                                         return(0);  
                         if ( ! (MD_OVERRIDE_ALL & p->flags))  
                                 space = 1;  
                         continue;  
                 }  
   
                 if (space && sz + p->pos >= COLUMNS) {  
                         if ( ! mbuf_newline(p))  
                                 return(0);  
                         if ( ! xml_indent(p))  
                                 return(0);  
                 } else if (space) {  
                         if ( ! xml_nputs(p, " ", 1))  
                                 return(0);  
                 }  
   
                 if ( ! xml_nputstring(p, bufp, sz))  
                         return(0);  
   
                 if ( ! (MD_OVERRIDE_ALL & p->flags))  
                         space = 1;  
         }  
   
         return(1);  
 }  
   
   
 int  int
 md_line_xml(void *arg, char *buf)  md_line_xml(void *data, char *buf)
 {  {
         struct md_xml   *p;  
   
         p = (struct md_xml *)arg;          return(mlg_line((struct md_mlg *)data, buf));
         return(roff_engine(p->tree, buf));  
 }  }
   
   
 int  int
 md_exit_xml(void *data, int flush)  md_exit_xml(void *data, int flush)
 {  {
         int              c;  
         struct md_xml   *p;  
   
         p = (struct md_xml *)data;          return(mlg_exit((struct md_mlg *)data, flush));
         c = roff_free(p->tree, flush);  
         free(p);  
   
         return(c);  
 }  }
   
   
Line 312  void *
Line 115  void *
 md_init_xml(const struct md_args *args,  md_init_xml(const struct md_args *args,
                 struct md_mbuf *mbuf, const struct md_rbuf *rbuf)                  struct md_mbuf *mbuf, const struct md_rbuf *rbuf)
 {  {
         struct roffcb    cb;  
         struct md_xml   *p;  
   
         cb.roffhead = roffhead;          return(mlg_alloc(args, rbuf, mbuf, xml_begintag, xml_endtag));
         cb.rofftail = rofftail;  
         cb.roffin = roffin;  
         cb.roffout = roffout;  
         cb.roffblkin = roffblkin;  
         cb.roffblkout = roffblkout;  
         cb.roffspecial = roffspecial;  
         cb.roffmsg = roffmsg;  
         cb.roffdata = roffdata;  
   
         if (NULL == (p = calloc(1, sizeof(struct md_xml))))  
                 err(1, "malloc");  
   
         p->args = args;  
         p->mbuf = mbuf;  
         p->rbuf = rbuf;  
   
         assert(mbuf);  
   
         if (NULL == (p->tree = roff_alloc(&cb, p))) {  
                 free(p);  
                 return(NULL);  
         }  
   
         return(p);  
 }  }
   
   
 /* ARGSUSED */  
 static int  
 roffhead(void *arg)  
 {  
         struct md_xml   *p;  
   
         assert(arg);  
         p = (struct md_xml *)arg;  
   
         if (-1 == xml_puts(p, "<?xml version=\"1.0\" "  
                                 "encoding=\"UTF-8\"?>\n"))  
                 return(0);  
         if (-1 == xml_puts(p, "<mdoc xmlns:block=\"block\" "  
                                 "xmlns:special=\"special\" "  
                                 "xmlns:inline=\"inline\">"))  
                 return(0);  
   
         p->indent++;  
         mbuf_mode(p, MD_BLKIN);  
         return(mbuf_newline(p));  
 }  
   
   
 static int  
 rofftail(void *arg)  
 {  
         struct md_xml   *p;  
   
         assert(arg);  
         p = (struct md_xml *)arg;  
   
         if (0 != p->pos && ! mbuf_newline(p))  
                 return(0);  
   
         mbuf_mode(p, MD_BLKOUT);  
         if ( ! xml_endtag(p, "mdoc", MD_NS_DEFAULT))  
                 return(0);  
         return(mbuf_newline(p));  
 }  
   
   
 /* ARGSUSED */  
 static int  
 roffspecial(void *arg, int tok, int *argc, char **argv, char **more)  
 {  
         struct md_xml   *p;  
   
         assert(arg);  
         p = (struct md_xml *)arg;  
   
         /* FIXME: this is completely ad hoc. */  
   
         switch (tok) {  
         case (ROFF_Ns):  
                 p->flags |= MD_OVERRIDE_ONE;  
                 break;  
         case (ROFF_Sm):  
                 assert(*more);  
                 if (0 == strcmp(*more, "on"))  
                         p->flags |= MD_OVERRIDE_ALL;  
                 else  
                         p->flags &= ~MD_OVERRIDE_ALL;  
                 break;  
         default:  
                 break;  
         }  
   
         return(1);  
 }  
   
   
 static int  
 roffblkin(void *arg, int tok, int *argc, char **argv)  
 {  
         struct md_xml   *p;  
   
         assert(arg);  
         p = (struct md_xml *)arg;  
   
         if (0 != p->pos) {  
                 if ( ! mbuf_newline(p))  
                         return(0);  
                 if ( ! xml_indent(p))  
                         return(0);  
         } else if ( ! xml_indent(p))  
                 return(0);  
   
         /* FIXME: xml won't like standards args (e.g., p1003.1-90). */  
   
         p->indent++;  
         mbuf_mode(p, MD_BLKIN);  
   
         if ( ! xml_begintag(p, toknames[tok], MD_NS_BLOCK,  
                                 argc, argv))  
                 return(0);  
         return(mbuf_newline(p));  
 }  
   
   
 static int  
 roffblkout(void *arg, int tok)  
 {  
         struct md_xml   *p;  
   
         assert(arg);  
         p = (struct md_xml *)arg;  
   
         p->indent--;  
   
         if (0 != p->pos) {  
                 if ( ! mbuf_newline(p))  
                         return(0);  
                 if ( ! xml_indent(p))  
                         return(0);  
         } else if ( ! xml_indent(p))  
                 return(0);  
   
         mbuf_mode(p, MD_BLKOUT);  
         if ( ! xml_endtag(p, toknames[tok], MD_NS_BLOCK))  
                 return(0);  
         return(mbuf_newline(p));  
 }  
   
   
 static int  
 roffin(void *arg, int tok, int *argc, char **argv)  
 {  
         struct md_xml   *p;  
   
         assert(arg);  
         p = (struct md_xml *)arg;  
   
         if ( ! (MD_OVERRIDE_ONE & p->flags) &&  
                         ! (MD_OVERRIDE_ALL & p->flags) &&  
                         p->pos + 11 > COLUMNS)  
                 if ( ! mbuf_newline(p))  
                         return(0);  
   
         if (0 != p->pos && (MD_TEXT == p->last || MD_OUT == p->last)  
                         && ! (MD_OVERRIDE_ONE & p->flags)  
                         && ! (MD_OVERRIDE_ALL & p->flags))  
                 if ( ! xml_nputs(p, " ", 1))  
                         return(0);  
   
         if (0 == p->pos && ! xml_indent(p))  
                 return(0);  
   
         mbuf_mode(p, MD_IN);  
         return(xml_begintag(p, toknames[tok],  
                                 MD_NS_INLINE, argc, argv));  
 }  
   
   
 static int  
 roffout(void *arg, int tok)  
 {  
         struct md_xml   *p;  
   
         assert(arg);  
         p = (struct md_xml *)arg;  
   
         if (0 == p->pos && ! xml_indent(p))  
                 return(0);  
   
         mbuf_mode(p, MD_OUT);  
         return(xml_endtag(p, toknames[tok], MD_NS_INLINE));  
 }  
   
   
 static void  
 roffmsg(void *arg, enum roffmsg lvl,  
                 const char *buf, const char *pos, char *msg)  
 {  
         char            *level;  
         struct md_xml   *p;  
   
         assert(arg);  
         p = (struct md_xml *)arg;  
   
         switch (lvl) {  
         case (ROFF_WARN):  
                 if ( ! (MD_WARN_ALL & p->args->warnings))  
                         return;  
                 level = "warning";  
                 break;  
         case (ROFF_ERROR):  
                 level = "error";  
                 break;  
         default:  
                 abort();  
         }  
   
         if (pos)  
                 (void)fprintf(stderr, "%s:%zu: %s: %s (column %zu)\n",  
                                 p->rbuf->name, p->rbuf->line, level,  
                                 msg, pos - buf);  
         else  
                 (void)fprintf(stderr, "%s: %s: %s\n",  
                                 p->rbuf->name, level, msg);  
   
 }  
   
   
 static int  
 roffdata(void *arg, int space, char *buf)  
 {  
         struct md_xml   *p;  
   
         assert(arg);  
         p = (struct md_xml *)arg;  
         if ( ! mbuf_data(p, space, buf))  
                 return(0);  
   
         mbuf_mode(p, MD_TEXT);  
         return(1);  
 }  
   
   
 #ifdef __linux /* FIXME: remove. */  
 /*      $OpenBSD$       */  
   
 /*  
  * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>  
  *  
  * Permission to use, copy, modify, and distribute this software for any  
  * purpose with or without fee is hereby granted, provided that the  
  * above copyright notice and this permission notice appear in all  
  * copies.  
  *  
  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL  
  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED  
  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE  
  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL  
  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR  
  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER  
  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR  
  * PERFORMANCE OF THIS SOFTWARE.  
  */  
 static size_t  
 strlcat(char *dst, const char *src, size_t siz)  
 {  
         char *d = dst;  
         const char *s = src;  
         size_t n = siz;  
         size_t dlen;  
   
         /* Find the end of dst and adjust bytes left but don't go past  
          * end */  
         while (n-- != 0 && *d != '\0')  
                 d++;  
         dlen = d - dst;  
         n = siz - dlen;  
   
         if (n == 0)  
                 return(dlen + strlen(s));  
         while (*s != '\0') {  
                 if (n != 1) {  
                         *d++ = *s;  
                         n--;  
                 }  
                 s++;  
         }  
         *d = '\0';  
   
         return(dlen + (s - src));       /* count does not include NUL */  
 }  
   
   
 static size_t  
 strlcpy(char *dst, const char *src, size_t siz)  
 {  
         char *d = dst;  
         const char *s = src;  
         size_t n = siz;  
   
         /* Copy as many bytes as will fit */  
         if (n != 0) {  
                 while (--n != 0) {  
                         if ((*d++ = *s++) == '\0')  
                                 break;  
                 }  
         }  
   
         /* Not enough room in dst, add NUL and traverse rest of src */  
         if (n == 0) {  
                 if (siz != 0)  
                         *d = '\0';              /* NUL-terminate dst */  
                 while (*s++)  
                         ;  
         }  
   
         return(s - src - 1);    /* count does not include NUL */  
 }  
 #endif /*__linux__*/  

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.10

CVSweb