Subversion Repositories tendra.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
7 7u83 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
 */
31
/*
2 7u83 32
    		 Crown Copyright (c) 1997
7 7u83 33
 
2 7u83 34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
7 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
7 7u83 45
 
2 7u83 46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
7 7u83 49
 
2 7u83 50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
7 7u83 53
 
2 7u83 54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
 
60
 
61
#include "config.h"
62
#include "types.h"
63
#include "check.h"
64
#include "de_types.h"
65
#include "de_capsule.h"
7 7u83 66
#include "de_unit.h"
2 7u83 67
#include "decode.h"
68
#include "fetch.h"
69
#include "high.h"
70
#include "node.h"
71
#include "table.h"
72
#include "tdf.h"
73
#include "utility.h"
74
 
75
 
76
/*
77
    ARRAY OF ALL LABELS
78
 
79
    The labels in a unit are held in the table labels of size max_lab_no.
80
*/
81
 
7 7u83 82
static long max_lab_no = 0;
83
static construct *labels;
2 7u83 84
 
85
 
86
/*
87
    SET UP LABELS
88
 
89
    A table of n labels is allocated and initialized.
90
*/
91
 
7 7u83 92
static void
93
set_up_labels(long n)
2 7u83 94
{
7 7u83 95
    long i;
96
    static long lno = 0;
97
    max_lab_no = n;
98
    labels = alloc_nof(construct, n);
99
    for (i = 0; i < n; i++) {
100
	char *nm = alloc_nof(char, 32);
101
	IGNORE sprintf(nm, "~~label_%ld", lno);
102
	labels[i].sortnum = SORT_label;
103
	labels[i].encoding = lno++;
104
	labels[i].name = nm;
105
	labels[i].alias = null;
106
	labels[i].next = null;
107
	if (add_to_var_hash(labels + i, SORT_label)) {
108
	    input_error("Label %s already defined", nm);
2 7u83 109
	}
110
    }
7 7u83 111
    return;
2 7u83 112
}
113
 
114
 
115
/*
116
    FIND A LABEL
117
 
118
    The nth label in the current unit is returned.
119
*/
120
 
7 7u83 121
construct *
122
find_label(long n)
2 7u83 123
{
7 7u83 124
    if (n < 0 || n >= max_lab_no) {
125
	input_error("Label number %ld too big", n);
126
	return(null);
2 7u83 127
    }
7 7u83 128
    return(labels + n);
2 7u83 129
}
130
 
131
 
132
/*
133
    DECODE A SORT NAME
134
 
135
    A sortname is decoded.  If expand is true the arguments of any high
136
    level sort will be stepped over.
137
*/
138
 
7 7u83 139
static sortname
140
de_sortname(boolean expand)
2 7u83 141
{
7 7u83 142
    long n = de_sortname_bits();
143
    if (n == SORT_token && expand) {
144
	long i, m;
145
	high_sort h, *hp;
146
	static int made_up_sorts = 0;
147
	h.res = de_sortname(1);
148
	de_list_start();
149
	m = tdf_int();
150
	h.no_args = (int)m;
151
	h.args = alloc_nof(sortname, m);
152
	h.name = alloc_nof(char, 32);
153
	IGNORE sprintf(h.name, "~~sort_%d", made_up_sorts++);
154
	for (i = 0; i < m; i++) {
155
	    h.args[i] = de_sortname(1);
2 7u83 156
	}
7 7u83 157
	hp = new_high_sort(&h);
158
	hp = unique_high_sort(hp);
159
	return(hp->id);
2 7u83 160
    }
7 7u83 161
    if (n == SORT_foreign) {
162
	warning("Foreign sorts not supported");
163
	IGNORE de_node("X");
164
	return(SORT_unknown);
2 7u83 165
    }
7 7u83 166
    return((sortname)n);
2 7u83 167
}
168
 
169
 
170
/*
171
    DECODE AN ALIGNMENT TAG DEFINITION UNIT
172
 
173
    A number of alignment tag definitions are decoded.
174
*/
175
 
