Subversion Repositories tendra.SVN

Rev

Rev 2 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2 Rev 7
Line -... Line 1...
-
 
1
/*
-
 
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
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1997
32
    		 Crown Copyright (c) 1997
3
    
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
36
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
37
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
38
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
39
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
40
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
41
    shall be deemed to be acceptance of the following conditions:-
12
    
42
 
13
        (1) Its Recipients shall ensure that this Notice is
43
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
44
        reproduced upon any copies or amended versions of it;
15
    
45
 
16
        (2) Any amended version of it shall be clearly marked to
46
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
47
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
48
        for the relevant amendment or amendments;
19
    
49
 
20
        (3) Its onward transfer from a recipient to another
50
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
51
        party shall be deemed to be that party's acceptance of
22
        these conditions;
52
        these conditions;
23
    
53
 
24
        (4) DERA gives no warranty or assurance as to its
54
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
55
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
56
        no liability whatsoever in relation to any use to which
27
        it may be put.
57
        it may be put.
28
*/
58
*/
29
 
59
 
30
 
60
 
31
#include "config.h"
61
#include "config.h"
32
#include <ctype.h>
62
#include <ctype.h>
33
#include "object.h"
63
#include "object.h"
34
#include "hash.h"
64
#include "hash.h"
35
#include "name.h"
65
#include "name.h"
Line 43... Line 73...
43
 
73
 
44
    These flags are set by the command-line options and determine the
74
    These flags are set by the command-line options and determine the
45
    action of the program.
75
    action of the program.
46
*/
76
*/
47
 
77
 
48
boolean allow_long_long = 0 ;
78
boolean allow_long_long = 0;
49
boolean force_output = 0 ;
79
boolean force_output = 0;
50
boolean local_input = 0 ;
80
boolean local_input = 0;
51
boolean restrict_depth = 1 ;
81
boolean restrict_depth = 1;
52
boolean restrict_use = 0 ;
82
boolean restrict_use = 0;
53
boolean unique_names = 0 ;
83
boolean unique_names = 0;
54
int verbose = 0 ;
84
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
 
85
 
72
 
86
 
73
/*
87
/*
74
    FIND THE BASENAME OF A FILE NAME
88
    FIND THE BASENAME OF A FILE NAME
75
 
89
 
76
    This routine returns the basename (i.e. just the final component) of
90
    This routine returns the basename (i.e. just the final component) of
77
    the filename nm.
91
    the filename nm.
78
*/
92
*/
79
 
93
 
80
char *basename
94
char *
81
    PROTO_N ( ( nm ) )
-
 
82
    PROTO_T ( char *nm )
95
basename(char *nm)
83
{
96
{
84
    char *b = nm ;
97
    char *b = nm;
85
    for ( ; *nm ; nm++ ) {
98
    for (; *nm; nm++) {
86
	if ( *nm == '/' ) b = nm + 1 ;
99
	if (*nm == '/')b = nm + 1;
87
    }
100
    }
88
    return ( b ) ;
101
    return(b);
89
}
102
}
90
 
103
 
91
 
104
 
92
/*
105
/*
93
    FIND THE DIRECTORY COMPONENT OF A FILE NAME
106
    FIND THE DIRECTORY COMPONENT OF A FILE NAME
94
 
107
 
95
    This routine returns a copy of the directory component of the filename
108
    This routine returns a copy of the directory component of the filename
96
    nm.
109
    nm.
97
*/
110
*/
98
 
111
 
99
char *dirname
112
char *
100
    PROTO_N ( ( nm ) )
-
 
101
    PROTO_T ( char *nm )
113
dirname(char *nm)
102
{
114
{
103
    char *p, *end = null ;
115
    char *p, *end = null;
104
    char *dir = string_copy ( nm ) ;
116
    char *dir = string_copy(nm);
105
    for ( p = dir ; *p ; p++ ) {
117
    for (p = dir; *p; p++) {
106
	if ( *p == '/' ) end = p ;
118
	if (*p == '/')end = p;
107
    }
119
    }
108
    if ( end == null || end == dir ) return ( null ) ;
120
    if (end == null || end == dir) return(null);
109
    *end = 0 ;
121
    *end = 0;
110
    return ( dir ) ;
122
    return(dir);
111
}
123
}
112
 
