]>
git.wh0rd.org - fontconfig.git/blob - doc/edit-sgml.c
2 * fontconfig/doc/edit-sgml.c
4 * Copyright © 2003 Keith Packard
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of Keith Packard not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission. Keith Packard makes no
13 * representations about the suitability of this software for any purpose. It
14 * is provided "as is" without express or implied warranty.
16 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
34 Reallocate (void *p
, int size
);
39 typedef enum { False
, True
} Bool
;
51 StringAdd (String
*s
, char c
);
54 StringAddString (String
*s
, char *buf
);
57 StringMake (char *buf
);
60 StringDel (String
*s
);
63 StringPut (FILE *f
, String
*s
);
66 StringDispose (String
*s
);
77 ReplaceDispose (Replace
*r
);
80 Bail (const char *format
, int line
, const char *arg
);
83 ReplaceRead (FILE *f
, int *linep
);
85 typedef struct _replaceList
{
86 struct _replaceList
*next
;
91 ReplaceListNew (Replace
*r
, ReplaceList
*next
);
94 ReplaceListDispose (ReplaceList
*l
);
101 ReplaceSetNew (void);
104 ReplaceSetDispose (ReplaceSet
*s
);
107 ReplaceSetAdd (ReplaceSet
*s
, Replace
*r
);
110 ReplaceSetFind (ReplaceSet
*s
, char *tag
);
113 ReplaceSetRead (FILE *f
, int *linep
);
115 typedef struct _skipStack
{
116 struct _skipStack
*prev
;
121 SkipStackPush (SkipStack
*prev
, int skipping
);
124 SkipStackPop (SkipStack
*prev
);
126 typedef struct _loopStack
{
127 struct _loopStack
*prev
;
134 LoopStackPush (LoopStack
*prev
, FILE *f
, char *tag
);
137 LoopStackLoop (ReplaceSet
*rs
, LoopStack
*ls
, FILE *f
);
140 LineSkip (FILE *f
, int *linep
);
143 DoReplace (FILE *f
, int *linep
, ReplaceSet
*s
);
145 #define STRING_INIT 128
150 void *m
= malloc (size
);
157 Reallocate (void *p
, int size
)
159 void *r
= realloc (p
, size
);
177 s
= New (sizeof (String
));
178 s
->buf
= New (STRING_INIT
);
179 s
->size
= STRING_INIT
- 1;
186 StringAdd (String
*s
, char c
)
188 if (s
->len
== s
->size
)
189 s
->buf
= Reallocate (s
->buf
, (s
->size
*= 2) + 1);
190 s
->buf
[s
->len
++] = c
;
191 s
->buf
[s
->len
] = '\0';
195 StringAddString (String
*s
, char *buf
)
198 StringAdd (s
, *buf
++);
202 StringMake (char *buf
)
204 String
*s
= StringNew ();
205 StringAddString (s
, buf
);
210 StringDel (String
*s
)
213 s
->buf
[--s
->len
] = '\0';
217 StringPut (FILE *f
, String
*s
)
225 #define StringLast(s) ((s)->len ? (s)->buf[(s)->len - 1] : '\0')
228 StringDispose (String
*s
)
237 Replace
*r
= New (sizeof (Replace
));
238 r
->tag
= StringNew ();
239 r
->text
= StringNew ();
244 ReplaceDispose (Replace
*r
)
246 StringDispose (r
->tag
);
247 StringDispose (r
->text
);
252 Bail (const char *format
, int line
, const char *arg
)
254 fprintf (stderr
, "fatal: ");
255 fprintf (stderr
, format
, line
, arg
);
256 fprintf (stderr
, "\n");
261 Getc (FILE *f
, int *linep
)
270 Ungetc (int c
, FILE *f
, int *linep
)
278 ReplaceRead (FILE *f
, int *linep
)
283 while ((c
= Getc (f
, linep
)) != '@')
289 while ((c
= Getc (f
, linep
)) != '@')
297 Bail ("%d: invalid character after tag %s", *linep
, r
->tag
->buf
);
298 StringAdd (r
->tag
, c
);
300 if (r
->tag
->buf
[0] == '\0')
305 while (isspace ((c
= Getc (f
, linep
))))
307 Ungetc (c
, f
, linep
);
308 while ((c
= Getc (f
, linep
)) != '@' && c
!= EOF
)
309 StringAdd (r
->text
, c
);
311 Ungetc (c
, f
, linep
);
312 while (isspace (StringLast (r
->text
)))
314 if (StringLast(r
->text
) == '%')
317 StringAdd (r
->text
, ' ');
323 ReplaceListNew (Replace
*r
, ReplaceList
*next
)
325 ReplaceList
*l
= New (sizeof (ReplaceList
));
332 ReplaceListDispose (ReplaceList
*l
)
336 ReplaceListDispose (l
->next
);
337 ReplaceDispose (l
->r
);
345 ReplaceSet
*s
= New (sizeof (ReplaceSet
));
351 ReplaceSetDispose (ReplaceSet
*s
)
353 ReplaceListDispose (s
->head
);
358 ReplaceSetAdd (ReplaceSet
*s
, Replace
*r
)
360 s
->head
= ReplaceListNew (r
, s
->head
);
364 ReplaceSetFind (ReplaceSet
*s
, char *tag
)
368 for (l
= s
->head
; l
; l
= l
->next
)
369 if (!strcmp (tag
, l
->r
->tag
->buf
))
375 ReplaceSetRead (FILE *f
, int *linep
)
377 ReplaceSet
*s
= ReplaceSetNew ();
380 while ((r
= ReplaceRead (f
, linep
)))
382 while (ReplaceSetFind (s
, r
->tag
->buf
))
383 StringAdd (r
->tag
, '+');
384 ReplaceSetAdd (s
, r
);
388 ReplaceSetDispose (s
);
395 SkipStackPush (SkipStack
*prev
, int skipping
)
397 SkipStack
*ss
= New (sizeof (SkipStack
));
399 ss
->skipping
= skipping
;
404 SkipStackPop (SkipStack
*prev
)
406 SkipStack
*ss
= prev
->prev
;
412 LoopStackPush (LoopStack
*prev
, FILE *f
, char *tag
)
414 LoopStack
*ls
= New (sizeof (LoopStack
));
416 ls
->tag
= StringMake (tag
);
417 ls
->extra
= StringNew ();
423 LoopStackLoop (ReplaceSet
*rs
, LoopStack
*ls
, FILE *f
)
425 String
*s
= StringMake (ls
->tag
->buf
);
429 StringAdd (ls
->extra
, '+');
430 StringAddString (s
, ls
->extra
->buf
);
431 loop
= ReplaceSetFind (rs
, s
->buf
) != 0;
434 fseek (f
, ls
->pos
, SEEK_SET
);
438 StringDispose (ls
->tag
);
439 StringDispose (ls
->extra
);
446 LineSkip (FILE *f
, int *linep
)
450 while ((c
= Getc (f
, linep
)) == '\n')
452 Ungetc (c
, f
, linep
);
456 DoReplace (FILE *f
, int *linep
, ReplaceSet
*s
)
465 while ((c
= Getc (f
, linep
)) != EOF
)
470 while ((c
= Getc (f
, linep
)) != '@')
477 StringAddString (tag
, ls
->extra
->buf
);
478 switch (tag
->buf
[0]) {
480 ss
= SkipStackPush (ss
, skipping
);
481 if (!ReplaceSetFind (s
, tag
->buf
+ 1))
488 if (ss
->skipping
== skipping
)
495 skipping
= ss
->skipping
;
496 ss
= SkipStackPop (ss
);
500 ls
= LoopStackPush (ls
, f
, tag
->buf
+ 1);
504 ls
= LoopStackLoop (s
, ls
, f
);
508 r
= ReplaceSetFind (s
, tag
->buf
);
510 StringPut (stdout
, r
->text
);
521 main (int argc
, char **argv
)
528 Bail ("usage: %*s <template.sgml>", 0, argv
[0]);
529 f
= fopen (argv
[1], "r");
532 Bail ("can't open file %s", 0, argv
[1]);
536 while ((s
= ReplaceSetRead (stdin
, &iline
)))
539 DoReplace (f
, &oline
, s
);
540 ReplaceSetDispose (s
);
544 Bail ("%s", 0, "error writing output");