7 7u83 176
void
177
de_aldef(void)
2 7u83 178
{
7 7u83 179
    long i, n = tdf_int();
180
    set_up_labels(n);
181
    n = tdf_int();
182
    for (i = 0; i < n; i++) {
183
	long t;
184
	node *d;
185
	construct *p;
186
	al_tag_info *info;
2 7u83 187
 
188
	/* Find the definition type */
7 7u83 189
	IGNORE de_al_tagdef_bits();
2 7u83 190
 
191
	/* Find the alignment tag */
7 7u83 192
	t = tdf_int();
193
	p = find_binding(crt_binding, al_tag_var, t);
194
	info = get_al_tag_info(p);
2 7u83 195
 
196
	/* Decode the definition (an alignment) */
7 7u83 197
	d = completion(de_alignment());
198
	if (info->def) {
199
	    if (!eq_node(info->def, d)) {
200
		is_fatal = 0;
201
		input_error("Alignment tag %s defined inconsistently",
202
			      p->name);
2 7u83 203
	    }
7 7u83 204
	    free_node(d);
2 7u83 205
	} else {
7 7u83 206
	    info->def = d;
2 7u83 207
	}
208
    }
7 7u83 209
    return;
2 7u83 210
}
211
 
212
 
213
/*
214
    DECODE A TAG DECLARATION UNIT
215
 
216
    A number of tag declarations are decoded.
217
*/
218
 
7 7u83 219
void
220
de_tagdec(void)
2 7u83 221
{
7 7u83 222
    long i, n = tdf_int();
223
    set_up_labels(n);
224
    n = tdf_int();
225
    for (i = 0; i < n; i++) {
226
	long t;
227
	node *d;
228
	boolean is_var;
229
	construct *p;
230
	tag_info *info;
2 7u83 231
 
232
	/* Find the declaration type */
7 7u83 233
	long m = de_tagdec_bits();
234
	if (m == ENC_make_id_tagdec) {
235
	    is_var = 0;
236
	} else if (m == ENC_make_var_tagdec) {
237
	    is_var = 1;
2 7u83 238
	} else {
7 7u83 239
	    is_var = 2;
2 7u83 240
	}
241
 
242
	/* Find the tag */
7 7u83 243
	t = tdf_int();
244
	p = find_binding(crt_binding, tag_var, t);
245
	set_tag_type(p, is_var);
246
	info = get_tag_info(p);
2 7u83 247
 
248
	/* Declaration = optional access + optional string + shape from 4.0 */
7 7u83 249
	d = completion(de_node("?[u]?[X]S"));
250
	info->var = is_var;
251
	if (info->dec) {
252
	    if (!eq_node(info->dec, d)) {
253
		is_fatal = 0;
254
		input_error("Tag %s declared inconsistently", p->name);
2 7u83 255
	    }
7 7u83 256
	    free_node(d);
2 7u83 257
	} else {
7 7u83 258
	    info->dec = d;
2 7u83 259
	}
260
    }
7 7u83 261
    return;
2 7u83 262
}
263
 
264
 
265
/*
266
    DECODE A TAG DEFINITION UNIT
267
 
268
    A number of tag definitions are decoded.
269
*/
270
 
7 7u83 271
void
272
de_tagdef(void)
2 7u83 273
{
7 7u83 274
    long i, n = tdf_int();
275
    set_up_labels(n);
276
    n = tdf_int();
277
    for (i = 0; i < n; i++) {
278
	long t;
279
	node *d;
280
	construct *p;
281
	tag_info *info;
282
	boolean is_var;
2 7u83 283
 
284
	/* Find the definition type */
7 7u83 285
	long m = de_tagdef_bits();
286
	if (m == ENC_make_id_tagdef) {
287
	    is_var = 0;
288
	} else if (m == ENC_make_var_tagdef) {
289
	    is_var = 1;
2 7u83 290
	} else {
7 7u83 291
	    is_var = 2;
2 7u83 292
	}
293
 
294
	/* Find the tag */
7 7u83 295
	t = tdf_int();
296
	p = find_binding(crt_binding, tag_var, t);
297
	info = get_tag_info(p);
298
	if (info->dec == null) {
299
	    input_error("Tag %s defined but not declared", p->name);
2 7u83 300
	}
7 7u83 301
	set_tag_type(p, is_var);
2 7u83 302
 
303
	/* Added signature in 4.0 */
7 7u83 304
	d = completion(de_node(is_var ? "?[u]?[X]x" : "?[X]x"));
305
	info->var = is_var;
306
	if (info->def) {
307
	    if (is_var == 2) {
308
		node *dp = info->def;
309
		while (dp->bro)dp = dp->bro;
310
		dp->bro = d;
2 7u83 311
	    } else {
7 7u83 312
		if (!eq_node(info->def, d)) {
313
		    is_fatal = 0;
314
		    input_error("Tag %s defined inconsistently", p->name);
2 7u83 315
		}
7 7u83 316
		free_node(d);
2 7u83 317
	    }
318
	} else {
7 7u83 319
	    info->def = d;
320
	    if (do_check)check_tagdef(p);
2 7u83 321
	}
322
    }
7 7u83 323
    return;
2 7u83 324
}
325
 
