Subversion Repositories tendra.SVN

Rev

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

Rev Author Line No. Line
2 7u83 1
/*
6 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
6 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:-
6 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
6 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;
6 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;
6 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 "ascii.h"
64
#include "file.h"
65
#include "pretty.h"
66
#include "tree.h"
67
#include "utility.h"
68
 
69
 
70
/*
71
    MACRO DEFINITIONS
72
 
73
    BUFFSIZE gives the size of the input buffer.  HI_MASK and LO_MASK
74
    are bit masks used to extract bits 8-15 and 0-7 respectively from
75
    an integer.
76
*/
77
 
6 7u83 78
#define BUFFSIZE	((size_t)1024)
79
#define HI_MASK		((unsigned)0xff00)
80
#define LO_MASK		((unsigned)0x00ff)
2 7u83 81
 
82
 
83
/*
84
    INPUT AND OUTPUT FILES AND BUFFERS
85
 
86
    The input TDF capsule is read from tdf_file.  The pretty-printed
87
    output is placed into pp_file.  The input uses the buffer
88
    inbuffer.
89
*/
90
 
6 7u83 91
FILE *pp_file;
92
static FILE *tdf_file;
93
static char inbuffer[BUFFSIZE];
94
static int ib_ptr, ib_size;
2 7u83 95
 
96
 
97
/*
98
    POSITION IN INPUT FILE
99
 
100
    The current position in the input file is recorded by means of a
101
    place.
102
*/
103
 
6 7u83 104
place here;
2 7u83 105
 
106
 
107
/*
108
    INPUT AND OUTPUT VARIABLES
109
 
110
    printflag is used to switch the printing on or off.  The present
111
    column number in the output file is given by column.  The maximum
112
    value attained by column is recorded in maximum.  The last character
113
    output is held in lastc.  The flag read_error is used to indicate
114
    that an error has occurred in reading the input file.
115
*/
116
 
6 7u83 117
int printflag = 1;
118
int column;
119
int maximum;
120
int lastc = 0;
121
int read_error = 0;
122
int dump = 0;
2 7u83 123
 
124
 
125
/*
126
    OPEN FILES
127
 
128
    The file name1 is opened for input and name2 for output.  If name2
129
    is the null string, the standard output is used.
130
*/
131
 
6 7u83 132
void
133
open_files(char *name1, char *name2)
2 7u83 134
{
6 7u83 135
    tdf_file = fopen(name1, "rb");
136
    if (tdf_file == null)fatal_error("Can't open %s", name1);
137
    if (name2 == null)dflag = 0;
138
    if (dflag) {
139
	pp_file = fopen(name2, "w");
140
	if (pp_file == null)fatal_error("Can't open %s", name2);
2 7u83 141
    } else {
6 7u83 142
	pp_file = stdout;
2 7u83 143
    }
6 7u83 144
    here.byte = 0;
145
    here.bit = 0;
146
    ib_size = 0;
147
    return;
2 7u83 148
}
149
 
150
 
151
/*
152
    READ THE NEXT BYTE FROM THE INPUT FILE
153
 
154
    This routine reads the next byte from the input file, putting it
155
    into the worksp field of here.
156
*/
157
 
6 7u83 158
static void
159
next_byte(void)
2 7u83 160
{
6 7u83 161
    if (read_error) {
162
	here.worksp = 0xff;
2 7u83 163
    } else {
164
	/* refill input buffer if required */
6 7u83 165
	if (ib_size == 0) {
166
	    ib_ptr = 0;
167
	    ib_size = (int)fread(inbuffer, 1, BUFFSIZE, tdf_file);
168
	    if (ib_size == 0) {
2 7u83 169
		/* if we have reached the end of the file... */
6 7u83 170
		read_error = 1;
171
		if (!dump) {
172
		    out("<reading error>");
173
		    input_error("Reading error");
2 7u83 174
		}
175
	    }
176
	}
177
	/* get the next character */
6 7u83 178
	if (read_error) {
179
	    here.worksp = 0xff;
2 7u83 180
	} else {
6 7u83 181
	    char c = inbuffer[ib_ptr++];
182
	    here.worksp = (unsigned)(c & 0xff);
183
	    ib_size--;
2 7u83 184
	}
185
    }
6 7u83 186
    return;
2 7u83 187
}
188
 
189
 
190
/*
191
    FETCH THE NEXT n BITS FROM THE INPUT FILE
192
 
193
    This routine reads the next n bits from the input file and returns
194
    them as an integer.  n will rarely be as much as 8, so there is
195
    no problem with overflow.
196
*/
197
 
