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 <limits.h>
33
#include "c_types.h"
34
#include "error.h"
35
#include "char.h"
36
#include "ustring.h"
37
#include "xalloc.h"
38
 
39
 
40
/*
41
    CONTROLLED VERSION OF MALLOC
42
 
43
    All the program's memory allocation is through the routines defined in
44
    this file.  This routine allocates sz bytes of memory.
45
*/
46
 
47
gen_ptr xmalloc
48
    PROTO_N ( ( sz ) )
49
    PROTO_T ( gen_size sz )
50
{
51
    gen_ptr p ;
52
    if ( sz == 0 ) sz = 1 ;
53
    p = malloc ( ( size_t ) sz ) ;
54
    if ( p == NULL ) {
55
	max_errors = ULONG_MAX ;
56
	error ( ERROR_INTERNAL, "Memory allocation error" ) ;
57
	term_error ( 1 ) ;
58
    }
59
    return ( p ) ;
60
}
61
 
62
 
63
/*
64
    CONTROLLED VERSION OF REALLOC
65
 
66
    This routine reallocates the block of memory p to contain sz bytes.
67
    p can be the result of a previous memory allocation routine, or NULL.
68
*/
69
 
70
gen_ptr xrealloc
71
    PROTO_N ( ( p, sz ) )
72
    PROTO_T ( gen_ptr p X gen_size sz )
73
{
74
    gen_ptr q ;
75
    if ( sz == 0 ) sz = 1 ;
76
    if ( p ) {
77
	q = realloc ( p, ( size_t ) sz ) ;
78
    } else {
79
	q = malloc ( ( size_t ) sz ) ;
80
    }
81
    if ( q == NULL ) {
82
	max_errors = ULONG_MAX ;
83
	error ( ERROR_INTERNAL, "Memory allocation error" ) ;
84
	term_error ( 1 ) ;
85
    }
86
    return ( q ) ;
87
}
88
 
89
 
90
/*
91
    CONTROLLED VERSION OF FREE
92
 
93
    This routine frees the block of memory p.  p can be the result of a
94
    previous memory allocation routine, or NULL.
95
*/
96
 
97
void xfree
98
    PROTO_N ( ( p ) )
99
    PROTO_T ( gen_ptr p )
100
{
101
    if ( p ) free ( p ) ;
102
    return ;
103
}
104
 
105
 
106
/*
107
    STRING ALLOCATION BUFFER
108
 
109
    This buffer is used in the allocation of small strings.
110
*/
111
 
112
static gen_size chars_left = 0 ;
113
static string chars_free = NULL ;
114
 
115
 
116
/*
117
    ALLOCATE SPACE FOR A STRING
118
 
119
    This routine allocates space for n characters.  The memory allocation
120
    is buffered except for very long strings.
121
*/
122
 
123
string xustr
124
    PROTO_N ( ( n ) )
125
    PROTO_T ( gen_size n )
126
{
127
    string r ;
128
    if ( n < 1000 ) {
129
	/* Small strings */
130
	if ( n >= chars_left ) {
131
	    chars_left = 5000 ;
132
	    chars_free = xmalloc_nof ( character, chars_left ) ;
133
	}
134
	r = chars_free ;
135
	chars_free += n ;
136
	chars_left -= n ;
137
    } else {
138
	/* Large strings */
139
	r = xmalloc_nof ( character, n ) ;
140
    }
141
    return ( r ) ;
142
}
143
 
144
 
145
/*
146
    FREE SPACE ALLOCATED FOR A STRING
147
 
148
    This routine frees the space allocated by a previous call to xustr.
149
    For small strings the memory is only freed for the last call to xustr.
150
*/
151
 
152
void xufree
153
    PROTO_N ( ( s, n ) )
154
    PROTO_T ( string s X gen_size n )
155
{
156
    if ( s ) {
157
	if ( n < 1000 ) {
158
	    /* Small strings */
159
	    if ( s + n == chars_free ) {
160
		chars_free = s ;
161
		chars_left += n ;
162
	    }
163
	} else {
164
	    /* Large strings */
165
	    xfree_nof ( s ) ;
166
	}
167
    }
168
    return ;
169
}
170
 
171
 
172
/*
173
    COPY A STRING OF A GIVEN LENGTH
174
 
175
    This routine allocates space for a persistent copy of the string s
176
    of length n.  There is only one copy of each small string, otherwise
177
    xustr is used to allocate the space.
178
*/
179
 
180
string xustrncpy
181
    PROTO_N ( ( s, n ) )
182
    PROTO_T ( string s X gen_size n )
183
{
184
    string r ;
185
    if ( n < 2 ) {
186
	/* Small strings */
187
	static character buff [ NO_CHAR ] [2] ;
188
	int c = ( int ) s [0] ;
189
	if ( c < NO_CHAR ) {
190
	    r = buff [c] ;
191
	    r [0] = ( character ) c ;
192
	    r [1] = 0 ;
193
	    return ( r ) ;
194
	}
195
    }
196
    /* Large strings */
197
    r = xustr ( n + 1 ) ;
198
    ustrcpy_v ( r, s ) ;
199
    return ( r ) ;
200
}
201
 
202
 
203
/*
204
    COPY A STRING
205
 
206
    This routine allocates space for a persistent copy of the string s.
207
*/
208
 
209
string xustrcpy
210
    PROTO_N ( ( s ) )
211
    PROTO_T ( string s )
212
{
213
    gen_size n ;
214
    if ( s == NULL ) return ( NULL ) ;
215
    n = ( gen_size ) ustrlen ( s ) ;
216
    return ( xustrncpy ( s, n ) ) ;
217
}
218
 
219
 
220
/*
221
    CONCATENATE TWO STRINGS
222
 
223
    This routine allocates space for a persistent copy of the string s
224
    followed by the string t.  The memory is allocated using xustr.
225
*/
226
 
227
string xustrcat
228
    PROTO_N ( ( s, t ) )
229
    PROTO_T ( string s X string t )
230
{
231
    string r ;
232
    gen_size n, m ;
233
    if ( s == NULL ) return ( xustrcpy ( t ) ) ;
234
    if ( t == NULL ) return ( xustrcpy ( s ) ) ;
235
    n = ( gen_size ) ustrlen ( s ) ;
236
    m = n + ( gen_size ) ustrlen ( t ) + 1 ;
237
    r = xustr ( m ) ;
238
    ustrcpy_v ( r, s ) ;
239
    ustrcpy_v ( r + n, t ) ;
240
    return ( r ) ;
241
}
242
 
243
 
244
/*
245
    COPY A NUMBER OF CHARACTERS
246
 
247
    This routine copies n characters from t to s.
248
*/
249
 
250
void xumemcpy
251
    PROTO_N ( ( s, t, n ) )
252
    PROTO_T ( string s X string t X gen_size n )
253
{
254
    if ( n ) memcpy_v ( ( gen_ptr ) s, ( gen_ptr ) t, ( size_t ) n ) ;
255
    return ;
256
}
257
 
258
 
259
/*
260
    COMPARE TWO SEQUENCES OF CHARACTERS
261
 
262
    This routine compares the n characters given by s and t.
263
*/
264
 
265
int xumemcmp
266
    PROTO_N ( ( s, t, n ) )
267
    PROTO_T ( string s X string t X gen_size n )
268
{
269
    if ( s == t || n == 0 ) return ( 0 ) ;
270
    return ( memcmp ( ( gen_ptr ) s, ( gen_ptr ) t, ( size_t ) n ) ) ;
271
}