326
 
327
/*
328
    DECODE A TOKEN DECLARATION UNIT
329
 
330
    A number of token declarations are decoded.
331
*/
332
 
7 7u83 333
void
334
de_tokdec(void)
2 7u83 335
{
7 7u83 336
    long i, n = tdf_int();
337
    for (i = 0; i < n; i++) {
338
	long t;
339
	node *sig;
340
	char *args;
341
	sortname rs;
342
	construct *p;
343
	tok_info *info;
2 7u83 344
 
345
	/* Find the declaration type */
7 7u83 346
	IGNORE de_tokdec_bits();
2 7u83 347
 
348
	/* Find the token */
7 7u83 349
	t = tdf_int();
350
	p = find_binding(crt_binding, tok_var, t);
351
	info = get_tok_info(p);
2 7u83 352
 
353
	/* Deal with signature */
7 7u83 354
	sig = de_node("?[X]");
2 7u83 355
 
356
	/* Decode token sort */
7 7u83 357
	rs = de_sortname(0);
358
	if (rs == SORT_token) {
359
	    long m;
360
	    rs = de_sortname(1);
361
	    de_list_start();
362
	    m = tdf_int();
363
	    if (m == 0) {
364
		args = null;
2 7u83 365
	    } else {
7 7u83 366
		long j;
367
		char abuff[100], *a = abuff;
368
		for (j = 0; j < m; j++) {
369
		    sortname ps = de_sortname(1);
370
		    if (is_high(ps)) {
371
			sprint_high_sort(a, ps);
372
			while (*a)a++;
2 7u83 373
		    } else {
7 7u83 374
			*(a++) = sort_letters[ps];
2 7u83 375
		    }
376
		}
7 7u83 377
		*a = 0;
378
		args = string_copy_aux(abuff);
2 7u83 379
	    }
380
	} else {
7 7u83 381
	    args = null;
2 7u83 382
	}
7 7u83 383
	if (is_high(rs)) {
384
	    input_error("Token %s has high-level result sort", p->name);
2 7u83 385
	}
7 7u83 386
	set_token_sort(p, rs, args, sig);
387
	info->dec = 1;
2 7u83 388
    }
7 7u83 389
    return;
2 7u83 390
}
391
 
392
 
393
/*
394
    DECODE A TOKEN DEFINITION BODY
395
 
396
    The actual body of a token definition is decoded.
397
*/
398
 
7 7u83 399
void
400
de_token_defn(construct *p, node *sig)
2 7u83 401
{
7 7u83 402
    long m;
403
    node *d;
404
    char *args;
405
    sortname rs;
406
    tok_info *info = get_tok_info(p);
407
    construct **old_pars = info->pars;
2 7u83 408
 
409
    /* Find the end of the definition */
7 7u83 410
    long end_posn = tdf_int();
411
    end_posn += input_posn();
2 7u83 412
 
413
    /* Find the definition type */
7 7u83 414
    IGNORE de_token_defn_bits();
2 7u83 415
 
416
    /* Decode the token sort */
7 7u83 417
    rs = de_sortname(1);
418
    de_list_start();
419
    m = tdf_int();
420
    if (m == 0) {
421
	args = null;
2 7u83 422
    } else {
7 7u83 423
	long j;
424
	char abuff[100], *a = abuff;
425
	if (!in_skip_pass) {
426
	    info->pars = alloc_nof(construct *, m + 1);
2 7u83 427
	}
7 7u83 428
	for (j = 0; j < m; j++) {
2 7u83 429
	    /* Decode the token arguments */
7 7u83 430
	    sortname ps = de_sortname(1);
431
	    long pn = tdf_int();
432
	    construct *q = find_binding(crt_binding, tok_var, pn);
433
	    set_token_sort(q, ps,(char *)null,(node *)null);
434
	    if (is_high(ps)) {
435
		sprint_high_sort(a, ps);
436
		while (*a)a++;
2 7u83 437
	    } else {
7 7u83 438
		*(a++) = sort_letters[ps];
2 7u83 439
	    }
7 7u83 440
	    if (!in_skip_pass)info->pars[j] = q;
2 7u83 441
	}
7 7u83 442
	*a = 0;
443
	args = string_copy_aux(abuff);
444
	if (!in_skip_pass)info->pars[j] = null;
2 7u83 445
    }
7 7u83 446
    if (is_high(rs)) {
447
	input_error("Token %s has high-level result sort", p->name);
2 7u83 448
    }
7 7u83 449
    set_token_sort(p, rs, args, sig);
450
    info->dec = 1;
2 7u83 451
 
452
    /* Decode the actual definition */
7 7u83 453
    if (in_skip_pass) {
454
	long bits = end_posn - input_posn();
455
	input_skip(bits);
2 7u83 456
    } else {
7 7u83 457
	char buff[2];
458
	buff[0] = sort_letters[rs];
459
	buff[1] = 0;
460
	d = completion(de_node(buff));
461
	if (info->def) {
462
	    if (!eq_node(info->def, d)) {
463
		is_fatal = 0;
464
		input_error("Token %s defined inconsistently",
465
			      p->name);
2 7u83 466
	    }
7 7u83 467
	    free_node(d);
468
	    info->pars = old_pars;
2 7u83 469
	} else {
7 7u83 470
	    info->def = d;
2 7u83 471
	}
7 7u83 472
	if (rs == SORT_unknown) {
473
	    long bits = end_posn - input_posn();
474
	    input_skip(bits);
2 7u83 475
	}
7 7u83 476
	if (input_posn()!= end_posn) {
477
	    input_error("Token %s definition length wrong", p->name);
2 7u83 478
	}
7 7u83 479
	if (info->pars) {
2 7u83 480
	    /* Mark the formal arguments as unused */
7 7u83 481
	    construct **ps;
482
	    for (ps = info->pars; *ps; ps++) {
483
		info = get_tok_info(*ps);
484
		info->dec = 0;
2 7u83 485
	    }
486
	}
487
    }
7 7u83 488
    return;
2 7u83 489
}
490
 
