Subversion Repositories tendra.SVN

Rev

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

Rev 2 Rev 7
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 48... Line 78...
48
 
78
 
49
    This macro gives a convenient method for testing whether the first
79
    This macro gives a convenient method for testing whether the first
50
    C characters of the strings A and B are equal.
80
    C characters of the strings A and B are equal.
51
*/
81
*/
52
 
82
 
53
#define strneq( A, B, C )\
83
#define strneq(A, B, C)\
54
	( strncmp ( ( A ), ( B ), ( size_t ) ( C ) ) == 0 )
84
	(strncmp((A), (B), (size_t)(C)) == 0)
55
 
85
 
56
 
86
 
57
/*
87
/*
58
    CURRENT OUTPUT FILE
88
    CURRENT OUTPUT FILE
59
 
89
 
60
    These variables describe the current output file.
90
    These variables describe the current output file.
61
*/
91
*/
62
 
92
 
63
static FILE *output_file ;
93
static FILE *output_file;
64
static char output_buff [512] ;
94
static char output_buff[512];
65
static int output_posn = 0 ;
95
static int output_posn = 0;
66
static unsigned crt_column = 0 ;
96
static unsigned crt_column = 0;
67
 
97
 
68
 
98
 
69
/*
99
/*
70
    CURRENT LOOP VARIABLES
100
    CURRENT LOOP VARIABLES
71
 
101
 
72
    These variables keep track of the current state of the various
102
    These variables keep track of the current state of the various
73
    output loops.
103
    output loops.
74
*/
104
*/
75
 
105
 
76
static unsigned crt_major = 0 ;
106
static unsigned crt_major = 0;
77
static unsigned crt_minor = 0 ;
107
static unsigned crt_minor = 0;
78
static int crt_unique = 0 ;
108
static int crt_unique = 0;
79
static SORT crt_sort = NULL_sort ;
109
static SORT crt_sort = NULL_sort;
80
static SORT_INFO crt_info = NULL_info ;
110
static SORT_INFO crt_info = NULL_info;
81
static CONSTRUCT crt_cons = NULL_cons ;
111
static CONSTRUCT crt_cons = NULL_cons;
82
static PARAMETER crt_param = NULL_par ;
112
static PARAMETER crt_param = NULL_par;
83
static int crt_param_no = 0 ;
113
static int crt_param_no = 0;
84
static int last_param_no = 0 ;
114
static int last_param_no = 0;
85
 
115
 
86
 
116
 
87
/*
117
/*
88
    PRINT A CHARACTER TO THE OUTPUT FILE
118
    PRINT A CHARACTER TO THE OUTPUT FILE
89
 
119
 
90
    This routine prints the character c to the output file updating the
120
    This routine prints the character c to the output file updating the
91
    current column number.
121
    current column number.
92
*/
122
*/
93
 
123
 
94
static void output_char
124
static void
95
    PROTO_N ( ( c ) )
-
 
96
    PROTO_T ( int c )
125
output_char(int c)
97
{
126
{
98
    int i = output_posn ;
127
    int i = output_posn;
99
    output_buff [i] = ( char ) c ;
128
    output_buff[i] = (char)c;
100
    if ( ++i >= 500 || c == '\n' ) {
129
    if (++i >= 500 || c == '\n') {
101
	output_buff [i] = 0 ;
130
	output_buff[i] = 0;
102
	IGNORE fputs ( output_buff, output_file ) ;
131
	IGNORE fputs(output_buff, output_file);
103
	i = 0 ;
132
	i = 0;
104
    }
133
    }
105
    if ( c == '\n' ) {
134
    if (c == '\n') {
106
	crt_column = 0 ;
135
	crt_column = 0;
107
    } else if ( c == '\t' ) {
136
    } else if (c == '\t') {
108
	crt_column = 8 * ( crt_column / 8 + 1 ) ;
137
	crt_column = 8 *(crt_column / 8 + 1);
109
    } else {
138
    } else {
110
	crt_column++ ;
139
	crt_column++;
111
    }
140
    }
112
    output_posn = i ;
141
    output_posn = i;
113
    return ;
142
    return;
114
}
143
}
115
 
144
 
116
 
145
 
117
/*
146
/*
118
    PRINT A STRING TO THE OUTPUT FILE
147
    PRINT A STRING TO THE OUTPUT FILE
119
 
148
 
120
    This routine prints the string s to the output file.
149
    This routine prints the string s to the output file.
121
*/
150
*/
122
 
151
 
123
static void output_string
152
static void
124
    PROTO_N ( ( s ) )
-
 
125
    PROTO_T ( char *s )
153
output_string(char *s)
126
{
154
{
127
    char c ;
155
    char c;
128
    while ( c = *( s++ ), c != 0 ) {
156
    while (c = *(s++), c != 0) {
129
	output_char ( ( int ) c ) ;
157
	output_char((int)c);
130
    }
158
    }
131
    return ;
159
    return;
132
}
160
}
133
 
161
 
134
 
162
 
135
/*
163
/*
136
    OUTPUT AN ENCODING STRING FOR A CONSTRUCT
164
    OUTPUT AN ENCODING STRING FOR A CONSTRUCT
137
 
165
 
138
    This routine writes the encoding strings for the parameter sorts of
166
    This routine writes the encoding strings for the parameter sorts of
139
    the construct cons to the output file.
167
    the construct cons to the output file.
140
*/
168
*/
141
 
169
 
142
static void output_cons
170
static void
143
    PROTO_N ( ( cons, intro ) )
-
 
144
    PROTO_T ( CONSTRUCT cons X int intro )
171
output_cons(CONSTRUCT cons, int intro)
145
{
172
{
146
    int c ;
173
    int c;
147
    int brks = 0 ;
174
    int brks = 0;
148
    unsigned kind = DEREF_unsigned ( cons_kind ( cons ) ) ;
175
    unsigned kind = DEREF_unsigned(cons_kind(cons));
149
    LIST ( PARAMETER ) p = DEREF_list ( cons_pars ( cons ) ) ;
176
    LIST(PARAMETER)p = DEREF_list(cons_pars(cons));
150
    while ( !IS_NULL_list ( p ) ) {
177
    while (!IS_NULL_list(p)) {
151
	PARAMETER par = DEREF_par ( HEAD_list ( p ) ) ;
178
	PARAMETER par = DEREF_par(HEAD_list(p));
152
	SORT sort = DEREF_sort ( par_type ( par ) ) ;
179
	SORT sort = DEREF_sort(par_type(par));
153
	int align = DEREF_int ( par_align ( par ) ) ;
180
	int align = DEREF_int(par_align(par));
154
	int brk = DEREF_int ( par_brk ( par ) ) ;
181
	int brk = DEREF_int(par_brk(par));
155
	int intro2 = DEREF_int ( par_intro ( par ) ) ;
182
	int intro2 = DEREF_int(par_intro(par));
156
	if ( align ) output_char ( '|' ) ;
183
	if (align) output_char('|');
157
	if ( brk ) output_char ( '{' ) ;
184
	if (brk) output_char('{');
158
	if ( intro2 ) intro = 1 ;
185
	if (intro2) intro = 1;
159
	c = output_sort ( sort, intro ) ;
186
	c = output_sort(sort, intro);
160
	if ( c == '@' && kind == KIND_cond ) {
187
	if (c == '@' && kind == KIND_cond) {
161
	    /* Conditional construct */
188
	    /* Conditional construct */
162
	    output_char ( '[' ) ;
189
	    output_char('[');
163
	    sort = DEREF_sort ( cons_res ( cons ) ) ;
190
	    sort = DEREF_sort(cons_res(cons));
164
	    IGNORE output_sort ( sort, intro ) ;
191
	    IGNORE output_sort(sort, intro);
165
	    output_char ( ']' ) ;
192
	    output_char(']');
166
	}
193
	}
167
	brks += brk ;
194
	brks += brk;
168
	p = TAIL_list ( p ) ;
195
	p = TAIL_list(p);
169
    }
196
    }
170
    while ( brks-- ) output_char ( '}' ) ;
197
    while (brks--)output_char('}');
171
    return ;
198
    return;
172
}
199
}
173
 
200
 
174
 
201
 
