Subversion Repositories tendra.SVN

Rev

Rev 2 | Go to most recent revision | Details | Compare with Previous | 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 "ascii.h"
34
#include "basic.h"
35
#include "file.h"
36
#include "pretty.h"
37
#include "tdf.h"
38
#include "tree.h"
39
#include "utility.h"
40
 
41
 
42
/*
43
    INTERNAL MEMORY STORAGE AREA
44
 
45
    Some strings are output directly.  Others are built up gradually
46
    in this buffer.  length gives the length of the current string.
47
    page_length gives the size of the buffer.
48
*/
49
 
50
int length ;
51
static int page_length ;
52
static char *page = null ;
53
 
54
 
55
/*
56
    TOP LEVEL WORD AND CURRENT WORD POINTER
57
 
58
    The top of the TDF tree is given by word1.  The current position in
59
    the tree is given by word_ptr.
60
*/
61
 
62
word word1 = { SIMPLE, 0, null, null, null } ;
63
word *word_ptr ;
64
 
65
 
66
/*
67
    SET UP INITIAL PAGE AND WORDS
68
 
69
    The page buffer is initialized and the current word pointer is set
70
    to the top-level word.
71
*/
72
 
73
void initialize_tree
74
    PROTO_Z ()
75
{
76
    if ( page == null ) {
77
	page = alloc_nof ( char, 10000 ) ;
78
	page_length = 10000 ;
79
    }
80
    word_ptr = &word1 ;
81
    length = 0 ;
82
    return ;
83
}
84
 
85
 
86
/*
87
    START A NEW WORD
88
 
89
    A new word of layout type c is created.
90
*/
91
 
92
word *new_word
93
    PROTO_N ( ( c ) )
94
    PROTO_T ( int c )
95
{
96
#define BLOCK 100
97
    static word *wblock ;
98
    static int block_count = BLOCK ;
99
 
100
    word *new_ptr ;
101
    if ( printflag ) {
102
 
103
	if ( block_count == BLOCK ) {
104
	    /* Allocate space if required */
105
	    wblock = alloc_nof ( word, BLOCK ) ;
106
	    block_count = 0 ;
107
	}
108
 
109
	/* set up fields of new word */
110
	new_ptr = wblock + ( block_count++ ) ;
111
	if ( word_ptr->type != SIMPLE && word_ptr->son == null ) {
112
	    word_ptr->son = new_ptr ;
113
	} else {
114
	    word_ptr->bro = new_ptr ;
115
	}
116
	word_ptr = new_ptr ;
117
	word_ptr->type = ( char ) c ;
118
	if ( length ) {
119
	    word_ptr->text = page ;
120
	    word_ptr->length = length ;
121
	    page += ( length + 1 ) ;
122
	    page_length -= ( length + 1 ) ;
123
	    if ( page_length < 100 ) {
124
		page = alloc_nof ( char, 10000 ) ;
125
		page_length = 10000 ;
126
	    }
127
	    length = 0 ;
128
	} else {
129
	    word_ptr->text = "" ;
130
	    word_ptr->length = 0 ;
131
	}
132
	word_ptr->son = null ;
133
	word_ptr->bro = null ;
134
    }
135
    return ( word_ptr ) ;
136
}
137
 
138
 
139
/*
140
    OUTPUT A SINGLE CHARACTER INTO INTERNAL MEMORY
141
 
142
    The character c is appended to the internal memory buffer.
143
*/
144
 
145
void out_char
146
    PROTO_N ( ( c ) )
147
    PROTO_T ( int c )
148
{
149
    if ( printflag ) {
150
	page [ length ] = ( char ) c ;
151
	length++ ;
152
	page [ length ] = 0 ;
153
    }
154
    return ;
155
}
156
 
157
 
158
/*
159
    OUTPUT A STRING INTO INTERNAL MEMORY
160
 
161
    The string str is appended to the internal memory buffer.
162
*/
163
 
164
void out_string
165
    PROTO_N ( ( str ) )
166
    PROTO_T ( char *str )
167
{
168
    if ( printflag ) {
169
	IGNORE strcpy ( page + length, str ) ;
170
	length += ( int ) strlen ( str ) ;
171
    }
172
    return ;
173
}
174
 
175
 
176
/*
177
    MAKE A STRING INTO A WORD
178
 
179
    This routine creates a simple word from the string str, appending it
180
    to any text in the internal memory buffer.
181
*/
182
 
183
void out
184
    PROTO_N ( ( str ) )
185
    PROTO_T ( char *str )
