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

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

version 1.2, 2008/11/30 23:05:57 version 1.9, 2008/12/02 18:26:57
Line 28 
Line 28 
 #include "libmdocml.h"  #include "libmdocml.h"
 #include "private.h"  #include "private.h"
   
 #define INDENT           4  #define COLUMNS          72
 #define COLUMNS          60  
   
 #ifdef  __linux__ /* FIXME */  enum    md_ns {
 #define strlcat          strncat          MD_NS_BLOCK,
 #endif          MD_NS_INLINE,
           MD_NS_DEFAULT
   };
   
 enum    md_tok {  enum    md_tok {
         MD_BLKIN,          MD_BLKIN,               /* Controls spacing. */
         MD_BLKOUT,          MD_BLKOUT,
         MD_IN,          MD_IN,
         MD_OUT,          MD_OUT,
Line 53  struct md_xml {
Line 54  struct md_xml {
         size_t           pos;          size_t           pos;
         enum md_tok      last;          enum md_tok      last;
         int              flags;          int              flags;
 #define MD_LITERAL      (1 << 0) /* FIXME */  #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,  static  void             roffmsg(void *arg, enum roffmsg,
Line 65  static int   roffdata(void *, int, char *);
Line 68  static int   roffdata(void *, int, char *);
 static  int              roffout(void *, int);  static  int              roffout(void *, int);
 static  int              roffblkin(void *, int, int *, char **);  static  int              roffblkin(void *, int, int *, char **);
 static  int              roffblkout(void *, int);  static  int              roffblkout(void *, int);
 static  int              roffspecial(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              mbuf_newline(struct md_xml *);
 static  int              mbuf_indent(struct md_xml *);  static  int              xml_indent(struct md_xml *);
 static  int              mbuf_data(struct md_xml *, int, char *);  static  int              mbuf_data(struct md_xml *, int, char *);
 static  int              mbuf_putstring(struct md_xml *,  static  int              xml_nputstring(struct md_xml *,
                                 const char *);  
 static  int              mbuf_nputstring(struct md_xml *,  
                                 const char *, size_t);                                  const char *, size_t);
 static  int              mbuf_puts(struct md_xml *, const char *);  static  int              xml_puts(struct md_xml *, const char *);
 static  int              mbuf_nputs(struct md_xml *,  static  int              xml_nputs(struct md_xml *,
                                 const char *, size_t);                                  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  static int
 mbuf_putstring(struct md_xml *p, const char *buf)  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;
   
         return(mbuf_nputstring(p, buf, strlen(buf)));          switch (ns) {
           case (MD_NS_BLOCK):
                   res = strlcpy(buf, "block:", sizeof(buf));
                   assert(res < sizeof(buf));
                   break;
           case (MD_NS_INLINE):
                   res = strlcpy(buf, "inline:", sizeof(buf));
                   assert(res < sizeof(buf));
                   break;
           default:
                   *buf = 0;
                   break;
           }
   
           res = strlcat(buf, name, sizeof(buf));
           assert(res < sizeof(buf));
   
           if (-1 == (sz = ml_begintag(p->mbuf, buf, argc, argv)))
                   return(0);
   
           p->pos += sz;
           return(1);
 }  }
   
   
 static int  static int
 mbuf_nputstring(struct md_xml *p, const char *buf, size_t sz)  xml_endtag(struct md_xml *p, const char *name, enum md_ns ns)
 {  {
         size_t           i;          char             buf[64];
           ssize_t          sz;
           size_t           res;
   
         for (i = 0; i < sz; i++) {          switch (ns) {
                 switch (buf[i]) {          case (MD_NS_BLOCK):
                 case ('&'):                  res = strlcpy(buf, "block:", sizeof(buf));
                         if ( ! md_buf_puts(p->mbuf, "&amp;", 5))                  assert(res < sizeof(buf));
                                 return(0);                  break;
                         p->pos += 5;          case (MD_NS_INLINE):
                         break;                  res = strlcpy(buf, "inline:", sizeof(buf));
                 case ('"'):                  assert(res < sizeof(buf));
                         if ( ! md_buf_puts(p->mbuf, "&quot;", 6))                  break;
                                 return(0);          default:
                         p->pos += 6;                  *buf = 0;
                         break;                  break;
                 default:  
                         if ( ! md_buf_putchar(p->mbuf, buf[i]))  
                                 return(0);  
                         p->pos++;  
                         break;  
                 }  
         }          }
   
           res = strlcat(buf, name, sizeof(buf));
           assert(res < sizeof(buf));
   
           if (-1 == (sz = ml_endtag(p->mbuf, buf)))
                   return(0);
   
           p->pos += sz;
         return(1);          return(1);
 }  }
   
   
 static int  static int
 mbuf_nputs(struct md_xml *p, const char *buf, size_t sz)  xml_nputstring(struct md_xml *p, const char *buf, size_t sz)
 {  {
           ssize_t          res;
   
         p->pos += sz;          if (-1 == (res = ml_nputstring(p->mbuf, buf, sz)))
         return(md_buf_puts(p->mbuf, buf, sz));                  return(0);
           p->pos += res;
           return(1);
 }  }
   
   
 static int  static int
 mbuf_puts(struct md_xml *p, const char *buf)  xml_nputs(struct md_xml *p, const char *buf, size_t sz)
 {  {
           ssize_t          res;
   
         return(mbuf_nputs(p, buf, strlen(buf)));          if (-1 == (res = ml_nputs(p->mbuf, buf, sz)))
                   return(0);
           p->pos += res;
           return(1);
 }  }
   
   
 static int  static int
 mbuf_indent(struct md_xml *p)  xml_puts(struct md_xml *p, const char *buf)
 {  {
         size_t           i;  
   
         assert(p->pos == 0);          return(xml_nputs(p, buf, strlen(buf)));
   }
   
         /* LINTED */  
         for (i = 0; i < MIN(p->indent, INDENT); i++)  
                 if ( ! md_buf_putstring(p->mbuf, "    "))  
                         return(0);  
   
         p->pos += i * INDENT;  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);          return(1);
 }  }
   
Line 170  mbuf_data(struct md_xml *p, int space, char *buf)
Line 228  mbuf_data(struct md_xml *p, int space, char *buf)
         assert(p->mbuf);          assert(p->mbuf);
         assert(0 != p->indent);          assert(0 != p->indent);
   
           if (MD_OVERRIDE_ONE & p->flags || MD_OVERRIDE_ALL & p->flags)
                   space = 0;
   
         if (MD_LITERAL & p->flags)          if (MD_LITERAL & p->flags)
                 return(mbuf_putstring(p, buf));                  return(xml_nputstring(p, buf, sizeof(buf)));
   
         while (*buf) {          while (*buf) {
                 while (*buf && isspace(*buf))                  while (*buf && isspace(*buf))
Line 190  mbuf_data(struct md_xml *p, int space, char *buf)
Line 251  mbuf_data(struct md_xml *p, int space, char *buf)
                 sz = strlen(bufp);                  sz = strlen(bufp);
   
                 if (0 == p->pos) {                  if (0 == p->pos) {
                         if ( ! mbuf_indent(p))                          if ( ! xml_indent(p))
                                 return(0);                                  return(0);
                         if ( ! mbuf_nputstring(p, bufp, sz))                          if ( ! xml_nputstring(p, bufp, sz))
                                 return(0);                                  return(0);
                         if (p->indent * INDENT + sz >= COLUMNS) {                          if (p->indent * MAXINDENT + sz >= COLUMNS)
                                 if ( ! mbuf_newline(p))                                  if ( ! mbuf_newline(p))
                                         return(0);                                          return(0);
                                 continue;                          if ( ! (MD_OVERRIDE_ALL & p->flags))
                         }                                  space = 1;
                         continue;                          continue;
                 }                  }
   
                 if (space && sz + p->pos >= COLUMNS) {                  if (space && sz + p->pos >= COLUMNS) {
                         if ( ! mbuf_newline(p))                          if ( ! mbuf_newline(p))
                                 return(0);                                  return(0);
                         if ( ! mbuf_indent(p))                          if ( ! xml_indent(p))
                                 return(0);                                  return(0);
                 } else if (space) {                  } else if (space) {
                         if ( ! mbuf_nputs(p, " ", 1))                          if ( ! xml_nputs(p, " ", 1))
                                 return(0);                                  return(0);
                 }                  }
   
                 if ( ! mbuf_nputstring(p, bufp, sz))                  if ( ! xml_nputstring(p, bufp, sz))
                         return(0);                          return(0);
   
                 if ( ! space && p->pos >= COLUMNS)                  if ( ! (MD_OVERRIDE_ALL & p->flags))
                         if ( ! mbuf_newline(p))                          space = 1;
                                 return(0);  
         }          }
   
         return(1);          return(1);
Line 292  roffhead(void *arg)
Line 352  roffhead(void *arg)
         assert(arg);          assert(arg);
         p = (struct md_xml *)arg;          p = (struct md_xml *)arg;
   
         if ( ! mbuf_puts(p, "<?xml version=\"1.0\" "          if (-1 == xml_puts(p, "<?xml version=\"1.0\" "
                                 "encoding=\"UTF-8\"?>\n"))                                  "encoding=\"UTF-8\"?>\n"))
                 return(0);                  return(0);
         if ( ! mbuf_puts(p, "<mdoc xmlns:block=\"block\" "          if (-1 == xml_puts(p, "<mdoc xmlns:block=\"block\" "
                                 "xmlns:special=\"special\" "                                  "xmlns:special=\"special\" "
                                 "xmlns:inline=\"inline\">"))                                  "xmlns:inline=\"inline\">"))
                 return(0);                  return(0);
   
         p->indent++;          p->indent++;
         p->last = MD_BLKIN;          mbuf_mode(p, MD_BLKIN);
         return(mbuf_newline(p));          return(mbuf_newline(p));
 }  }
   
