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-2006 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) 1996
33
 
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:-
42
 
43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
45
 
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;
49
 
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;
53
 
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
			    VERSION INFORMATION
61
			    ===================
62
 
63
--------------------------------------------------------------------------
64
$Header: /u/g/release/CVSROOT/Source/src/installers/680x0/common/utility.c,v 1.1.1.1 1998/01/17 15:55:49 release Exp $
65
--------------------------------------------------------------------------
66
$Log: utility.c,v $
67
 * Revision 1.1.1.1  1998/01/17  15:55:49  release
68
 * First version to be checked into rolling release.
69
 *
70
Revision 1.1.1.1  1997/10/13 12:43:00  ma
71
First version.
72
 
73
Revision 1.3  1997/10/13 08:50:16  ma
74
Made all pl_tests for general proc & exception handling pass.
75
 
76
Revision 1.2  1997/03/20 12:52:20  ma
77
Removed #if 0 and #endif around used definitions.
78
 
79
Revision 1.1.1.1  1997/03/14 07:50:19  ma
80
Imported from DRA
81
 
82
 * Revision 1.1.1.1  1996/09/20  10:56:59  john
83
 *
84
 * Revision 1.1.1.1  1996/03/26  15:45:18  john
85
 *
86
 * Revision 1.4  94/11/08  11:24:26  11:24:26  ra (Robert Andrews)
87
 * Changed error reporting format slightly.
88
 *
89
 * Revision 1.3  94/02/21  16:05:37  16:05:37  ra (Robert Andrews)
90
 * Clear up a long-int confusion.
91
 *
92
 * Revision 1.2  93/04/19  13:37:53  13:37:53  ra (Robert Andrews)
93
 * Line numbers in error reports were wrong.
94
 *
95
 * Revision 1.1  93/02/22  17:16:55  17:16:55  ra (Robert Andrews)
96
 * Initial revision
97
 *
98
--------------------------------------------------------------------------
99
*/
100
 
101
 
102
#include "config.h"
103
#if FS_STDARG
104
#include <stdarg.h>
105
#else
106
#include <varargs.h>
107
#endif
108
#include "common_types.h"
109
#include "basicread.h"
110
#include "instrs.h"
111
#include "utility.h"
6 7u83 112
extern long crt_line_num;
113
extern char *crt_fname;
114
extern char *progname;
115
long total_calloced;
2 7u83 116
#if 0
117
/* Makes automatically generated makefile work */
118
#include "xalloc.c"
119
#endif
120
 
121
 
122
/*
123
    FIND THE BASENAME OF A FILE
124
 
125
    The string nm is analysed and a pointer to the character after the
126
    last '/' is returned.
127
*/
128
 
6 7u83 129
char *
130
basename(char *nm)
2 7u83 131
{
6 7u83 132
	char *bn = nm;
133
	for (; *nm; nm++) {
134
		if (*nm == '/') {
135
			bn = nm + 1;
136
		}
137
	}
138
	return (bn);
2 7u83 139
}
140
 
141
 
142
/*
143
    FIND THE FIRST NONZERO BIT
144
 
145
    This routine returns the bit number of the least significant set
146
    bit in n.  For 0 it returns -1.
147
*/
148
 
6 7u83 149
int
150
bit_one(bitpattern n)
2 7u83 151
{
6 7u83 152
	int c = 0;
153
	bitpattern m;
154
	for (m = n; m; m >>= 1, c++) {
155
		if (m & 1) {
156
			return (c);
157
		}
158
	}
159
	return (-1);
2 7u83 160
}
161
 
162
 
163
/*
164
    FIND THE NUMBER OF SET BITS
165
 
166
    The number of set bits in n is returned.
167
*/
168
 
