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 40... Line 70...
40
    LIST OF FREE NODES
70
    LIST OF FREE NODES
41
 
71
 
42
    Nodes are allocated from this list.
72
    Nodes are allocated from this list.
43
*/
73
*/
44
 
74
 
45
static node *free_nodes = null ;
75
static node *free_nodes = null;
46
 
76
 
47
 
77
 
48
/*
78
/*
49
    CREATE A NEW NODE
79
    CREATE A NEW NODE
50
 
80
 
51
    A new node is created and its fields cleared.
81
    A new node is created and its fields cleared.
52
*/
82
*/
53
 
83
 
54
node *new_node
84
node *
55
    PROTO_Z ()
85
new_node(void)
56
{
86
{
57
    node *p = free_nodes ;
87
    node *p = free_nodes;
58
    if ( p == null ) {
88
    if (p == null) {
59
	int i, m = 1000 ;
89
	int i, m = 1000;
60
	p = alloc_nof ( node, m ) ;
90
	p = alloc_nof(node, m);
61
	for ( i = 0 ; i < m - 1 ; i++ ) {
91
	for (i = 0; i < m - 1; i++) {
62
	    ( p + i )->bro = p + ( i + 1 ) ;
92
	   (p + i) ->bro = p + (i + 1);
63
	    ( p + i )->son = null ;
93
	   (p + i) ->son = null;
64
	}
94
	}
65
	( p + ( m - 1 ) )->bro = null ;
95
	(p + (m - 1)) ->bro = null;
66
	( p + ( m - 1 ) )->son = null ;
96
	(p + (m - 1)) ->son = null;
67
	free_nodes = p ;
97
	free_nodes = p;
68
    }
98
    }
69
    free_nodes = p->bro ;
99
    free_nodes = p->bro;
70
    p->cons = null ;
100
    p->cons = null;
71
    p->son = null ;
101
    p->son = null;
72
    p->bro = null ;
102
    p->bro = null;
73
    p->shape = null ;
103
    p->shape = null;
74
    return ( p ) ;
104
    return(p);
75
}
105
}
76
 
106
 
77
 
107
 
78
/*
108
/*
79
    FREE A NODE
109
    FREE A NODE
80
 
110
 
81
    The node p is recursively returned to the free list.
111
    The node p is recursively returned to the free list.
82
*/
112
*/
83
 
113
 
84
void free_node
114
void
85
    PROTO_N ( ( p ) )
-
 
86
    PROTO_T ( node *p )
115
free_node(node *p)
87
{
116
{
88
    while ( p ) {
117
    while (p) {
89
	node *q = p->bro ;
118
	node *q = p->bro;
90
	if ( p->son ) free_node ( p->son ) ;
119
	if (p->son)free_node(p->son);
91
	p->bro = free_nodes ;
120
	p->bro = free_nodes;
92
	free_nodes = p ;
121
	free_nodes = p;
93
	p = q ;
122
	p = q;
94
    }
123
    }
95
    return ;
124
    return;
96
}
125
}
97
 
126
 
98
 
127
 
99
/*
128
/*
100
    FORM THE COMPLETION OF A NODE
129
    FORM THE COMPLETION OF A NODE
Line 102... Line 131...
102
    The completion of the node p is created.  This consists of p itself
131
    The completion of the node p is created.  This consists of p itself
103
    and the list of all local variable sorts created during the
132
    and the list of all local variable sorts created during the
104
    construction of p, as recorded by the removals list.
133
    construction of p, as recorded by the removals list.
105
*/
134
*/
106
 
135
 
107
node *completion
136
node *
108
    PROTO_N ( ( p ) )
-
 
109
    PROTO_T ( node *p )
137
completion(node *p)
110
{
138
{
111
    node *q = new_node () ;
139
    node *q = new_node();
112
    construct *v = make_construct ( SORT_completion ) ;
140
    construct *v = make_construct(SORT_completion);
113
    v->next = removals ;
141
    v->next = removals;
114
    removals = null ;
142
    removals = null;
115
    q->cons = v ;
143
    q->cons = v;
116
    q->son = p ;
144
    q->son = p;
117
    return ( q ) ;
145
    return(q);
118
}
146
}
119
 
147
 
120
 
148
 