175
/*
202
/*
176
    OUTPUT AN ENCODING STRING FOR A SORT
203
    OUTPUT AN ENCODING STRING FOR A SORT
Line 180... Line 207...
180
    allows every sort to be expressed as a sequence of characters.  This
207
    allows every sort to be expressed as a sequence of characters.  This
181
    routine prints this encoding string for the sort sort to the output
208
    routine prints this encoding string for the sort sort to the output
182
    file
209
    file
183
*/
210
*/
184
 
211
 
185
int output_sort
212
int
186
    PROTO_N ( ( sort, intro ) )
-
 
187
    PROTO_T ( SORT sort X int intro )
213
output_sort(SORT sort, int intro)
188
{
214
{
189
    int c = DEREF_int ( sort_code ( sort ) ) ;
215
    int c = DEREF_int(sort_code(sort));
190
    SORT_INFO info = DEREF_info ( sort_info ( sort ) ) ;
216
    SORT_INFO info = DEREF_info(sort_info(sort));
191
    if ( !IS_NULL_info ( info ) ) {
217
    if (!IS_NULL_info(info)) {
192
	switch ( TAG_info ( info ) ) {
218
	switch (TAG_info(info)) {
193
	    case info_builtin_tag :
219
	    case info_builtin_tag:
194
	    case info_basic_tag : {
220
	    case info_basic_tag: {
195
		if ( c < 32 ) {
221
		if (c < 32) {
196
		    char buff [10] ;
222
		    char buff[10];
197
		    sprintf_v ( buff, "\\%03o", ( unsigned ) c ) ;
223
		    sprintf_v(buff, "\\%03o",(unsigned)c);
198
		    output_string ( buff ) ;
224
		    output_string(buff);
199
		} else {
225
		} else {
200
		    output_char ( c ) ;
226
		    output_char(c);
201
		}
227
		}
202
		if ( intro ) {
228
		if (intro) {
203
		    int edge = DEREF_int ( sort_edge ( sort ) ) ;
229
		    int edge = DEREF_int(sort_edge(sort));
204
		    if ( edge ) output_char ( '&' ) ;
230
		    if (edge) output_char('&');
205
		}
231
		}
206
		break ;
232
		break;
207
	    }
233
	    }
208
	    case info_dummy_tag : {
234
	    case info_dummy_tag: {
209
		CONSTRUCT cons = DEREF_cons ( info_dummy_cons ( info ) ) ;
235
		CONSTRUCT cons = DEREF_cons(info_dummy_cons(info));
210
		output_cons ( cons, intro ) ;
236
		output_cons(cons, intro);
211
		break ;
237
		break;
212
	    }
238
	    }
213
	    case info_clist_tag :
239
	    case info_clist_tag:
214
	    case info_slist_tag :
240
	    case info_slist_tag:
215
	    case info_option_tag : {
241
	    case info_option_tag: {
216
		sort = DEREF_sort ( info_clist_etc_arg ( info ) ) ;
242
		sort = DEREF_sort(info_clist_etc_arg(info));
217
		output_char ( c ) ;
243
		output_char(c);
218
		output_char ( '[' ) ;
244
		output_char('[');
219
		IGNORE output_sort ( sort, intro ) ;
245
		IGNORE output_sort(sort, intro);
220
		output_char ( ']' ) ;
246
		output_char(']');
221
		break ;
247
		break;
222
	    }
248
	    }
223
	}
249
	}
224
    }
250
    }
225
    return ( c ) ;
251
    return(c);
226
}
252
}
227
 
253
 
228
 
254
 
229
/*
255
/*
230
    OUTPUT A FORMAT STRING
256
    OUTPUT A FORMAT STRING
231
 
257
 
232
    This routine writes the format string s to the output file.
258
    This routine writes the format string s to the output file.
233
*/
259
*/
234
 
260
 
235
static void output
261
static void
236
    PROTO_N ( ( s ) )
-
 
237
    PROTO_T ( string s )
