Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – tendra.SVN – Blame – /branches/tendra5/src/tools/tcc/filename.c – Rev 2

Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | 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 "filename.h"
33
#include "list.h"
34
#include "external.h"
35
#include "flags.h"
36
#include "startup.h"
37
#include "suffix.h"
38
#include "utility.h"
39
 
40
 
41
/*
42
    CASE SENSITIVITY FLAG
43
 
44
    This flag may be set to true to make tcc ignore case in filename
45
    suffixes.
46
*/
47
 
48
boolean case_insensitive = 0 ;
49
 
50
 
51
/*
52
    IS A CHARACTER UPPER CASE?
53
 
54
    This macro checks whether the character C is upper case.  It is ASCII
55
    dependent.
56
*/
57
 
58
#define is_upper_case( C )	( ( C ) >= 'A' && ( C ) <= 'Z' )
59
 
60
 
61
/*
62
    CONVERT A STRING TO LOWER CASE
63
 
64
    This routine converts the string s to lower case.
65
*/
66
 
67
static void to_lower_case
68
    PROTO_N ( ( s ) )
69
    PROTO_T ( char *s )
70
{
71
    char c ;
72
    while ( c = *s, c != 0 ) {
73
	if ( is_upper_case ( c ) ) {
74
	    *s = ( char ) ( c - 'A' + 'a' ) ;
75
	}
76
	s++ ;
77
    }
78
    return ;
79
}
80
 
81
 
82
/*
83
    SUFFIX OVERRIDES
84
 
85
    This table contains the strings which are used when the suffix
86
    overrides are set from the command line.  Initially, it is
87
    empty.  This table needs to be kept in step with Table 1.
88
*/
89
 
90
char *suffixes [ TYPE_ARRAY_SIZE ] = {
91
    null,	/* C_SOURCE */
92
    null,	/* PREPROC_C */
93
    "cpp",	/* CPP_SOURCE */
94
    null,	/* PREPROC_CPP */
95
    null,	/* INDEP_TDF */
96
    null,	/* DEP_TDF */
97
    null,	/* AS_SOURCE */
98
    null,	/* BINARY_OBJ */
99
    null,	/* EXECUTABLE */
100
    null,	/* PRETTY_TDF */
101
    null,	/* PL_TDF */
102
    null,	/* TDF_ARCHIVE */
103
    null,	/* MIPS_G_FILE */
104
    null,	/* MIPS_T_FILE */
105
    null,	/* C_SPEC */
106
    null,	/* CPP_SPEC */
107
    null,  	/* ERROR_FILE */
108
    null,	/* STARTUP_FILE */
109
    null,	/* UNKNOWN_TYPE */
110
    null,	/* INDEP_TDF_COMPLEX (dummy type) */
111
    null,	/* C_SPEC_1 (dummy type) */
112
    null,	/* C_SPEC_2 (dummy type) */
113
    null,	/* INDEP_TDF_AUX (dummy type) */
114
    null	/* BINARY_OBJ_AUX (dummy type) */
115
} ;
116
 
117
 
118
/*
119
    FILE STORAGE LOCATIONS
120
 
121
    Output files may be stored either in the temporary directory, tempdir,
122
    or the work directory, workdir.
123
*/
124
 
125
char *tempdir = null ;
126
char *workdir = null  ;
127
 
128
 
129
/*
130
    FIND THE BASE NAME OF A FILE
131
 
132
    This routine returns the basename of the file name s.
133
*/
134
 
135
char *find_basename
136
    PROTO_N ( ( s ) )
137
    PROTO_T ( char *s )
138
{
139
    char *r = s ;
140
    for ( ; *s ; s++ ) {
141
	if ( *s == '/' ) r = s + 1 ;
142
    }
143
    return ( r ) ;
144
}
145
 
146
 
147
/*
148
    FIND THE FULL NAME OF A FILE
149
 
150
    This routine returns the full name of the file name s.
151
*/
152
 
153
char *find_fullname
154
    PROTO_N ( ( s ) )
155
    PROTO_T ( char *s )
156
{
157
    static char *pwd = null ;
158
    if ( *s == '/' ) return ( s ) ;
159
    if ( pwd == null ) {
160
	if ( get_cwd ( buffer, buffer_size ) ) {
161
	    pwd = string_concat ( buffer, "/" ) ;
162
	} else {
163
	    error ( WARNING, "Can't determine current working directory" ) ;
164
	    pwd = "" ;
165
	}
166
    }
167
    return ( string_concat ( pwd, s ) ) ;
168
}
169
 