121
/*
149
/*
122
    AUXILIARY EQUALITY ROUTINE
150
    AUXILIARY EQUALITY ROUTINE
123
 
151
 
124
    This routine checks the nodes p and q for equality modulo the
152
    This routine checks the nodes p and q for equality modulo the
125
    lists of local variables ap and aq (which are known to correspond).
153
    lists of local variables ap and aq (which are known to correspond).
126
*/
154
*/
127
 
155
 
128
static boolean eq_node_aux
156
static boolean
129
    PROTO_N ( ( p, q, ap, aq, args ) )
-
 
130
    PROTO_T ( node *p X node *q X construct *ap X construct *aq X int args )
157
eq_node_aux(node *p, node *q, construct *ap, construct *aq, int args)
131
{
158
{
132
    while ( p != null && q != null ) {
159
    while (p != null && q != null) {
133
	if ( p->cons != q->cons ) {
160
	if (p->cons != q->cons) {
134
	    sortname s = p->cons->sortnum ;
161
	    sortname s = p->cons->sortnum;
135
	    if ( s != q->cons->sortnum ) return ( 0 ) ;
162
	    if (s != q->cons->sortnum) return(0);
136
	    switch ( s ) {
163
	    switch (s) {
137
 
164
 
138
		case SORT_bytestream :
165
		case SORT_bytestream:
139
		case SORT_option : {
166
		case SORT_option: {
140
		    /* Just check son */
167
		    /* Just check son */
141
		    break ;
168
		    break;
142
		}
169
		}
143
 
170
 
144
		case SORT_tdfbool :
171
		case SORT_tdfbool:
145
		case SORT_small_tdfint :
172
		case SORT_small_tdfint:
146
		case SORT_repeat : {
173
		case SORT_repeat: {
147
		    /* Check value or number of repeats */
174
		    /* Check value or number of repeats */
148
		    if ( p->cons->encoding != q->cons->encoding ) {
175
		    if (p->cons->encoding != q->cons->encoding) {
149
			return ( 0 ) ;
176
			return(0);
150
		    }
177
		    }
151
		    break ;
178
		    break;
152
		}
179
		}
153
 
180
 
154
		case SORT_tdfint :
181
		case SORT_tdfint:
155
		case SORT_tdfstring : {
182
		case SORT_tdfstring: {
156
		    /* Check value */
183
		    /* Check value */
157
		    if ( !streq ( p->cons->name, q->cons->name ) ) {
184
		    if (!streq(p->cons->name, q->cons->name)) {
158
			return ( 0 ) ;
185
			return(0);
159
		    }
186
		    }
160
		    break ;
187
		    break;
161
		}
188
		}
162
 
189
 
163
		default : {
190
		default : {
164
		    /* Check lists of local variables */
191
		    /* Check lists of local variables */
165
		    boolean ok = 0 ;
192
		    boolean ok = 0;
166
		    construct *xp = ap ;
193
		    construct *xp = ap;
167
		    construct *xq = aq ;
194
		    construct *xq = aq;
168
		    while ( xp && !ok ) {
195
		    while (xp && !ok) {
169
			if ( xp == p->cons && xq == q->cons ) ok = 1 ;
196
			if (xp == p->cons && xq == q->cons)ok = 1;
170
			xp = xp->next ;
197
			xp = xp->next;
171
			xq = xq->next ;
198
			xq = xq->next;
172
		    }
199
		    }
173
		    if ( !ok ) return ( 0 ) ;
200
		    if (!ok) return(0);
174
		    break ;
201
		    break;
175
		}
202
		}
176
	    }
203
	    }
177
	}
204
	}
178
	if ( !eq_node_aux ( p->son, q->son, ap, aq, 1 ) ) return ( 0 ) ;
205
	if (!eq_node_aux(p->son, q->son, ap, aq, 1)) return(0);
179
	if ( !args ) return ( 1 ) ;
206
	if (!args) return(1);
180
	p = p->bro ;
207
	p = p->bro;
181
	q = q->bro ;
208
	q = q->bro;
182
    }
209
    }
183
    if ( p == q ) return ( 1 ) ;
210
    if (p == q) return(1);
184
    return ( 0 ) ;
211
    return(0);
185
}
212
}
186
 
213
 
187
 
214
 
188
/*
215
/*
189
    CHECK TWO LISTS OF CONSTRUCTS
216
    CHECK TWO LISTS OF CONSTRUCTS
190
 
217
 
191
    The lists of local variables ap and aq are checked to have the
218
    The lists of local variables ap and aq are checked to have the
192
    same length and corresponds sorts in each position.
219
    same length and corresponds sorts in each position.
193
*/
220
*/
194
 
