Subversion Repositories tendra.SVN

Rev

Rev 2 | Rev 6 | 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 <ctype.h>
33
#include "object.h"
34
#include "hash.h"
35
#include "name.h"
36
#include "type.h"
37
#include "utility.h"
38
#include "variable.h"
39
 
40
 
41
/*
42
    STANDARD FLAGS
43
 
44
    These flags are set by the command-line options and determine the
45
    action of the program.
46
*/
47
 
48
boolean allow_long_long = 0 ;
49
boolean force_output = 0 ;
50
boolean local_input = 0 ;
51
boolean restrict_depth = 1 ;
52
boolean restrict_use = 0 ;
53
boolean unique_names = 0 ;
54
int verbose = 0 ;
55
 
56
 
57
/*
58
    INPUT AND OUTPUT DIRECTORIES
59
 
60
    The variable input_dir consists of a colon-separated list of directories
61
    to be searched for input files.  output_incl_dir and output_src_dir
62
    give respectively the output include and output source directories.
63
    The lengths of these directory names (plus one) are also given.
64
*/
65
 
66
char *input_dir = INPUT_DIR ;
67
char *output_incl_dir = INCLUDE_DIR ;
68
char *output_src_dir = SRC_DIR ;
69
int output_incl_len = ( int ) sizeof ( INCLUDE_DIR ) ;
70
int output_src_len = ( int ) sizeof ( SRC_DIR ) ;
71
 
72
 
73
/*
74
    FIND THE BASENAME OF A FILE NAME
75
 
76
    This routine returns the basename (i.e. just the final component) of
77
    the filename nm.
78
*/
79
 
80
char *basename
81
    PROTO_N ( ( nm ) )
82
    PROTO_T ( char *nm )
83
{
84
    char *b = nm ;
85
    for ( ; *nm ; nm++ ) {
86
	if ( *nm == '/' ) b = nm + 1 ;
87
    }
88
    return ( b ) ;
89
}
90
 
91
 
92
/*
93
    FIND THE DIRECTORY COMPONENT OF A FILE NAME
94
 
95
    This routine returns a copy of the directory component of the filename
96
    nm.
97
*/
98
 
99
char *dirname
100
    PROTO_N ( ( nm ) )
101
    PROTO_T ( char *nm )
102
{
103
    char *p, *end = null ;
104
    char *dir = string_copy ( nm ) ;
105
    for ( p = dir ; *p ; p++ ) {
106
	if ( *p == '/' ) end = p ;
107
    }
108
    if ( end == null || end == dir ) return ( null ) ;
109
    *end = 0 ;
110
    return ( dir ) ;
111
}
112
 
113
 
114
/*
115
    FIND A RELATIVE PATHNAME
116
 
117
    This routine prints the relative pathname from the file from to the
118
    file to, ignoring the first n characters.
119
*/
120
 
121
char *relative
122
    PROTO_N ( ( from, to, n ) )
123
    PROTO_T ( char *from X char *to X int n )
124
{
125
    char *s = buffer ;
126
    if ( from == null ) return ( to ) ;
127
    if ( to == null ) return ( from ) ;
128
    for ( from = from + n; *from ; from++ ) {
129
	if ( *from == '/' ) {
130
	    IGNORE strcpy ( s, "../" ) ;
131
	    s += 3 ;
132
	}
133
    }
134
    IGNORE strcpy ( s, to + n ) ;
135
    return ( buffer ) ;
136
}
137
 
138
 
139
/*
140
    HACK A NAME
141
 
142
    This routine hacks the name nm according to the given key.
143
*/
144
 
145
char *hack_name
146
    PROTO_N ( ( nm, key ) )
147
    PROTO_T ( char *nm X char *key )
148
{
149
    char *p = string_copy ( nm ), *q ;
150
    for ( q = p ; *q ; q++ ) {
151
	char c = *q ;
152
	if ( isalpha ( c ) && isupper ( c ) ) {
153
	    /* The second letter of key maps upper case letters */
154
	    if ( key [1] == 'a' ) *q = ( char ) tolower ( c ) ;
155
	} else if ( isalpha ( c ) && islower ( c ) ) {
156
	    /* The third letter of key maps lower case letters */
157
	    if ( key [2] == 'A' ) *q = ( char ) toupper ( c ) ;
158
	} else if ( isdigit ( c ) ) {
159
	    /* The fourth letter of key maps digits */
160
	    *q = ( char ) ( c - '0' + key [3] ) ;
161
	} else if ( strchr ( key + 4, c ) ) {
162
	    /* The rest of key gives special characters */
163
	} else {
164
	    /* The first letter of key is the default */
165
	    *q = key [0] ;
166
	}
167
    }
168
    return ( p ) ;
169
}
170
 
171
 
172
/*
173
    FIND A TOKEN NAME
174
 
175
    This routine makes up a token name for an object named nm.  If
176
    unique_names is false this is just nm, otherwise it is prefixed by
177
    a string depending on the current input file.
178
*/
179
 
180
char *token_name
181
    PROTO_N ( ( nm ) )
182
    PROTO_T ( char *nm )
183
{
184
    if ( strneq ( nm, HIDDEN_NAME, HIDDEN_LEN ) ) {
185
	nm = string_concat ( "~", nm + HIDDEN_LEN ) ;
186
    }
187
    if ( unique_names && crt_object ) {
188
	info *i = crt_object->u.u_info ;
189
	char *pfx = i->prefix ;
190
	if ( pfx == null ) {
191
	    pfx = token_prefix ( i->api, i->file, i->subset ) ;
192
	    i->prefix = pfx ;
193
	}
194
	if ( *pfx ) return ( string_printf ( "%s.%s", pfx, nm ) ) ;
195
    }
196
    return ( nm ) ;
197
}
198
 