262
output(string s)
238
{
263
{
239
    char c ;
264
    char c;
240
    while ( c = *( s++ ), c != 0 ) {
265
    while (c = *(s++), c != 0) {
241
	if ( c == '%' ) {
266
	if (c == '%') {
242
	    char *s0 = s ;
267
	    char *s0 = s;
243
	    int prec = 100 ;
268
	    int prec = 100;
244
	    char buff [120] ;
269
	    char buff[120];
245
	    int have_prec = 0 ;
270
	    int have_prec = 0;
246
	    SORT cs = crt_sort ;
271
	    SORT cs = crt_sort;
247
	    SORT_INFO ci = crt_info ;
272
	    SORT_INFO ci = crt_info;
248
	    CONSTRUCT cc = crt_cons ;
273
	    CONSTRUCT cc = crt_cons;
249
	    PARAMETER cp = crt_param ;
274
	    PARAMETER cp = crt_param;
250
	    c = *( s++ ) ;
275
	    c = *(s++);
251
	    if ( c >= '0' && c <= '9' ) {
276
	    if (c >= '0' && c <= '9') {
252
		/* Read precision */
277
		/* Read precision */
253
		prec = ( int ) ( c - '0' ) ;
278
		prec = (int)(c - '0');
254
		while ( c = *( s++ ), ( c >= '0' && c <= '9' ) ) {
279
		while (c = *(s++), (c >= '0' && c <= '9')) {
255
		    prec = 10 * prec + ( int ) ( c - '0' ) ;
280
		    prec = 10 * prec + (int)(c - '0');
256
		}
281
		}
257
		have_prec = 1 ;
282
		have_prec = 1;
258
	    }
283
	    }
259
	    switch ( c ) {
284
	    switch (c) {
260
 
285
 
261
		case 'C' :
286
		case 'C':
262
		cons_format : {
287
		cons_format : {
263
		    /* Construct information */
288
		    /* Construct information */
264
		    if ( IS_NULL_cons ( cc ) ) goto misplaced_arg ;
289
		    if (IS_NULL_cons(cc)) goto misplaced_arg;
265
		    c = *( s++ ) ;
290
		    c = *(s++);
266
		    switch ( c ) {
291
		    switch (c) {
267
			case 'N' : {
292
			case 'N': {
268
			    /* '%CN' -> construct name */
293
			    /* '%CN' -> construct name */
269
			    string nm = DEREF_string ( cons_name ( cc ) ) ;
294
			    string nm = DEREF_string(cons_name(cc));
270
			    sprintf_v ( buff, "%.*s", prec, nm ) ;
295
			    sprintf_v(buff, "%.*s", prec, nm);
271
			    output_string ( buff ) ;
296
			    output_string(buff);
272
			    break ;
297
			    break;
273
			}
298
			}
274
			case 'E' : {
299
			case 'E': {
275
			    /* '%CE' -> construct encoding */
300
			    /* '%CE' -> construct encoding */
276
			    unsigned e ;
301
			    unsigned e;
277
			    e = DEREF_unsigned ( cons_encode ( cc ) ) ;
302
			    e = DEREF_unsigned(cons_encode(cc));
278
			    sprintf_v ( buff, "%u", e ) ;
303
			    sprintf_v(buff, "%u", e);
279
			    output_string ( buff ) ;
304
			    output_string(buff);
280
			    break ;
305
			    break;
281
			}
306
			}
282
			case 'S' : {
307
			case 'S': {
283
			    /* '%CS' -> construct result sort */
308
			    /* '%CS' -> construct result sort */
284
			    goto sort_format ;
309
			    goto sort_format;
285
			}
310
			}
286
			case 'X' : {
311
			case 'X': {
287
			    /* '%CX' -> construct encoding string */
312
			    /* '%CX' -> construct encoding string */
288
			    output_cons ( cc, 0 ) ;
313
			    output_cons(cc, 0);
289
			    break ;
314
			    break;
290
			}
315
			}
291
			default : {
316
			default : {
292
			    goto bad_format ;
317
			    goto bad_format;
293
			}
318
			}
294
		    }
319
		    }
295
		    break ;
320
		    break;
296
		}
321
		}
297
 
322
 
298
		case 'P' : {
323
		case 'P': {
299
		    /* Parameter information */
324
		    /* Parameter information */
300
		    if ( IS_NULL_par ( cp ) ) goto misplaced_arg ;
325
		    if (IS_NULL_par(cp)) goto misplaced_arg;
301
		    c = *( s++ ) ;
326
		    c = *(s++);
302
		    if ( c == 'N' ) {
327
		    if (c == 'N') {
303
			/* '%PN' -> parameter name */
328
			/* '%PN' -> parameter name */
304
			string nm = DEREF_string ( par_name ( cp ) ) ;
329
			string nm = DEREF_string(par_name(cp));
305
			sprintf_v ( buff, "%.*s", prec, nm ) ;
330
			sprintf_v(buff, "%.*s", prec, nm);
306
			output_string ( buff ) ;
331
			output_string(buff);
307
		    } else if ( c == 'S' ) {
332
		    } else if (c == 'S') {
308
			/* '%PS' -> parameter sort */
333
			/* '%PS' -> parameter sort */
309
			cs = DEREF_sort ( par_type ( cp ) ) ;
334
			cs = DEREF_sort(par_type(cp));
310
			ci = DEREF_info ( sort_info ( cs ) ) ;
335
			ci = DEREF_info(sort_info(cs));
311
			goto sort_format ;
336
			goto sort_format;
312
		    } else if ( c == 'E' ) {
337
		    } else if (c == 'E') {
313
			/* '%PE' -> parameter number */
338
			/* '%PE' -> parameter number */
314
			sprintf_v ( buff, "%d", crt_param_no ) ;
339
			sprintf_v(buff, "%d", crt_param_no);
315
			output_string ( buff ) ;
340
			output_string(buff);
316
		    } else {
341
		    } else {
317
			goto bad_format ;
342
			goto bad_format;
318
		    }
343
		    }
319
		    break ;
344
		    break;
320
		}
345
		}
321
 
346
 
322
		case 'S' :
347
		case 'S':
323
		sort_format : {
348
		sort_format : {
324
		    /* Sort information */
349
		    /* Sort information */
325
		    if ( IS_NULL_info ( ci ) ) goto misplaced_arg ;
350
		    if (IS_NULL_info(ci)) goto misplaced_arg;
326
		    c = *( s++ ) ;
351
		    c = *(s++);
327
		    switch ( c ) {
352
		    switch (c) {
328
			case 'N' : {
353
			case 'N': {
329
			    /* '%SN' -> sort name */
354
			    /* '%SN' -> sort name */
330
			    string nm = DEREF_string ( sort_name ( cs ) ) ;
355
			    string nm = DEREF_string(sort_name(cs));
331
			    sprintf_v ( buff, "%.*s", prec, nm ) ;
356
			    sprintf_v(buff, "%.*s", prec, nm);
332
			    output_string ( buff ) ;
357
			    output_string(buff);
333
			    break ;
358
			    break;
334
			}
359
			}
335
			case 'T' : {
360
			case 'T': {
336
			    /* '%ST' -> sort name in capitals */
361
			    /* '%ST' -> sort name in capitals */
337
			    string nm = DEREF_string ( sort_caps ( cs ) ) ;
362
			    string nm = DEREF_string(sort_caps(cs));
338
			    sprintf_v ( buff, "%.*s", prec, nm ) ;
363
			    sprintf_v(buff, "%.*s", prec, nm);
339
			    output_string ( buff ) ;
364
			    output_string(buff);
340
			    break ;
365
			    break;
341
			}
366
			}
342
			case 'L' : {
367
			case 'L': {
343
			    /* '%SL' -> sort unit name */
368
			    /* '%SL' -> sort unit name */
344
			    string nm = DEREF_string ( sort_link ( cs ) ) ;
369
			    string nm = DEREF_string(sort_link(cs));
345
			    if ( nm ) {
370
			    if (nm) {
346
				sprintf_v ( buff, "%.*s", prec, nm ) ;
371
				sprintf_v(buff, "%.*s", prec, nm);
347
				output_string ( buff ) ;
372
				output_string(buff);
348
			    }
373
			    }
349
			    break ;
374
			    break;
350
			}
375
			}
351
			case 'U' : {
376
			case 'U': {
352
			    /* '%SU' -> sort unit name */
377
			    /* '%SU' -> sort unit name */
353
			    string nm = DEREF_string ( sort_unit ( cs ) ) ;
378
			    string nm = DEREF_string(sort_unit(cs));
354
			    if ( nm ) {
379
			    if (nm) {
355
				sprintf_v ( buff, "%.*s", prec, nm ) ;
380
				sprintf_v(buff, "%.*s", prec, nm);
356
				output_string ( buff ) ;
381
				output_string(buff);
357
			    }
382
			    }
358
			    break ;
383
			    break;
359
			}
384
			}
360
			case 'B' : {
385
			case 'B': {
361
			    /* '%SB' -> bits in encoding */
386
			    /* '%SB' -> bits in encoding */
362
			    unsigned b = 0 ;
387
			    unsigned b = 0;
363
			    if ( IS_info_basic ( ci ) ) {
388
			    if (IS_info_basic(ci)) {
364
				b = DEREF_unsigned ( info_basic_bits ( ci ) ) ;
389
				b = DEREF_unsigned(info_basic_bits(ci));
365
			    }
390
			    }
366
			    sprintf_v ( buff, "%u", b ) ;
391
			    sprintf_v(buff, "%u", b);
367
			    output_string ( buff ) ;
392
			    output_string(buff);
368
			    break ;
393
			    break;
369
			}
394
			}
370
			case 'E' : {
395
			case 'E': {
371
			    /* '%SE' -> extended encoding */
396
			    /* '%SE' -> extended encoding */
372
			    unsigned e = 0 ;
397
			    unsigned e = 0;
373
			    if ( IS_info_basic ( ci ) ) {
398
			    if (IS_info_basic(ci)) {
374
				e = DEREF_unsigned ( info_basic_extend ( ci ) ) ;
399
				e = DEREF_unsigned(info_basic_extend(ci));
375
			    }
400
			    }
376
			    sprintf_v ( buff, "%u", e ) ;
401
			    sprintf_v(buff, "%u", e);
377
			    output_string ( buff ) ;
402
			    output_string(buff);
378
			    break ;
403
			    break;
379
			}
404
			}
380
			case 'M' : {
405
			case 'M': {
381
			    /* '%SM' -> maximum encoding */
406
			    /* '%SM' -> maximum encoding */
382
			    unsigned m = 0 ;
407
			    unsigned m = 0;
383
			    if ( IS_info_basic ( ci ) ) {
408
			    if (IS_info_basic(ci)) {
384
				m = DEREF_unsigned ( info_basic_max ( ci ) ) ;
409
				m = DEREF_unsigned(info_basic_max(ci));
385
			    }
410
			    }
386
			    if ( have_prec ) m += ( unsigned ) prec ;
411
			    if (have_prec) m += (unsigned)prec;
387
			    sprintf_v ( buff, "%u", m ) ;
412
			    sprintf_v(buff, "%u", m);
388
			    output_string ( buff ) ;
413
			    output_string(buff);
389
			    break ;
414
			    break;
390
			}
415
			}
391
			case 'C' : {
416
			case 'C': {
392
			    /* '%SC' -> sortname information */
417
			    /* '%SC' -> sortname information */
393
			    cc = NULL_cons ;
418
			    cc = NULL_cons;
394
			    if ( IS_info_basic ( ci ) ) {
419
			    if (IS_info_basic(ci)) {
395
				cc = DEREF_cons ( info_basic_sortname ( ci ) ) ;
420
				cc = DEREF_cons(info_basic_sortname(ci));
396
			    }
421
			    }
397
			    goto cons_format ;
422
			    goto cons_format;
398
			}
423
			}
399
			case 'S' : {
424
			case 'S': {
400
			    /* '%SS' -> subsort information */
425
			    /* '%SS' -> subsort information */
401
			    if ( IS_info_clist_etc ( ci ) ) {
426
			    if (IS_info_clist_etc(ci)) {
402
				cs = DEREF_sort ( info_clist_etc_arg ( ci ) ) ;
427
				cs = DEREF_sort(info_clist_etc_arg(ci));
403
				ci = DEREF_info ( sort_info ( cs ) ) ;
428
				ci = DEREF_info(sort_info(cs));
404
			    }
429
			    }
405
			    goto sort_format ;
430
			    goto sort_format;
406
			}
431
			}
407
			case 'X' : {
432
			case 'X': {
408
			    /* '%SX' -> construct encoding string */
433
			    /* '%SX' -> construct encoding string */
409
			    IGNORE output_sort ( cs, 0 ) ;
434
			    IGNORE output_sort(cs, 0);
410
			    break ;
435
			    break;
411
			}
436
			}
412
			default : {
437
			default : {
413
			    goto bad_format ;
438
			    goto bad_format;
414
			}
439
			}
415
		    }
440
		    }
416
		    break ;
441
		    break;
417
		}
442
		}
418
 
443
 
419
		case 'V' : {
444
		case 'V': {
420
		    c = *( s++ ) ;
445
		    c = *(s++);
421
		    if ( c == 'A' ) {
446
		    if (c == 'A') {
422
			/* '%VA' -> major version number */
447
			/* '%VA' -> major version number */
423
			sprintf_v ( buff, "%u", crt_major ) ;
448
			sprintf_v(buff, "%u", crt_major);
424
			output_string ( buff ) ;
449
			output_string(buff);
425
		    } else if ( c == 'B' ) {
450
		    } else if (c == 'B') {
426
			/* '%VB' -> minor version number */
451
			/* '%VB' -> minor version number */
427
			sprintf_v ( buff, "%u", crt_minor ) ;
452
			sprintf_v(buff, "%u", crt_minor);
428
			output_string ( buff ) ;
453
			output_string(buff);
429
		    } else {
454
		    } else {
430
			goto bad_format ;
455
			goto bad_format;
431
		    }
456
		    }
432
		    break ;
457
		    break;
433
		}
458
		}
434
 
459
 
435
		case 'Z' : {
460
		case 'Z': {
436
		    c = *( s++ ) ;
461
		    c = *(s++);
437
		    if ( c == 'V' ) {
462
		    if (c == 'V') {
438
			/* %ZV -> program version */
463
			/* %ZV -> program version */
439
			sprintf_v ( buff, "%.*s", prec, progvers ) ;
464
			sprintf_v(buff, "%.*s", prec, progvers);
440
			output_string ( buff ) ;
465
			output_string(buff);
441
		    } else if ( c == 'X' ) {
466
		    } else if (c == 'X') {
442
			/* %ZX -> program name */
467
			/* %ZX -> program name */
443
			sprintf_v ( buff, "%.*s", prec, progname ) ;
468
			sprintf_v(buff, "%.*s", prec, progname);
444
			output_string ( buff ) ;
469
			output_string(buff);
445
		    } else {
470
		    } else {
446
			goto bad_format ;
471
			goto bad_format;
447
		    }
472
		    }
448
		    break ;
473
		    break;
449
		}
474
		}
450
 
475
 
451
		case 'b' : {
476
		case 'b': {
452
		    /* '%b' -> backspaces */
477
		    /* '%b' -> backspaces */
453
		    if ( !have_prec ) prec = 1 ;
478
		    if (!have_prec) prec = 1;
454
		    output_posn -= prec ;
479
		    output_posn -= prec;
455
		    if ( output_posn < 0 ) output_posn = 0 ;
480
		    if (output_posn < 0) output_posn = 0;
456
		    break ;
481
		    break;
457
		}
482
		}
458
 
483
 
459
		case 't' : {
484
		case 't': {
460
		    /* '%t' -> tabs */
485
		    /* '%t' -> tabs */
461
		    if ( have_prec ) {
486
		    if (have_prec) {
462
			while ( crt_column < ( unsigned ) prec ) {
487
			while (crt_column < (unsigned)prec) {
463
			    output_char ( '\t' ) ;
488
			    output_char('\t');
464
			}
489
			}
465
		    }
490
		    }
466
		    break ;
491
		    break;
467
		}
492
		}
468
 
493
 
469
		case 'u' : {
494
		case 'u': {
470
		    /* '%u' -> unique value */
495
		    /* '%u' -> unique value */
471
		    if ( have_prec ) {
496
		    if (have_prec) {
472
			crt_unique = prec ;
497
			crt_unique = prec;
473
		    } else {
498
		    } else {
474
			prec = crt_unique++ ;
499
			prec = crt_unique++;
475
			sprintf_v ( buff, "%d", prec ) ;
500
			sprintf_v(buff, "%d", prec);
476
			output_string ( buff ) ;
501
			output_string(buff);
477
		    }
502
		    }
478
		    break ;
503
		    break;
479
		}
504
		}
480
 
505
 
481
		case '%' : {
506
		case '%': {
482
		    /* '%%' -> '%' */
507
		    /* '%%' -> '%' */
483
		    output_char ( '%' ) ;
508
		    output_char('%');
484
		    break ;
509
		    break;
485
		}
510
		}
486
 
511
 
487
		case '@' : {
512
		case '@': {
488
		    /* '%@' -> '@' */
513
		    /* '%@' -> '@' */
489
		    output_char ( '@' ) ;
514
		    output_char('@');
490
		    break ;
515
		    break;
491
		}
516
		}
492
 
517
 
493
		case '\n' : {
518
		case '\n': {
494
		    /* Escaped newline */
519
		    /* Escaped newline */
495
		    break ;
520
		    break;
496
		}
521
		}
497
 
522
 
498
		case '_' : {
523
		case '_': {
499
		    /* Dummy end marker */
524
		    /* Dummy end marker */
500
		    break ;
525
		    break;
501
		}
526
		}
502
 
527
 
503
		misplaced_arg : {
528
		misplaced_arg : {
504
		    error ( ERROR_SERIOUS, "Misplaced format, '%%%.2s'", s0 ) ;
529
		    error(ERROR_SERIOUS, "Misplaced format, '%%%.2s'", s0);
505
		    output_string ( "<error>" ) ;
530
		    output_string("<error>");
506
		    break ;
531
		    break;
507
		}
532
		}
508
 
533
 
509
		default :
534
		default :
510
		bad_format : {
535
		bad_format : {
511
		    error ( ERROR_SERIOUS, "Unknown format, '%%%.2s'", s0 ) ;
536
		    error(ERROR_SERIOUS, "Unknown format, '%%%.2s'", s0);
512
		    output_string ( "<error>" ) ;
537
		    output_string("<error>");
513
		    break ;
538
		    break;
514
		}
539
		}
515
	    }
540
	    }
516
	} else {
541
	} else {
517
	    output_char ( ( int ) c ) ;
542
	    output_char((int)c);
518
	}
543
	}
519
    }
544
    }
520
    return ;
545
    return;
521
}
546
}
522
 