221
 
195
static boolean eq_cons_list
222
static boolean
196
    PROTO_N ( ( ap, aq ) )
-
 
197
    PROTO_T ( construct *ap X construct *aq )
223
eq_cons_list(construct *ap, construct *aq)
198
{
224
{
199
    while ( ap != null && aq != null ) {
225
    while (ap != null && aq != null) {
200
	if ( ap->sortnum != aq->sortnum ) return ( 0 ) ;
226
	if (ap->sortnum != aq->sortnum) return(0);
201
	ap = ap->next ;
227
	ap = ap->next;
202
	aq = aq->next ;
228
	aq = aq->next;
203
    }
229
    }
204
    if ( ap == aq ) return ( 1 ) ;
230
    if (ap == aq) return(1);
205
    return ( 0 ) ;
231
    return(0);
206
}
232
}
207
 
233
 
208
 
234
 
209
/*
235
/*
210
    FLAG : SHOULD WE CHECK EQUALITY OF NODES?
236
    FLAG : SHOULD WE CHECK EQUALITY OF NODES?
211
 
237
 
212
    This should be set to 1 to suppress the check in eq_node.
238
    This should be set to 1 to suppress the check in eq_node.
213
*/
239
*/
214
 
240
 
215
boolean dont_check = 0 ;
241
boolean dont_check = 0;
216
 
242
 
217
 
243
 
218
/*
244
/*
219
    ARE TWO NODES EQUAL?
245
    ARE TWO NODES EQUAL?
220
 
246
 
221
    The nodes p and q are checked for equality.
247
    The nodes p and q are checked for equality.
222
*/
248
*/
223
 
249
 
224
boolean eq_node
250
boolean
225
    PROTO_N ( ( p, q ) )
-
 
226
    PROTO_T ( node *p X node *q )
251
eq_node(node *p, node *q)
227
{
252
{
228
    construct *ap = null ;
253
    construct *ap = null;
229
    construct *aq = null ;
254
    construct *aq = null;
230
    if ( dont_check ) return ( 1 ) ;
255
    if (dont_check) return(1);
231
    if ( p == q ) return ( 1 ) ;
256
    if (p == q) return(1);
232
    if ( p == null || q == null ) return ( 0 ) ;
257
    if (p == null || q == null) return(0);
233
    if ( p->cons->sortnum == SORT_completion ) {
258
    if (p->cons->sortnum == SORT_completion) {
234
	ap = p->cons->next ;
259
	ap = p->cons->next;
235
	p = p->son ;
260
	p = p->son;
236
    }
261
    }
237
    if ( q->cons->sortnum == SORT_completion ) {
262
    if (q->cons->sortnum == SORT_completion) {
238
	aq = q->cons->next ;
263
	aq = q->cons->next;
239
	q = q->son ;
264
	q = q->son;
240
    }
265
    }
241
    if ( !eq_cons_list ( ap, aq ) ) return ( 0 ) ;
266
    if (!eq_cons_list(ap, aq)) return(0);
242
    return ( eq_node_aux ( p, q, ap, aq, 0 ) ) ;
267
    return(eq_node_aux(p, q, ap, aq, 0));
243
}
268
}
244
 
269
 
245
 
270
 
246
/*
271
/*
247
    LIST OF FREE CONSTRUCTS
272
    LIST OF FREE CONSTRUCTS
248
 
273
 
249
    Constructs are allocated from this list.
274
    Constructs are allocated from this list.
250
*/
275
*/
251
 
276
 
252
static construct *free_constructs = null ;
277
static construct *free_constructs = null;
253
 
278
 
254
 
279
 
255
/*
280
/*
256
    CREATE A NEW CONSTRUCT
281
    CREATE A NEW CONSTRUCT
257
 
282
 
258
    A new construct is allocated.  Its fields are not initialized.
283
    A new construct is allocated.  Its fields are not initialized.
259
*/
284
*/
260
 
285
 
261
construct *new_construct
286
construct *
262
    PROTO_Z ()