199
 
200
/*
201
    FIND TOKEN PREFIX
202
 
203
    This routine finds the token prefix for the API subset api:file:subset.
204
*/
205
 
206
char *token_prefix
207
    PROTO_N ( ( api, file, subset ) )
208
    PROTO_T ( char *api X char *file X char *subset )
209
{
210
    UNUSED ( subset ) ;
211
    if ( unique_names ) {
212
	int n ;
213
	if ( file == null ) return ( api ) ;
214
	IGNORE sprintf ( buffer, "%s.%s", api, basename ( file ) ) ;
215
	n = ( int ) strlen ( buffer ) - 2 ;
216
	if ( n >= 0 && buffer [n] == '.' ) buffer [n] = 0 ;
217
	return ( hack_name ( buffer, "_Aa0." ) ) ;
218
    }
219
    return ( null ) ;
220
}
221
 
222
 
223
/*
224
    FIND A SUBSET NAME
225
 
226
    This routine finds the name associated with the API subset with API
227
    api, header file and subset subset.
228
*/
229
 
230
char *subset_name
231
    PROTO_N ( ( api, file, subset ) )
232
    PROTO_T ( char *api X char *file X char *subset )
233
{
234
    char *sn ;
235
    if ( subset ) {
236
	char *f = ( file ? file : "" ) ;
237
	sn = string_printf ( "%s:%s:%s", api, f, subset ) ;
238
    } else if ( file ) {
239
	sn = string_printf ( "%s:%s", api, file ) ;
240
    } else {
241
	sn = string_printf ( "%s", api ) ;
242
    }
243
    return ( sn ) ;
244
}
245
 
246
 
247
/*
248
    FIND AN INCLUDE OUTPUT FILE NAME
249
 
250
    This routine finds the include output file name for the API subset
251
    api:file:subset using the directory dir as a base.
252
*/
253
 
254
char *include_name
255
    PROTO_N ( ( dir, api, file, subset ) )
256
    PROTO_T ( char *dir X char *api X char *file X char *subset )
257
{
258
    char *nm ;
259
    if ( subset ) {
260
	char s [20] ;
261
	IGNORE strncpy ( s, subset, 18 ) ;
262
	s [ OUTPUT_LENGTH ] = 0 ;
263
	nm = string_printf ( OUTPUT_SUBSET, dir, api, s ) ;
264
    } else if ( file ) {
265
	nm = string_printf ( OUTPUT_FILE, dir, api, file ) ;
266
    } else {
267
	nm = string_printf ( OUTPUT_API, dir, api ) ;
268
    }
269
    return ( nm ) ;
270
}
271
 
272
 
273
/*
274
    FIND A SOURCE OUTPUT FILE NAME
275
 
276
    This routine finds the source output file name for the API subset
277
    api:file:subset using the directory dir as a base.
278
*/
279
 
280
char *src_name
281
    PROTO_N ( ( dir, api, file, subset ) )
282
    PROTO_T ( char *dir X char *api X char *file X char *subset )
283
{
284
    char *nm ;
285
    if ( subset ) {
286
	char s [20] ;
287
	IGNORE strncpy ( s, subset, 18 ) ;
288
	s [ OUTPUT_LENGTH ] = 0 ;
289
	nm = string_printf ( SOURCE_SUBSET, dir, api, s ) ;
290
    } else if ( file ) {
291
	int n ;
292
	nm = string_printf ( SOURCE_FILE, dir, api, basename ( file ) ) ;
293
	n = ( int ) strlen ( nm ) - 4 ;
294
	if ( n >= 0 && streq ( nm + n, ".h.c" ) ) {
295
	    IGNORE strcpy ( nm + n, ".c" ) ;
296
	}
297
    } else {
298
	nm = string_printf ( SOURCE_API, dir, api ) ;
299
    }
300
    return ( nm ) ;
301
}
302
 
303
 
304
/*
305
    FIND A MACRO NAME
306
 
307
    This routine finds the protection (or other) macro for the API subset
308
    api:file:subset using the macro prefix pfx.
309
*/
310
 
311
char *macro_name
312
    PROTO_N ( ( pfx, api, file, subset ) )
313
    PROTO_T ( char *pfx X char *api X char *file X char *subset )
314
{
315
    if ( subset ) {
316
	char *f = ( file ? file : "" ) ;
317
	IGNORE sprintf ( buffer, "%s_%s_%s_%s", pfx, api, f, subset ) ;
318
    } else if ( file ) {
319
	IGNORE sprintf ( buffer, "%s_%s_%s", pfx, api, file ) ;
320
    } else {
321
	IGNORE sprintf ( buffer, "%s_%s", pfx, api ) ;
322
    }
323
    return ( hack_name ( buffer, "_AA0" ) ) ;
324
}
325
 
326
 
327
/*
328
    FIND A DECLARATION BLOCK NAME
329
 
330
    This routine finds the declaration block name for the API subset
331
    api:file:subset.
332
*/
333
 
334
char *block_name
335
    PROTO_N ( ( api, file, subset ) )
336
    PROTO_T ( char *api X char *file X char *subset )
337
{
338
    char * pfx = ( subset ? "subset" : "api" ) ;
339
    if ( file ) {
340
	int len;
341
	IGNORE sprintf ( buffer, "%s__%s__%s", pfx, api, file ) ;
342
	/* remove any trailing ".h" */
343
	len = ( int ) strlen ( buffer ) ;
344
	if ( streq ( buffer + len - 2, ".h" ) )
345
	    buffer [ len - 2 ] = '\0' ;
346
    } else {
347
	IGNORE sprintf ( buffer, "%s__%s", pfx, api ) ;
348
    }
349
    return ( hack_name ( buffer, "_Aa0" ) ) ;
350
}