Subversion Repositories tendra.SVN

Rev

Rev 5 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5 Rev 6
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
-
 
3
 * All rights reserved.
-
 
4
 *
-
 
5
 * Redistribution and use in source and binary forms, with or without
-
 
6
 * modification, are permitted provided that the following conditions are met:
-
 
7
 *
-
 
8
 * 1. Redistributions of source code must retain the above copyright notice,
-
 
9
 *    this list of conditions and the following disclaimer.
-
 
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
-
 
11
 *    this list of conditions and the following disclaimer in the documentation
-
 
12
 *    and/or other materials provided with the distribution.
-
 
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
-
 
14
 *    may be used to endorse or promote products derived from this software
-
 
15
 *    without specific, prior written permission.
-
 
16
 *
-
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
-
 
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-
 
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-
 
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
-
 
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-
 
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-
 
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-
 
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-
 
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-
 
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-
 
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 
28
 *
-
 
29
 * $Id$
-
 
30
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1997
32
    		 Crown Copyright (c) 1997
3
    
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
36
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
37
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
38
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
39
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
40
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
41
    shall be deemed to be acceptance of the following conditions:-
12
    
42
 
13
        (1) Its Recipients shall ensure that this Notice is
43
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
44
        reproduced upon any copies or amended versions of it;
15
    
45
 
16
        (2) Any amended version of it shall be clearly marked to
46
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
47
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
48
        for the relevant amendment or amendments;
19
    
49
 
20
        (3) Its onward transfer from a recipient to another
50
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
51
        party shall be deemed to be that party's acceptance of
22
        these conditions;
52
        these conditions;
23
    
53
 
24
        (4) DERA gives no warranty or assurance as to its
54
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
55
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
56
        no liability whatsoever in relation to any use to which
27
        it may be put.
57
        it may be put.
28
*/
58
*/
Line 35... Line 65...
35
#include "common.h"
65
#include "common.h"
36
#include "output.h"
66
#include "output.h"
37
#include "template.h"
67
#include "template.h"
38
#include "xalloc.h"
68
#include "xalloc.h"
39
 
69
 
40
 
70
 
41
/*
71
/*
42
    GET A COMMAND FROM A STRING
72
 * GET A COMMAND FROM A STRING
43
 
73
 *
44
    This routine returns the address of the first non-white space character
74
 * This routine returns the address of the first non-white space character
45
    from the string ps.  It returns the null pointer if the end of the line
75
 * from the string ps.  It returns the null pointer if the end of the line
46
    is reached.
76
 * is reached.
47
*/
77
 */
48
 
78
 
49
static char *get_command
79
static char *
50
    PROTO_N ( ( ps ) )
-
 
51
    PROTO_T ( char **ps )
80
get_command(char **ps)
52
{
81
{
53
    char *t = *ps ;
82
    char *t = *ps;
54
    char *s = t ;
83
    char *s = t;
55
    if ( s ) {
84
    if (s) {
56
	char c ;
85
	char c;
57
	while ( c = *s, ( c == ' ' || c == '\t' || c == '\r' ) ) {
86
	while (c = *s,(c == ' ' || c == '\t' || c == '\r')) {
58
	    *s = 0 ;
87
	    *s = 0;
59
	    s++ ;
88
	    s++;
60
	}
89
	}
61
	if ( c == '#' || c == '\n' || c == 0 ) {
90
	if (c == '#' || c == '\n' || c == 0) {
62
	    *s = 0 ;
91
	    *s = 0;
63
	    *ps = NULL ;
92
	    *ps = NULL;
64
	    return ( NULL ) ;
93
	    return(NULL);
65
	}
94
	}
66
	t = s ;
95
	t = s;
67
	while ( c = *s, !( c == ' ' || c == '\t' || c == '\r' ||
96
	while (c = *s, !(c == ' ' || c == '\t' || c == '\r' ||
68
			   c == '\n' || c == 0 ) ) {
97
			   c == '\n' || c == 0)) {
69
	    s++ ;
98
	    s++;
70
	}
99
	}
71
	*ps = s ;
100
	*ps = s;
72
    }
101
    }
73
    return ( t ) ;
102
    return(t);
74
}
103
}
75
 
104
 
76
 