547
 
523
 
548
 
524
/*
549
/*
525
    EVALUATE A CONDITION
550
    EVALUATE A CONDITION
526
 
551
 
527
    This routine evaluates the condition given by the string s.
552
    This routine evaluates the condition given by the string s.
528
*/
553
*/
529
 
554
 
530
static int eval_cond
555
static int
531
    PROTO_N ( ( s ) )
-
 
532
    PROTO_T ( string s )
556
eval_cond(string s)
533
{
557
{
534
    string s0 = s ;
558
    string s0 = s;
535
    SORT cs = crt_sort ;
559
    SORT cs = crt_sort;
536
    SORT_INFO ci = crt_info ;
560
    SORT_INFO ci = crt_info;
537
    CONSTRUCT cc = crt_cons ;
561
    CONSTRUCT cc = crt_cons;
538
    PARAMETER cp = crt_param ;
562
    PARAMETER cp = crt_param;
539
 
563
 
540
    if ( s [0] == '!' ) {
564
    if (s[0] == '!') {
541
	/* Negate condition */
565
	/* Negate condition */
542
	return ( !eval_cond ( s + 1 ) ) ;
566
	return(!eval_cond(s + 1));
543
    }
567
    }
544
 
568
 
545
    if ( strneq ( s, "sort.", 5 ) ) {
569
    if (strneq(s, "sort.", 5)) {
546
	/* Sort conditions */
570
	/* Sort conditions */
547
	s += 5 ;
571
	s += 5;
548
	sort_label : {
572
	sort_label : {
549
	    unsigned tag = 100 ;
573
	    unsigned tag = 100;
550
	    if ( !IS_NULL_info ( ci ) ) tag = TAG_info ( ci ) ;
574
	    if (!IS_NULL_info(ci)) tag = TAG_info(ci);
551
	    if ( streq ( s, "builtin" ) ) return ( tag == info_builtin_tag ) ;
575
	    if (streq(s, "builtin")) return(tag == info_builtin_tag);
552
	    if ( streq ( s, "basic" ) ) return ( tag == info_basic_tag ) ;
576
	    if (streq(s, "basic")) return(tag == info_basic_tag);
553
	    if ( streq ( s, "dummy" ) ) return ( tag == info_dummy_tag ) ;
577
	    if (streq(s, "dummy")) return(tag == info_dummy_tag);
554
	    if ( streq ( s, "list" ) ) return ( tag == info_clist_tag ) ;
578
	    if (streq(s, "list")) return(tag == info_clist_tag);
555
	    if ( streq ( s, "slist" ) ) return ( tag == info_slist_tag ) ;
579
	    if (streq(s, "slist")) return(tag == info_slist_tag);
556
	    if ( streq ( s, "option" ) ) return ( tag == info_option_tag ) ;
580
	    if (streq(s, "option")) return(tag == info_option_tag);
557
	    if ( streq ( s, "simple" ) ) {
581
	    if (streq(s, "simple")) {
558
		return ( tag == info_basic_tag || tag == info_dummy_tag ) ;
582
		return(tag == info_basic_tag || tag == info_dummy_tag);
559
	    }
583
	    }
560
	    if ( streq ( s, "compound" ) ) {
584
	    if (streq(s, "compound")) {
561
		if ( tag == info_option_tag ) return ( 1 ) ;
585
		if (tag == info_option_tag) return(1);
562
		return ( tag == info_clist_tag || tag == info_slist_tag ) ;
586
		return(tag == info_clist_tag || tag == info_slist_tag);
563
	    }
587
	    }
564
	    if ( streq ( s, "extends" ) ) {
588
	    if (streq(s, "extends")) {
565
		if ( tag == info_basic_tag ) {
589
		if (tag == info_basic_tag) {
566
		    unsigned a = DEREF_unsigned ( info_basic_extend ( ci ) ) ;
590
		    unsigned a = DEREF_unsigned(info_basic_extend(ci));
567
		    if ( a ) return ( 1 ) ;
591
		    if (a) return(1);
568
		}
592
		}
569
		return ( 0 ) ;
593
		return(0);
570
	    }
594
	    }
571
	    if ( streq ( s, "special" ) ) {
595
	    if (streq(s, "special")) {
572
		int a = 0 ;
596
		int a = 0;
573
		if ( !IS_NULL_sort ( cs ) ) {
597
		if (!IS_NULL_sort(cs)) {
574
		    a = DEREF_int ( sort_special ( cs ) ) ;
598
		    a = DEREF_int(sort_special(cs));
575
		}
599
		}
576
		return ( a ) ;
600
		return(a);
577
	    }
601
	    }
578
	    if ( streq ( s, "edge" ) ) {
602
	    if (streq(s, "edge")) {
579
		int a = 0 ;
603
		int a = 0;
580
		if ( !IS_NULL_sort ( cs ) ) {
604
		if (!IS_NULL_sort(cs)) {
581
		    a = DEREF_int ( sort_edge ( cs ) ) ;
605
		    a = DEREF_int(sort_edge(cs));
582
		}
606
		}
583
		return ( a ) ;
607
		return(a);
584
	    }
608
	    }
585
	    if ( streq ( s, "link" ) ) {
609
	    if (streq(s, "link")) {
586
		if ( !IS_NULL_sort ( cs ) ) {
610
		if (!IS_NULL_sort(cs)) {
587
		    string nm = DEREF_string ( sort_link ( cs ) ) ;
611
		    string nm = DEREF_string(sort_link(cs));
588
		    if ( nm ) return ( 1 ) ;
612
		    if (nm) return(1);
589
		}
613
		}
590
		return ( 0 ) ;
614
		return(0);
591
	    }
615
	    }
592
	    if ( streq ( s, "unit" ) ) {
616
	    if (streq(s, "unit")) {
593
		if ( !IS_NULL_sort ( cs ) ) {
617
		if (!IS_NULL_sort(cs)) {
594
		    string nm = DEREF_string ( sort_unit ( cs ) ) ;
618
		    string nm = DEREF_string(sort_unit(cs));
595
		    if ( nm ) return ( 1 ) ;
619
		    if (nm) return(1);
596
		}
620
		}
597
		return ( 0 ) ;
621
		return(0);
598
	    }
622
	    }
599
	    if ( strneq ( s, "name.", 5 ) ) {
623
	    if (strneq(s, "name.", 5)) {
600
		if ( tag == info_basic_tag ) {
624
		if (tag == info_basic_tag) {
601
		    cc = DEREF_cons ( info_basic_sortname ( ci ) ) ;
625
		    cc = DEREF_cons(info_basic_sortname(ci));
602
		} else {
626
		} else {
603
		    cc = NULL_cons ;
627
		    cc = NULL_cons;
604
		}
628
		}
605
		goto cons_label ;
629
		goto cons_label;
606
	    }
630
	    }
607
	    if ( strneq ( s, "sub.", 4 ) ) {
631
	    if (strneq(s, "sub.", 4)) {
608
		s += 4 ;
632
		s += 4;
609
		if ( tag == info_clist_tag || tag == info_slist_tag ||
633
		if (tag == info_clist_tag || tag == info_slist_tag ||
610
		     tag == info_option_tag ) {
634
		     tag == info_option_tag) {
611
		    cs = DEREF_sort ( info_clist_etc_arg ( ci ) ) ;
635
		    cs = DEREF_sort(info_clist_etc_arg(ci));
612
		    ci = DEREF_info ( sort_info ( cs ) ) ;
636
		    ci = DEREF_info(sort_info(cs));
613
		}
637
		}
614
		goto sort_label ;
638
		goto sort_label;
615
	    }
639
	    }
616
	    if ( strneq ( s, "eq.", 3 ) ) {
640
	    if (strneq(s, "eq.", 3)) {
617
		s += 3 ;
641
		s += 3;
618
		if ( !IS_NULL_sort ( cs ) ) {
642
		if (!IS_NULL_sort(cs)) {
619
		    string nm = DEREF_string ( sort_name ( cs ) ) ;
643
		    string nm = DEREF_string(sort_name(cs));
620
		    if ( streq ( nm, s ) ) return ( 1 ) ;
644
		    if (streq(nm, s)) return(1);
621
		}
645
		}
622
		return ( 0 ) ;
646
		return(0);
623
	    }
647
	    }
624
	}
648
	}
625
 
649
 
626
    } else if ( strneq ( s, "cons.", 5 ) ) {
650
    } else if (strneq(s, "cons.", 5)) {
627
	/* Construct conditions */
651
	/* Construct conditions */
628
	cons_label : {
652
	cons_label : {
629
	    unsigned kind = KIND_dummy ;
653
	    unsigned kind = KIND_dummy;
630
	    s += 5 ;
654
	    s += 5;
631
	    if ( strneq ( s, "sort.", 5 ) ) {
655
	    if (strneq(s, "sort.", 5)) {
632
		s += 5 ;
656
		s += 5;
633
		if ( IS_NULL_cons ( cc ) ) {
657
		if (IS_NULL_cons(cc)) {
634
		    cs = NULL_sort ;
658
		    cs = NULL_sort;
635
		    ci = NULL_info ;
659
		    ci = NULL_info;
636
		}
660
		}
637
		goto sort_label ;
661
		goto sort_label;
638
	    }
662
	    }
639
	    if ( !IS_NULL_cons ( cc ) ) {
663
	    if (!IS_NULL_cons(cc)) {
640
		kind = DEREF_unsigned ( cons_kind ( cc ) ) ;
664
		kind = DEREF_unsigned(cons_kind(cc));
641
	    }
665
	    }
642
	    if ( streq ( s, "simple" ) ) return ( kind == KIND_simple ) ;
666
	    if (streq(s, "simple")) return(kind == KIND_simple);
643
	    if ( streq ( s, "token" ) ) return ( kind == KIND_token ) ;
667
	    if (streq(s, "token")) return(kind == KIND_token);
644
	    if ( streq ( s, "cond" ) ) return ( kind == KIND_cond ) ;
668
	    if (streq(s, "cond")) return(kind == KIND_cond);
645
	    if ( streq ( s, "edge" ) ) return ( kind == KIND_edge ) ;
669
	    if (streq(s, "edge")) return(kind == KIND_edge);
646
	    if ( streq ( s, "foreign" ) ) return ( kind == KIND_foreign ) ;
670
	    if (streq(s, "foreign")) return(kind == KIND_foreign);
647
	    if ( streq ( s, "special" ) ) return ( kind == KIND_special ) ;
671
	    if (streq(s, "special")) return(kind == KIND_special);
648
	    if ( streq ( s, "params" ) ) {
672
	    if (streq(s, "params")) {
649
		if ( !IS_NULL_cons ( cc ) ) {
673
		if (!IS_NULL_cons(cc)) {
650
		    LIST ( PARAMETER ) p = DEREF_list ( cons_pars ( cc ) ) ;
674
		    LIST(PARAMETER)p = DEREF_list(cons_pars(cc));
651
		    if ( !IS_NULL_list ( p ) ) return ( 1 ) ;
675
		    if (!IS_NULL_list(p)) return(1);
652
		}
676
		}
653
		return ( 0 ) ;
677
		return(0);
654
	    }
678
	    }
655
	    if ( streq ( s, "extends" ) ) {
679
	    if (streq(s, "extends")) {
656
		if ( !IS_NULL_cons ( cc ) ) {
680
		if (!IS_NULL_cons(cc)) {
657
		    if ( !IS_NULL_info ( ci ) && IS_info_basic ( ci ) ) {
681
		    if (!IS_NULL_info(ci) && IS_info_basic(ci)) {
658
			unsigned b, e ;
682
			unsigned b, e;
659
			b = DEREF_unsigned ( info_basic_bits ( ci ) ) ;
683
			b = DEREF_unsigned(info_basic_bits(ci));
660
			e = DEREF_unsigned ( cons_encode ( cc ) ) ;
684
			e = DEREF_unsigned(cons_encode(cc));
661
			if ( e >= ( ( unsigned ) 1 << b ) ) return ( 1 ) ;
685
			if (e >= ((unsigned)1 << b)) return(1);
662
		    }
686
		    }
663
		}
687
		}
664
		return ( 0 ) ;
688
		return(0);
665
	    }
689
	    }
666
	    if ( strneq ( s, "eq.", 3 ) ) {
690
	    if (strneq(s, "eq.", 3)) {
667
		s += 3 ;
691
		s += 3;
668
		if ( !IS_NULL_cons ( cc ) ) {
692
		if (!IS_NULL_cons(cc)) {
669
		    string nm = DEREF_string ( cons_name ( cc ) ) ;
693
		    string nm = DEREF_string(cons_name(cc));
670
		    if ( streq ( nm, s ) ) return ( 1 ) ;
694
		    if (streq(nm, s)) return(1);
671
		}
695
		}
672
		return ( 0 ) ;
696
		return(0);
673
	    }
697
	    }
674
	}
698
	}
675
 
699
 
676
    } else if ( strneq ( s, "param.", 6 ) ) {
700
    } else if (strneq(s, "param.", 6)) {
677
	/* Parameter conditions */
701
	/* Parameter conditions */
678
	s += 6 ;
702
	s += 6;
679
	if ( strneq ( s, "sort.", 5 ) ) {
703
	if (strneq(s, "sort.", 5)) {
680
	    s += 5 ;
704
	    s += 5;
681
	    if ( !IS_NULL_par ( cp ) ) {
705
	    if (!IS_NULL_par(cp)) {
682
		cs = DEREF_sort ( par_type ( cp ) ) ;
706
		cs = DEREF_sort(par_type(cp));
683
		ci = DEREF_info ( sort_info ( cs ) ) ;
707
		ci = DEREF_info(sort_info(cs));
684
	    } else {
708
	    } else {
685
		cs = NULL_sort ;
709
		cs = NULL_sort;
686
		ci = NULL_info ;
710
		ci = NULL_info;
687
	    }
711
	    }
688
	    goto sort_label ;
712
	    goto sort_label;
689
	}
713
	}
690
	if ( streq ( s, "align" ) ) {
714
	if (streq(s, "align")) {
691
	    int a = 0 ;
715
	    int a = 0;
692
	    if ( !IS_NULL_par ( cp ) ) a = DEREF_int ( par_align ( cp ) ) ;
716
	    if (!IS_NULL_par(cp)) a = DEREF_int(par_align(cp));
693
	    return ( a ) ;
717
	    return(a);
694
	}
718
	}
695
	if ( streq ( s, "break" ) ) {
719
	if (streq(s, "break")) {
696
	    int a = 0 ;
720
	    int a = 0;
697
	    if ( !IS_NULL_par ( cp ) ) a = DEREF_int ( par_brk ( cp ) ) ;
721
	    if (!IS_NULL_par(cp)) a = DEREF_int(par_brk(cp));
698
	    return ( a ) ;
722
	    return(a);
699
	}
723
	}
700
	if ( streq ( s, "intro" ) ) {
724
	if (streq(s, "intro")) {
701
	    int a = 0 ;
725
	    int a = 0;
702
	    if ( !IS_NULL_par ( cp ) ) a = DEREF_int ( par_intro ( cp ) ) ;
726
	    if (!IS_NULL_par(cp)) a = DEREF_int(par_intro(cp));
703
	    return ( a ) ;
727
	    return(a);
704
	}
728
	}
705
	if ( streq ( s, "first" ) ) {
729
	if (streq(s, "first")) {
706
	    return ( crt_param_no == 0 ) ;
730
	    return(crt_param_no == 0);
707
	}
731
	}
708
	if ( streq ( s, "last" ) ) {
732
	if (streq(s, "last")) {
709
	    return ( crt_param_no == last_param_no ) ;
733
	    return(crt_param_no == last_param_no);
710
	}
734
	}
711
	if ( strneq ( s, "eq.", 3 ) ) {
735
	if (strneq(s, "eq.", 3)) {
712
	    s += 3 ;
736
	    s += 3;
713
	    if ( !IS_NULL_par ( cp ) ) {
737
	    if (!IS_NULL_par(cp)) {
714
		string nm = DEREF_string ( par_name ( cp ) ) ;
738
		string nm = DEREF_string(par_name(cp));
715
		if ( streq ( nm, s ) ) return ( 1 ) ;
739
		if (streq(nm, s)) return(1);
716
	    }
740
	    }
717
	    return ( 0 ) ;
741
	    return(0);
718
	}
742
	}
719
 
743
 
720
    } else {
744
    } else {
721
	/* Other conditions */
745
	/* Other conditions */
722
	if ( streq ( s, "uniq" ) ) return ( crt_unique ) ;
746
	if (streq(s, "uniq")) return(crt_unique);
723
	if ( streq ( s, "true" ) ) return ( 1 ) ;
747
	if (streq(s, "true")) return(1);
724
	if ( streq ( s, "false" ) ) return ( 0 ) ;
748
	if (streq(s, "false")) return(0);
725
    }
749
    }
726
    error ( ERROR_SERIOUS, "Unknown condition, '%s'", s0 ) ;
750
    error(ERROR_SERIOUS, "Unknown condition, '%s'", s0);
727
    return ( 0 ) ;
751
    return(0);
728
}
752
}
729
 
