Subversion Repositories tendra.SVN

Rev

Rev 7 | 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
#define calculus_IO_ROUTINES
62
#include "config.h"
63
#include "read.h"
64
#include "calculus.h"
65
#include "common.h"
66
#include "error.h"
67
#include "output.h"
68
#include "xalloc.h"
69
 
70
 
71
/*
7 7u83 72
 * BITMASKS
73
 *
74
 * This array gives the masks for each bit value.
75
 */
2 7u83 76
 
7 7u83 77
unsigned long bitmask[CHAR_BIT];
2 7u83 78
 
79
 
80
/*
7 7u83 81
 * INITIALISE MASKS
82
 *
83
 * This routine initialises the array of bitmasks.  This is done
84
 * dynamically rather than statically in case CHAR_BIT is not 8.
85
 */
2 7u83 86
 
7 7u83 87
void
88
init_bitmask(void)
2 7u83 89
{
7 7u83 90
    int i;
91
    for (i = 0; i < CHAR_BIT; i++) {
92
	    bitmask[i] = MASK(i);
93
    }
94
    return;
2 7u83 95
}
96
 
97
 
98
/*
7 7u83 99
 * INPUT FILE
100
 *
101
 * These variables describe the input file.  There is a one byte input
102
 * buffer.
103
 */
2 7u83 104
 
7 7u83 105
static FILE *input_file;
106
static unsigned long input_buff = 0;
107
static int input_bits = 0;
2 7u83 108
 
109
 
110
/*
7 7u83 111
 * READ A NUMBER OF BITS
112
 *
113
 * This routine reads the next n bits from the input file.
114
 */
2 7u83 115
 
7 7u83 116
static unsigned long
117
read_bits(int n)
2 7u83 118
{
7 7u83 119
    int b = input_bits;
120
    unsigned long m = input_buff;
121
    unsigned long r = 0;
122
    while (n) {
123
	if (b == 0) {
2 7u83 124
	    /* Read next byte */
7 7u83 125
	    int c = getc(input_file);
126
	    if (c == EOF) {
127
		error(ERROR_FATAL, "Premature end of file");
2 7u83 128
	    } else {
7 7u83 129
		m = (((unsigned long)c) & MASK(CHAR_BIT));
2 7u83 130
	    }
7 7u83 131
	    b = CHAR_BIT;
2 7u83 132
	}
7 7u83 133
	if (n >= b) {
134
	    r = (r << b) | m;
135
	    n -= b;
136
	    b = 0;
2 7u83 137
	} else {
7 7u83 138
	    int c = b - n;
139
	    r = (r << n) | (m >> c);
140
	    m &= bitmask[c];
141
	    n = 0;
142
	    b = c;
2 7u83 143
	}
144
    }
7 7u83 145
    input_bits = b;
146
    input_buff = m;
147
    return(r);
2 7u83 148
}
149
 
150
 
151
/*
7 7u83 152
 * READ AN INTEGER
153
 *
154
 * This routine reads an integer from the input file.  This is encoded
155
 * as a sequence of octal digits with a marker bit for the end of the
156
 * number.
157
 */
2 7u83 158
 
7 7u83 159
static unsigned long
160
read_int(void)
2 7u83 161
{
7 7u83 162
    unsigned long r = 0, d;
163
    while (d = read_bits(4), (d & 0x08) == 0) {
164
	r = (r << 3) | d;
2 7u83 165
    }
7 7u83 166
    r = (r << 3) | (d & 0x07);
167
    return(r);
2 7u83 168
}
169
 
170
 
171
/*
7 7u83 172
 * READ A STRING
173
 *
174
 * This routine reads an integer from the input file.  This is encoded
175
 * as the string length followed by the characters comprising the
176
 * string (8 bits each).
177
 */
2 7u83 178
 
7 7u83 179
static char *
180
read_string(void)
2 7u83 181
{
7 7u83 182
    unsigned long i, n = read_int();
183
    char *s = xstr((long)(n + 1));
184
    for (i = 0; i < n; i++) {
185
	s[i] = (char)read_bits(8);
2 7u83 186
    }
7 7u83 187
    s[n] = 0;
188
    return(s);
2 7u83 189
}
190
 
191
 
192
/*
7 7u83 193
 * READ A FILENAME
194
 *
195
 * File names are just strings, however they are buffered to save
196
 * space.
197
 */
