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
#if FS_STDARG
63
#include <stdarg.h>
64
#else
65
#include <varargs.h>
66
#endif
67
#include "types.h"
68
#include "read_types.h"
69
#include "analyser.h"
70
#include "fetch.h"
71
#include "file.h"
72
#include "table.h"
73
#include "utility.h"
74
#include "write.h"
7 7u83 75
extern char *progname;
76
extern char *capname;
77
extern int decode_status;
78
extern int have_version;
2 7u83 79
 
80
 
81
/*
82
    ARE INPUT AND OUTPUT TEXT OR CODE?
83
 
84
    The form of any error message depends on whether the input file
85
    is text or code.
86
*/
87
 
7 7u83 88
boolean text_input = 1;
89
boolean text_output = 0;
2 7u83 90
 
91
 
92
/*
93
    EXIT STATUS
94
 
95
    The overall exit status of the program.
96
*/
97
 
7 7u83 98
int exit_status = EXIT_SUCCESS;
2 7u83 99
 
100
 
101
/*
102
    REPORT A FATAL ERROR
103
 
104
    The error s is reported and the program exits.
105
*/
106
 
7 7u83 107
void
108
fatal_error(char *s, ...) /* VARARGS */
2 7u83 109
{
7 7u83 110
    va_list args;
2 7u83 111
#if FS_STDARG
7 7u83 112
    va_start(args, s);
2 7u83 113
#else
7 7u83 114
    char *s;
115
    va_start(args);
116
    s = va_arg(args, char *);
2 7u83 117
#endif
7 7u83 118
    if (progname)IGNORE fprintf(stderr, "%s: ", progname);
119
    IGNORE fprintf(stderr, "Error: ");
120
    IGNORE vfprintf(stderr, s, args);
121
    IGNORE fprintf(stderr, ".\n");
122
    va_end(args);
123
    exit(EXIT_FAILURE);
2 7u83 124
}
125
 
126
 
127
/*
128
    IS AN INPUT ERROR FATAL?
129
 
130
    Not all input errors cause an immediate exit.  These should set
131
    is_fatal to false before calling input_error.
132
*/
133
 
7 7u83 134
boolean is_fatal = 1;
2 7u83 135
 
136
 
137
/*
138
    REPORT AN INPUT ERROR
139
 
140
    The input error s is reported and the program exits.
141
*/
142
 
7 7u83 143
void
144
input_error(char *s, ...) /* VARARGS */
2 7u83 145
{
7 7u83 146
    va_list args;
2 7u83 147
#if FS_STDARG
7 7u83 148
    va_start(args, s);
2 7u83 149
#else
7 7u83 150
    char *s;
151
    va_start(args);
152
    s = va_arg(args, char *);
2 7u83 153
#endif
7 7u83 154
    if (progname)IGNORE fprintf(stderr, "%s: ", progname);
155
    IGNORE fprintf(stderr, "Error: ");
156
    IGNORE vfprintf(stderr, s, args);
157
    if (input_file) {
158
	IGNORE fprintf(stderr, ", %s", input_file);
159
	if (text_input) {
160
	    IGNORE fprintf(stderr, ", line %ld", line_no);
2 7u83 161
	} else {
7 7u83 162
	    long b = input_posn();
163
	    if (capname) {
164
		IGNORE fprintf(stderr, ", capsule %s", capname);
2 7u83 165
	    }
7 7u83 166
	    switch (decode_status) {
167
		case 0: {
168
		    IGNORE fprintf(stderr, " (at outermost level)");
169
		    break;
2 7u83 170
		}
7 7u83 171
		case 1: {
172
		    IGNORE fprintf(stderr, " (in linking information)");
173
		    break;
2 7u83 174
		}
7 7u83 175
		case 2: {
176
		    IGNORE fprintf(stderr, " (in unit body)");
177
		    break;
2 7u83 178
		}
179
	    }
7 7u83 180
	    IGNORE fprintf(stderr, ", byte %ld, bit %ld", b / 8, b % 8);
181
	    if (decode_status == 0) {
182
		IGNORE fprintf(stderr, " (Illegal TDF capsule?)");
2 7u83 183
	    }
7 7u83 184
	    if (decode_status >= 1 && !have_version) {
185
		IGNORE fprintf(stderr, " (TDF version error?)");
2 7u83 186
	    }
187
	}
188
    }
7 7u83 189
    IGNORE fprintf(stderr, ".\n");
190
    va_end(args);
191
    if (is_fatal) {
192
	if (text_output) {
193
	    sort_all();
194
	    print_capsule();
195
	    IGNORE fputs("# TERMINATED ON INPUT ERROR\n", output);
2 7u83 196
	}
7 7u83 197
	exit(EXIT_FAILURE);
2 7u83 198
    }
7 7u83 199
    is_fatal = 1;
200
    exit_status = EXIT_FAILURE;
201
    return;
2 7u83 202
}
203
 
204
 
205
/*
206
    ISSUE A WARNING
207
 
208
    The warning message s is printed.
209
*/
210
 