170
 
171
/*
172
    SPLIT OFF THE SUFFIX OF A FILE NAME
173
 
174
    This routine splits the file name s into two part, the base part and
175
    the file suffix, and returns the latter.
176
*/
177
 
178
static char *split_name
179
    PROTO_N ( ( s ) )
180
    PROTO_T ( char *s )
181
{
182
    int i, n = ( int ) strlen ( s ) ;
183
    for ( i = n - 1 ; i >= 0 ; i-- ) {
184
	if ( s [i] == '.' ) {
185
	    s [i] = 0 ;
186
	    if ( case_insensitive ) {
187
		/* Allow for case insensitive systems */
188
		to_lower_case ( s + ( i + 1 ) ) ;
189
	    }
190
	    return ( s + ( i + 1 ) ) ;
191
	}
192
    }
193
    return ( "" ) ;
194
}
195
 
196
 
197
/*
198
    CREATE A NEW FILENAME
199
 
200
    This routine allocates a new filename structure.
201
*/
202
 
203
static filename *new_filename
204
    PROTO_Z ()
205
{
206
    static int no_free = 0 ;
207
    static filename *free_objs = null ;
208
    if ( no_free == 0 ) {
209
	no_free = 1000 ;
210
	free_objs = alloc_nof ( filename, no_free ) ;
211
    }
212
    return ( free_objs + ( --no_free ) ) ;
213
}
214
 
215
 
216
/*
217
    ADD A FILENAME TO A LIST
218
 
219
    This routine joins the two filename lists, p and q, returning the
220
    result.
221
*/
222
 
223
filename *add_filename
224
    PROTO_N ( ( p, q ) )
225
    PROTO_T ( filename *p X filename *q )
226
{
227
    filename *r ;
228
    if ( p == null ) return ( q ) ;
229
    if ( q == null ) return ( p ) ;
230
    for ( r = p ; r->next != null ; r = r->next ) /* empty */ ;
231
    r->next = q ;
232
    return ( p ) ;
233
}
234
 
235
 
236
/*
237
    CONVERT A KEY LETTER TO A FILE TYPE
238
 
239
    This routine converts the letter s, which can be a file suffix (if
240
    suff is true), or a stage identifier (otherwise), to a file type.
241
    This routine needs to be kept in step with Table 1 and Table 2.
242
*/
243
 
244
int find_type
245
    PROTO_N ( ( s, suff ) )
246
    PROTO_T ( int s X int suff )
247
{
248
    switch ( s ) {
249
	case C_SOURCE_KEY : return ( C_SOURCE ) ;
250
	case PREPROC_C_KEY : return ( PREPROC_C ) ;
251
	case CPP_SOURCE_KEY : return ( CPP_SOURCE ) ;
252
	case PREPROC_CPP_KEY : return ( PREPROC_CPP ) ;
253
	case AS_SOURCE_KEY : return ( AS_SOURCE ) ;
254
	case BINARY_OBJ_KEY : return ( BINARY_OBJ ) ;
255
	case C_SPEC_KEY : return ( C_SPEC ) ;
256
	case CPP_SPEC_KEY : return ( CPP_SPEC ) ;
257
    }
258
    if ( !checker ) {
259
	switch ( s ) {
260
	    case INDEP_TDF_KEY : return ( INDEP_TDF ) ;
261
	    case DEP_TDF_KEY : return ( DEP_TDF ) ;
262
	    case PRETTY_TDF_KEY : return ( PRETTY_TDF ) ;
263
	}
264
    }
265
    if ( suff ) return ( DEFAULT_TYPE ) ;
266
    switch ( s ) {
267
	case MIPS_G_FILE_KEY : return ( MIPS_G_FILE ) ;
268
	case MIPS_T_FILE_KEY : return ( MIPS_T_FILE ) ;
269
	case STARTUP_FILE_KEY : return ( STARTUP_FILE ) ;
270
	case ALL_KEY : return ( ALL_TYPES ) ;
271
    }
272
    if ( !checker ) {
273
	switch ( s ) {
274
	    case PL_TDF_KEY : return ( PL_TDF ) ;
275
	    case TDF_ARCHIVE_KEY : return ( TDF_ARCHIVE ) ;
276
	}
277
    }
278
    error ( WARNING, "Unknown file type, '%c'", ( unsigned char ) s ) ;
279
    return ( UNKNOWN_TYPE ) ;
280
}
281
 