753
 
730
 
754
 
731
/*
755
/*
732
    WRITE A TEMPLATE FILE
756
    WRITE A TEMPLATE FILE
733
 
757
 
734
    This routine writes the template file given by the commands cmd for
758
    This routine writes the template file given by the commands cmd for
735
    the specification spec to the output file.
759
    the specification spec to the output file.
736
*/
760
*/
737
 
761
 
738
static void output_template
762
static void
739
    PROTO_N ( ( spec, cmd ) )
-
 
740
    PROTO_T ( SPECIFICATION spec X COMMAND cmd )
763
output_template(SPECIFICATION spec, COMMAND cmd)
741
{
764
{
742
    if ( !IS_NULL_cmd ( cmd ) ) {
765
    if (!IS_NULL_cmd(cmd)) {
743
	crt_line_no = DEREF_int ( cmd_line ( cmd ) ) ;
766
	crt_line_no = DEREF_int(cmd_line(cmd));
744
	switch ( TAG_cmd ( cmd ) ) {
767
	switch (TAG_cmd(cmd)) {
745
	    case cmd_simple_tag : {
768
	    case cmd_simple_tag: {
746
		string s = DEREF_string ( cmd_simple_text ( cmd ) ) ;
769
		string s = DEREF_string(cmd_simple_text(cmd));
747
		output ( s ) ;
770
		output(s);
748
		break ;
771
		break;
749
	    }
772
	    }
750
	    case cmd_compound_tag : {
773
	    case cmd_compound_tag: {
751
		LIST ( COMMAND ) p ;
774
		LIST(COMMAND)p;
752
		p = DEREF_list ( cmd_compound_seq ( cmd ) ) ;
775
		p = DEREF_list(cmd_compound_seq(cmd));
753
		while ( !IS_NULL_list ( p ) ) {
776
		while (!IS_NULL_list(p)) {
754
		    COMMAND a = DEREF_cmd ( HEAD_list ( p ) ) ;
777
		    COMMAND a = DEREF_cmd(HEAD_list(p));
755
		    output_template ( spec, a ) ;
778
		    output_template(spec, a);
756
		    p = TAIL_list ( p ) ;
779
		    p = TAIL_list(p);
757
		}
780
		}
758
		break ;
781
		break;
759
	    }
782
	    }
760
	    case cmd_loop_tag : {
783
	    case cmd_loop_tag: {
761
		string s = DEREF_string ( cmd_loop_control ( cmd ) ) ;
784
		string s = DEREF_string(cmd_loop_control(cmd));
762
		COMMAND a = DEREF_cmd ( cmd_loop_body ( cmd ) ) ;
785
		COMMAND a = DEREF_cmd(cmd_loop_body(cmd));
763
		if ( streq ( s, "sort" ) ) {
786
		if (streq(s, "sort")) {
764
		    /* Loop over all sorts */
787
		    /* Loop over all sorts */
765
		    SORT ls = crt_sort ;
788
		    SORT ls = crt_sort;
766
		    SORT_INFO li = crt_info ;
789
		    SORT_INFO li = crt_info;
767
		    LIST ( SORT ) ps = DEREF_list ( spec_sorts ( spec ) ) ;
790
		    LIST(SORT)ps = DEREF_list(spec_sorts(spec));
768
		    while ( !IS_NULL_list ( ps ) ) {
791
		    while (!IS_NULL_list(ps)) {
769
			SORT cs = DEREF_sort ( HEAD_list ( ps ) ) ;
792
			SORT cs = DEREF_sort(HEAD_list(ps));
770
			int mark = DEREF_int ( sort_mark ( cs ) ) ;
793
			int mark = DEREF_int(sort_mark(cs));
771
			if ( mark ) {
794
			if (mark) {
772
			    SORT_INFO ci = DEREF_info ( sort_info ( cs ) ) ;
795
			    SORT_INFO ci = DEREF_info(sort_info(cs));
773
			    if ( !IS_NULL_info ( ci ) ) {
796
			    if (!IS_NULL_info(ci)) {
774
				crt_sort = cs ;
797
				crt_sort = cs;
775
				crt_info = ci ;
798
				crt_info = ci;
776
				output_template ( spec, a ) ;
799
				output_template(spec, a);
777
			    }
800
			    }
778
			}
801
			}
779
			ps = TAIL_list ( ps ) ;
802
			ps = TAIL_list(ps);
780
		    }
803
		    }
781
		    crt_sort = ls ;
804
		    crt_sort = ls;
782
		    crt_info = li ;
805
		    crt_info = li;
783
 
806
 
784
		} else if ( streq ( s, "sort.cons" ) ) {
807
		} else if (streq(s, "sort.cons")) {
785
		    /* Loop over all constructs */
808
		    /* Loop over all constructs */
786
		    CONSTRUCT lc = crt_cons ;
809
		    CONSTRUCT lc = crt_cons;
787
		    SORT_INFO ci = crt_info ;
810
		    SORT_INFO ci = crt_info;
788
		    if ( !IS_NULL_info ( ci ) ) {
811
		    if (!IS_NULL_info(ci)) {
789
			if ( IS_info_basic ( ci ) ) {
812
			if (IS_info_basic(ci)) {
790
			    LIST ( CONSTRUCT ) pc ;
813
			    LIST(CONSTRUCT)pc;
791
			    pc = DEREF_list ( info_basic_cons ( ci ) ) ;
814
			    pc = DEREF_list(info_basic_cons(ci));
792
			    while ( !IS_NULL_list ( pc ) ) {
815
			    while (!IS_NULL_list(pc)) {
793
				crt_cons = DEREF_cons ( HEAD_list ( pc ) ) ;
816
				crt_cons = DEREF_cons(HEAD_list(pc));
794
				output_template ( spec, a ) ;
817
				output_template(spec, a);
795
				pc = TAIL_list ( pc ) ;
818
				pc = TAIL_list(pc);
796
			    }
819
			    }
797
			} else if ( IS_info_dummy ( ci ) ) {
820
			} else if (IS_info_dummy(ci)) {
798
			    crt_cons = DEREF_cons ( info_dummy_cons ( ci ) ) ;
821
			    crt_cons = DEREF_cons(info_dummy_cons(ci));
799
			    output_template ( spec, a ) ;
822
			    output_template(spec, a);
800
			}
823
			}
801
		    }
824
		    }
802
		    crt_cons = lc ;
825
		    crt_cons = lc;
803
 
826
 
804
		} else if ( streq ( s, "cons.param" ) ) {
827
		} else if (streq(s, "cons.param")) {
805
		    /* Loop over all parameters */
828
		    /* Loop over all parameters */
806
		    int np = crt_param_no ;
829
		    int np = crt_param_no;
807
		    int mp = last_param_no ;
830
		    int mp = last_param_no;
808
		    PARAMETER lp = crt_param ;
831
		    PARAMETER lp = crt_param;
809
		    CONSTRUCT cc = crt_cons ;
832
		    CONSTRUCT cc = crt_cons;
810
		    if ( !IS_NULL_cons ( cc ) ) {
833
		    if (!IS_NULL_cons(cc)) {
811
			LIST ( PARAMETER ) pp ;
834
			LIST(PARAMETER)pp;
812
			pp = DEREF_list ( cons_pars ( cc ) ) ;
835
			pp = DEREF_list(cons_pars(cc));
813
			crt_param_no = 0 ;
836
			crt_param_no = 0;
814
			last_param_no = ( int ) LENGTH_list ( pp ) - 1 ;
837
			last_param_no = (int)LENGTH_list(pp) - 1;
815
			while ( !IS_NULL_list ( pp ) ) {
838
			while (!IS_NULL_list(pp)) {
816
			    crt_param = DEREF_par ( HEAD_list ( pp ) ) ;
839
			    crt_param = DEREF_par(HEAD_list(pp));
817
			    output_template ( spec, a ) ;
840
			    output_template(spec, a);
818
			    crt_param_no++ ;
841
			    crt_param_no++;
819
			    pp = TAIL_list ( pp ) ;
842
			    pp = TAIL_list(pp);
820
			}
843
			}
821
		    }
844
		    }
822
		    last_param_no = mp ;
845
		    last_param_no = mp;
823
		    crt_param_no = np ;
846
		    crt_param_no = np;
824
		    crt_param = lp ;
847
		    crt_param = lp;
825
 
848
 
826
		} else if ( streq ( s, "param.prev" ) ) {
849
		} else if (streq(s, "param.prev")) {
827
		    /* Loop over all previous parameters */
850
		    /* Loop over all previous parameters */
828
		    int np = crt_param_no ;
851
		    int np = crt_param_no;
829
		    int mp = last_param_no ;
852
		    int mp = last_param_no;
830
		    PARAMETER lp = crt_param ;
853
		    PARAMETER lp = crt_param;
831
		    CONSTRUCT cc = crt_cons ;
854
		    CONSTRUCT cc = crt_cons;
832
		    if ( !IS_NULL_cons ( cc ) ) {
855
		    if (!IS_NULL_cons(cc)) {
833
			LIST ( PARAMETER ) pp ;
856
			LIST(PARAMETER)pp;
834
			pp = DEREF_list ( cons_pars ( cc ) ) ;
857
			pp = DEREF_list(cons_pars(cc));
835
			crt_param_no = 0 ;
858
			crt_param_no = 0;
836
			last_param_no = np - 1 ;
859
			last_param_no = np - 1;
837
			while ( !IS_NULL_list ( pp ) && crt_param_no < np ) {
860
			while (!IS_NULL_list(pp) && crt_param_no < np) {
838
			    crt_param = DEREF_par ( HEAD_list ( pp ) ) ;
861
			    crt_param = DEREF_par(HEAD_list(pp));
839
			    output_template ( spec, a ) ;
862
			    output_template(spec, a);
840
			    crt_param_no++ ;
863
			    crt_param_no++;
841
			    pp = TAIL_list ( pp ) ;
864
			    pp = TAIL_list(pp);
842
			}
865
			}
843
		    }
866
		    }
844
		    last_param_no = mp ;
867
		    last_param_no = mp;
845
		    crt_param_no = np ;
868
		    crt_param_no = np;
846
		    crt_param = lp ;
869
		    crt_param = lp;
847
 
870
 
848
		} else {
871
		} else {
849
		    error ( ERROR_SERIOUS, "Unknown control, '%s'", s ) ;
872
		    error(ERROR_SERIOUS, "Unknown control, '%s'", s);
850
		}
873
		}
851
		break ;
874
		break;
852
	    }
875
	    }
853
	    case cmd_cond_tag : {
876
	    case cmd_cond_tag: {
854
		string s = DEREF_string ( cmd_cond_control ( cmd ) ) ;
877
		string s = DEREF_string(cmd_cond_control(cmd));
855
		COMMAND a = DEREF_cmd ( cmd_cond_true_code ( cmd ) ) ;
878
		COMMAND a = DEREF_cmd(cmd_cond_true_code(cmd));
856
		COMMAND b = DEREF_cmd ( cmd_cond_false_code ( cmd ) ) ;
879
		COMMAND b = DEREF_cmd(cmd_cond_false_code(cmd));
857
		if ( eval_cond ( s ) ) {
880
		if (eval_cond(s)) {
858
		    output_template ( spec, a ) ;
881
		    output_template(spec, a);
859
		} else {
882
		} else {
860
		    output_template ( spec, b ) ;
883
		    output_template(spec, b);
861
		}
884
		}
862
		break ;
885
		break;
863
	    }
886
	    }
864
	    case cmd_use_tag : {
887
	    case cmd_use_tag: {
865
		int m = 1 ;
888
		int m = 1;
866
		string c = DEREF_string ( cmd_use_cons ( cmd ) ) ;
889
		string c = DEREF_string(cmd_use_cons(cmd));
867
		string s = DEREF_string ( cmd_use_sort ( cmd ) ) ;
890
		string s = DEREF_string(cmd_use_sort(cmd));
868
		while ( s [0] == '!' ) {
891
		while (s[0] == '!') {
869
		    m = !m ;
892
		    m = !m;
870
		    s++ ;
893
		    s++;
871
		}
894
		}
872
		if ( c == NULL && streq ( s, "all" ) ) {
895
		if (c == NULL && streq(s, "all")) {
873
		    mark_all_sorts ( m ) ;
896
		    mark_all_sorts(m);
874
		} else {
897
		} else {
875
		    SORT sn = find_sort ( s, 0 ) ;
898
		    SORT sn = find_sort(s, 0);
876
		    if ( c ) {
899
		    if (c) {
877
			CONSTRUCT cn = find_construct ( sn, c ) ;
900
			CONSTRUCT cn = find_construct(sn, c);
878
			mark_construct ( cn, m ) ;
901
			mark_construct(cn, m);
879
		    } else {
902
		    } else {
880
			mark_sort ( sn, m ) ;
903
			mark_sort(sn, m);
881
		    }
904
		    }
882
		}
905
		}
883
		break ;
906
		break;
884
	    }
907
	    }
885
	    case cmd_special_tag : {
908
	    case cmd_special_tag: {
886
		SORT sn ;
909
		SORT sn;
887
		int m = 1 ;
910
		int m = 1;
888
		string c = DEREF_string ( cmd_special_cons ( cmd ) ) ;
911
		string c = DEREF_string(cmd_special_cons(cmd));
889
		string s = DEREF_string ( cmd_special_sort ( cmd ) ) ;
912
		string s = DEREF_string(cmd_special_sort(cmd));
890
		while ( s [0] == '!' ) {
913
		while (s[0] == '!') {
891
		    m = !m ;
914
		    m = !m;
892
		    s++ ;
915
		    s++;
893
		}
916
		}
894
		sn = find_sort ( s, 0 ) ;
917
		sn = find_sort(s, 0);
895
		if ( c ) {
918
		if (c) {
896
		    if ( m ) {
919
		    if (m) {
897
			set_special ( sn, c, KIND_special ) ;
920
			set_special(sn, c, KIND_special);
898
		    } else {
921
		    } else {
899
			set_special ( sn, c, KIND_simple ) ;
922
			set_special(sn, c, KIND_simple);
900
		    }
923
		    }
901
		} else {
924
		} else {
902
		    COPY_int ( sort_special ( sn ), m ) ;
925
		    COPY_int(sort_special(sn), m);
903
		}
926
		}
904
		mark_sort ( sn, 1 ) ;
927
		mark_sort(sn, 1);
905
		break ;
928
		break;
906
	    }
929
	    }
907
	}
930
	}
908
    }
931
    }
909
    return ;
932
    return;
910
}
933
}
911
 