105
 
77
/*
106
/*
78
    READ A TEMPLATE FILE
107
 * READ A TEMPLATE FILE
79
 
108
 *
80
    This routine reads a template file from the file f.
109
 * This routine reads a template file from the file f.
81
*/
110
 */
82
 
111
 
83
static COMMAND read_template
112
static COMMAND
84
    PROTO_N ( ( f, p ) )
-
 
85
    PROTO_T ( FILE *f X COMMAND p )
113
read_template(FILE *f, COMMAND p)
86
{
114
{
87
    int go = 1 ;
115
    int go = 1;
88
    char buff [1000] ;
116
    char buff[1000];
89
    int ln1 = crt_line_no ;
117
    int ln1 = crt_line_no;
90
    LIST ( COMMAND ) q = NULL_list ( COMMAND ) ;
118
    LIST(COMMAND)q = NULL_list(COMMAND);
91
    do {
119
    do {
92
	COMMAND r = NULL_cmd ;
120
	COMMAND r = NULL_cmd;
93
	int ln2 = crt_line_no ;
121
	int ln2 = crt_line_no;
94
	char *s = fgets ( buff, 1000, f ) ;
122
	char *s = fgets(buff, 1000, f);
95
	if ( s == NULL ) {
123
	if (s == NULL) {
96
	    /* End of file */
124
	    /* End of file */
97
	    if ( IS_cmd_cond ( p ) ) {
125
	    if (IS_cmd_cond(p)) {
98
		error ( ERROR_SERIOUS, "End of '@if' expected" ) ;
126
		error(ERROR_SERIOUS, "End of '@if' expected");
99
	    } else if ( IS_cmd_loop ( p ) ) {
127
	    } else if (IS_cmd_loop(p)) {
100
		error ( ERROR_SERIOUS, "End of '@loop' expected" ) ;
128
		error(ERROR_SERIOUS, "End of '@loop' expected");
101
	    }
129
	    }
102
	    break ;
130
	    break;
103
	}
131
	}
104
	s = xstrcpy ( s ) ;
132
	s = xstrcpy(s);
105
	if ( s [0] == '@' ) {
133
	if (s[0] == '@') {
106
	    /* Complex command */
134
	    /* Complex command */
107
	    char *s1, *s2, *s3 ;
135
	    char *s1, *s2, *s3;
108
	    s++ ;
136
	    s++;
109
	    s1 = get_command ( &s ) ;
137
	    s1 = get_command(&s);
110
	    if ( s1 == NULL ) s1 = "<empty>" ;
138
	    if (s1 == NULL) {
-
 
139
		    s1 = "<empty>";
-
 
140
	    }
111
	    s2 = get_command ( &s ) ;
141
	    s2 = get_command(&s);
112
	    s3 = get_command ( &s ) ;
142
	    s3 = get_command(&s);
113
	    if ( streq ( s1, "if" ) ) {
143
	    if (streq(s1, "if")) {
114
		if ( s2 == NULL ) {
144
		if (s2 == NULL) {
115
		    error ( ERROR_SERIOUS, "Incomplete '@%s' command", s1 ) ;
145
		    error(ERROR_SERIOUS, "Incomplete '@%s' command", s1);
116
		    s2 = "true" ;
146
		    s2 = "true";
-
 
147
		}
-
 
148
		MAKE_cmd_cond(ln2, s2, NULL_cmd, NULL_cmd, r);
-
 
149
	    } else if (streq(s1, "else")) {
-
 
150
		if (IS_cmd_cond(p)) {
-
 
151
		    COMMAND v = DEREF_cmd(cmd_cond_true_code(p));
-
 
152
		    if (!IS_NULL_cmd(v)) {
-
 
153
			error(ERROR_SERIOUS, "Duplicate '@%s' command", s1);
-
 
154
		    }
-
 
155
		    q = REVERSE_list(q);
-
 
156
		    MAKE_cmd_compound(ln1, q, v);
-
 
157
		    COPY_cmd(cmd_cond_true_code(p), v);
-
 
158
		    q = NULL_list(COMMAND);
-
 
159
		    ln1 = ln2;
-
 
160
		} else {
-
 
161
		    error(ERROR_SERIOUS, "Misplaced '@%s' command", s1);
-
 
162
		}
-
 
163
		s3 = s2;
-
 
164
	    } else if (streq(s1, "endif")) {
-
 
165
		if (IS_cmd_cond(p)) {
-
 
166
		    go = 0;
-
 
167
		} else {
-
 
168
		    error(ERROR_SERIOUS, "Misplaced '@%s' command", s1);
-
 
169
		}
-
 
170
		s3 = s2;
-
 
171
	    } else if (streq(s1, "loop")) {
-
 
172
		if (s2 == NULL) {
-
 
173
		    error(ERROR_SERIOUS, "Incomplete '@%s' command", s1);
-
 
174
		    s2 = "false";
-
 
175
		}
-
 
176
		MAKE_cmd_loop(ln2, s2, NULL_cmd, r);
-
 
177
	    } else if (streq(s1, "end")) {
-
 
178
		if (IS_cmd_loop(p)) {
-
 
179
		    go = 0;
-
 
180
		} else {
-
 
181
		    error(ERROR_SERIOUS, "Misplaced '@%s' command", s1);
117
		}
182
		}
118
		MAKE_cmd_cond ( ln2, s2, NULL_cmd, NULL_cmd, r ) ;
-
 
119
	    } else if ( streq ( s1, "else" ) ) {
-
 
120
		if ( IS_cmd_cond ( p ) ) {
-
 
121
		    COMMAND v = DEREF_cmd ( cmd_cond_true_code ( p ) ) ;
-
 
122
		    if ( !IS_NULL_cmd ( v ) ) {
-
 
123
			error ( ERROR_SERIOUS, "Duplicate '@%s' command", s1 ) ;
-
 
124
		    }
-
 
125
		    q = REVERSE_list ( q ) ;
-
 
126
		    MAKE_cmd_compound ( ln1, q, v ) ;
-
 
127
		    COPY_cmd ( cmd_cond_true_code ( p ), v ) ;
-
 
128
		    q = NULL_list ( COMMAND ) ;
-
 
129
		    ln1 = ln2 ;
-
 
130
		} else {
-
 
131
		    error ( ERROR_SERIOUS, "Misplaced '@%s' command", s1 ) ;
-
 
132
		}
-
 
133
		s3 = s2 ;
-
 
134
	    } else if ( streq ( s1, "endif" ) ) {
-
 
135
		if ( IS_cmd_cond ( p ) ) {
-
 
136
		    go = 0 ;
-
 
137
		} else {
-
 
138
		    error ( ERROR_SERIOUS, "Misplaced '@%s' command", s1 ) ;
-
 
139
		}
-
 
140
		s3 = s2 ;
-
 
141
	    } else if ( streq ( s1, "loop" ) ) {
-
 
142
		if ( s2 == NULL ) {
-
 
143
		    error ( ERROR_SERIOUS, "Incomplete '@%s' command", s1 ) ;
-
 
144
		    s2 = "false" ;
-
 
145
		}
-
 
146
		MAKE_cmd_loop ( ln2, s2, NULL_cmd, r ) ;
-
 
147
	    } else if ( streq ( s1, "end" ) ) {
-
 
148
		if ( IS_cmd_loop ( p ) ) {
-
 
149
		    go = 0 ;
-
 
150
		} else {
-
 
151
		    error ( ERROR_SERIOUS, "Misplaced '@%s' command", s1 ) ;
-
 
152
		}
-
 
153
		s3 = s2 ;
183
		s3 = s2;
154
	    } else if ( streq ( s1, "comment" ) ) {
184
	    } else if (streq(s1, "comment")) {
155
		s3 = NULL ;
185
		s3 = NULL;
156
	    } else {
186
	    } else {
157
		error ( ERROR_SERIOUS, "Unknown command, '@%s'", s1 ) ;
187
		error(ERROR_SERIOUS, "Unknown command, '@%s'", s1);
158
		s3 = NULL ;
188
		s3 = NULL;
-
 
189
	    }
-
 
190
	    if (s3) {
-
 
191
		error(ERROR_SERIOUS, "End of '@%s' expected", s1);
159
	    }
192
	    }
160
	    if ( s3 ) {
-
 
161
		error ( ERROR_SERIOUS, "End of '@%s' expected", s1 ) ;
-
 
162
	    }
-
 
163
	    crt_line_no = ln2 + 1 ;
193
	    crt_line_no = ln2 + 1;
164
	    if ( !IS_NULL_cmd ( r ) ) {
194
	    if (!IS_NULL_cmd(r)) {
165
		/* Read body of command */
195
		/* Read body of command */
166
		COMMAND u = read_template ( f, r ) ;
196
		COMMAND u = read_template(f, r);
167
		if ( IS_cmd_cond ( r ) ) {
197
		if (IS_cmd_cond(r)) {
168
		    COMMAND v = DEREF_cmd ( cmd_cond_true_code ( r ) ) ;
198
		    COMMAND v = DEREF_cmd(cmd_cond_true_code(r));
169
		    if ( IS_NULL_cmd ( v ) ) {
199
		    if (IS_NULL_cmd(v)) {
170
			COPY_cmd ( cmd_cond_true_code ( r ), u ) ;
200
			COPY_cmd(cmd_cond_true_code(r), u);
171
		    } else {
201
		    } else {
172
			COPY_cmd ( cmd_cond_false_code ( r ), u ) ;
202
			COPY_cmd(cmd_cond_false_code(r), u);
173
		    }
203
		    }
174
		} else if ( IS_cmd_loop ( r ) ) {
204
		} else if (IS_cmd_loop(r)) {
175
		    COPY_cmd ( cmd_loop_body ( r ), u ) ;
205
		    COPY_cmd(cmd_loop_body(r), u);
176
		}
206
		}
177
		CONS_cmd ( r, q, q ) ;
207
		CONS_cmd(r, q, q);
178
	    }
208
	    }
179
	} else {
209
	} else {
180
	    /* Simple command */
210
	    /* Simple command */
181
	    MAKE_cmd_simple ( ln2, s, r ) ;
211
	    MAKE_cmd_simple(ln2, s, r);
182
	    CONS_cmd ( r, q, q ) ;
212
	    CONS_cmd(r, q, q);
183
	    crt_line_no = ln2 + 1 ;
213
	    crt_line_no = ln2 + 1;
184
	}
214
	}
185
    } while ( go ) ;
215
    } while (go);
186
    q = REVERSE_list ( q ) ;
216
    q = REVERSE_list(q);
187
    MAKE_cmd_compound ( ln1, q, p ) ;
217
    MAKE_cmd_compound(ln1, q, p);
188
    return ( p ) ;
218
    return(p);
189
}
219
}
190
 