282
 
283
/*
284
    FIND A FILE SUFFIX
285
 
286
    This routine converts a file type, t, into the corresponding file
287
    suffix.  It needs to be kept in step with Table 1 and Table 2.
288
*/
289
 
290
static char *file_suffix
291
    PROTO_N ( ( t ) )
292
    PROTO_T ( int t )
293
{
294
    static char suff [3] ;
295
    suff [0] = 0 ;
296
    suff [1] = 0 ;
297
    suff [2] = 0 ;
298
    switch ( t ) {
299
	case C_SOURCE : suff [0] = C_SOURCE_KEY ; break ;
300
	case PREPROC_C : suff [0] = PREPROC_C_KEY ; break ;
301
	case CPP_SOURCE : suff [0] = CPP_SOURCE_KEY ; break ;
302
	case PREPROC_CPP : suff [0] = PREPROC_CPP_KEY ; break ;
303
	case INDEP_TDF : suff [0] = INDEP_TDF_KEY ; break ;
304
	case INDEP_TDF_AUX : {
305
	    suff [0] = INDEP_TDF_KEY ;
306
	    suff [1] = EXTRA_KEY ;
307
	    break ;
308
	}
309
	case DEP_TDF : suff [0] = DEP_TDF_KEY ; break ;
310
	case AS_SOURCE : suff [0] = AS_SOURCE_KEY ; break ;
311
	case BINARY_OBJ : suff [0] = BINARY_OBJ_KEY ; break ;
312
	case BINARY_OBJ_AUX : {
313
	    if ( ( use_sparc_cc == 1 ) && use_system_cc ) {
314
		suff [0] = '.' ;
315
		suff [1] = BINARY_OBJ_KEY ;
316
	    } else {
317
		suff [0] = BINARY_OBJ_AUX_KEY ;
318
	    }
319
	    break ;
320
	}
321
	case PRETTY_TDF : suff [0] = PRETTY_TDF_KEY ; break ;
322
	case PL_TDF : suff [0] = PL_TDF_KEY ; break ;
323
	case MIPS_G_FILE : suff [0] = MIPS_G_FILE_KEY ; break ;
324
	case MIPS_T_FILE : suff [0] = MIPS_T_FILE_KEY ; break ;
325
	case C_SPEC : suff [0] = C_SPEC_KEY ; break ;
326
	case CPP_SPEC : suff [0] = CPP_SPEC_KEY ; break ;
327
    }
328
    if ( suff [0] ) {
329
	if ( case_insensitive && is_upper_case ( suff [0] ) ) {
330
	    /* Make allowances for case insensitive systems */
331
	    to_lower_case ( suff ) ;
332
	    suff [1] = suff [0] ;
333
	}
334
	return ( suff ) ;
335
    }
336
    error ( SERIOUS, "Illegal file type" ) ;
337
    return ( file_suffix ( DEFAULT_TYPE ) ) ;
338
}
339
 
340
 
341
/*
342
    NEXT FILENAME IS ACTUALLY AN INPUT OPTION
343
 
344
    Some command-line options, for example, system libraries, are treated
345
    like input files.  This flag is set to indicate that the next input
346
    file is actually an input option.
347
*/
348
 
349
boolean option_next = 0 ;
350
 
351
 
352
/*
353
    COUNT OF NUMBER OF INPUT FILES
354
 
355
    The number of calls to find_filename is recorded.  Input options are
356
    excluded from this count.
357
*/
358
 
359
int no_input_files = 0 ;
360
 
361
 
362
/*
363
    ALLOCATE A NEW UNIQUE IDENTIFIER
364
 
365
    Each file is assigned a unique number which identifies it and all the
366
    files derived from it.  This macro assigns a new unique number.
367
*/
368
 
369
static int uniq_no = 0 ;
370
#define new_unique()	( uniq_no++ )
371
 
372
 
373
/*
374
    CREATE A FILENAME FROM A PATHNAME
375
 
376
    This routine creates a new filename structure, corresponding to the
377
    file with name s and type t.  If t is UNKNOWN_TYPE then the actual
378
    file type is deduced from the file suffix.  This routine needs to
379
    be kept in step with Table 1, Table 2 and Table 3.
380
*/
381
 