6 7u83 169
int
170
bits_in(bitpattern n)
2 7u83 171
{
6 7u83 172
	/* Table of bits in : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F */
173
	static int b[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
174
	int c = 0;
175
	while (n) {
176
		c += b[n & 0xf];
177
		n >>= 4;
178
	}
179
	return (c);
2 7u83 180
}
181
 
182
 
183
/*
184
    BIT PATTERNS
185
 
186
    lo_bits [n] is the number with its bottom n bits set and the rest
187
    zero.  hi_bits [n] is the number with its top n bits set and the rest
188
    zero.
189
*/
190
 
6 7u83 191
bitpattern lo_bits[] = { 0,
192
	0x00000001, 0x00000003, 0x00000007, 0x0000000f,
193
	0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
194
	0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
195
	0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
196
	0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
197
	0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
198
	0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
199
	0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff };
2 7u83 200
 
6 7u83 201
bitpattern hi_bits[] = { 0,
202
	0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
203
	0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
204
	0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
205
	0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
206
	0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
207
	0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
208
	0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
209
	0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff };
2 7u83 210
 
211
 
212
/*
6 7u83 213
   NUMBER OF ERRORS
2 7u83 214
 
6 7u83 215
   errors is the number of errors which have occurred.  max_errors is
216
   the maximum number of errors that will be tolerated before exiting.
217
 */
2 7u83 218
 
6 7u83 219
int errors = 0;
2 7u83 220
#ifdef EBUG
6 7u83 221
int max_errors = 10;
2 7u83 222
#else
6 7u83 223
int max_errors = 1;
2 7u83 224
#endif
225
 
226
 
227
/*
6 7u83 228
   PRINT AN ERROR REPORT
2 7u83 229
 
6 7u83 230
   This routine prints the error report s together with any additional
231
   arguments.
232
 */
2 7u83 233
 
6 7u83 234
void
235
error(char *s, ...)
2 7u83 236
{
6 7u83 237
	char c;
238
	char *p;
239
	va_list args;
2 7u83 240
#if FS_STDARG
6 7u83 241
	va_start(args, s);
242
	p = s;
2 7u83 243
#else
6 7u83 244
	va_start(args);
245
	p = va_arg(args, char *);
2 7u83 246
#endif
6 7u83 247
	if (progname) {
248
		fprintf(stderr, "%s : ", progname);
249
	}
250
	fprintf(stderr, "Error : ");
251
	c = *p;
252
	if (c >= 'a' && c <= 'z') {
253
		c += ('A' - 'a');
254
		fputc(c, stderr);
255
		p++;
256
	}
257
	vfprintf(stderr, p, args);
258
	if (crt_line_num != -1 && crt_fname) {
259
		fprintf(stderr, ", %s, line %ld", crt_fname, crt_line_num);
260
	}
261
	fprintf(stderr, ".\n");
262
	va_end(args);
2 7u83 263
#ifdef IGNORE_ERRORS
6 7u83 264
	return;
2 7u83 265
#endif
6 7u83 266
	if (max_errors == 0) {
267
		exit(EXIT_FAILURE);
268
	}
269
	if (++errors > max_errors) {
270
		fprintf(stderr, "%s : Too many errors.\n", progname);
271
		exit(EXIT_FAILURE);
272
	}
273
	return;
2 7u83 274
}
275
 
276
/*
277
    PRINT A SIMPLE ERROR
278
 
279
    This routine prints the simple error report s.
280
*/
281
 
6 7u83 282
void
283
failer(char *s)
2 7u83 284
{
6 7u83 285
	error(s);
286
	return;
2 7u83 287
}
288
 
289
 
290
/*
291
    PRINT A WARNING
292
 
293
    This routine prints the warning message s together with any additional
294
    arguments.
295
*/
296
 
6 7u83 297
void
298
warning(char *s, ...)
2 7u83 299
{
6 7u83 300
	char c;
301
	char *p;
302
	va_list args;
2 7u83 303
#if FS_STDARG
6 7u83 304
	va_start(args, s);
305
	p = s;
2 7u83 306
#else
6 7u83 307
	va_start(args);
308
	p = va_arg(args, char *);
2 7u83 309
#endif
6 7u83 310
	if (progname) {
311
		(void)fprintf(stderr, "%s : ", progname);
312
	}
313
	fprintf(stderr, "Warning : ");
314
	c = *p;
315
	if (c >= 'a' && c <= 'z') {
316
		c += ('A' - 'a');
317
		fputc(c, stderr);
318
		p++;
319
	}
320
	(void)vfprintf(stderr, p, args);
321
	(void)fprintf(stderr, ".\n");
322
	va_end(args);
323
	return;
2 7u83 324
}
325
 
326
 
327
/*
328
    MEMORY HACK VALUE
329
*/
330
 
331
#define memhack 0
332
 
333
/*
334
    ALLOCATE A BLOCK OF MEMORY
335
 
336
    A pointer to a block of memory of size sz is returned.  Failure to
337
    allocate this memory gives an immediate fatal error.
338
*/
339
 
6 7u83 340
voidstar
341
xmalloc(size_t sz)
2 7u83 342
{
6 7u83 343
	voidstar res;
344
	if (sz == 0) {
345
		return (null);
346
	}
347
	res = (voidstar)malloc(sz + memhack);
348
	if (res == null) {
349
		error("Can't allocate memory");
350
		exit(EXIT_FAILURE);
351
	}
2 7u83 352
#ifdef MEM_DEBUG
6 7u83 353
	printf("%d (malloc, %d bytes)\n", res, sz);
354
	fflush(stdout);
2 7u83 355
#endif
6 7u83 356
	return (res);
2 7u83 357
}
358
 
359
 
360
/*
361
    ALLOCATE ROOM IN MEMORY
362
 
363
    A pointer to a block of memory of size n * sz is returned.  This
364
    memory is initialized to 0.  Failure to allocate memory gives an
365
    immediate fatal error.
366
*/
367
 
6 7u83 368
voidstar
369
xcalloc(int n, size_t sz)
2 7u83 370
{
6 7u83 371
	voidstar res;
372
	if (n == 0 || sz == 0) {
373
		return (null);
2 7u83 374
	}
6 7u83 375
	if (sz == sizeof(char) && n < 100) {
376
		/* Be careful not to free character arrays */
377
		static char *cbuffer = null;
378
		static size_t cbuffsz = 0;
379
		if (n + memhack >= cbuffsz) {
380
			cbuffsz = 2000;
381
			cbuffer = (char *)calloc(cbuffsz, sizeof(char));
382
			if (cbuffer == null) {
383
				error("Can't allocate memory");
384
				exit(EXIT_FAILURE);
385
			}
386
		}
387
		res = (voidstar)cbuffer;
388
		cbuffer += (n + memhack);
389
		cbuffsz -= (n + memhack);
390
	} else {
391
		res = (voidstar)calloc(n + memhack, sz);
392
		if (res == null) {
393
			error("Can't allocate memory");
394
			exit(EXIT_FAILURE);
395
		}
2 7u83 396
	}
397
#ifdef MEM_DEBUG
6 7u83 398
	printf("%d (calloc, %d bytes)\n", res, n * sz);
399
	fflush(stdout);
2 7u83 400
#endif
6 7u83 401
	return (res);
2 7u83 402
}
403
 
404
 
405
/*
406
    REALLOCATE A BLOCK OF MEMORY
407
 
408
    The previously allocated memory pointed to by p is reallocated
409
    to size n.  A pointer to the new block of memory is returned.
410
    Failure to allocate memory gives an immediate fatal error.
411
*/
412
 
6 7u83 413
voidstar
414
xrealloc(voidstar p, size_t sz)
2 7u83 415
{
6 7u83 416
	voidstar res;
417
	if (p == null) {
418
		return (xmalloc(sz));
419
	}
420
	if (sz == 0) {
421
		return (null);
422
	}
423
	res = (voidstar)realloc(p, sz + memhack);
424
	if (res == null) {
425
		error("Can't reallocate memory");
426
		exit(EXIT_FAILURE);
427
	}
2 7u83 428
#ifdef MEM_DEBUG
6 7u83 429
	printf("%d (realloc, %d bytes)\n", res, sz);
430
	fflush(stdout);
2 7u83 431
#endif
6 7u83 432
	return (res);
2 7u83 433
}
434
 
435
 
436
/*
437
    FREE A BLOCK OF MEMORY
438
 
439
    The block of memory pointed to by p is returned to free.  p must
440
    previously have been allocated using one of the routines above.
441
*/
442
 
6 7u83 443
void
444
xfree(voidstar p)
2 7u83 445
{
6 7u83 446
	if (p == null) {
447
		return;
448
	}
449
	free(p);
450
	return;
2 7u83 451
}
452