124
 
113
 
125
 
114
/*
126
/*
115
    FIND A RELATIVE PATHNAME
127
    FIND A RELATIVE PATHNAME
116
 
128
 
117
    This routine prints the relative pathname from the file from to the
129
    This routine prints the relative pathname from the file from to the
118
    file to, ignoring the first n characters.
130
    file to, ignoring the first n characters.
119
*/
131
*/
120
 
132
 
121
char *relative
133
char *
122
    PROTO_N ( ( from, to, n ) )
-
 
123
    PROTO_T ( char *from X char *to X int n )
134
relative(char *from, char *to, int n)
124
{
135
{
125
    char *s = buffer ;
136
    char *s = buffer;
126
    if ( from == null ) return ( to ) ;
137
    if (from == null) return(to);
127
    if ( to == null ) return ( from ) ;
138
    if (to == null) return(from);
128
    for ( from = from + n; *from ; from++ ) {
139
    for (from = from + n; *from; from++) {
129
	if ( *from == '/' ) {
140
	if (*from == '/') {
130
	    IGNORE strcpy ( s, "../" ) ;
141
	    IGNORE strcpy(s, "../");
131
	    s += 3 ;
142
	    s += 3;
132
	}
143
	}
133
    }
144
    }
134
    IGNORE strcpy ( s, to + n ) ;
145
    IGNORE strcpy(s, to + n);
135
    return ( buffer ) ;
146
    return(buffer);
136
}
147
}
137
 
148
 
138
 
149
 
139
/*
150
/*
140
    HACK A NAME
151
    HACK A NAME
141
 
152
 
142
    This routine hacks the name nm according to the given key.
153
    This routine hacks the name nm according to the given key.
143
*/
154
*/
144
 
155
 
145
char *hack_name
156
char *
146
    PROTO_N ( ( nm, key ) )
-
 
147
    PROTO_T ( char *nm X char *key )
157
hack_name(char *nm, char *key)
148
{
158
{
149
    char *p = string_copy ( nm ), *q ;
159
    char *p = string_copy(nm), *q;
150
    for ( q = p ; *q ; q++ ) {
160
    for (q = p; *q; q++) {
151
	char c = *q ;
161
	char c = *q;
152
	if ( isalpha ( c ) && isupper ( c ) ) {
162
	if (isalpha(c) && isupper(c)) {
153
	    /* The second letter of key maps upper case letters */
163
	    /* The second letter of key maps upper case letters */
154
	    if ( key [1] == 'a' ) *q = ( char ) tolower ( c ) ;
164
	    if (key [1] == 'a')*q = (char)tolower(c);
155
	} else if ( isalpha ( c ) && islower ( c ) ) {
165
	} else if (isalpha(c) && islower(c)) {
156
	    /* The third letter of key maps lower case letters */
166
	    /* The third letter of key maps lower case letters */
157
	    if ( key [2] == 'A' ) *q = ( char ) toupper ( c ) ;
167
	    if (key [2] == 'A')*q = (char)toupper(c);
158
	} else if ( isdigit ( c ) ) {
168
	} else if (isdigit(c)) {
159
	    /* The fourth letter of key maps digits */
169
	    /* The fourth letter of key maps digits */
160
	    *q = ( char ) ( c - '0' + key [3] ) ;
170
	    *q = (char)(c - '0' + key [3]);
161
	} else if ( strchr ( key + 4, c ) ) {
171
	} else if (strchr(key + 4, c)) {
162
	    /* The rest of key gives special characters */
172
	    /* The rest of key gives special characters */
163
	} else {
173
	} else {
164
	    /* The first letter of key is the default */
174
	    /* The first letter of key is the default */
165
	    *q = key [0] ;
175
	    *q = key [0];
166
	}
176
	}
167
    }
177
    }
168
    return ( p ) ;
178
    return(p);
169
}
179
}
170
 
180
 
171
 
181
 