Line 317  rofftail(void *arg)
Line 377  rofftail(void *arg)
         if (0 != p->pos && ! mbuf_newline(p))          if (0 != p->pos && ! mbuf_newline(p))
                 return(0);                  return(0);
   
         if ( ! mbuf_puts(p, "</mdoc>"))          mbuf_mode(p, MD_BLKOUT);
           if ( ! xml_endtag(p, "mdoc", MD_NS_DEFAULT))
                 return(0);                  return(0);
   
         p->last = MD_BLKOUT;  
         return(mbuf_newline(p));          return(mbuf_newline(p));
 }  }
   
   
 /* ARGSUSED */  /* ARGSUSED */
 static int  static int
 roffspecial(void *arg, int tok)  roffspecial(void *arg, int tok, int *argc, char **argv, char **more)
 {  {
           struct md_xml   *p;
   
         /* FIXME */          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);          return(1);
 }  }
   
Line 339  static int
Line 418  static int
 roffblkin(void *arg, int tok, int *argc, char **argv)  roffblkin(void *arg, int tok, int *argc, char **argv)
 {  {
         struct md_xml   *p;          struct md_xml   *p;
         int              i;  
   
         assert(arg);          assert(arg);
         p = (struct md_xml *)arg;          p = (struct md_xml *)arg;
Line 347  roffblkin(void *arg, int tok, int *argc, char **argv)
Line 425  roffblkin(void *arg, int tok, int *argc, char **argv)
         if (0 != p->pos) {          if (0 != p->pos) {
                 if ( ! mbuf_newline(p))                  if ( ! mbuf_newline(p))
                         return(0);                          return(0);
                 if ( ! mbuf_indent(p))                  if ( ! xml_indent(p))
                         return(0);                          return(0);
         } else if ( ! mbuf_indent(p))          } else if ( ! xml_indent(p))
                 return(0);                  return(0);
   
         if ( ! mbuf_nputs(p, "<", 1))  
                 return(0);  
         if ( ! mbuf_nputs(p, "block:", 6))  
                 return(0);  
         if ( ! mbuf_puts(p, toknames[tok]))  
                 return(0);  
   
         /* FIXME: xml won't like standards args (e.g., p1003.1-90). */          /* FIXME: xml won't like standards args (e.g., p1003.1-90). */
   
         for (i = 0; ROFF_ARGMAX != argc[i]; i++) {          p->indent++;
                 if ( ! mbuf_nputs(p, " ", 1))          mbuf_mode(p, MD_BLKIN);
                         return(0);  
                 if ( ! mbuf_puts(p, tokargnames[argc[i]]))  
                         return(0);  
                 if ( ! mbuf_nputs(p, "=\"", 2))  
                         return(0);  
                 if ( ! mbuf_putstring(p, argv[i] ? argv[i] : "true"))  
                         return(0);  
                 if ( ! mbuf_nputs(p, "\"", 1))  
                         return(0);  
         }  
   
         if ( ! mbuf_nputs(p, ">", 1))          if ( ! xml_begintag(p, toknames[tok], MD_NS_BLOCK,
                                   argc, argv))
                 return(0);                  return(0);
   
         p->last = MD_BLKIN;  
         p->indent++;  
         return(mbuf_newline(p));          return(mbuf_newline(p));
 }  }
   