220
 
191
 
221
 
192
/*
222
/*
193
    TOKEN CONDITION
223
 * TOKEN CONDITION
194
 
224
 *
195
    This variable gives the value of the token condition.
225
 * This variable gives the value of the token condition.
196
*/
226
 */
197
 
227
 
198
int token_cond = 0 ;
228
int token_cond = 0;
199
 
229
 
200
 
230
 
201
/*
231
/*
202
    EVALUATE A CONDITION
232
 * EVALUATE A CONDITION
-
 
233
 *
-
 
234
 * This routine evaluates the condition s.
-
 
235
 */
203
 
236
 
204
    This routine evaluates the condition s.
-
 
205
*/
-
 
206
 
-
 
207
static int eval_cond
237
static int
208
    PROTO_N ( ( s ) )
-
 
209
    PROTO_T ( char *s )
238
eval_cond(char *s)
210
{
239
{
211
    if ( s [0] == '!' ) {
240
    if (s[0] == '!') {
212
	/* Negate condition */
241
	/* Negate condition */
213
	return ( !eval_cond ( s + 1 ) ) ;
242
	return(!eval_cond(s + 1));
214
    }
243
    }
215
    if ( streq ( s, "comp.complex" ) ) {
244
    if (streq(s, "comp.complex")) {
216
	/* Complex component type */
245
	/* Complex component type */
217
	if ( HAVE_COMPONENT ) {
246
	if (HAVE_COMPONENT) {
218
	    TYPE_P_P pt = cmp_type ( CRT_COMPONENT ) ;
247
	    TYPE_P_P pt = cmp_type(CRT_COMPONENT);
219
	    TYPE_P t = DEREF_ptr ( pt ) ;
248
	    TYPE_P t = DEREF_ptr(pt);
220
	    return ( is_complex_type ( t ) ) ;
249
	    return(is_complex_type(t));
221
	}
250
	}
222
	return ( 0 ) ;
251
	return(0);
223
    }
252
    }
224
    if ( streq ( s, "comp.default" ) ) {
253
    if (streq(s, "comp.default")) {
225
	/* Component default value */
254
	/* Component default value */
226
	if ( HAVE_COMPONENT ) {
255
	if (HAVE_COMPONENT) {
227
	    string_P pv = cmp_name ( CRT_COMPONENT ) ;
256
	    string_P pv = cmp_name(CRT_COMPONENT);
228
	    string v = DEREF_string ( pv ) ;
257
	    string v = DEREF_string(pv);
229
	    if ( v ) return ( 1 ) ;
258
	    if (v) return(1);
230
	}
259
	}
231
	return ( 0 ) ;
260
	return(0);
232
    }
261
    }
233
    if ( streq ( s, "token" ) ) return ( token_cond ) ;
262
    if (streq(s, "token")) {
-
 
263
	    return(token_cond);
-
 
264
    }
234
    if ( streq ( s, "true" ) ) return ( 1 ) ;
265
    if (streq(s, "true")) {
-
 
266
	    return(1);
-
 
267
    }
235
    if ( streq ( s, "false" ) ) return ( 0 ) ;
268
    if (streq(s, "false")) {
-
 
269
	    return(0);
-
 
270
    }
236
    error ( ERROR_SERIOUS, "Unknown condition, '%s'", s ) ;
271
    error(ERROR_SERIOUS, "Unknown condition, '%s'", s);
237
    return ( 0 ) ;
272
    return(0);
238
}
273
}
239
 