287
new_construct(void)
263
{
288
{
264
    construct *p = free_constructs ;
289
    construct *p = free_constructs;
265
    if ( p == null ) {
290
    if (p == null) {
266
	int i, m = 100 ;
291
	int i, m = 100;
267
	p = alloc_nof ( construct, m ) ;
292
	p = alloc_nof(construct, m);
268
	for ( i = 0 ; i < m - 1 ; i++ ) ( p + i )->next = p + ( i + 1 ) ;
293
	for (i = 0; i < m - 1; i++)(p + i) ->next = p + (i + 1);
269
	( p + ( m - 1 ) )->next = null ;
294
	(p + (m - 1)) ->next = null;
270
	free_constructs = p ;
295
	free_constructs = p;
271
    }
296
    }
272
    free_constructs = p->next ;
297
    free_constructs = p->next;
273
    p->alias = null ;
298
    p->alias = null;
274
    p->next = null ;
299
    p->next = null;
275
    return ( p ) ;
300
    return(p);
276
}
301
}
277
 
302
 
278
 
303
 
279
/*
304
/*
280
    CREATE A NEW CONSTRUCT OF A GIVEN SORT
305
    CREATE A NEW CONSTRUCT OF A GIVEN SORT
281
 
306
 
282
    A new construct is allocated.  Its fields are initialized for a
307
    A new construct is allocated.  Its fields are initialized for a
283
    construct of sort s.
308
    construct of sort s.
284
*/
309
*/
285
 
310
 
286
construct *make_construct
311
construct *
287
    PROTO_N ( ( s ) )
-
 
288
    PROTO_T ( sortname s )
312
make_construct(sortname s)
289
{
313
{
290
    construct *p = new_construct () ;
314
    construct *p = new_construct();
291
    p->sortnum = s ;
315
    p->sortnum = s;
292
    if ( s >= 0 ) {
316
    if (s >= 0) {
293
	p->encoding = ( sort_count [s] )++ ;
317
	p->encoding = (sort_count[s]) ++;
294
    } else {
318
    } else {
295
	p->encoding = 0 ;
319
	p->encoding = 0;
296
    }
320
    }
297
    p->name = null ;
321
    p->name = null;
298
    p->ename = null ;
322
    p->ename = null;
299
    p->next = null ;
323
    p->next = null;
300
    switch ( s ) {
324
    switch (s) {
301
 
325
 
302
	case SORT_al_tag : {
326
	case SORT_al_tag: {
303
	    /* Initialize alignment tag */
327
	    /* Initialize alignment tag */
304
	    al_tag_info *q = get_al_tag_info ( p ) ;
328
	    al_tag_info *q = get_al_tag_info(p);
305
	    q->def = null ;
329
	    q->def = null;
306
	    break ;
330
	    break;
307
	}
331
	}
308
 
332
 
309
	case SORT_tag : {
333
	case SORT_tag: {
310
	    /* Initialize tag */
334
	    /* Initialize tag */
311
	    tag_info *q = get_tag_info ( p ) ;
335
	    tag_info *q = get_tag_info(p);
312
	    q->var = 3 ;
336
	    q->var = 3;
313
	    q->vis = 0 ;
337
	    q->vis = 0;
314
	    q->dec = null ;
338
	    q->dec = null;
315
	    q->def = null ;
339
	    q->def = null;
316
	    break ;
340
	    break;
317
	}
341
	}
318
 
342
 
319
	case SORT_token : {
343
	case SORT_token: {
320
	    /* Initialize token */
344
	    /* Initialize token */
321
	    tok_info *q = get_tok_info ( p ) ;
345
	    tok_info *q = get_tok_info(p);
322
	    q->dec = 0 ;
346
	    q->dec = 0;
323
	    q->res = SORT_unknown ;
347
	    q->res = SORT_unknown;
324
	    q->args = null ;
348
	    q->args = null;
325
	    q->sig = null ;
349
	    q->sig = null;
326
	    q->def = null ;
350
	    q->def = null;
327
	    q->pars = null ;
351
	    q->pars = null;
328
	    q->depth = 0 ;
352
	    q->depth = 0;
329
	    break ;
353
	    break;
330
	}
354
	}
331
    }
355
    }
332
    return ( p ) ;
356
    return(p);
333
}
357
}
334
 
358
 
335
 
359
 
336
/*
360
/*
337
    FREE A LIST OF CONSTRUCTS
361
    FREE A LIST OF CONSTRUCTS
338
 
362
 
339
    The list of constructed pointed to by p is returned to free.
363
    The list of constructed pointed to by p is returned to free.
340
*/
364
*/
341
 