Line 396  roffblkout(void *arg, int tok)
Line 455  roffblkout(void *arg, int tok)
         if (0 != p->pos) {          if (0 != p->pos) {
                 if ( ! mbuf_newline(p))                  if ( ! mbuf_newline(p))
                         return(0);                          return(0);
                 if ( ! mbuf_indent(p))                  if ( ! xml_indent(p))
                         return(0);                          return(0);
         } else if ( ! mbuf_indent(p))          } else if ( ! xml_indent(p))
                 return(0);                  return(0);
   
         if ( ! mbuf_nputs(p, "</", 2))          mbuf_mode(p, MD_BLKOUT);
           if ( ! xml_endtag(p, toknames[tok], MD_NS_BLOCK))
                 return(0);                  return(0);
         if ( ! mbuf_nputs(p, "block:", 6))  
                 return(0);  
         if ( ! mbuf_puts(p, toknames[tok]))  
                 return(0);  
         if ( ! mbuf_nputs(p, ">", 1))  
                 return(0);  
   
         p->last = MD_BLKOUT;  
         return(mbuf_newline(p));          return(mbuf_newline(p));
 }  }
   
Line 419  static int
Line 471  static int
 roffin(void *arg, int tok, int *argc, char **argv)  roffin(void *arg, int tok, int *argc, char **argv)
 {  {
         struct md_xml   *p;          struct md_xml   *p;
         int              i;  
   
         assert(arg);          assert(arg);
         p = (struct md_xml *)arg;          p = (struct md_xml *)arg;
   
         /*          if ( ! (MD_OVERRIDE_ONE & p->flags) &&
          * FIXME: put all of this in a buffer, then check the buffer                          ! (MD_OVERRIDE_ALL & p->flags) &&
          * length versus the column width for nicer output.  This is a                          p->pos + 11 > COLUMNS)
          * bit hacky.  
          */  
   
         if (p->pos + 11 > COLUMNS)  
                 if ( ! mbuf_newline(p))                  if ( ! mbuf_newline(p))
                         return(0);                          return(0);
   
         if (0 != p->pos) {          if (0 != p->pos && (MD_TEXT == p->last || MD_OUT == p->last)
                 switch (p->last) {                          && ! (MD_OVERRIDE_ONE & p->flags)
                 case (MD_TEXT):                          && ! (MD_OVERRIDE_ALL & p->flags))
                         /* FALLTHROUGH */                  if ( ! xml_nputs(p, " ", 1))
                 case (MD_OUT):                          return(0);
                         if ( ! mbuf_nputs(p, " ", 1))  
                                 return(0);  
                         break;  
                 default:  
                         break;  
                 }  
         } else if ( ! mbuf_indent(p))  
                 return(0);  
   
         p->last = MD_IN;          if (0 == p->pos && ! xml_indent(p))
   
         if ( ! mbuf_nputs(p, "<", 1))  
                 return(0);                  return(0);
         if ( ! mbuf_nputs(p, "inline:", 7))  
                 return(0);  
         if ( ! mbuf_puts(p, toknames[tok]))  
                 return(0);  
   
         for (i = 0; ROFF_ARGMAX != argc[i]; i++) {          mbuf_mode(p, MD_IN);
                 if ( ! mbuf_nputs(p, " ", 1))          return(xml_begintag(p, toknames[tok],
                         return(0);                                  MD_NS_INLINE, argc, argv));
                 if ( ! mbuf_puts(p, tokargnames[argc[i]]))  
                         return(0);  
                 if ( ! mbuf_nputs(p, "=\"", 2))  
                         return(0);  
                 if ( ! mbuf_putstring(p, argv[i] ? argv[i] : "true"))  
                         return(0);  
                 if ( ! mbuf_nputs(p, "\"", 1))  
                         return(0);  
         }  
         return(mbuf_nputs(p, ">", 1));  
 }  }
   
   
Line 481  roffout(void *arg, int tok)
Line 504  roffout(void *arg, int tok)
         assert(arg);          assert(arg);
         p = (struct md_xml *)arg;          p = (struct md_xml *)arg;
   
         if (0 == p->pos && ! mbuf_indent(p))          if (0 == p->pos && ! xml_indent(p))
                 return(0);                  return(0);
   
         p->last = MD_OUT;          mbuf_mode(p, MD_OUT);
           return(xml_endtag(p, toknames[tok], MD_NS_INLINE));
         if ( ! mbuf_nputs(p, "</", 2))  
                 return(0);  
         if ( ! mbuf_nputs(p, "inline:", 7))  
                 return(0);  
         if ( ! mbuf_puts(p, toknames[tok]))  
                 return(0);  
         return(mbuf_nputs(p, ">", 1));  
 }  }
   
   
Line 540  roffdata(void *arg, int space, char *buf)
Line 556  roffdata(void *arg, int space, char *buf)
         if ( ! mbuf_data(p, space, buf))          if ( ! mbuf_data(p, space, buf))
                 return(0);                  return(0);
   
         p->last = MD_TEXT;          mbuf_mode(p, MD_TEXT);
         return(1);          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.2  
changed lines
  Added in v.1.9

CVSweb