/*
- * $Id$
+ * fontconfig/doc/edit-sgml.c
*
- * Copyright © 2003 Keith Packard
+ * 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
* 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,
+ * THE AUTHOR(S) 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
+ * EVENT SHALL THE AUTHOR(S) 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
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <ctype.h>
+static void *
+New (int size);
+
+static void *
+Reallocate (void *p, int size);
+
+static void
+Dispose (void *p);
+
typedef enum { False, True } Bool;
typedef struct {
int len;
} String;
+static String *
+StringNew (void);
+
+static void
+StringAdd (String *s, char c);
+
+static void
+StringAddString (String *s, char *buf);
+
+static String *
+StringMake (char *buf);
+
+static void
+StringDel (String *s);
+
+static void
+StringPut (FILE *f, String *s);
+
+static void
+StringDispose (String *s);
+
+typedef struct {
+ String *tag;
+ String *text;
+} Replace;
+
+static Replace *
+ReplaceNew (void);
+
+static void
+ReplaceDispose (Replace *r);
+
+static void
+Bail (const char *format, int line, const char *arg);
+
+static Replace *
+ReplaceRead (FILE *f, int *linep);
+
+typedef struct _replaceList {
+ struct _replaceList *next;
+ Replace *r;
+} ReplaceList;
+
+static ReplaceList *
+ReplaceListNew (Replace *r, ReplaceList *next);
+
+static void
+ReplaceListDispose (ReplaceList *l);
+
+typedef struct {
+ ReplaceList *head;
+} ReplaceSet;
+
+static ReplaceSet *
+ReplaceSetNew (void);
+
+static void
+ReplaceSetDispose (ReplaceSet *s);
+
+static void
+ReplaceSetAdd (ReplaceSet *s, Replace *r);
+
+static Replace *
+ReplaceSetFind (ReplaceSet *s, char *tag);
+
+static ReplaceSet *
+ReplaceSetRead (FILE *f, int *linep);
+
+typedef struct _skipStack {
+ struct _skipStack *prev;
+ int skipping;
+} SkipStack;
+
+static SkipStack *
+SkipStackPush (SkipStack *prev, int skipping);
+
+static SkipStack *
+SkipStackPop (SkipStack *prev);
+
+typedef struct _loopStack {
+ struct _loopStack *prev;
+ String *tag;
+ String *extra;
+ long pos;
+} LoopStack;
+
+static LoopStack *
+LoopStackPush (LoopStack *prev, FILE *f, char *tag);
+
+static LoopStack *
+LoopStackLoop (ReplaceSet *rs, LoopStack *ls, FILE *f);
+
+static void
+LineSkip (FILE *f, int *linep);
+
+static void
+DoReplace (FILE *f, int *linep, ReplaceSet *s);
+
#define STRING_INIT 128
-void *
+static void *
New (int size)
{
void *m = malloc (size);
return m;
}
-void *
+static void *
Reallocate (void *p, int size)
{
void *r = realloc (p, size);
return r;
}
-void
+static void
Dispose (void *p)
{
free (p);
}
-String *
+static String *
StringNew (void)
{
String *s;
return s;
}
-void
+static void
StringAdd (String *s, char c)
{
if (s->len == s->size)
s->buf[s->len] = '\0';
}
-void
+static void
StringAddString (String *s, char *buf)
{
while (*buf)
StringAdd (s, *buf++);
}
-String *
+static String *
StringMake (char *buf)
{
String *s = StringNew ();
return s;
}
-void
+static void
StringDel (String *s)
{
if (s->len)
s->buf[--s->len] = '\0';
}
-void
+static void
StringPut (FILE *f, String *s)
{
char *b = s->buf;
#define StringLast(s) ((s)->len ? (s)->buf[(s)->len - 1] : '\0')
-void
+static void
StringDispose (String *s)
{
Dispose (s->buf);
Dispose (s);
}
-typedef struct {
- String *tag;
- String *text;
-} Replace;
-
-Replace *
+static Replace *
ReplaceNew (void)
{
Replace *r = New (sizeof (Replace));
return r;
}
-void
+static void
ReplaceDispose (Replace *r)
{
StringDispose (r->tag);
Dispose (r);
}
-void
-Bail (char *format, char *arg)
+static void
+Bail (const char *format, int line, const char *arg)
{
fprintf (stderr, "fatal: ");
- fprintf (stderr, format, arg);
+ fprintf (stderr, format, line, arg);
fprintf (stderr, "\n");
exit (1);
}
-Replace *
-ReplaceRead (FILE *f)
+static int
+Getc (FILE *f, int *linep)
+{
+ int c = getc (f);
+ if (c == '\n')
+ ++(*linep);
+ return c;
+}
+
+static void
+Ungetc (int c, FILE *f, int *linep)
+{
+ if (c == '\n')
+ --(*linep);
+ ungetc (c, f);
+}
+
+static Replace *
+ReplaceRead (FILE *f, int *linep)
{
int c;
Replace *r;
- while ((c = getc (f)) != '@')
+ while ((c = Getc (f, linep)) != '@')
{
if (c == EOF)
return 0;
}
r = ReplaceNew();
- while ((c = getc (f)) != '@')
+ while ((c = Getc (f, linep)) != '@')
{
if (c == EOF)
{
return 0;
}
if (isspace (c))
- Bail ("invalid character after tag %s", r->tag->buf);
+ Bail ("%d: invalid character after tag %s", *linep, r->tag->buf);
StringAdd (r->tag, c);
}
if (r->tag->buf[0] == '\0')
ReplaceDispose (r);
return 0;
}
- while (isspace ((c = getc (f))))
+ while (isspace ((c = Getc (f, linep))))
;
- ungetc (c, f);
- while ((c = getc (f)) != '@' && c != EOF)
+ Ungetc (c, f, linep);
+ while ((c = Getc (f, linep)) != '@' && c != EOF)
StringAdd (r->text, c);
if (c == '@')
- ungetc (c, f);
- while (StringLast (r->text) == '\n')
+ Ungetc (c, f, linep);
+ while (isspace (StringLast (r->text)))
StringDel (r->text);
+ if (StringLast(r->text) == '%')
+ {
+ StringDel (r->text);
+ StringAdd (r->text, ' ');
+ }
return r;
}
-typedef struct _replaceList {
- struct _replaceList *next;
- Replace *r;
-} ReplaceList;
-
-ReplaceList *
+static ReplaceList *
ReplaceListNew (Replace *r, ReplaceList *next)
{
ReplaceList *l = New (sizeof (ReplaceList));
return l;
}
-void
+static void
ReplaceListDispose (ReplaceList *l)
{
if (l)
}
}
-typedef struct {
- ReplaceList *head;
-} ReplaceSet;
-
-ReplaceSet *
+static ReplaceSet *
ReplaceSetNew (void)
{
ReplaceSet *s = New (sizeof (ReplaceSet));
return s;
}
-void
+static void
ReplaceSetDispose (ReplaceSet *s)
{
ReplaceListDispose (s->head);
Dispose (s);
}
-void
+static void
ReplaceSetAdd (ReplaceSet *s, Replace *r)
{
s->head = ReplaceListNew (r, s->head);
}
-Replace *
+static Replace *
ReplaceSetFind (ReplaceSet *s, char *tag)
{
ReplaceList *l;
return 0;
}
-ReplaceSet *
-ReplaceSetRead (FILE *f)
+static ReplaceSet *
+ReplaceSetRead (FILE *f, int *linep)
{
ReplaceSet *s = ReplaceSetNew ();
Replace *r;
- while ((r = ReplaceRead (f)))
+ while ((r = ReplaceRead (f, linep)))
{
while (ReplaceSetFind (s, r->tag->buf))
StringAdd (r->tag, '+');
return s;
}
-typedef struct _skipStack {
- struct _skipStack *prev;
- int skipping;
-} SkipStack;
-
-SkipStack *
+static SkipStack *
SkipStackPush (SkipStack *prev, int skipping)
{
SkipStack *ss = New (sizeof (SkipStack));
return ss;
}
-SkipStack *
+static SkipStack *
SkipStackPop (SkipStack *prev)
{
SkipStack *ss = prev->prev;
return ss;
}
-typedef struct _loopStack {
- struct _loopStack *prev;
- String *tag;
- String *extra;
- long pos;
-} LoopStack;
-
-LoopStack *
+static LoopStack *
LoopStackPush (LoopStack *prev, FILE *f, char *tag)
{
LoopStack *ls = New (sizeof (LoopStack));
return ls;
}
-LoopStack *
+static LoopStack *
LoopStackLoop (ReplaceSet *rs, LoopStack *ls, FILE *f)
{
String *s = StringMake (ls->tag->buf);
return ret;
}
-void
-LineSkip (FILE *f)
+static void
+LineSkip (FILE *f, int *linep)
{
int c;
- while ((c = getc (f)) == '\n')
+ while ((c = Getc (f, linep)) == '\n')
;
- ungetc (c, f);
+ Ungetc (c, f, linep);
}
-void
-DoReplace (FILE *f, ReplaceSet *s)
+static void
+DoReplace (FILE *f, int *linep, ReplaceSet *s)
{
int c;
String *tag;
LoopStack *ls = 0;
int skipping = 0;
- while ((c = getc (f)) != EOF)
+ while ((c = Getc (f, linep)) != EOF)
{
if (c == '@')
{
tag = StringNew ();
- while ((c = getc (f)) != '@')
+ while ((c = Getc (f, linep)) != '@')
{
if (c == EOF)
abort ();
ss = SkipStackPush (ss, skipping);
if (!ReplaceSetFind (s, tag->buf + 1))
skipping++;
- LineSkip (f);
+ LineSkip (f, linep);
break;
case ':':
if (!ss)
++skipping;
else
--skipping;
- LineSkip (f);
+ LineSkip (f, linep);
break;
case ';':
skipping = ss->skipping;
ss = SkipStackPop (ss);
- LineSkip (f);
+ LineSkip (f, linep);
break;
case '{':
ls = LoopStackPush (ls, f, tag->buf + 1);
- LineSkip (f);
+ LineSkip (f, linep);
break;
case '}':
ls = LoopStackLoop (s, ls, f);
- LineSkip (f);
+ LineSkip (f, linep);
break;
default:
r = ReplaceSetFind (s, tag->buf);
{
FILE *f;
ReplaceSet *s;
+ int iline, oline;
if (!argv[1])
- Bail ("usage: %s <template.sgml>", argv[0]);
+ Bail ("usage: %*s <template.sgml>", 0, argv[0]);
f = fopen (argv[1], "r");
if (!f)
{
- Bail ("can't open file %s", argv[1]);
+ Bail ("can't open file %s", 0, argv[1]);
exit (1);
}
- while ((s = ReplaceSetRead (stdin)))
+ iline = 1;
+ while ((s = ReplaceSetRead (stdin, &iline)))
{
- DoReplace (f, s);
+ oline = 1;
+ DoReplace (f, &oline, s);
ReplaceSetDispose (s);
rewind (f);
}
if (ferror (stdout))
- Bail ("%s", "error writing output");
+ Bail ("%s", 0, "error writing output");
exit (0);
}