172
/*
182
/*
173
    FIND A TOKEN NAME
183
    FIND A TOKEN NAME
Line 175... Line 185...
175
    This routine makes up a token name for an object named nm.  If
185
    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
186
    unique_names is false this is just nm, otherwise it is prefixed by
177
    a string depending on the current input file.
187
    a string depending on the current input file.
178
*/
188
*/
179
 
189
 
180
char *token_name
190
char *
181
    PROTO_N ( ( nm ) )
-
 
182
    PROTO_T ( char *nm )
191
token_name(char *nm)
183
{
192
{
184
    if ( strneq ( nm, HIDDEN_NAME, HIDDEN_LEN ) ) {
193
    if (strneq(nm, HIDDEN_NAME, HIDDEN_LEN)) {
185
	nm = string_concat ( "~", nm + HIDDEN_LEN ) ;
194
	nm = string_concat("~", nm + HIDDEN_LEN);
186
    }
195
    }
187
    if ( unique_names && crt_object ) {
196
    if (unique_names && crt_object) {
188
	info *i = crt_object->u.u_info ;
197
	info *i = crt_object->u.u_info;
189
	char *pfx = i->prefix ;
198
	char *pfx = i->prefix;
190
	if ( pfx == null ) {
199
	if (pfx == null) {
191
	    pfx = token_prefix ( i->api, i->file, i->subset ) ;
200
	    pfx = token_prefix(i->api, i->file, i->subset);
192
	    i->prefix = pfx ;
201
	    i->prefix = pfx;
193
	}
202
	}
194
	if ( *pfx ) return ( string_printf ( "%s.%s", pfx, nm ) ) ;
203
	if (*pfx) return(string_printf("%s.%s", pfx, nm));
195
    }
204
    }
196
    return ( nm ) ;
205
    return(nm);
197
}
206
}
198
 
207
 
199
 
208
 
200
/*
209
/*
201
    FIND TOKEN PREFIX
210
    FIND TOKEN PREFIX
202
 
211
 
203
    This routine finds the token prefix for the API subset api:file:subset.
212
    This routine finds the token prefix for the API subset api:file:subset.
204
*/
213
*/
205
 
214
 
206
char *token_prefix
215
char *
207
    PROTO_N ( ( api, file, subset ) )
-
 
208
    PROTO_T ( char *api X char *file X char *subset )
216
token_prefix(char *api, char *file, char *subset)
209
{
217
{
210
    UNUSED ( subset ) ;
218
    UNUSED(subset);
211
    if ( unique_names ) {
219
    if (unique_names) {
212
	int n ;
220
	int n;
213
	if ( file == null ) return ( api ) ;
221
	if (file == null) return(api);
214
	IGNORE sprintf ( buffer, "%s.%s", api, basename ( file ) ) ;
222
	IGNORE sprintf(buffer, "%s.%s", api, basename(file));
215
	n = ( int ) strlen ( buffer ) - 2 ;
223
	n = (int)strlen(buffer) - 2;
216
	if ( n >= 0 && buffer [n] == '.' ) buffer [n] = 0 ;
224
	if (n >= 0 && buffer [n] == '.')buffer [n] = 0;
217
	return ( hack_name ( buffer, "_Aa0." ) ) ;
225
	return(hack_name(buffer, "_Aa0."));
218
    }
226
    }
219
    return ( null ) ;
227
    return(null);
220
}
228
}
221
 
229
 
222
 
230
 
223
/*
231
/*
224
    FIND A SUBSET NAME
232
    FIND A SUBSET NAME
225
 
233
 
226
    This routine finds the name associated with the API subset with API
234
    This routine finds the name associated with the API subset with API
227
    api, header file and subset subset.
235
    api, header file and subset subset.
228
*/
236
*/
229
 
237
 
230
char *subset_name
238
char *
231
    PROTO_N ( ( api, file, subset ) )
-
 
232
    PROTO_T ( char *api X char *file X char *subset )