934
 
912
 
935
 
913
/*
936
/*
914
    MAIN OUTPUT ROUTINE
937
    MAIN OUTPUT ROUTINE
915
 
938
 
916
    This routine outputs all the information concerning the TDF specification
939
    This routine outputs all the information concerning the TDF specification
917
    spec to the output file nm using the template cmd.
940
    spec to the output file nm using the template cmd.
918
*/
941
*/
919
 
942
 
920
void output_spec
943
void
921
    PROTO_N ( ( nm, spec, cmd ) )
-
 
922
    PROTO_T ( char *nm X SPECIFICATION spec X COMMAND cmd )
944
output_spec(char *nm, SPECIFICATION spec, COMMAND cmd)
923
{
945
{
924
    CONST char *tnm = crt_file_name ;
946
    CONST char *tnm = crt_file_name;
925
    crt_line_no = 1 ;
947
    crt_line_no = 1;
926
    if ( nm == NULL || streq ( nm, "-" ) ) {
948
    if (nm == NULL || streq(nm, "-")) {
927
	crt_file_name = "<stdout>" ;
949
	crt_file_name = "<stdout>";
928
	output_file = stdout ;
950
	output_file = stdout;
929
	nm = NULL ;
951
	nm = NULL;
930
    } else {
952
    } else {
931
	crt_file_name = nm ;
953
	crt_file_name = nm;
932
	output_file = fopen ( nm, "w" ) ;
954
	output_file = fopen(nm, "w");
933
	if ( output_file == NULL ) {
955
	if (output_file == NULL) {
934
	    error ( ERROR_SERIOUS, "Can't open output file, '%s'", nm ) ;
956
	    error(ERROR_SERIOUS, "Can't open output file, '%s'", nm);
935
	    return ;
957
	    return;
936
	}
958
	}
937
    }
959
    }
938
    output_posn = 0 ;
960
    output_posn = 0;
939
    crt_column = 0 ;
961
    crt_column = 0;
940
    crt_file_name = tnm ;
962
    crt_file_name = tnm;
941
    crt_major = DEREF_unsigned ( spec_major ( spec ) ) ;
963
    crt_major = DEREF_unsigned(spec_major(spec));
942
    crt_minor = DEREF_unsigned ( spec_minor ( spec ) ) ;
964
    crt_minor = DEREF_unsigned(spec_minor(spec));
943
    output_template ( spec, cmd ) ;
965
    output_template(spec, cmd);
944
    if ( output_posn ) output_char ( '\n' ) ;
966
    if (output_posn) output_char('\n');
945
    if ( nm ) fclose_v ( output_file ) ;
967
    if (nm) fclose_v(output_file);
946
    return ;
968
    return;
947
}
969
}