382
filename *find_filename
383
    PROTO_N ( ( s, t ) )
384
    PROTO_T ( char *s X int t )
385
{
386
    filename *p = new_filename () ;
387
    char *b = string_copy ( find_basename ( s ) ) ;
388
    char *e = split_name ( b ) ;
389
    int i ;
390
 
391
    /* Find the file type */
392
    if ( suffix_overrides && t == UNKNOWN_TYPE ) {
393
	for ( i = 0 ; i < TYPE_ARRAY_SIZE ; i++ ) {
394
	    if ( suffixes [ i ] != null && streq ( e, suffixes [ i ] ) ) {
395
		if ( checker ) {
396
		    if ( i == PL_TDF || i == TDF_ARCHIVE ) continue ;
397
		}
398
		t = i ;
399
		break ;
400
	    }
401
	}
402
    }
403
    if ( t == UNKNOWN_TYPE ) {
404
	if ( e [0] ) {
405
	    if ( e [1] ) {
406
		if ( e [2] ) {
407
		    /* Length >= 3 */
408
		    if ( streq ( e, CPP_2_SUFFIX ) ) {
409
			t = CPP_SOURCE ;
410
		    } else if ( streq ( e, PREPROC_CPP_2_SUFFIX ) ) {
411
			t = PREPROC_CPP ;
412
		    } else if ( streq ( e, AS_2_SUFFIX ) ) {
413
			t = AS_SOURCE ;
414
		    } else {
415
			t = DEFAULT_TYPE ;
416
		    }
417
		} else {
418
		    /* Length == 2 */
419
		    if ( e [1] == EXTRA_KEY ) {
420
			t = find_type ( e [0], 1 ) ;
421
		    } else if ( streq ( e, CPP_1_SUFFIX ) ) {
422
			t = CPP_SOURCE ;
423
		    } else if ( streq ( e, PREPROC_CPP_1_SUFFIX ) ) {
424
			t = PREPROC_CPP ;
425
		    } else if ( streq ( e, CPP_SPEC_1_SUFFIX ) ) {
426
			t = CPP_SPEC ;
427
		    } else if ( checker ) {
428
			t = DEFAULT_TYPE ;
429
		    } else if ( streq ( e, PL_TDF_SUFFIX ) ) {
430
			t = PL_TDF ;
431
		    } else if ( streq ( e, TDF_ARCHIVE_SUFFIX ) ) {
432
			t = TDF_ARCHIVE ;
433
		    } else {
434
			t = DEFAULT_TYPE ;
435
		    }
436
		}
437
	    } else {
438
		/* Length == 1 */
439
		t = find_type ( e [0], 1 ) ;
440
	    }
441
	} else {
442
	    /* Length == 0 */
443
	    t = DEFAULT_TYPE ;
444
	}
445
    }
446
 
447
    /* Return the result */
448
    p->name = s ;
449
    p->bname = b ;
450
    p->uniq = new_unique () ;
451
    p->type = t ;
452
    if ( option_next ) {
453
	p->storage = INPUT_OPTION ;
454
	option_next = 0 ;
455
    } else {
456
	p->storage = INPUT_FILE ;
457
	no_input_files++ ;
458
    }
459
    p->final = 0 ;
460
    p->aux = null ;
461
    p->next = null ;
462
    return ( p ) ;
463
}
464
 
465
 
466
/*
467
    FIND WHERE TO STORE FILES OF A GIVEN TYPE
468
 
469
    This routine returns the storage class for files of type t.  Note
470
    that this may be PRESERVED_FILE which is only a legal storage type
471
    when it is passed to make_filename (which turns it into OUTPUT_FILE).
472
*/
473
 
474
int where
475
    PROTO_N ( ( t ) )
476
    PROTO_T ( int t )
477
{
478
    if ( !keeps [t] ) return ( TEMP_FILE ) ;
479
    if ( !stops [t] ) return ( PRESERVED_FILE ) ;
480
    return ( OUTPUT_FILE ) ;
481
}
482
 
483
 
484
/*
485
    CREATE A FILENAME FROM ANOTHER FILENAME
486
 
487
    This routine creates a new filename structure by forming the file
488
    derived from p which has type t and storage s.  This routine needs
489
    to be kept in step with Table 1 and Table 2.
490
*/
491
 