239
subset_name(char *api, char *file, char *subset)
233
{
240
{
234
    char *sn ;
241
    char *sn;
235
    if ( subset ) {
242
    if (subset) {
236
	char *f = ( file ? file : "" ) ;
243
	char *f = (file ? file : "");
237
	sn = string_printf ( "%s:%s:%s", api, f, subset ) ;
244
	sn = string_printf("%s:%s:%s", api, f, subset);
238
    } else if ( file ) {
245
    } else if (file) {
239
	sn = string_printf ( "%s:%s", api, file ) ;
246
	sn = string_printf("%s:%s", api, file);
240
    } else {
247
    } else {
241
	sn = string_printf ( "%s", api ) ;
248
	sn = string_printf("%s", api);
242
    }
249
    }
243
    return ( sn ) ;
250
    return(sn);
244
}
251
}
245
 
252
 
246
 
253
 
247
/*
254
/*
248
    FIND AN INCLUDE OUTPUT FILE NAME
255
    FIND AN INCLUDE OUTPUT FILE NAME
249
 
256
 
250
    This routine finds the include output file name for the API subset
257
    This routine finds the include output file name for the API subset
251
    api:file:subset using the directory dir as a base.
258
    api:file:subset using the directory dir as a base.
252
*/
259
*/
253
 
260
 
254
char *include_name
261
char *
255
    PROTO_N ( ( dir, api, file, subset ) )
-
 
256
    PROTO_T ( char *dir X char *api X char *file X char *subset )
262
include_name(char *dir, char *api, char *file, char *subset)
257
{
263
{
258
    char *nm ;
264
    char *nm;
259
    if ( subset ) {
265
    if (subset) {
260
	char s [20] ;
266
	char s [20];
261
	IGNORE strncpy ( s, subset, 18 ) ;
267
	IGNORE strncpy(s, subset, 18);
262
	s [ OUTPUT_LENGTH ] = 0 ;
268
	s [ OUTPUT_LENGTH ] = 0;
263
	nm = string_printf ( OUTPUT_SUBSET, dir, api, s ) ;
269
	nm = string_printf(OUTPUT_SUBSET, dir, api, s);
264
    } else if ( file ) {
270
    } else if (file) {
265
	nm = string_printf ( OUTPUT_FILE, dir, api, file ) ;
271
	nm = string_printf(OUTPUT_FILE, dir, api, file);
266
    } else {
272
    } else {
267
	nm = string_printf ( OUTPUT_API, dir, api ) ;
273
	nm = string_printf(OUTPUT_API, dir, api);
268
    }
274
    }
269
    return ( nm ) ;
275
    return(nm);
270
}
276
}
271
 
277
 
272
 
278
 
273
/*
279
/*
274
    FIND A SOURCE OUTPUT FILE NAME
280
    FIND A SOURCE OUTPUT FILE NAME
275
 
281
 
276
    This routine finds the source output file name for the API subset
282
    This routine finds the source output file name for the API subset
277
    api:file:subset using the directory dir as a base.
283
    api:file:subset using the directory dir as a base.
278
*/
284
*/
279
 
285
 
280
char *src_name
286
char *
281
    PROTO_N ( ( dir, api, file, subset ) )
-
 
282
    PROTO_T ( char *dir X char *api X char *file X char *subset )
287
src_name(char *dir, char *api, char *file, char *subset)
283
{
288
{
284
    char *nm ;
289
    char *nm;
285
    if ( subset ) {
290
    if (subset) {
286
	char s [20] ;
291
	char s [20];
287
	IGNORE strncpy ( s, subset, 18 ) ;
292
	IGNORE strncpy(s, subset, 18);
288
	s [ OUTPUT_LENGTH ] = 0 ;
293
	s [ OUTPUT_LENGTH ] = 0;
289
	nm = string_printf ( SOURCE_SUBSET, dir, api, s ) ;
294
	nm = string_printf(SOURCE_SUBSET, dir, api, s);
290
    } else if ( file ) {
295
    } else if (file) {
291
	int n ;
296
	int n;
292
	nm = string_printf ( SOURCE_FILE, dir, api, basename ( file ) ) ;
297
	nm = string_printf(SOURCE_FILE, dir, api, basename(file));
293
	n = ( int ) strlen ( nm ) - 4 ;
298
	n = (int)strlen(nm) - 4;
294
	if ( n >= 0 && streq ( nm + n, ".h.c" ) ) {
299
	if (n >= 0 && streq(nm + n, ".h.c")) {
295
	    IGNORE strcpy ( nm + n, ".c" ) ;
300
	    IGNORE strcpy(nm + n, ".c");
296
	}
301
	}
297
    } else {
302
    } else {
298
	nm = string_printf ( SOURCE_API, dir, api ) ;
303
	nm = string_printf(SOURCE_API, dir, api);
299
    }
304
    }
300
    return ( nm ) ;
305
    return(nm);
301
}
306
}
302
 
