Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – tendra.SVN – Blame – /branches/tendra5-amd64/src/tools/tnc/decode.c – Rev 5

Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
#include "config.h"
32
#include "types.h"
33
#include "check.h"
34
#include "de_types.h"
35
#include "de_capsule.h"
36
#include "de_unit.h"
37
#include "decode.h"
38
#include "eval.h"
39
#include "fetch.h"
40
#include "high.h"
41
#include "node.h"
42
#include "shape.h"
43
#include "table.h"
44
#include "tdf.h"
45
#include "utility.h"
46
 
47
 
48
/*
49
    DECODE AN EXTENDED VALUE
50
 
51
    An extended n bit encoding is decoded.
52
*/
53
 
54
long fetch_extn
55
    PROTO_N ( ( n ) )
56
    PROTO_T ( int n )
57
{
58
    long r = 0, s ;
59
    while ( s = fetch ( n ), s == 0 ) r += ( ( 1 << n ) - 1 ) ;
60
    return ( r + s ) ;
61
}
62
 
63
 
64
/*
65
    DECODE A TDF INTEGER
66
 
67
    A TDF integer is decoded and returned as a long (no overflow checks).
68
*/
69
 
70
long tdf_int
71
    PROTO_Z ()
72
{
73
    long d, n = 0 ;
74
    do {
75
	d = fetch ( 4 ) ;
76
	n = 8 * n + ( d & 7 ) ;
77
    } while ( !( d & 8 ) ) ;
78
    return ( n ) ;
79
}
80
 
81
 
82
/*
83
    DECODE A TOKEN APPLICATION
84
 
85
    A token application returning sort s is appended to p.  If s is
86
    SORT_unknown a simple token (rather than a token application) is
87
    read.
88
*/
89
 
90
construct *de_token
91
    PROTO_N ( ( p, s ) )
92
    PROTO_T ( node *p X sortname s )
93
{
94
    long bits ;
95
    construct *t ;
96
    tok_info *info ;
97
    construct dummy ;
98
 
99
    /* Find token type */
100
    long n = de_token_bits () ;
101
    if ( n == ENC_make_tok ) {
102
	long m = tdf_int () ;
103
	t = find_binding ( crt_binding, tok_var, m ) ;
104
	info = get_tok_info ( t ) ;
105
	p->son = new_node () ;
106
	p->son->cons = t ;
107
    } else if ( n == ENC_use_tokdef ) {
108
	char *nm ;
109
	t = make_construct ( SORT_token ) ;
110
	nm = alloc_nof ( char, 32 ) ;
111
	IGNORE sprintf ( nm, "~~token_%ld", t->encoding ) ;
112
	t->name = nm ;
113
	if ( add_to_var_hash ( t, SORT_token ) ) {
114
	    input_error ( "%s has already been defined", nm ) ;
115
	}
116
	de_token_defn ( t, ( node * ) null ) ;
117
	info = get_tok_info ( t ) ;
118
	p->son = new_node () ;
119
	p->son->cons = t ;
120
    } else {
121
	high_sort *h ;
122
	construct *tt ;
123
	tt = de_token ( p, SORT_token ) ;
124
	info = get_tok_info ( tt ) ;
125
	h = high_sorts + high_no ( info->res ) ;
126
	dummy.name = "high level token" ;
127
	dummy.u.tok_u.res = h->res ;
128
	dummy.u.tok_u.args = find_decode_string ( h ) ;
129
	t = &dummy ;
130
	info = &dummy.u.tok_u ;
131
    }
132
 
133
    /* Quit here if only reading token */
134
    if ( s == SORT_unknown ) {
135
	if ( !text_output ) {
136
	    p->son->son = new_node () ;
137
	    p->son->son->cons = &token_cons ;
138
	}
139
	return ( null ) ;
140
    }
141
 
142
    /* Find the length of the arguments */
143
    bits = tdf_int () ;
144
 
145
    if ( info->res == SORT_unknown ) {
146
	/* Unknown token */
147
	if ( bits ) {
148
	    /* Step over arguments */
149
	    char *args ;
150
	    if ( streq ( t->name, "~dg_exp" ) ) {
151
		args = "xFF" ;
152
	    } else if ( streq ( t->name, "~exp_to_source" ) ) {
153
		args = "xFF" ;
154
	    } else if ( streq ( t->name, "~diag_id_scope" ) ) {
155
		args = "x$xF" ;
156
	    } else if ( streq ( t->name, "~diag_type_scope" ) ) {
157
		args = "x$F" ;
158
	    } else if ( streq ( t->name, "~diag_tag_scope" ) ) {
159
		args = "x$F" ;
160
	    } else {
161
		warning ( "Token %s undeclared", t->name ) ;
162
		args = "F" ;
163
	    }
164
	    bits += input_posn () ;
165
	    p->son->son = de_node ( args ) ;
166
	    bits -= input_posn () ;
167
	    if ( bits < 0 ) {
168
		input_error ( "Token %s, arguments length wrong", t->name ) ;
169
		return ( t ) ;
170
	    }
171
	    input_skip ( bits ) ;
172
	} else {
173
	    /* No argument - can deduce token sort */
174
	    info->res = s ;
175
	    info->dec = 1 ;
176
	}
177
    } else {
178
	/* Known token */
179
	if ( s == SORT_token ) {
180
	    /* Must be high level */
181
	    if ( !is_high ( info->res ) ) {
182
		input_error ( "Sort error in token %s", t->name ) ;
183
	    }
184
	} else if ( info->res != s ) {
185
	    /* Result sort must match */
186
	    input_error ( "Sort error in token %s", t->name ) ;
187
	}
188
	if ( info->args ) {
189
	    /* Decode arguments */
190
	    long end_posn = input_posn () + bits ;
191
	    p->son->son = de_node ( info->args ) ;
192
	    if ( input_posn () != end_posn ) {
193
		input_error ( "Token %s, arguments length wrong", t->name ) ;
194
		return ( t ) ;
195
	    }
196
	} else {
197
	    /* No arguments */
198
	    if ( bits ) {
199
		input_error ( "Token %s, arguments length wrong", t->name ) ;
200
		return ( t ) ;
201
	    }
202
	}
203
	info->dec = 1 ;
204
    }
205
 
206
    /* Mark used tokens */
207
    if ( info->dec ) adjust_token ( t ) ;
208
    return ( t ) ;
209
}
210
 