492
filename *make_filename
493
    PROTO_N ( ( p, t, s ) )
494
    PROTO_T ( filename *p X int t X int s )
495
{
496
    boolean f = 0 ;
497
    char *b, *d, *e ;
498
    char *nm = null ;
499
    filename *q = new_filename () ;
500
 
501
    /* Examine the storage class */
502
    switch ( s ) {
503
	case INPUT_FILE :
504
	case INPUT_OPTION : {
505
	    /* This shouldn't occur */
506
	    d = null ;
507
	    break ;
508
	}
509
	case OUTPUT_FILE : {
510
	    /* Check output file name */
511
	    if ( final_name ) {
512
		static boolean used_final_name = 0 ;
513
		if ( used_final_name ) {
514
		    error ( WARNING, "Can only name one file with '-o'" ) ;
515
		} else {
516
		    nm = final_name ;
517
		    b = find_basename ( nm ) ;
518
#ifdef EXECUTABLE_SUFFIX
519
		    if ( t == EXECUTABLE && strchr ( b, '.' ) == null ) {
520
			/* Add '.exe' suffix if necessary */
521
			nm = string_concat ( nm, EXECUTABLE_SUFFIX ) ;
522
			b = string_concat ( b, EXECUTABLE_SUFFIX ) ;
523
		    }
524
#endif
525
		    used_final_name = 1 ;
526
		    f = 1 ;
527
		}
528
	    }
529
	    d = workdir ;
530
	    break ;
531
	}
532
	case PRESERVED_FILE : {
533
	    /* Preserved files are turned into output files */
534
	    d = workdir ;
535
	    s = OUTPUT_FILE ;
536
	    break ;
537
	}
538
	case TEMP_FILE : {
539
	    /* Temporary files */
540
	    d = tempdir ;
541
	    break ;
542
	}
543
	default : {
544
	    error ( INTERNAL, "Illegal storage type" ) ;
545
	    d = null ;
546
	    break ;
547
	}
548
    }
549
 
550
    /* Find the file name */
551
    if ( nm == null ) {
552
	if ( p != null && p->type == t ) {
553
	    nm = find_basename ( p->name ) ;
554
	    if ( d != null ) {
555
		IGNORE sprintf ( buffer, "%s/%s", d, nm ) ;
556
		nm = string_copy ( buffer ) ;
557
	    }
558
	    b = p->bname ;
559
	} else if ( s == TEMP_FILE && p != null && !verbose ) {
560
	    switch ( t ) {
561
		case BINARY_OBJ_AUX :
562
		case BINARY_OBJ : break ;
563
		case C_SPEC : break ;
564
		case CPP_SPEC : break ;
565
		case INDEP_TDF_AUX :
566
		case INDEP_TDF : {
567
		    if ( make_archive || make_complex || tokdef_name ) {
568
			break ;
569
		    }
570
		    goto default_lab ;
571
		}
572
		default :
573
		default_lab : {
574
		    b = p->bname ;
575
		    e = file_suffix ( t ) ;
576
		    IGNORE sprintf ( buffer, "%s/%s.%s", d, TEMP_NAME, e ) ;
577
		    nm = string_copy ( buffer ) ;
578
		    break ;
579
		}
580
	    }
581
	}
582
    }
583
 
584
    /* Find the file name */
585
    if ( nm == null ) {
586
	if ( p == null || make_up_names ) {
587
	    static int seq = 0 ;
588
	    IGNORE sprintf ( buffer, MADE_UP_NAME, seq++ ) ;
589
	    b = string_copy ( buffer ) ;
590
	} else {
591
	    b = p->bname ;
592
	}
593
	e = file_suffix ( t ) ;
594
	if ( d == null ) {
595
	    IGNORE sprintf ( buffer, "%s.%s", b, e ) ;
596
	} else {
597
	    IGNORE sprintf ( buffer, "%s/%s.%s", d, b, e ) ;
598
	}
599
	nm = string_copy ( buffer ) ;
600
    }
601
 
602
    /* Fill in the fields of the result */
603
    SET ( b ) ;
604
    q->name = nm ;
605
    q->bname = b ;
606
    q->uniq = ( p ? p->uniq : new_unique () ) ;
607
    q->type = t ;
608
    q->storage = s ;
609
    q->final = f ;
610
    q->aux = null ;
611
    q->next = null ;
612
    return ( q ) ;
613
}