186
{
187
    if ( printflag ) {
188
	if ( length ) {
189
	    out_string ( str ) ;
190
	    IGNORE new_word ( SIMPLE ) ;
191
	} else {
192
	    word *ptr = new_word ( SIMPLE ) ;
193
	    ptr->text = str ;
194
	    ptr->length = ( int ) strlen ( str ) ;
195
	}
196
    }
197
    return ;
198
}
199
 
200
 
201
/*
202
    MAKE AN INTEGER INTO A WORD
203
 
204
    This routine creates a simple word from an integer.
205
*/
206
 
207
void out_int
208
    PROTO_N ( ( n ) )
209
    PROTO_T ( long n )
210
{
211
    if ( printflag ) {
212
	/* Note that the input is cast to an unsigned int */
213
	unsigned long m = ( unsigned long ) n, dig, power = 1 ;
214
 
215
	/* Get the highest power of 10 dividing m */
216
	while ( ( m / power ) >= 10 ) power *= 10 ;
217
 
218
	/* Now output digits of m */
219
	while ( power != 0 ) {
220
	    dig = ( m / power ) ;
221
	    m -= dig * power ;
222
	    power = ( power / 10 ) ;
223
	    out_char ( charact ( dig ) ) ;
224
	}
225
	/* Make this into a simple word */
226
	IGNORE new_word ( SIMPLE ) ;
227
    }
228
    return ;
229
}
230
 
231
 
232
/*
233
    MAKE A STRING OF OCTAL DIGITS INTO A WORD
234
 
235
    This routine creates a simple word from a string of octal digits
236
    and a sign.  If the string of octal digits corresponds to a
237
    number of at most 32 bits, out_int is used, otherwise the string
238
    is output directly.
239
*/
240
 
241
void out_signed
242
    PROTO_N ( ( n, sn ) )
243
    PROTO_T ( char *n X int sn )
244
{
245
    if ( printflag ) {
246
	/* Calculate the number of binary digits in n */
247
	int a = digit ( *n ), d ;
248
	if ( a & 4 ) {
249
	    d = 3 * tdf_int_digits ;
250
	} else {
251
	    if ( a & 2 ) {
252
		d = 3 * tdf_int_digits - 1 ;
253
	    } else {
254
		d = 3 * tdf_int_digits - 2 ;
255
	    }
256
	}
257
	if ( d <= BYTESIZE * ( int ) sizeof ( long ) ) {
258
	    /* If n will fit into a long work out its value */
259
	    char *s ;
260
	    long t = 0 ;
261
	    for ( s = n ; *s ; s++ ) t = 8 * t + digit ( *s ) ;
262
	    if ( sn && t ) out_char ( '-' ) ;
263
	    out_int ( t ) ;
264
	} else {
265
	    /* Otherwise output n as a string of octal digits */
266
	    word *w ;
267
	    out_string ( "octal" ) ;
268
	    w = new_word ( HORIZ_BRACKETS ) ;
269
	    out_string ( sn ? "-0" : "0" ) ;
270
	    out ( n ) ;
271
	    end_word ( w ) ;
272
	}
273
    }
274
    return ;
275
}
276
 
277
 
278
/*
279
    MAKE A UNIQUE INTO A WORD
280
 
281
    The unique u is output.
282
*/
283
 
284
void out_unique
285
    PROTO_N ( ( u ) )
286
    PROTO_T ( unique u )
287
{
288
    word *w ;
289
    out_string ( "unique" ) ;
290
    w = new_word ( HORIZ_BRACKETS ) ;
291
    while ( *u ) {
292
	out ( *u ) ;
293
	u++ ;
294
    }
295
    end_word ( w ) ;
296
    return ;
297
}
298
 
299
 
300
/*
301
    UTILITY FORMATTING ROUTINE
302
 
303
    This routine is used to format a function and its arguments.  The
304
    function name is given by func, the layout type by c, and the
305
    arguments by the decode string args.
306
*/
307
 
308
void format
309
    PROTO_N ( ( c, func, args ) )
310
    PROTO_T ( int c X char *func X char *args )
311
{
312
    if ( printflag ) {
313
	word *ptr ;
314
	if ( length ) {
315
	    out_string ( func ) ;
316
	    ptr = new_word ( c ) ;
317
	} else {
318
	    ptr = new_word ( c ) ;
319
	    ptr->text = func ;
320
	    ptr->length = ( int ) strlen ( func ) ;
321
	}
322
	decode ( args ) ;
323
	end_word ( ptr ) ;
324
    } else {
325
	decode ( args ) ;
326
    }
327
    return ;
328
}