Subversion Repositories tendra.SVN

Rev

Rev 6 | Details | Compare with Previous | Last modification | View Log | RSS feed

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