211
 
212
/*
213
    DECODE A VARIABLE SORT
214
 
215
    A construct of the vth variable sort is decoded.
216
*/
217
 
218
node *de_var_sort
219
    PROTO_N ( ( v ) )
220
    PROTO_T ( long v )
221
{
222
    long n = tdf_int () ;
223
    node *p = new_node () ;
224
    p->cons = find_binding ( crt_binding, v, n ) ;
225
    return ( p ) ;
226
}
227
 
228
 
229
/*
230
    DECODE A LABEL
231
 
232
    A label construct is decoded.
233
*/
234
 
235
void de_make_label
236
    PROTO_N ( ( p ) )
237
    PROTO_T ( node *p )
238
{
239
    long n = tdf_int () ;
240
    p->son = new_node () ;
241
    p->son->cons = find_label ( n ) ;
242
    return ;
243
}
244
 
245
 
246
/*
247
    DECODE A STRING OF DECODE CHARACTERS
248
 
249
    The string of decode character str is decoded.
250
*/
251
 
252
node *de_node
253
    PROTO_N ( ( str ) )
254
    PROTO_T ( char *str )
255
{
256
    char c ;
257
    node *p, *q = null, *qe = null ;
258
    while ( c = *str, c != 0 && c != ']' ) {
259
	switch ( c ) {
260
 
261
	    case '[' :
262
	    case '{' :
263
	    case '}' :
264
	    case '&' :
265
	    case '^' : {
266
		/* Ignore these cases */
267
		p = null ;
268
		break ;
269
	    }
270
 
271
	    case '|' : {
272
		/* Align input stream */
273
		byte_align () ;
274
		p = null ;
275
		break ;
276
	    }
277
 
278
	    case 'i' : {
279
		/* Decode an integer as a string of octal digits */
280
		long d, n = 0 ;
281
		char buff [1000] ;
282
		do {
283
		    d = fetch ( 4 ) ;
284
		    buff [n] = ( char ) ( '0' + ( d & 7 ) ) ;
285
		    n++ ;
286
		} while ( !( d & 8 ) ) ;
287
		buff [n] = 0 ;
288
		p = new_node () ;
289
		p->cons = new_construct () ;
290
		if ( fits_ulong ( buff, 1 ) ) {
291
		    p->cons->sortnum = SORT_small_tdfint ;
292
		    p->cons->encoding = ( long ) octal_to_ulong ( buff ) ;
293
		} else {
294
		    p->cons->sortnum = SORT_tdfint ;
295
		    p->cons->name = string_copy_aux ( buff ) ;
296
		}
297
		break ;
298
	    }
299
 
300
	    case 'j' : {
301
		/* Decode a bit */
302
		p = new_node () ;
303
		p->cons = ( tdf_bool () ? &true_cons : &false_cons ) ;
304
		break ;
305
	    }
306
 
307
	    case '$' : {
308
		/* Decode a string */
309
		long i, n = tdf_int () ;
310
		if ( n == 8 ) {
311
		    char *s ;
312
		    n = tdf_int () ;
313
		    s = alloc_nof ( char, n + 1 ) ;
314
		    p = new_node () ;
315
		    p->cons = new_construct () ;
316
		    p->cons->sortnum = SORT_tdfstring ;
317
		    p->cons->encoding = n ;
318
		    p->cons->name = s ;
319
		    p->cons->next = null ;
320
		    for ( i = 0 ; i < n ; i++ ) {
321
			s [i] = ( char ) fetch ( 8 ) ; /* LINT */
322
		    }
323
		    s [n] = 0 ;
324
		} else {
325
		    long m ;
326
		    node *px ;
327
		    p = new_node () ;
328
		    p->cons = &string_cons ;
329
		    p->son = make_int ( n ) ;
330
		    m = tdf_int () ;
331
		    px = new_node () ;
332
		    px->cons = new_construct () ;
333
		    px->cons->sortnum = SORT_repeat ;
334
		    px->cons->encoding = m ;
335
		    p->son->bro->bro = px ;
336
		    for ( i = 0 ; i < m ; i++ ) {
337
			long v = fetch ( ( int ) n ) ;
338
			if ( i == 0 ) {
339
			    px->son = make_int ( v ) ;
340
			    px = px->son ;
341
			} else {
342
			    px->bro->bro = make_int ( v ) ;
343
			    px = px->bro->bro ;
344
			}
345
		    }
346
		}
347
		break ;
348
	    }
349
 
350
	    case '=' : {
351
		/* Decode an aligned string */
352
		char *s ;
353
		long i, n = tdf_int () ;
354
		if ( n != 8 ) input_error ( "Only 8-bit strings allowed" ) ;
355
		n = tdf_int () ;
356
		byte_align () ;
357
		s = alloc_nof ( char, n + 1 ) ;
358
		p = new_node () ;
359
		p->cons = new_construct () ;
360
		p->cons->sortnum = SORT_tdfstring ;
361
		p->cons->encoding = n ;
362
		p->cons->name = s ;
363
		p->cons->next = null ;
364
		for ( i = 0 ; i < n ; i++ ) {
365
		    s [i] = ( char ) fetch ( 8 ) ; /* LINT */
366
		}
367
		s [n] = 0 ;
368
		byte_align () ;
369
		break ;
370
	    }
371
 
372
	    case '*' : {
373
		/* The following text is repeated n times */
374
		de_list_start () ;
375
		goto percent_case ;
376
	    }
377
 
378
	    case '%' :
379
	    percent_case : {
380
		/* The following text is repeated n times */
381
		node *pe = null ;
382
		long i, n = tdf_int () ;
383
		p = new_node () ;
384
		p->cons = new_construct () ;
385
		p->cons->sortnum = SORT_repeat ;
386
		p->cons->encoding = n ;
387
		str += 2 ;
388
		for ( i = 0 ; i < n ; i++ ) {
389
		    node *pi = de_node ( str ) ;
390
		    if ( pe == null ) {
391
			p->son = pi ;
392
		    } else {
393
			pe->bro = pi ;
394
		    }
395
		    pe = pi ;
396
		    while ( pe->bro ) pe = pe->bro ;
397
		}
398
		str = skip_text ( str ) ;
399
		break ;
400
	    }
401
 
402
	    case '?' : {
403
		/* The following text is optional */
404
		p = new_node () ;
405
		p->cons = &optional_cons ;
406
		str += 2 ;
407
		if ( tdf_bool () ) {
408
		    p->son = de_node ( str ) ;
409
		    if ( *str == '*' && p->son->cons->encoding == 0 ) {
410
			/* Get rid of optional empty lists */
411
			p->son = null ;
412
		    }
413
		}
414
		str = skip_text ( str ) ;
415
		break ;
416
	    }
417
 
418
	    case '@' : {
419
		/* The following text is a bitstream */
420
		long len, pos ;
421
		str += 2 ;
422
		len = tdf_int () ;
423
		pos = input_posn () ;
424
		p = new_node () ;
425
		p->cons = &bytestream_cons ;
426
		p->son = de_node ( str ) ;
427
		if ( len + pos != input_posn () ) {
428
		    input_error ( "Conditional length wrong" ) ;
429
		}
430
		str = skip_text ( str ) ;
431
		break ;
432
	    }
433
 
434
	    case 'T' : {
435
		node dummy ;
436
		str = find_sortname ( str, ( sortname * ) null ) ;
437
		IGNORE de_token ( &dummy, SORT_unknown ) ;
438
		p = dummy.son ;
439
		break ;
440
	    }
441
 
442
	    case 'F' : {
443
		/* Unknown sort */
444
		p = new_node () ;
445
		p->cons = &unknown_cons ;
446
		break ;
447
	    }
448
 
449
	    default : {
450
		/* Basic sorts */
451
		sortname s = find_sort ( c ) ;
452
		p = ( sort_decode [s] ) () ;
453
		break ;
454
	    }
455
	}
456
	if ( p ) {
457
	    if ( qe == null ) {
458
		q = p ;
459
	    } else {
460
		qe->bro = p ;
461
	    }
462
	    qe = p ;
463
	    while ( qe->bro ) qe = qe->bro ;
464
	}
465
	str++ ;
466
    }
467
    return ( q ) ;
468
}