]> git.wh0rd.org Git - fontconfig.git/commitdiff
Add func doc creation program edit-sgml
authorKeith Packard <keithp@keithp.com>
Fri, 7 Mar 2003 06:17:36 +0000 (06:17 +0000)
committerKeith Packard <keithp@keithp.com>
Fri, 7 Mar 2003 06:17:36 +0000 (06:17 +0000)
doc/edit-sgml.c [new file with mode: 0644]

diff --git a/doc/edit-sgml.c b/doc/edit-sgml.c
new file mode 100644 (file)
index 0000000..6e04e1c
--- /dev/null
@@ -0,0 +1,426 @@
+/*
+ * $Id$
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+typedef enum { False, True } Bool;
+
+typedef struct {
+    char    *buf;
+    int            size;
+    int            len;
+} String;
+
+#define STRING_INIT 128
+
+void *
+New (int size)
+{
+    void    *m = malloc (size);
+    if (!m)
+       abort ();
+    return m;
+}
+
+void *
+Reallocate (void *p, int size)
+{
+    void    *r = realloc (p, size);
+
+    if (!r)
+       abort ();
+    return r;
+}
+
+void
+Dispose (void *p)
+{
+    free (p);
+}
+
+String *
+StringNew (void)
+{
+    String  *s;
+
+    s = New (sizeof (String));
+    s->buf = New (STRING_INIT);
+    s->size = STRING_INIT - 1;
+    s->buf[0] = '\0';
+    s->len = 0;
+    return s;
+}
+
+void
+StringAdd (String *s, char c)
+{
+    if (s->len == s->size)
+       s->buf = Reallocate (s->buf, (s->size *= 2) + 1);
+    s->buf[s->len++] = c;
+    s->buf[s->len] = '\0';
+}
+
+void
+StringAddString (String *s, char *buf)
+{
+    while (*buf)
+       StringAdd (s, *buf++);
+}
+
+String *
+StringMake (char *buf)
+{
+    String  *s = StringNew ();
+    StringAddString (s, buf);
+    return s;
+}
+
+void
+StringDel (String *s)
+{
+    if (s->len)
+       s->buf[--s->len] = '\0';
+}
+
+void
+StringPut (FILE *f, String *s)
+{
+    char    *b = s->buf;
+
+    while (*b)
+       putc (*b++, f);
+}
+
+#define StringLast(s)  ((s)->len ? (s)->buf[(s)->len - 1] : '\0')
+
+void
+StringDispose (String *s)
+{
+    Dispose (s->buf);
+    Dispose (s);
+}
+
+typedef struct {
+    String  *tag;
+    String  *text;
+} Replace;
+
+Replace *
+ReplaceNew (void)
+{
+    Replace *r = New (sizeof (Replace));
+    r->tag = StringNew ();
+    r->text = StringNew ();
+    return r;
+}
+
+void
+ReplaceDispose (Replace *r)
+{
+    StringDispose (r->tag);
+    StringDispose (r->text);
+    Dispose (r);
+}
+
+Replace *
+ReplaceRead (FILE *f)
+{
+    int            c;
+    Replace *r;
+
+    while ((c = getc (f)) != '@')
+    {
+       if (c == EOF)
+           return 0;
+    }
+    r = ReplaceNew();
+    while ((c = getc (f)) != '@')
+    {
+       if (c == EOF)
+       {
+           ReplaceDispose (r);
+           return 0;
+       }
+       StringAdd (r->tag, c);
+    }
+    if (r->tag->buf[0] == '\0')
+    {
+       ReplaceDispose (r);
+       return 0;
+    }
+    while (isspace ((c = getc (f))))
+       ;
+    ungetc (c, f);
+    while ((c = getc (f)) != '@' && c != EOF)
+       StringAdd (r->text, c);
+    if (c == '@')
+       ungetc (c, f);
+    while (StringLast (r->text) == '\n')
+       StringDel (r->text);
+    return r;
+}
+
+typedef struct _replaceList {
+    struct _replaceList        *next;
+    Replace            *r;
+} ReplaceList;
+
+ReplaceList *
+ReplaceListNew (Replace *r, ReplaceList *next)
+{
+    ReplaceList        *l = New (sizeof (ReplaceList));
+    l->r = r;
+    l->next = next;
+    return l;
+}
+
+void
+ReplaceListDispose (ReplaceList *l)
+{
+    if (l)
+    {
+       ReplaceListDispose (l->next);
+       ReplaceDispose (l->r);
+       Dispose (l);
+    }
+}
+
+typedef struct {
+    ReplaceList        *head;
+} ReplaceSet;
+
+ReplaceSet *
+ReplaceSetNew (void)
+{
+    ReplaceSet *s = New (sizeof (ReplaceSet));
+    s->head = 0;
+    return s;
+}
+
+void
+ReplaceSetDispose (ReplaceSet *s)
+{
+    ReplaceListDispose (s->head);
+    Dispose (s);
+}
+
+void
+ReplaceSetAdd (ReplaceSet *s, Replace *r)
+{
+    s->head = ReplaceListNew (r, s->head);
+}
+
+Replace *
+ReplaceSetFind (ReplaceSet *s, char *tag)
+{
+    ReplaceList        *l;
+
+    for (l = s->head; l; l = l->next)
+       if (!strcmp (tag, l->r->tag->buf))
+           return l->r;
+    return 0;
+}
+
+ReplaceSet *
+ReplaceSetRead (FILE *f)
+{
+    ReplaceSet *s = ReplaceSetNew ();
+    Replace    *r;
+
+    while ((r = ReplaceRead (f)))
+    {
+       while (ReplaceSetFind (s, r->tag->buf))
+           StringAdd (r->tag, '+');
+       ReplaceSetAdd (s, r);
+    }
+    if (!s->head)
+    {
+       ReplaceSetDispose (s);
+       s = 0;
+    }
+    return s;
+}
+
+typedef struct _skipStack {
+    struct _skipStack  *prev;
+    int                        skipping;
+} SkipStack;
+
+SkipStack *
+SkipStackPush (SkipStack *prev, int skipping)
+{
+    SkipStack  *ss = New (sizeof (SkipStack));
+    ss->prev = prev;
+    ss->skipping = skipping;
+    return ss;
+}
+
+SkipStack *
+SkipStackPop (SkipStack *prev)
+{
+    SkipStack  *ss = prev->prev;
+    Dispose (prev);
+    return ss;
+}
+
+typedef struct _loopStack {
+    struct _loopStack  *prev;
+    String             *tag;
+    String             *extra;
+    long               pos;
+} LoopStack;
+
+LoopStack *
+LoopStackPush (LoopStack *prev, FILE *f, char *tag)
+{
+    LoopStack  *ls = New (sizeof (LoopStack));
+    ls->prev = prev;
+    ls->tag = StringMake (tag);
+    ls->extra = StringNew ();
+    ls->pos = ftell (f);
+    return ls;
+}
+
+LoopStack *
+LoopStackLoop (ReplaceSet *rs, LoopStack *ls, FILE *f)
+{
+    String     *s = StringMake (ls->tag->buf);
+    LoopStack  *ret = ls;
+    Bool       loop;
+
+    StringAdd (ls->extra, '+');
+    StringAddString (s, ls->extra->buf);
+    loop = ReplaceSetFind (rs, s->buf) != 0;
+    StringDispose (s);
+    if (loop)
+       fseek (f, ls->pos, SEEK_SET);
+    else
+    {
+       ret = ls->prev;
+       StringDispose (ls->tag);
+       StringDispose (ls->extra);
+       Dispose (ls);
+    }
+    return ret;
+}
+
+void
+LineSkip (FILE *f)
+{
+    int        c;
+
+    while ((c = getc (f)) == '\n')
+       ;
+    ungetc (c, f);
+}
+
+void
+DoReplace (FILE *f, ReplaceSet *s)
+{
+    int                c;
+    String     *tag;
+    Replace    *r;
+    SkipStack  *ss = 0;
+    LoopStack  *ls = 0;
+    int                skipping = 0;
+
+    while ((c = getc (f)) != EOF)
+    {
+       if (c == '@')
+       {
+           tag = StringNew ();
+           while ((c = getc (f)) != '@')
+           {
+               if (c == EOF)
+                   abort ();
+               StringAdd (tag, c);
+           }
+           if (ls)
+               StringAddString (tag, ls->extra->buf);
+           switch (tag->buf[0]) {
+           case '?':
+               ss = SkipStackPush (ss, skipping);
+               if (!ReplaceSetFind (s, tag->buf + 1))
+                   skipping++;
+               LineSkip (f);
+               break;
+           case ':':
+               if (!ss)
+                   abort ();
+               if (ss->skipping == skipping)
+                   ++skipping;
+               else
+                   --skipping;
+               LineSkip (f);
+               break;
+           case ';':
+               skipping = ss->skipping;
+               ss = SkipStackPop (ss);
+               LineSkip (f);
+               break;
+           case '{':
+               ls = LoopStackPush (ls, f, tag->buf + 1);
+               LineSkip (f);
+               break;
+           case '}':
+               ls = LoopStackLoop (s, ls, f);
+               LineSkip (f);
+               break;
+           default:
+               r = ReplaceSetFind (s, tag->buf);
+               if (r && !skipping)
+                   StringPut (stdout, r->text);
+               break;
+           }
+           StringDispose (tag);
+       }
+       else if (!skipping)
+           putchar (c);
+    }
+}
+
+int
+main (int argc, char **argv)
+{
+    FILE       *f;
+    ReplaceSet *s;
+
+    f = fopen (argv[1], "r");
+    if (!f)
+    {
+       perror (argv[1]);
+       exit (1);
+    }
+    while ((s = ReplaceSetRead (stdin)))
+    {
+       DoReplace (f, s);
+       ReplaceSetDispose (s);
+       rewind (f);
+    }
+    if (ferror (stdout))
+       exit (1);
+    exit (0);
+}