491
 
492
/*
493
    DECODE A TOKEN DEFINITION UNIT
494
 
495
    A number of token definitions are decoded.
496
*/
497
 
7 7u83 498
void
499
de_tokdef(void)
2 7u83 500
{
7 7u83 501
    long i, n = tdf_int();
502
    set_up_labels(n);
503
    n = tdf_int();
504
    for (i = 0; i < n; i++) {
505
	long t;
506
	node *sig;
507
	construct *p;
2 7u83 508
 
509
	/* Find the definition type */
7 7u83 510
	IGNORE de_tokdef_bits();
2 7u83 511
 
512
	/* Find the token */
7 7u83 513
	t = tdf_int();
514
	p = find_binding(crt_binding, tok_var, t);
2 7u83 515
 
516
	/* Deal with signature */
7 7u83 517
	sig = de_node("?[X]");
2 7u83 518
 
519
	/* Decode token definition */
7 7u83 520
	de_token_defn(p, sig);
2 7u83 521
    }
7 7u83 522
    return;
2 7u83 523
}
524
 
525
 
526
/*
527
    FLAG
528
 
529
    Has a version number been read?
530
*/
531
 
7 7u83 532
int have_version = 0;
2 7u83 533
 
534
 
535
/*
536
    CHECK A VERSION NUMBER
537
 
538
    This routine reads and checks a version number.
539
*/
540
 
7 7u83 541
static void
542
de_version_number(void)
2 7u83 543
{
7 7u83 544
    long v1 = tdf_int();
545
    long v2 = tdf_int();
546
    if (v1 != VERSION_major || v2 > VERSION_minor) {
547
	input_error("Illegal version number, %ld.%ld", v1, v2);
2 7u83 548
    }
7 7u83 549
    have_version = 1;
550
    return;
2 7u83 551
}
552
 
553
 
554
/*
555
    DECODE A VERSION UNIT
556
 
557
    A number of TDF version numbers are decoded.  These were only
558
    introduced for version 2.1 of the TDF specification.
559
*/
560
 
7 7u83 561
void
562
de_version(void)
2 7u83 563
{
7 7u83 564
    long i, n = tdf_int();
565
    for (i = 0; i < n; i++) {
566
	long m = de_version_bits();
567
	if (m == ENC_make_version) {
568
	    de_version_number();
569
	} else if (m == ENC_user_info) {
570
	    IGNORE de_node("X");
2 7u83 571
	}
572
    }
7 7u83 573
    return;
2 7u83 574
}
575
 
576
 
577
/*
578
    DECODE A MAGIC NUMBER
579
*/
580
 
7 7u83 581
void
582
de_magic(char *m)
2 7u83 583
{
7 7u83 584
    int i, n = (int)strlen(m);
585
    for (i = 0; i < n; i++) {
586
	long c = fetch(8);
587
	if (c != (long)m[i]) {
588
	    input_error("Bad magic number");
589
	    return;
2 7u83 590
	}
591
    }
7 7u83 592
    de_version_number();
593
    byte_align();
594
    return;
2 7u83 595
}