274
 
240
 
275
 
241
/*
276
/*
242
    WRITE A TEMPLATE FILE
277
 * WRITE A TEMPLATE FILE
243
 
278
 *
244
    This routine writes the template file given by the commands cmd.
279
 * This routine writes the template file given by the commands cmd.
245
*/
280
 */
246
 
281
 
247
static void write_template
282
static void
248
    PROTO_N ( ( cmd ) )
-
 
249
    PROTO_T ( COMMAND cmd )
283
write_template(COMMAND cmd)
250
{
284
{
251
    if ( !IS_NULL_cmd ( cmd ) ) {
285
    if (!IS_NULL_cmd(cmd)) {
252
	crt_line_no = DEREF_int ( cmd_line ( cmd ) ) ;
286
	crt_line_no = DEREF_int(cmd_line(cmd));
253
	switch ( TAG_cmd ( cmd ) ) {
287
	switch (TAG_cmd(cmd)) {
254
	    case cmd_simple_tag : {
288
	    case cmd_simple_tag: {
255
		string s = DEREF_string ( cmd_simple_text ( cmd ) ) ;
289
		string s = DEREF_string(cmd_simple_text(cmd));
256
		output ( s ) ;
290
		output(s);
257
		break ;
291
		break;
258
	    }
292
	    }
259
	    case cmd_compound_tag : {
293
	    case cmd_compound_tag: {
260
		LIST ( COMMAND ) p ;
294
		LIST(COMMAND)p;
261
		p = DEREF_list ( cmd_compound_seq ( cmd ) ) ;
295
		p = DEREF_list(cmd_compound_seq(cmd));
262
		while ( !IS_NULL_list ( p ) ) {
296
		while (!IS_NULL_list(p)) {
263
		    COMMAND a = DEREF_cmd ( HEAD_list ( p ) ) ;
297
		    COMMAND a = DEREF_cmd(HEAD_list(p));
264
		    write_template ( a ) ;
298
		    write_template(a);
265
		    p = TAIL_list ( p ) ;
299
		    p = TAIL_list(p);
266
		}
300
		}
267
		break ;
301
		break;
268
	    }
302
	    }
269
	    case cmd_loop_tag : {
303
	    case cmd_loop_tag: {
270
		string s = DEREF_string ( cmd_loop_control ( cmd ) ) ;
304
		string s = DEREF_string(cmd_loop_control(cmd));
271
		COMMAND a = DEREF_cmd ( cmd_loop_body ( cmd ) ) ;
305
		COMMAND a = DEREF_cmd(cmd_loop_body(cmd));
272
		if ( streq ( s, "enum" ) ) {
306
		if (streq(s, "enum")) {
273
		    LOOP_ENUM write_template ( a ) ;
307
		    LOOP_ENUM write_template(a);
274
		} else if ( streq ( s, "enum.const" ) ) {
308
		} else if (streq(s, "enum.const")) {
275
		    if ( HAVE_ENUM ) {
309
		    if (HAVE_ENUM) {
276
			LOOP_ENUM_CONST write_template ( a ) ;
310
			LOOP_ENUM_CONST write_template(a);
277
		    }
311
		    }
278
		} else if ( streq ( s, "identity" ) ) {
312
		} else if (streq(s, "identity")) {
279
		    LOOP_IDENTITY write_template ( a ) ;
313
		    LOOP_IDENTITY write_template(a);
280
		} else if ( streq ( s, "primitive" ) ) {
314
		} else if (streq(s, "primitive")) {
281
		    LOOP_PRIMITIVE write_template ( a ) ;
315
		    LOOP_PRIMITIVE write_template(a);
282
		} else if ( streq ( s, "struct" ) ) {
316
		} else if (streq(s, "struct")) {
283
		    LOOP_STRUCTURE write_template ( a ) ;
317
		    LOOP_STRUCTURE write_template(a);
284
		} else if ( streq ( s, "struct.comp" ) ) {
318
		} else if (streq(s, "struct.comp")) {
285
		    if ( HAVE_STRUCTURE ) {
319
		    if (HAVE_STRUCTURE) {
286
			LOOP_STRUCTURE_COMPONENT write_template ( a ) ;
320
			LOOP_STRUCTURE_COMPONENT write_template(a);
287
		    }
321
		    }
288
		} else if ( streq ( s, "union" ) ) {
322
		} else if (streq(s, "union")) {
289
		    LOOP_UNION write_template ( a ) ;
323
		    LOOP_UNION write_template(a);
290
		} else if ( streq ( s, "union.comp" ) ) {
324
		} else if (streq(s, "union.comp")) {
291
		    if ( HAVE_UNION ) {
325
		    if (HAVE_UNION) {
292
			LOOP_UNION_COMPONENT write_template ( a ) ;
326
			LOOP_UNION_COMPONENT write_template(a);
293
		    }
327
		    }
294
		} else if ( streq ( s, "union.field" ) ) {
328
		} else if (streq(s, "union.field")) {
295
		    if ( HAVE_UNION ) {
329
		    if (HAVE_UNION) {
296
			LOOP_UNION_FIELD write_template ( a ) ;
330
			LOOP_UNION_FIELD write_template(a);
297
		    }
331
		    }
298
		} else if ( streq ( s, "union.field.comp" ) ) {
332
		} else if (streq(s, "union.field.comp")) {
299
		    if ( HAVE_UNION && HAVE_FIELD ) {
333
		    if (HAVE_UNION && HAVE_FIELD) {
300
			LOOP_FIELD_COMPONENT write_template ( a ) ;
334
			LOOP_FIELD_COMPONENT write_template(a);
301
		    }
-
 
302
		} else if ( streq ( s, "union.map" ) ) {
-
 
303
		    if ( HAVE_UNION ) {
-
 
304
			LOOP_UNION_MAP write_template ( a ) ;
-
 
305
		    }
335
		    }
-
 
336
		} else if (streq(s, "union.map")) {
-
 
337
		    if (HAVE_UNION) {
-
 
338
			LOOP_UNION_MAP write_template(a);
-
 
339
		    }
306
		} else if ( streq ( s, "union.map.arg" ) ) {
340
		} else if (streq(s, "union.map.arg")) {
307
		    if ( HAVE_UNION && HAVE_MAP ) {
341
		    if (HAVE_UNION && HAVE_MAP) {
308
			LOOP_MAP_ARGUMENT write_template ( a ) ;
342
			LOOP_MAP_ARGUMENT write_template(a);
309
		    }
343
		    }
310
		} else {
344
		} else {
311
		    error ( ERROR_SERIOUS, "Unknown control, '%s'", s ) ;
345
		    error(ERROR_SERIOUS, "Unknown control, '%s'", s);
312
		}
-
 
313
		break ;
-
 
314
	    }
-
 
315
	    case cmd_cond_tag : {
-
 
316
		string s = DEREF_string ( cmd_cond_control ( cmd ) ) ;
-
 
317
		COMMAND a = DEREF_cmd ( cmd_cond_true_code ( cmd ) ) ;
-
 
318
		COMMAND b = DEREF_cmd ( cmd_cond_false_code ( cmd ) ) ;
-
 
319
		if ( eval_cond ( s ) ) {
-
 
320
		    write_template ( a ) ;
-
 
321
		} else {
-
 
322
		    write_template ( b ) ;
-
 
323
		}
346
		}
324
		break ;
347
		break;
325
	    }
348
	    }
-
 
349
	    case cmd_cond_tag: {
-
 
350
		string s = DEREF_string(cmd_cond_control(cmd));
-
 
351
		COMMAND a = DEREF_cmd(cmd_cond_true_code(cmd));
-
 
352
		COMMAND b = DEREF_cmd(cmd_cond_false_code(cmd));
-
 
353
		if (eval_cond(s)) {
-
 
354
		    write_template(a);
-
 
355
		} else {
-
 
356
		    write_template(b);
-
 
357
		}
-
 
358
		break;
-
 
359
	    }
326
	}
360
	}
327
    }
361
    }
328
    return ;
362
    return;
329
}
363
}
330
 