2 7u83 198
 
7 7u83 199
static char *
200
read_filename(void)
2 7u83 201
{
7 7u83 202
    char *s;
203
    static char *last_filename = "????";
204
    if (read_bits(1)) {
205
	s = last_filename;
2 7u83 206
    } else {
7 7u83 207
	s = read_string();
208
	last_filename = s;
2 7u83 209
    }
7 7u83 210
    return(s);
2 7u83 211
}
212
 
213
 
214
/*
7 7u83 215
 * AUTOMATICALLY GENERATED DISK READING ROUTINES
216
 *
217
 * The main disk reading routines are automatically generated.  The
218
 * various macros are used to customise these routines.
219
 */
2 7u83 220
 
7 7u83 221
#define READ_BITS(N)		((unsigned)read_bits(N))
222
#define READ_ALIAS()		((unsigned)read_int())
223
#define READ_DIM()		((unsigned)read_int())
224
#define READ_int()		((int)read_int())
225
#define READ_number()		((number)read_int())
226
#define READ_string()		read_string()
227
#define READ_name_string()	read_filename()
2 7u83 228
#define READ_zero_int()		0
229
 
230
#include "read_def.h"
231
 
232
 
233
/*
7 7u83 234
 * READ AN INPUT FILE
235
 *
236
 * This routine reads an algebra from the input file nm.
237
 */
2 7u83 238
 
7 7u83 239
void
240
read_file(char *nm)
2 7u83 241
{
7 7u83 242
    char *s;
2 7u83 243
 
244
    /* Open file */
7 7u83 245
    crt_line_no = -1;
246
    crt_file_name = nm;
247
    input_file = fopen(nm, "rb");
248
    if (input_file == NULL) {
249
	error(ERROR_SERIOUS, "Can't open input file, '%s'", nm);
250
	return;
2 7u83 251
    }
7 7u83 252
    init_bitmask();
253
    input_buff = 0;
254
    input_bits = 0;
2 7u83 255
 
256
    /* Confirm file header */
7 7u83 257
    s = READ_string();
258
    if (!streq(s, calculus_NAME)) {
259
	error(ERROR_FATAL, "Invalid file header identifier");
2 7u83 260
    }
7 7u83 261
    s = READ_string();
262
    if (!streq(s, calculus_VERSION)) {
263
	error(ERROR_FATAL, "Invalid file header version, '%s'", s);
2 7u83 264
    }
265
 
266
    /* Read the algebra */
7 7u83 267
    algebra->name = READ_string();
268
    algebra->major_no = READ_int();
269
    algebra->minor_no = READ_int();
270
    algebra->types = READ_list_ptr_type();
271
    clear_calculus_alias();
2 7u83 272
 
273
    /* Extract lists of primitives etc */
274
    LOOP_TYPE {
7 7u83 275
	TYPE_P t = CRT_TYPE;
276
	TYPE t0 = DEREF_type(t);
277
	switch (TAG_type(t0)) {
278
	    case type_primitive_tag: {
279
		PRIMITIVE_P p = DEREF_ptr(type_primitive_prim(t0));
280
		CONS_ptr(p, algebra->primitives, algebra->primitives);
281
		break;
2 7u83 282
	    }
7 7u83 283
	    case type_ident_tag: {
284
		IDENTITY_P p = DEREF_ptr(type_ident_id(t0));
285
		CONS_ptr(p, algebra->identities, algebra->identities);
286
		break;
2 7u83 287
	    }
7 7u83 288
	    case type_enumeration_tag: {
289
		ENUM_P p = DEREF_ptr(type_enumeration_en(t0));
290
		CONS_ptr(p, algebra->enumerations, algebra->enumerations);
291
		break;
2 7u83 292
	    }
7 7u83 293
	    case type_structure_tag: {
294
		STRUCTURE_P p = DEREF_ptr(type_structure_struc(t0));
295
		CONS_ptr(p, algebra->structures, algebra->structures);
296
		break;
2 7u83 297
	    }
7 7u83 298
	    case type_onion_tag: {
299
		UNION_P p = DEREF_ptr(type_onion_un(t0));
300
		CONS_ptr(p, algebra->unions, algebra->unions);
301
		break;
2 7u83 302
	    }
303
	}
304
    }
305
 
306
    /* Close file */
7 7u83 307
    fclose_v(input_file);
308
    return;
2 7u83 309
}