307
 
303
 
308
 
304
/*
309
/*
305
    FIND A MACRO NAME
310
    FIND A MACRO NAME
306
 
311
 
307
    This routine finds the protection (or other) macro for the API subset
312
    This routine finds the protection (or other) macro for the API subset
308
    api:file:subset using the macro prefix pfx.
313
    api:file:subset using the macro prefix pfx.
309
*/
314
*/
310
 
315
 
311
char *macro_name
316
char *
312
    PROTO_N ( ( pfx, api, file, subset ) )
-
 
313
    PROTO_T ( char *pfx X char *api X char *file X char *subset )
317
macro_name(char *pfx, char *api, char *file, char *subset)
314
{
318
{
315
    if ( subset ) {
319
    if (subset) {
316
	char *f = ( file ? file : "" ) ;
320
	char *f = (file ? file : "");
317
	IGNORE sprintf ( buffer, "%s_%s_%s_%s", pfx, api, f, subset ) ;
321
	IGNORE sprintf(buffer, "%s_%s_%s_%s", pfx, api, f, subset);
318
    } else if ( file ) {
322
    } else if (file) {
319
	IGNORE sprintf ( buffer, "%s_%s_%s", pfx, api, file ) ;
323
	IGNORE sprintf(buffer, "%s_%s_%s", pfx, api, file);
320
    } else {
324
    } else {
321
	IGNORE sprintf ( buffer, "%s_%s", pfx, api ) ;
325
	IGNORE sprintf(buffer, "%s_%s", pfx, api);
322
    }
326
    }
323
    return ( hack_name ( buffer, "_AA0" ) ) ;
327
    return(hack_name(buffer, "_AA0"));
324
}
328
}
325
 
329
 
326
 
330
 
327
/*
331
/*
328
    FIND A DECLARATION BLOCK NAME
332
    FIND A DECLARATION BLOCK NAME
329
 
333
 
330
    This routine finds the declaration block name for the API subset
334
    This routine finds the declaration block name for the API subset
331
    api:file:subset.
335
    api:file:subset.
332
*/
336
*/
333
 
337
 
334
char *block_name
338
char *
335
    PROTO_N ( ( api, file, subset ) )
-
 
336
    PROTO_T ( char *api X char *file X char *subset )
339
block_name(char *api, char *file, char *subset)
337
{
340
{
338
    char * pfx = ( subset ? "subset" : "api" ) ;
341
    char * pfx = (subset ? "subset" : "api");
339
    if ( file ) {
342
    if (file) {
340
	int len;
343
	int len;
341
	IGNORE sprintf ( buffer, "%s__%s__%s", pfx, api, file ) ;
344
	IGNORE sprintf(buffer, "%s__%s__%s", pfx, api, file);
342
	/* remove any trailing ".h" */
345
	/* remove any trailing ".h" */
343
	len = ( int ) strlen ( buffer ) ;
346
	len = (int)strlen(buffer);
344
	if ( streq ( buffer + len - 2, ".h" ) )
347
	if (streq(buffer + len - 2, ".h"))
345
	    buffer [ len - 2 ] = '\0' ;
348
	    buffer [ len - 2 ] = '\0';
346
    } else {
349
    } else {
347
	IGNORE sprintf ( buffer, "%s__%s", pfx, api ) ;
350
	IGNORE sprintf(buffer, "%s__%s", pfx, api);
348
    }
351
    }
349
    return ( hack_name ( buffer, "_Aa0" ) ) ;
352
    return(hack_name(buffer, "_Aa0"));
350
}
353
}