364
 
331
 
365
 
332
/*
366
/*
333
    PROCESS A TEMPLATE FILE
367
 * PROCESS A TEMPLATE FILE
-
 
368
 *
-
 
369
 * This routine processes the template file in to the output file out.
-
 
370
 */
334
 
371
 
335
    This routine processes the template file in to the output file out.
-
 
336
*/
372
void
337
 
-
 
338
void template_file
-
 
339
    PROTO_N ( ( in, out ) )
-
 
340
    PROTO_T ( char *in X char *out )
373
template_file(char *in, char *out)
341
{
374
{
342
    COMMAND cmd ;
375
    COMMAND cmd;
343
    FILE *input_file ;
376
    FILE *input_file;
344
    crt_line_no = 1 ;
377
    crt_line_no = 1;
345
    crt_file_name = in ;
378
    crt_file_name = in;
346
    input_file = fopen ( in, "r" ) ;
379
    input_file = fopen(in, "r");
347
    if ( input_file == NULL ) {
380
    if (input_file == NULL) {
348
	error ( ERROR_SERIOUS, "Can't open template file, '%s'", in ) ;
381
	error(ERROR_SERIOUS, "Can't open template file, '%s'", in);
349
	return ;
382
	return;
350
    }
383
    }
351
    MAKE_cmd_simple ( 1, "<dummy>", cmd ) ;
384
    MAKE_cmd_simple(1, "<dummy>", cmd);
352
    cmd = read_template ( input_file, cmd ) ;
385
    cmd = read_template(input_file, cmd);
353
    fclose_v ( input_file ) ;
386
    fclose_v(input_file);
354
    if ( streq ( out, "." ) ) {
387
    if (streq(out, ".")) {
355
	output_file = stdout ;
388
	output_file = stdout;
356
    } else {
389
    } else {
357
	output_file = fopen ( out, "w" ) ;
390
	output_file = fopen(out, "w");
358
	if ( output_file == NULL ) {
391
	if (output_file == NULL) {
359
	    error ( ERROR_SERIOUS, "Can't open output file, '%s'", out ) ;
392
	    error(ERROR_SERIOUS, "Can't open output file, '%s'", out);
360
	    return ;
393
	    return;
361
	}
394
	}
362
    }
395
    }
363
    have_varargs = 0 ;
396
    have_varargs = 0;
364
    write_template ( cmd ) ;
397
    write_template(cmd);
365
    have_varargs = 1 ;
398
    have_varargs = 1;
366
    flush_output () ;
399
    flush_output();
367
    if ( output_file != stdout ) fclose_v ( output_file ) ;
400
    if (output_file != stdout) {
-
 
401
	    fclose_v(output_file);
-
 
402
    }
368
    return ;
403
    return;
369
}
404
}