Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtdocbook / sgmls / sgmlsasp.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: sgmlsasp.c /main/3 1996/06/19 17:18:11 drk $ */
24 /* sgmlsasp.c
25    Translate sgmls output using ASP replacement file.
26
27    Written by James Clark (jjc@jclark.com). */
28
29 #include "sgmlsasp.h"
30 #include "sgmls.h"
31 #include "replace.h"
32 #include "getopt.h"
33
34 /* Non-zero if general (non-entity) names should be folded to upper case. */
35 int fold_general_names = 1;
36
37 static char *program_name;
38 static char last_char = '\n';
39
40 static void output_begin_line P((void));
41 static void output_data P((struct sgmls_data *, int));
42 static void output_pi P((char *, unsigned));
43 static void output_token P((char *));
44 static void output_attribute P((struct sgmls_attribute *));
45 static void output_data_char P((int));
46 static void output_replacement
47   P((struct replacement *, struct sgmls_attribute *));
48 static void do_file P((FILE *, struct replacement_table *));
49 static void usage P((void));
50 static void input_error P((int, char *, unsigned long));
51
52 #define output_char(c) (last_char = (c), putchar(c))
53
54 int main(argc, argv)
55      int argc;
56      char **argv;
57 {
58   struct replacement_table *tablep;
59   int i;
60   int opt;
61   program_name = argv[0];
62
63   while ((opt = getopt(argc, argv, "n")) != EOF)
64     switch (opt) {
65     case 'n':
66       fold_general_names = 0;
67       break;
68     case '?':
69       usage();
70     default:
71       assert(0);
72     }
73   if (argc - optind <= 0)
74     usage();
75   tablep = make_replacement_table();
76   for (i = optind; i < argc; i++)
77     load_replacement_file(tablep, argv[i]);
78   (void)sgmls_set_errhandler(input_error);
79   do_file(stdin, tablep);
80   exit(0);
81 }
82
83 static
84 void usage()
85 {
86   fprintf(stderr, "usage: %s [-n] replacement_file...\n", program_name);
87   exit(1);
88 }
89
90 static
91 void input_error(num, str, lineno)
92      int num;
93      char *str;
94      unsigned long lineno;
95 {
96   error("Error at input line %lu: %s", lineno, str);
97 }
98
99 static
100 void do_file(fp, tablep)
101      FILE *fp;
102      struct replacement_table *tablep;
103 {
104   struct sgmls *sp;
105   struct sgmls_event e;
106
107   sp = sgmls_create(fp);
108   while (sgmls_next(sp, &e))
109     switch (e.type) {
110     case SGMLS_EVENT_DATA:
111       output_data(e.u.data.v, e.u.data.n);
112       break;
113     case SGMLS_EVENT_ENTITY:
114       /* XXX what should we do here? */
115       break;
116     case SGMLS_EVENT_PI:
117       output_pi(e.u.pi.s, e.u.pi.len);
118       break;
119     case SGMLS_EVENT_START:
120       output_replacement(lookup_replacement(tablep,
121                                             START_ELEMENT, e.u.start.gi),
122                          e.u.start.attributes);
123       sgmls_free_attributes(e.u.start.attributes);
124       break;
125     case SGMLS_EVENT_END:
126       output_replacement(lookup_replacement(tablep, END_ELEMENT, e.u.end.gi),
127                          0);
128       break;
129     case SGMLS_EVENT_SUBSTART:
130       break;
131     case SGMLS_EVENT_SUBEND:
132       break;
133     case SGMLS_EVENT_APPINFO:
134       break;
135     case SGMLS_EVENT_CONFORMING:
136       break;
137     default:
138       abort();
139     }
140   sgmls_free(sp);
141 }
142
143 static
144 void output_data(v, n)
145 struct sgmls_data *v;
146 int n;
147 {
148   int i;
149
150   for (i = 0; i < n; i++) {
151     char *s = v[i].s;
152     int len = v[i].len;
153     for (; len > 0; len--, s++)
154       output_data_char(*s);
155   }
156 }
157
158 static
159 void output_pi(s, len)
160      char *s;
161      unsigned len;
162 {
163   for (; len > 0; len--, s++)
164     output_data_char(*s);
165 }
166
167 static
168 void output_replacement(repl, attributes)
169 struct replacement *repl;
170 struct sgmls_attribute *attributes;
171 {
172   struct replacement_item *p;
173   struct sgmls_attribute *a;
174   int i;
175
176   if (!repl)
177     return;
178   if (repl->flags & NEWLINE_BEGIN)
179     output_begin_line();
180   
181   for (p = repl->items; p; p = p->next)
182     switch (p->type) {
183     case DATA_REPL:
184       for (i = 0; i < p->u.data.n; i++)
185         output_char(p->u.data.s[i]);
186       break;
187     case ATTR_REPL:
188       for (a = attributes; a; a = a->next)
189         if (strcmp(a->name, p->u.attr) == 0) {
190           output_attribute(a);
191           break;
192         }
193       break;
194     default:
195       abort();
196     }
197
198   if (repl->flags & NEWLINE_END)
199     output_begin_line();
200 }
201
202 static
203 void output_attribute(p)
204 struct sgmls_attribute *p;
205 {
206   switch (p->type) {
207   case SGMLS_ATTR_IMPLIED:
208     break;
209   case SGMLS_ATTR_CDATA:
210     output_data(p->value.data.v, p->value.data.n);
211     break;
212   case SGMLS_ATTR_TOKEN:
213     {
214       char **token = p->value.token.v;
215       int n = p->value.token.n;
216       
217       if (n > 0) {
218         int i;
219         output_token(token[0]);
220         for (i = 1; i < n; i++) {
221           output_char(' ');
222           output_token(token[i]);
223         }
224       }
225     }
226     break;
227   case SGMLS_ATTR_ENTITY:
228     {
229       struct sgmls_entity **v = p->value.entity.v;
230       int n = p->value.entity.n;
231       int i;
232
233       for (i = 0; i < n; i++) {
234         if (i > 0)
235           output_char(' ');
236         output_token(v[i]->is_internal
237                      ? v[i]->u.internal.name
238                      : v[i]->u.external.name);
239       }
240     }
241     break;
242   case SGMLS_ATTR_NOTATION:
243     if (p->value.notation)
244       output_token(p->value.notation->name);
245     break;
246   default:
247     abort();
248   }
249 }
250
251 static
252 void output_token(s)
253      char *s;
254 {
255   for (; *s; s++)
256     output_char(*s);
257 }
258
259 static
260 void output_data_char(c)
261      int c;
262 {
263   if (c != RSCHAR) {
264     if (c == RECHAR)
265       c = '\n';
266     output_char(c);
267   }
268 }
269
270 static
271 void output_begin_line()
272 {
273   if (last_char != '\n')
274     output_char('\n');
275 }
276
277 NO_RETURN
278 #ifdef VARARGS
279 void error(va_alist) va_dcl
280 #else
281 void error(char *message,...)
282 #endif
283 {
284 #ifdef VARARGS
285      char *message;
286 #endif
287      va_list ap;
288      
289      fprintf(stderr, "%s: ", program_name);
290 #ifdef VARARGS
291      va_start(ap);
292      message = va_arg(ap, char *);
293 #else
294      va_start(ap, message);
295 #endif
296      vfprintf(stderr, message, ap);
297      va_end(ap);
298      fputc('\n', stderr);
299      fflush(stderr);
300      exit(EXIT_FAILURE);
301 }