365
 
342
void free_construct
366
void
343
    PROTO_N ( ( p ) )
-
 
344
    PROTO_T ( construct **p )
367
free_construct(construct **p)
345
{
368
{
346
    construct *q = *p ;
369
    construct *q = *p;
347
    if ( q ) {
370
    if (q) {
348
	while ( q->next ) q = q->next ;
371
	while (q->next)q = q->next;
349
	q->next = free_constructs ;
372
	q->next = free_constructs;
350
	free_constructs = *p ;
373
	free_constructs = *p;
351
    }
374
    }
352
    *p = null ;
375
    *p = null;
353
    return ;
376
    return;
354
}
377
}
355
 
378
 
356
 
379
 
357
/*
380
/*
358
    SET THE SORT OF A TOKEN
381
    SET THE SORT OF A TOKEN
359
 
382
 
360
    The token construct p is set to have result sort rs and argument
383
    The token construct p is set to have result sort rs and argument
361
    sorts args.
384
    sorts args.
362
*/
385
*/
363
 
386
 
364
void set_token_sort
387
void
365
    PROTO_N ( ( p, rs, args, sig ) )
-
 
366
    PROTO_T ( construct *p X sortname rs X char *args X node *sig )
388
set_token_sort(construct *p, sortname rs, char *args, node *sig)
367
{
389
{
368
    tok_info *info = get_tok_info ( p ) ;
390
    tok_info *info = get_tok_info(p);
369
    if ( info->res != SORT_unknown ) {
391
    if (info->res != SORT_unknown) {
370
	boolean error = 0 ;
392
	boolean error = 0;
371
	if ( info->res != rs ) error = 1 ;
393
	if (info->res != rs)error = 1;
372
	if ( args ) {
394
	if (args) {
373
	    if ( info->args == null || !streq ( args, info->args ) ) {
395
	    if (info->args == null || !streq(args, info->args)) {
374
		error = 1 ;
396
		error = 1;
375
	    }
397
	    }
376
	} else {
398
	} else {
377
	    if ( info->args ) error = 1 ;
399
	    if (info->args)error = 1;
378
	}
400
	}
379
	if ( error ) {
401
	if (error) {
380
	    is_fatal = 0 ;
402
	    is_fatal = 0;
381
	    input_error ( "Token %s declared inconsistently", p->name ) ;
403
	    input_error("Token %s declared inconsistently", p->name);
382
	}
404
	}
383
    }
405
    }
384
    info->res = rs ;
406
    info->res = rs;
385
    info->args = args ;
407
    info->args = args;
386
    info->sig = sig ;
408
    info->sig = sig;
387
    return ;
409
    return;
388
}
410
}
389
 
411
 
390
 
412
 
391
/*
413
/*
392
    SET TAG TYPE
414
    SET TAG TYPE
393
 
415
 
394
    The tag construct p is set to be a variable or an identity, depending
416
    The tag construct p is set to be a variable or an identity, depending
395
    on the flag is_var.
417
    on the flag is_var.
396
*/
418
*/
397
 
419
 
398
void set_tag_type
420
void
399
    PROTO_N ( ( p, is_var ) )
-
 
400
    PROTO_T ( construct *p X int is_var )
421
set_tag_type(construct *p, int is_var)
401
{
422
{
402
    tag_info *info = get_tag_info ( p ) ;
423
    tag_info *info = get_tag_info(p);
403
    if ( info->var != 3 ) {
424
    if (info->var != 3) {
404
	if ( info->var != is_var ) {
425
	if (info->var != is_var) {
405
	    is_fatal = 0 ;
426
	    is_fatal = 0;
406
	    input_error ( "Tag %s declared inconsistently", p->name ) ;
427
	    input_error("Tag %s declared inconsistently", p->name);
407
	}
428
	}
408
    }
429
    }
409
#if 0
430
#if 0
410
    info->var = is_var ;
431
    info->var = is_var;
411
#endif
432
#endif
412
    return ;
433
    return;
413
}
434
}
414
 
435
 
415
 
436
 