7 7u83 211
void
212
warning(char *s, ...) /* VARARGS */
2 7u83 213
{
7 7u83 214
    va_list args;
2 7u83 215
#if FS_STDARG
7 7u83 216
    va_start(args, s);
2 7u83 217
#else
7 7u83 218
    char *s;
219
    va_start(args);
220
    s = va_arg(args, char *);
2 7u83 221
#endif
7 7u83 222
    if (progname)IGNORE fprintf(stderr, "%s: ", progname);
223
    IGNORE fprintf(stderr, "Warning: ");
224
    IGNORE vfprintf(stderr, s, args);
225
    IGNORE fprintf(stderr, ".\n");
226
    va_end(args);
227
    return;
2 7u83 228
}
229
 
230
 
231
/*
232
    ALLOCATE A SECTION OF MEMORY
233
 
234
    This routine allocates n bytes of memory.
235
*/
236
 
7 7u83 237
pointer
238
xalloc(int n)
2 7u83 239
{
7 7u83 240
    pointer ptr;
241
    if (n == 0) return(null);
242
    ptr = (pointer)malloc((size_t)n);
243
    if (ptr == null) {
244
	if (!text_input && decode_status == 0) {
245
	    fatal_error("Memory allocation error (Illegal TDF capsule?)");
2 7u83 246
	}
7 7u83 247
	fatal_error("Memory allocation error");
2 7u83 248
    }
7 7u83 249
    return(ptr);
2 7u83 250
}
251
 
252
 
253
/*
254
    REALLOCATE A SECTION OF MEMORY
255
 
256
    This routine reallocates n bytes of memory for the pointer p.
257
*/
258
 
7 7u83 259
pointer
260
xrealloc(pointer p, int n)
2 7u83 261
{
7 7u83 262
    pointer ptr;
263
    if (n == 0) return(null);
264
    if (p == null) return(xalloc(n));
265
    ptr = (pointer)realloc(p,(size_t)n);
266
    if (ptr == null)fatal_error("Memory allocation error");
267
    return(ptr);
2 7u83 268
}
269
 
270
 
271
/*
272
    MAKE A COPY OF A STRING
273
 
274
    This routine makes a permanent copy of the string s of length n.
275
*/
276
 
7 7u83 277
char *
278
string_copy(char *s, int n)
2 7u83 279
{
7 7u83 280
    int m = (n + 1)*(int)sizeof(char);
281
    char *p = (char *)xalloc(m);
282
    IGNORE strncpy(p, s,(size_t)n);
283
    p[n] = 0;
284
    return(p);
2 7u83 285
}
286
 
287
 
288
/*
289
    MAKE A TEMPORARY COPY OF A STRING
290
 
291
    This routine copies a string into a temporary buffer.
292
*/
293
 
7 7u83 294
char *
295
temp_copy(char *s)
2 7u83 296
{
7 7u83 297
    static char *buff = null;
298
    static int bufflen = 0;
299
    int n = (int)strlen(s) + 1;
300
    if (n >= bufflen) {
301
	bufflen = n + 100;
302
	buff = (char *)xrealloc((pointer)buff, bufflen);
2 7u83 303
    }
7 7u83 304
    IGNORE strcpy(buff, s);
305
    return(buff);
2 7u83 306
}
307
 
308
 
309
/*
310
    CONVERT AN UNSIGNED LONG TO OCTAL
311
 
312
    The result is returned as a string of octal digits.
313
*/
314
 
7 7u83 315
char *
316
ulong_to_octal(unsigned long n)
2 7u83 317
{
7 7u83 318
    int i = 99;
319
    char buff[100];
320
    if (n == 0) return("0");
321
    buff[i] = 0;
322
    while (n) {
323
	buff[--i] = (char)('0' + (n & 7));
324
	n >>= 3;
2 7u83 325
    }
7 7u83 326
    return(string_copy(buff + i, 99 - i));
2 7u83 327
}
328
 
329
 
330
/*
331
    CONVERT AN OCTAL STRING TO AN UNSIGNED LONG
332
 
333
    Any overflow is ignored (but see below).
334
*/
335
 
7 7u83 336
unsigned long
337
octal_to_ulong(char *num)
2 7u83 338
{
7 7u83 339
    unsigned long n = 0;
340
    for (; *num; num++) {
341
	n = (n << 3) + (unsigned long)(*num - '0');
2 7u83 342
    }
7 7u83 343
    return(n);
2 7u83 344
}
345
 
346
 
347
/*
348
    DOES THE GIVEN OCTAL STRING FIT INTO AN UNSIGNED LONG?
349
 
350
    The number of binary digits needed to represent the octal number
351
    is calculated and compared against the number of bits in an
352
    unsigned long, minus sz (to allow for a sign bit).
353
*/
354
 
7 7u83 355
boolean
356
fits_ulong(char *num, int sz)
2 7u83 357
{
7 7u83 358
    int n = 3 *(int)strlen(num);
359
    int m = BYTESIZE *(int)sizeof(unsigned long) - sz;
360
    switch (*num) {
361
	case '0': n -= 3; break;
362
	case '1': n -= 2; break;
363
	case '2': n -= 1; break;
364
	case '3': n -= 1; break;
2 7u83 365
    }
7 7u83 366
    if (n <= m) return(1);
367
    return(0);
2 7u83 368
}