6 7u83 198
long
199
fetch(int n)
2 7u83 200
{
6 7u83 201
    int m;
202
    unsigned a = 0;
203
    while (n) {
2 7u83 204
	/* read the next byte if necessary */
6 7u83 205
	if (here.bit == 0)next_byte();
2 7u83 206
	/* m = number of bits we need from this byte */
6 7u83 207
	m = BYTESIZE - here.bit;
208
	if (n < m)m = n;
2 7u83 209
	/* extract m bytes from here.worksp */
6 7u83 210
	here.worksp <<= m;
211
	a = (a << m) + ((here.worksp & HI_MASK) >> BYTESIZE);
212
	here.worksp &= LO_MASK;
213
	n -= m;
214
	here.bit += m;
215
	if (here.bit == BYTESIZE) {
216
	    here.bit = 0;
217
	    here.byte++;
2 7u83 218
	}
219
    }
6 7u83 220
    return((long)a);
2 7u83 221
}
222
 
223
 
224
/*
225
    ALIGN INPUT FILE TO AN 8 BIT BOUNDARY
226
 
227
    Bits are read from the input file until it is on an 8 bit boundary.
228
*/
229
 
6 7u83 230
void
231
byte_align(void)
2 7u83 232
{
6 7u83 233
    while (!(here.bit == 0 || here.bit == BYTESIZE)) {
234
	IGNORE fetch(1);
2 7u83 235
    }
6 7u83 236
    return;
2 7u83 237
}
238
 
239
 
240
/*
241
    GO TO A GIVEN PLACE IN THE INPUT FILE
242
 
243
    The current position is set to the position indicated by the place p.
244
*/
245
 
6 7u83 246
void
247
set_place(place *p)
2 7u83 248
{
6 7u83 249
    int s;
250
    here.byte = p->byte;
251
    here.bit = 0;
252
    s = fseek(tdf_file, here.byte, SEEK_SET);
253
    if (s)fatal_error("Internal file seek error");
254
    ib_size = 0;
255
    IGNORE fetch(p->bit);
256
    return;
2 7u83 257
}
258
 
259
 
260
/*
261
    SKIP THE NEXT n BITS IN THE INPUT FILE
262
 
263
    If n is small, the next n bits are read but discarded.  Otherwise
264
    set_place is used.
265
*/
266
 
6 7u83 267
void
268
skip_bits(long n)
2 7u83 269
{
6 7u83 270
    if (read_error) return;
271
    if (n <= 4 * BYTESIZE) {
272
	IGNORE fetch((int)n);
2 7u83 273
    } else {
6 7u83 274
	place p;
275
	long b = posn(here) + n;
276
	p.byte = b / BYTESIZE;
277
	p.bit = (int)(b % BYTESIZE);
278
	set_place(&p);
2 7u83 279
    }
6 7u83 280
    return;
2 7u83 281
}
282
 
283
 
284
/*
285
    ARRAY OF SPACES
286
 
287
    The indentation spaces used during pretty-printing are stored in
288
    an array.
289
*/
290
 
6 7u83 291
static char *spaces1;
2 7u83 292
 
293
 
294
/*
295
    INITIALIZE SPACES
296
 
297
    This routine initializes the array of indentation spaces, spaces1.
298
*/
299
 
6 7u83 300
void
301
init_spaces(int d)
2 7u83 302
{
6 7u83 303
    int i, j;
304
    if (helpflag) {
305
	spaces1 = alloc_nof(char, 5000);
2 7u83 306
	/* every dth character should be a '.' */
6 7u83 307
	for (i = 0, j = 0; i < 5000; i++) {
308
	    if (++j == d) {
309
		spaces1[i] = '.';
310
		j = 0;
2 7u83 311
	    } else {
6 7u83 312
		spaces1[i] = ' ';
2 7u83 313
	    }
314
	}
315
    }
6 7u83 316
    return;
2 7u83 317
}
318
 
319
 
320
/*
321
    OUTPUT n SPACES
322
 
323
    This routine outputs n indentation spaces, using the array spaces1
324
    when appropriate.
325
*/
326
 
6 7u83 327
void
328
spaces(int n)
2 7u83 329
{
6 7u83 330
    if (n < 0)n = 0;
331
    if (printflag) {
332
	if (helpflag) {
333
	    if (n) {
334
		 IGNORE fwrite(spaces1, sizeof(char),
335
				  (size_t)n, pp_file);
2 7u83 336
	    }
337
	} else {
6 7u83 338
	    int i;
339
	    int q = (n / TBSIZE);
340
	    int r = (n % TBSIZE);
341
	    for (i = 0; i < q; i++)IGNORE fputc(TAB, pp_file);
342
	    for (i = 0; i < r; i++)IGNORE fputc(SPACE, pp_file);
2 7u83 343
	}
344
    }
6 7u83 345
    column = n;
346
    lastc = ' ';
347
    return;
2 7u83 348
}