416
/*
437
/*
417
    CREATE A COPY OF A CONSTRUCT
438
    CREATE A COPY OF A CONSTRUCT
Line 419... Line 440...
419
    This routine creates a copy of the construct p.  This is used during
440
    This routine creates a copy of the construct p.  This is used during
420
    token expansion to ensure that tags and labels which are local to a
441
    token expansion to ensure that tags and labels which are local to a
421
    token definition are handled correctly.
442
    token definition are handled correctly.
422
*/
443
*/
423
 
444
 
424
void copy_construct
445
void
425
    PROTO_N ( ( p ) )
-
 
426
    PROTO_T ( construct *p )
446
copy_construct(construct *p)
427
{
447
{
428
    sortname s = p->sortnum ;
448
    sortname s = p->sortnum;
429
    construct *q = make_construct ( s ) ;
449
    construct *q = make_construct(s);
430
    if ( s == SORT_tag ) {
450
    if (s == SORT_tag) {
431
	tag_info *pi = get_tag_info ( p ) ;
451
	tag_info *pi = get_tag_info(p);
432
	tag_info *qi = get_tag_info ( q ) ;
452
	tag_info *qi = get_tag_info(q);
433
	qi->var = pi->var ;
453
	qi->var = pi->var;
434
	qi->vis = pi->vis ;
454
	qi->vis = pi->vis;
435
    }
455
    }
436
    q->name = p->name ;
456
    q->name = p->name;
437
    p->alias = q ;
457
    p->alias = q;
438
    ( sort_removed [s] )++ ;
458
   (sort_removed[s]) ++;
439
    return ;
459
    return;
440
}
460
}
441
 
461
 
442
 
462
 
443
/*
463
/*
444
    SKIP TEXT ENCLOSED IN SQUARE BRACKETS
464
    SKIP TEXT ENCLOSED IN SQUARE BRACKETS
445
 
465
 
446
    The decode string s is analysed and a pointer to the first ']'
466
    The decode string s is analysed and a pointer to the first ']'
447
    which is not balanced by a '[' is returned.
467
    which is not balanced by a '[' is returned.
448
*/
468
*/
449
 
469
 
450
char *skip_text
470
char *
451
    PROTO_N ( ( s ) )
-
 
452
    PROTO_T ( char *s )
471
skip_text(char *s)
453
{
472
{
454
    int n = 0 ;
473
    int n = 0;
455
    while ( *s ) {
474
    while (*s) {
456
	if ( *s == '[' ) n++ ;
475
	if (*s == '[')n++;
457
	if ( *s == ']' ) {
476
	if (*s == ']') {
458
	    if ( n == 0 ) return ( s ) ;
477
	    if (n == 0) return(s);
459
	    n-- ;
478
	    n--;
460
	}
479
	}
461
	s++ ;
480
	s++;
462
    }
481
    }
463
    fatal_error ( "Illegal decoding string" ) ;
482
    fatal_error("Illegal decoding string");
464
    return ( s ) ;
483
    return(s);
465
}
484
}
466
 
485
 
467
 
486
 
468
/*
487
/*
469
    LOCAL IDENTIFIER PREFIX
488
    LOCAL IDENTIFIER PREFIX
470
 
489
 
471
    All tag, token and alignment tags with this prefix are treated as if
490
    All tag, token and alignment tags with this prefix are treated as if
472
    they were declared local.
491
    they were declared local.
473
*/
492
*/
474
 
493
 
475
char *local_prefix = "<none>" ;
494
char *local_prefix = "<none>";
476
 
495
 
477
 
496
 
478
/*
497
/*
479
    IS AN IDENTIFIER LOCAL?
498
    IS AN IDENTIFIER LOCAL?
480
 
499
 
481
    This routine checks whether the identifier name s begins with the
500
    This routine checks whether the identifier name s begins with the
482
    local identifier prefix above.
501
    local identifier prefix above.
483
*/
502
*/
484
 
503
 
485
boolean is_local_name
504
boolean
486
    PROTO_N ( ( s ) )
-
 
487
    PROTO_T ( char *s )
505
is_local_name(char *s)
488
{
506
{
489
    char *t = local_prefix ;
507
    char *t = local_prefix;
490
    while ( *s == *t ) {
508
    while (*s == *t) {
491
	s++ ;
509
	s++;
492
	t++ ;
510
	t++;
493
    }
511
    }
494
    if ( *t == 0 ) return ( 1 ) ;
512
    if (*t == 0) return(1);
495
    return ( 0 ) ;
513
    return(0);
496
}
514
}