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 "filename.h"
33
#include "list.h"
34
#include "archive.h"
35
#include "execute.h"
36
#include "flags.h"
37
#include "options.h"
38
#include "stages.h"
39
#include "startup.h"
40
#include "suffix.h"
41
#include "utility.h"
42
 
43
 
44
/*
45
    BINARY OBJECT FILE TYPE
46
 
47
    The type of binary object file to be produced, for example, by the
48
    assembler varies according to whether it will later be included in
49
    a spec archive.  This value determines this file type.
50
*/
51
 
52
int binary_obj_type = BINARY_OBJ ;
53
 
54
 
55
/*
56
    COPY A FILE
57
 
58
    This routine moves the file from to the file to.  If to is null
59
    then from is copied to the standard output.  All the routines in
60
    this module return their set of output files.  This may be null if
61
    an error has occurred.
62
*/
63
 
64
static filename *do_move
65
    PROTO_N ( ( from, to ) )
66
    PROTO_T ( filename *from X filename *to )
67
{
68
    if ( from == null ) return ( from ) ;
69
    if ( to ) {
70
	if ( streq ( from->name, to->name ) ) return ( to ) ;
71
	cmd_list ( exec_move ) ;
72
	cmd_filename ( from ) ;
73
	cmd_filename ( to ) ;
74
    } else {
75
	cmd_list ( exec_cat ) ;
76
	cmd_filename ( from ) ;
77
    }
78
    return ( execute ( from, to ) ) ;
79
}
80
 
81
 
82
/*
83
    PRESERVE A FILE
84
 
85
    This routine preserves the file p by moving it, if necessary, to the
86
    work directory.  It returns the new location of p.
87
*/
88
 
89
filename *do_keep
90
    PROTO_N ( ( p ) )
91
    PROTO_T ( filename *p )
92
{
93
    if ( p->storage == TEMP_FILE ) {
94
	filename *q = make_filename ( p, p->type, PRESERVED_FILE ) ;
95
	cmd_list ( exec_move ) ;
96
	cmd_filename ( p ) ;
97
	cmd_filename ( q ) ;
98
	IGNORE execute ( no_filename, no_filename ) ;
99
	return ( q ) ;
100
    }
101
    return ( p ) ;
102
}
103
 
104
 
105
/*
106
    TEMPORARY FILE NAME
107
 
108
    This is set by uniq_filename to be either its output file or a
109
    temporary file if the output corresponds to an input file.
110
*/
111
 
112
static filename *uniq_tempfile = null ;
113
 
114
 
115
/*
116
    MAKE A UNIQUE FILE NAME
117
 
118
    This routine creates a filename with name nm, type t and storage s.
119
    If this coincides with one of the files in input then a temporary
120
    file is stored in uniq_tempfile, otherwise it holds the output file.
121
*/
122
 
123
static filename *uniq_filename
124
    PROTO_N ( ( nm, t, s, input ) )
125
    PROTO_T ( char *nm X int t X int s X filename *input )
126
{
127
    filename *p = find_filename ( nm, t ) ;
128
    filename *q = make_filename ( p, t, s ) ;
129
    uniq_tempfile = q ;
130
    for ( p = input ; p != null ; p = p->next ) {
131
	if ( streq ( p->name, q->name ) ) {
132
	    if ( p->storage == TEMP_FILE ) {
133
		uniq_tempfile = make_filename ( no_filename, t, TEMP_FILE ) ;
134
	    } else {
135
		char *m ;
136
		static char plus [] = { EXTRA_KEY, 0 } ;
137
		q->name = string_concat ( q->name, plus ) ;
138
		switch ( t ) EXHAUSTIVE {
139
		    case INDEP_TDF : m = "merged TDF capsule" ; break ;
140
		    case TDF_ARCHIVE : m = "archive file" ; break ;
141
		    case C_SPEC : m = "linked C spec file" ; break ;
142
		    case CPP_SPEC : m = "linked C++ spec file" ; break ;
143
		    case EXECUTABLE : m = "executable" ; break ;
144
		}
145
		error ( WARNING,
146
			"Renaming %s '%s' to '%s' to avoid clash with input",
147
			m, p->name, q->name ) ;
148
	    }
149
	    return ( q ) ;
150
	}
151
    }
152
    return ( q ) ;
153
}
154
 
155
 
156
/*
157
    PRINT PRODUCER/PREPROCESSOR OPTIONS
158
 
159
    The C/C++ to TDF producers and the TDF C/C++ preprocessor accept
160
    the same command-line options; the parameter 'pp' is used to
161
    determine which startup files are appropriate.
162
*/
163
 
164
static void producer_options
165
    PROTO_N ( ( pp ) )
166
    PROTO_T ( int pp )
167
{
168
    boolean is_c = ( pp == PRODUCE_ID || pp == PREPROC_ID ) ;
169
    if ( !flag_nepc && std_prod_portfile ) {
170
	cmd_string ( "-n" ) ;
171
	cmd_string ( std_prod_portfile->item ) ;
172
    }
173
    if ( flag_diag ) {
174
	if ( flag_diag == 1 ) {
175
	    cmd_string ( "-g1" ) ;
176
	} else {
177
	    cmd_string ( "-g2" ) ;
178
	}
179
    }
180
    if ( flag_incl ) cmd_string ( "-H" ) ;
181
    if ( flag_startup ) {
182
	if ( is_c ) {
183
	    cmd_list ( std_prod_startup ) ;
184
	    cmd_list ( usr_prod_startup ) ;
185
	} else {
186
	    cmd_list ( std_cpp_prod_startup ) ;
187
	    cmd_list ( usr_cpp_prod_startup ) ;
188
	}
189
	if ( startup_opt ) cmd_string ( startup_opt ) ;
190
	cmd_list ( usr_prod_foptions ) ;
191
	cmd_list ( usr_prod_eoptions ) ;
192
	if ( endup_opt ) cmd_string ( endup_opt ) ;
193
    }
194
    cmd_list ( usr_prod_incldirs ) ;
195
    if ( !is_c ) cmd_list ( std_cpp_prod_incldirs ) ;
196
    cmd_list ( std_prod_incldirs ) ;
197
    if ( flag_startup ) {
198
	if ( is_c ) {
199
	    cmd_list ( std_prod_startdirs ) ;
200
	} else {
201
	    cmd_list ( std_cpp_prod_startdirs ) ;
202
	}
203
    }
204
    if ( checker ) cmd_string ( "-c" ) ;
205
    if ( make_pretty ) cmd_string ( "-t" ) ;
206
    return ;
207
}
208
 
209
 
210
/*
211
    APPLY THE C PRODUCER
212
 
213
    This routine applies the C to TDF producer to input and returns
214
    the result.
215
*/
216
 
217
filename *do_produce
218
    PROTO_N ( ( input ) )
219
    PROTO_T ( filename *input )
220
{
221
    boolean spec_produced ;
222
    filename *output, *spec ;
223
    if ( input == null ) return ( input ) ;
224
    output = make_filename ( input, INDEP_TDF, where ( INDEP_TDF ) ) ;
225
    cmd_list ( exec_produce ) ;
226
    if ( allow_specs == 1 ) {
227
	spec = make_filename ( input, C_SPEC, where ( C_SPEC ) ) ;
228
	if ( dump_opts ) {
229
	    cmd_string ( string_concat ( dump_opts, spec->name ) ) ;
230
	} else {
231
	    cmd_string ( "-s" ) ;
232
	    cmd_string ( spec->name ) ;
233
	}
234
    }
235
    cmd_list ( opt_produce ) ;
236
    producer_options ( PRODUCE_ID ) ;
237
    cmd_filename ( input ) ;
238
    cmd_filename ( output ) ;
239
 
240
    /* Execute the command */
241
    enable_delayed_signal () ;
242
    output = execute ( input, output ) ;
243
    spec_produced = ( allow_specs == 1 ) && ( last_return != 2 ) &&
244
			( checker || output != null ) ;
245
    disable_delayed_signal () ;
246
    process_delayed_signal () ;
247
    if ( spec_produced ) {
248
	SET ( spec ) ;
249
	output = add_filename ( output, spec ) ;
250
    }
251
    if ( allow_specs == 2 ) {
252
	spec = make_filename ( input, C_SPEC, where ( C_SPEC ) ) ;
253
	cmd_list ( exec_touch ) ;
254
	cmd_filename ( spec ) ;
255
	cmd_string ( "-k" ) ;
256
	spec = execute ( no_filename, spec ) ;
257
	output = add_filename ( output, spec ) ;
258
    }
259
    return ( output ) ;
260
}
261
 
262
 
263
/*
264
    APPLY THE C PREPROCESSOR
265
 
266
    This routine applies the TDF C preprocessor to input and returns
267
    the result.  If files of type PREPROC_C are not being preserved
268
    then the output is sent to the standard output.
269
*/
270
 
271
filename *do_preproc
272
    PROTO_N ( ( input ) )
273
    PROTO_T ( filename *input )
274
{
275
    filename *output ;
276
    if ( input == null ) return ( input ) ;
277
    if ( checker && !use_system_cc ) return ( input ) ;
278
    if ( keeps [ PREPROC_C ] ) {
279
	output = make_filename ( input, PREPROC_C, where ( PREPROC_C ) ) ;
280
    } else {
281
	output = null ;
282
    }
283
    cmd_list ( exec_preproc ) ;
284
    cmd_list ( opt_preproc ) ;
285
    producer_options ( PREPROC_ID ) ;
286
    cmd_filename ( input ) ;
287
    if ( output ) cmd_filename ( output ) ;
288
    output = execute ( input, output ) ;
289
    return ( output ) ;
290
}
291
 
292
 
293
/*
294
    APPLY THE C++ PRODUCER
295
 
296
    This routine applies the C++ to TDF producer to input and returns
297
    the result.
298
*/
299
 
300
filename *do_cpp_produce
301
    PROTO_N ( ( input ) )
302
    PROTO_T ( filename *input )
303
{
304
    filename *spec ;
305
    filename *output, *producer_output ;
306
    if ( input == null ) return ( input ) ;
307
    output = make_filename ( input, INDEP_TDF, where ( INDEP_TDF ) ) ;
308
    cmd_list ( exec_cpp_produce ) ;
309
    if ( allow_specs == 1 ) {
310
	spec = make_filename ( input, CPP_SPEC, where ( CPP_SPEC ) ) ;
311
	if ( dump_opts ) {
312
	    cmd_string ( string_concat ( dump_opts, spec->name ) ) ;
313
	} else {
314
	    cmd_string ( "-s" ) ;
315
	    cmd_string ( spec->name ) ;
316
	}
317
    }
318
    cmd_list ( opt_cpp_produce ) ;
319
    producer_options ( CPP_PRODUCE_ID ) ;
320
    cmd_filename ( input ) ;
321
    cmd_filename ( output ) ;
322
    producer_output = execute ( input, output ) ;
323
 
324
    /* If we are in checker mode and intermodular checks are enabled
325
       we must ignore any errors from the producer and continue
326
       to run the dump_linker. */
327
    if ( checker ) {
328
	reset_exec_error () ;
329
    } else {
330
	output = producer_output ;
331
    }
332
    if ( allow_specs == 1 ) {
333
	SET ( spec ) ;
334
	output = add_filename ( output, spec ) ;
335
    }
336
    if ( allow_specs == 2 && output ) {
337
	spec = make_filename ( input, CPP_SPEC, where ( CPP_SPEC ) ) ;
338
	cmd_list ( exec_touch ) ;
339
	cmd_filename ( spec ) ;
340
	cmd_string ( "-k" ) ;
341
	spec = execute ( no_filename, spec ) ;
342
	output = add_filename ( output, spec ) ;
343
    }
344
    return ( output ) ;
345
}
346
 
347
 
348
/*
349
    APPLY THE C++ PREPROCESSOR
350
 
351
    This routine applies the TDF C++ preprocessor to input and
352
    returns the result.  If files of type PREPROC_C are not being
353
    preserved then the output is copied to the standard output.
354
*/
355
 
356
filename *do_cpp_preproc
357
    PROTO_N ( ( input ) )
358
    PROTO_T ( filename *input )
359
{
360
    filename *output ;
361
    if ( input == null ) return ( input ) ;
362
    if ( checker && !use_system_cc ) return ( input ) ;
363
    if ( keeps [ PREPROC_CPP ] ) {
364
	output = make_filename ( input, PREPROC_CPP, where ( PREPROC_CPP ) ) ;
365
    } else {
366
	output = null ;
367
    }
368
    cmd_list ( exec_cpp_preproc ) ;
369
    cmd_list ( opt_cpp_preproc ) ;
370
    producer_options ( CPP_PREPROC_ID ) ;
371
    cmd_filename ( input ) ;
372
    if ( output != null ) cmd_filename ( output ) ;
373
    output = execute ( input, output ) ;
374
    return ( output ) ;
375
}
376
 
377
 
378
/*
379
    APPLY THE TDF LINKER
380
 
381
    This routine applies the TDF linker to input and returns the result.
382
    This is the normal action of the TDF linker - linking target
383
    independent TDF with the TDF libraries to form target dependent
384
    TDF (also see do_tdf_build).
385
*/
386
 
387
filename *do_tdf_link
388
    PROTO_N ( ( input ) )
389
    PROTO_T ( filename *input )
390
{
391
    filename *output ;
392
    if ( input == null || stops [ INDEP_TDF ] ) return ( input ) ;
393
    output = make_filename ( input, DEP_TDF, where ( DEP_TDF ) ) ;
394
    cmd_list ( exec_tdf_link ) ;
395
    cmd_list ( opt_tdf_link ) ;
396
    cmd_list ( usr_tdf_link_libdirs ) ;
397
    cmd_list ( std_tdf_link_libdirs ) ;
398
    cmd_list ( usr_tdf_link_libs ) ;
399
    cmd_list ( std_tdf_link_libs ) ;
400
    cmd_string ( "-o" ) ;
401
    cmd_filename ( output ) ;
402
    cmd_filename ( input ) ;
403
    if ( tokdef_output ) cmd_string ( tokdef_output ) ;
404
    return ( execute ( input, output ) ) ;
405
}
406
 
407
 
408
/*
409
    APPLY THE TDF LINKER TO BUILD A COMPLEX
410
 
411
    This routine applies the TDF linker to combine a set of target
412
    independent TDF capsules, input, into a single independent TDF
413
    capsule, which is then returned.  To avoid possible clashes with
414
    the input files, the output is firstly directed to a temporary
415
    file, which is then moved to the output file.
416
*/
417
 
418
filename *do_tdf_build
419
    PROTO_N ( ( input ) )
420
    PROTO_T ( filename *input )
421
{
422
    int keep ;
423
    filename *output ;
424
    if ( input == null ) return ( input ) ;
425
    if ( exec_error ) return ( null ) ;
426
    keep = where ( INDEP_TDF_COMPLEX ) ;
427
    output = uniq_filename ( name_j_file, INDEP_TDF, keep, input ) ;
428
    cmd_list ( exec_tdf_link ) ;
429
    cmd_list ( opt_tdf_link ) ;
430
    if ( flag_merge_all ) {
431
	cmd_string ( "-a" ) ;
432
	cmd_string ( "-k" ) ;
433
	cmd_string ( "tag" ) ;
434
	cmd_string ( "main" ) ;
435
    }
436
    cmd_string ( "-o" ) ;
437
    cmd_filename ( uniq_tempfile ) ;
438
    cmd_filename ( input ) ;
439
    return ( do_move ( execute ( input, uniq_tempfile ), output ) ) ;
440
}
441
 
442
 
443
/*
444
    APPLY THE TRANSLATOR
445
 
446
    This routine applies the TDF translator to the input files, input,
447
    and returns the result.  This routine is complicated by the fact
448
    that most TDF translators produce assembler source, but some bypass
449
    the assembler to directly produce binary object files.  The mips
450
    translator produces two output files, a .G file and a .T file, so
451
    this is also a special case.
452
*/
453
 
454
filename *do_translate
455
    PROTO_N ( ( input ) )
456
    PROTO_T ( filename *input )
457
{
458
    int t ;
459
    filename *output ;
460
    if ( input == null || stops [ DEP_TDF ] ) return ( input ) ;
461
    if ( use_assembler ) {
462
	t = AS_SOURCE ;
463
	output = make_filename ( input, t, where ( t ) ) ;
464
    } else {
465
	t = binary_obj_type ;
466
	output = make_filename ( input, t, where ( t ) ) ;
467
	output->type = BINARY_OBJ ;
468
    }
469
    cmd_list ( exec_translate ) ;
470
    if ( flag_diag ) {
471
	if ( flag_diag == 2 ) {
472
	    cmd_string ( "-J" ) ;
473
	} else {
474
	    if ( flag_optim ) {
475
		cmd_string ( "-HO" ) ;
476
	    } else {
477
		cmd_string ( "-H" ) ;
478
	    }
479
	}
480
    }
481
    if ( flag_nepc ) cmd_string ( "-E" ) ;
482
    if ( use_mips_assembler ) {
483
	static char *vflag = null ;
484
	if ( vflag == null ) vflag = string_concat ( "-V", version_flag ) ;
485
	cmd_string ( vflag ) ;
486
    }
487
    cmd_list ( opt_translate ) ;
488
 
489
    if ( use_mips_assembler || use_alpha_assembler ) {
490
	/* Deal with the mips assembler */
491
	t = MIPS_G_FILE ;
492
	output->aux = make_filename ( input, t, where ( t ) ) ;
493
	t = MIPS_T_FILE ;
494
	output->aux->aux = make_filename ( input, t, where ( t ) ) ;
495
	if ( keeps [ AS_SOURCE ] ) {
496
	    cmd_string ( "-S" ) ;
497
	    cmd_filename ( input ) ;
498
	    cmd_filename ( output->aux ) ;
499
	    cmd_filename ( output->aux->aux ) ;
500
	    cmd_filename ( output ) ;
501
	} else {
502
	    cmd_filename ( input ) ;
503
	    cmd_filename ( output->aux ) ;
504
	    cmd_filename ( output->aux->aux ) ;
505
	}
506
    } else if ( use_assembler ) {
507
	/* Deal with normal assemblers */
508
	cmd_filename ( input ) ;
509
	cmd_filename ( output ) ;
510
    } else {
511
	/* Deal with non-assemblers */
512
	if ( keeps [ AS_SOURCE ] ) {
513
	    t = AS_SOURCE ;
514
	    output->aux = make_filename ( input, t, where ( t ) ) ;
515
	    cmd_string ( "-S" ) ;
516
	    cmd_filename ( input ) ;
517
	    cmd_filename ( output ) ;
518
	    cmd_filename ( output->aux ) ;
519
	} else {
520
	    cmd_filename ( input ) ;
521
	    cmd_filename ( output ) ;
522
	}
523
    }
524
    return ( execute ( input, output ) ) ;
525
}
526
 
527
 
528
/*
529
    APPLY THE ASSEMBLER
530
 
531
    This routine applies the assembler to the input files, input, and
532
    returns the result.  The routine is complicated because of the need
533
    to handle the .G and .T files output by the mips translator.
534
*/
535
 
536
filename *do_assemble
537
    PROTO_N ( ( input ) )
538
    PROTO_T ( filename *input )
539
{
540
    filename *output ;
541
    int t = binary_obj_type ;
542
    if ( input == null || stops [ AS_SOURCE ] ) return ( input ) ;
543
    output = make_filename ( input, t, where ( t ) ) ;
544
    output->type = BINARY_OBJ ;
545
    if ( input->aux && input->aux->type == MIPS_G_FILE &&
546
	 input->aux->aux && input->aux->aux->type == MIPS_T_FILE ) {
547
	/* Deal with the mips assembler */
548
	cmd_list ( exec_assemble_mips ) ;
549
	cmd_list ( opt_assemble_mips ) ;
550
	cmd_string ( "-o" ) ;
551
	cmd_filename ( output ) ;
552
	cmd_filename ( input->aux ) ;
553
	cmd_string ( "-t" ) ;
554
	cmd_filename ( input->aux->aux ) ;
555
    } else {
556
	/* Deal with normal assemblers */
557
	cmd_list ( exec_assemble ) ;
558
	cmd_list ( opt_assemble ) ;
559
	cmd_string ( "-o" ) ;
560
	cmd_filename ( output ) ;
561
	cmd_filename ( input ) ;
562
    }
563
    return ( execute ( input, output ) ) ;
564
}
565
 
566
 
567
/*
568
    LIST OF LIBRARIES
569
 
570
    This is set by linker_options to be the list of libraries
571
    passed to the linker.  Needs to be passed twice in the
572
    case of DYNLINK with shared libaries.
573
*/
574
 
575
static list *dl_libs = null ;
576
 
577
 
578
/*
579
    DYNLINK SWITCH
580
 
581
    This remains 0 if normal linking is being done, and is set
582
    to 1 before the first-stage dynamic-initialisation linking.
583
    After the first call to 'linker_options', the value is
584
    increase so that it becomes two for the second-stage link.
585
*/
586
 
587
static int dl_state = 0 ;
588
 
589
 
590
/*
591
    PRINT LINK/DYNLINK OPTIONS
592
 
593
    The link and dynlink stages use the same command-line options
594
    with the exception of crt0, crt1 and crtn files since the
595
    dynamic-initialisation linking doesn't produce an executable.
596
    The variable 'use_dynlink' is either 1, 2 or 3 depending on
597
    whether the CRT startup files are linked on the first, second
598
    or both of the two dynlink stages.
599
*/
600
 
601
static void linker_options
602
    PROTO_N ( ( input, output ) )
603
    PROTO_T ( filename *input X filename *output )
604
{
605
    if ( use_system_cc ) {
606
	cmd_list ( exec_cc ) ;
607
	if ( flag_diag ) cmd_string ( "-g" ) ;
608
	if ( flag_strip ) cmd_string ( "-s" ) ;
609
	cmd_list ( opt_cc ) ;
610
	cmd_string ( "-o" ) ;
611
	cmd_filename ( output ) ;
612
    } else {
613
	cmd_list ( exec_link ) ;
614
	if ( dl_state == 1 ) {
615
	    cmd_string ( "-r" ) ;
616
	} else {
617
	    cmd_list ( std_link_entry ) ;
618
	}
619
	if ( flag_strip && ( dl_state != 1 ) ) cmd_string ( "-s" ) ;
620
	cmd_list ( opt_link ) ;
621
	cmd_string ( "-o" ) ;
622
	cmd_filename ( output ) ;
623
	if ( ( dl_state == 0 ) || ( dl_state & use_dynlink ) != 0 ) {
624
	    cmd_list ( std_link_crt0 ) ;
625
	    cmd_list ( std_link_crt1 ) ;
626
	}
627
    }
628
    if ( use_hp_linker ) {
629
	filename *p ;
630
	for ( p = input ; p != null ; p = p->next ) {
631
	    char *arg = p->name ;
632
	    if ( strneq ( arg, "-B", 2 ) ) {
633
		cmd_string ( "-B" ) ;
634
		cmd_string ( arg + 2 ) ;
635
	    } else if ( strneq ( arg, "-L", 2 ) ) {
636
		cmd_string ( "-L" ) ;
637
		cmd_string ( arg + 2 ) ;
638
	    } else if ( strneq ( arg, "-l", 2 ) ) {	      
639
	        /* save up -l options for inclusion after any -L options */
640
	        dl_libs = add_item ( dl_libs, arg ) ;	      
641
	    } else {	      
642
		cmd_string ( arg ) ;
643
	    }
644
	}
645
    } else {
646
      filename *p ;
647
	for ( p = input ; p != null ; p = p->next ) {
648
	    char *arg = p->name ;
649
	    if ( strneq ( arg, "-l", 2 ) ) {	      
650
	        /* save up -l options for inclusion after any -L options */
651
	        dl_libs = add_item ( dl_libs, arg ) ;	      
652
	    } else if ( dl_state && ( p->storage == INPUT_OPTION ) ) {
653
		/* Add input options to user link options for subsequent use */
654
		opt_link = add_item ( opt_link, arg ) ;
655
		cmd_string ( arg ) ;
656
	    } else {
657
		cmd_string ( arg ) ;
658
	    }
659
	}
660
    }
661
    if ( !use_system_cc ) {
662
	/* usr_link_libdirs forms part of input */
663
        cmd_list ( std_link_libdirs ) ;
664
    }
665
    /* now include the -l options */
666
    if ( dl_libs != null ) {      
667
        cmd_list ( dl_libs ) ;
668
    }
669
    if ( !use_system_cc ) {
670
	/* usr_link_libs forms part of input */
671
	cmd_list ( std_link_libs ) ;
672
	cmd_list ( std_link_c_libs ) ;
673
	if ( ( dl_state == 0 ) || ( dl_state & use_dynlink ) != 0 ) {
674
	    cmd_list ( std_link_crtp_n ) ;
675
	    cmd_list ( std_link_crtn ) ;
676
	}
677
    }
678
    dl_state++ ;
679
    return ;
680
}
681
 
682
 
683
/*
684
    APPLY THE RS6000/SPARC DYNAMIC INITIALISATION PROGRAM
685
 
686
    This routine calls the program to create a .s file with the
687
    necessary dynamic initialisation calls for AIX and SunOS,
688
    and adds the corresponding .o to the file list.
689
*/
690
 
691
filename *do_dynlink
692
    PROTO_N ( ( input ) )
693
    PROTO_T ( filename *input )
694
{
695
    filename *linked_ofiles, *extra_sfile, *output = null ;
696
    if ( input == null || stops [ BINARY_OBJ ] ) return ( input ) ;
697
    if ( checker && !use_system_cc ) return ( input ) ;
698
    if ( !exec_error ) {
699
	linked_ofiles = make_filename ( no_filename, binary_obj_type, TEMP_FILE ) ;
700
	dl_state = 1 ;
701
	linker_options ( input, linked_ofiles ) ;
702
	IGNORE execute ( input, output ) ;
703
    }
704
    if ( !exec_error ) {
705
	output = make_filename ( no_filename, AS_SOURCE, TEMP_FILE ) ;
706
	cmd_list ( exec_dynlink ) ;
707
	cmd_list ( opt_dynlink ) ;
708
	SET ( linked_ofiles ) ;
709
	cmd_filename ( linked_ofiles ) ;
710
	cmd_filename ( output ) ;
711
	extra_sfile = execute ( linked_ofiles, output ) ;
712
    }
713
    if ( exec_error ) {
714
	last_return = 1 ;
715
	return ( null ) ;
716
    }
717
    SET ( linked_ofiles ) ;
718
    SET ( extra_sfile ) ;
719
    output = do_assemble ( extra_sfile ) ;
720
    if ( use_dynlink == 3 ) {
721
	return ( add_filename ( output, input ) ) ;
722
    }
723
    return ( add_filename ( output, linked_ofiles ) ) ;
724
}
725
 
726
 
727
/*
728
    APPLY THE SYSTEM LINKER
729
 
730
    This routine applies the system linker to the input files, input,
731
    and returns the result.  The output executable name is, by default,
732
    EXECUTABLE_NAME.  Things are slightly complicated by the fact that
733
    the HP linkers insist on certain options being in two parts.
734
*/
735
 
736
filename *do_link
737
    PROTO_N ( ( input ) )
738
    PROTO_T ( filename *input )
739
{
740
    int keep ;
741
    filename *output ;
742
    if ( input == null || stops [ BINARY_OBJ ] ) return ( input ) ;
743
    if ( checker && !use_system_cc ) return ( input ) ;
744
    if ( exec_error ) {
745
	last_return = 1 ;
746
	return ( null ) ;
747
    }
748
    keep = where ( EXECUTABLE ) ;
749
    output = uniq_filename ( EXECUTABLE_NAME, EXECUTABLE, keep, no_filename ) ;
750
    linker_options ( input, output ) ;
751
    return ( execute ( input, output ) ) ;
752
}
753
 
754
 
755
/*
756
    APPLY THE TDF NOTATION COMPILER
757
 
758
    This routine applies the TDF notation compiler to the input files,
759
    input, and returns the result.
760
*/
761
 
762
filename *do_notation
763
    PROTO_N ( ( input ) )
764
    PROTO_T ( filename *input )
765
{
766
    int keep ;
767
    filename *output ;
768
    if ( input == null ) return ( input ) ;
769
    keep = where ( INDEP_TDF ) ;
770
    if ( tokdef_name && streq ( input->name, tokdef_name ) ) keep = TEMP_FILE ;
771
    output = make_filename ( input, INDEP_TDF, keep ) ;
772
    cmd_list ( exec_notation ) ;
773
    cmd_list ( opt_notation ) ;
774
    cmd_list ( usr_prod_incldirs ) ;
775
    cmd_filename ( input ) ;
776
    cmd_filename ( output ) ;
777
    return ( execute ( input, output ) ) ;
778
}
779
 
780
 
781
/*
782
    APPLY THE PL_TDF COMPILER
783
 
784
    This routine applies the PL_TDF compiler to the input files, input,
785
    and returns the result.
786
*/
787
 
788
filename *do_pl_tdf
789
    PROTO_N ( ( input ) )
790
    PROTO_T ( filename *input )
791
{
792
    filename *output ;
793
    if ( input == null ) return ( input ) ;
794
    output = make_filename ( input, INDEP_TDF, where ( INDEP_TDF ) ) ;
795
    cmd_list ( exec_pl_tdf ) ;
796
    cmd_list ( opt_pl_tdf ) ;
797
    cmd_list ( usr_pl_tdf_incldirs ) ;
798
    if ( flag_diag ) cmd_string ( "-g" ) ;
799
    cmd_filename ( input ) ;
800
    cmd_filename ( output ) ;
801
    return ( execute ( input, output ) ) ;
802
}
803
 
804
 
805
/*
806
    APPLY THE TDF PRETTY PRINTER
807
 
808
    This routine applies the TDF pretty printer to the input files,
809
    input, and returns the result.
810
*/
811
 
812
filename *do_pretty
813
    PROTO_N ( ( input ) )
814
    PROTO_T ( filename *input )
815
{
816
    filename *output ;
817
    if ( input == null || stops [ DEP_TDF ] ) return ( input ) ;
818
    output = make_filename ( input, PRETTY_TDF, where ( PRETTY_TDF ) ) ;
819
    cmd_list ( exec_pretty ) ;
820
    if ( flag_diag ) cmd_string ( "-g" ) ;
821
    cmd_list ( opt_pretty ) ;
822
    cmd_filename ( input ) ;
823
    cmd_filename ( output ) ;
824
    return ( execute ( input, output ) ) ;
825
}
826
 
827
 
828
/*
829
    SPLIT A TDF ARCHIVE
830
 
831
    This routine splits the TDF archive, input, and returns the result.
832
*/
833
 
834
filename *do_split_arch
835
    PROTO_N ( ( input ) )
836
    PROTO_T ( filename *input )
837
{
838
    if ( input == null ) return ( input ) ;
839
    cmd_list ( exec_split_arch ) ;
840
    cmd_filename ( input ) ;
841
    return ( execute ( input, no_filename ) ) ;
842
}
843
 
844
 
845
/*
846
    BUILD A TDF ARCHIVE
847
 
848
    This routine creates a TDF archive from the input files, input,
849
    and the archive options, opt_archive, and returns the result.
850
    The output archive name is, by default, TDF_ARCHIVE_NAME.  The
851
    aux field of the output contains the archive contents.
852
*/
853
 
854
filename *do_build_arch
855
    PROTO_N ( ( input ) )
856
    PROTO_T ( filename *input )
857
{
858
    int keep ;
859
    filename *output ;
860
    if ( input == null || stops [ INDEP_TDF ] ) return ( input ) ;
861
    if ( exec_error ) return ( null ) ;
862
    archive_type = TDF_ARCHIVE ;
863
    keep = where ( TDF_ARCHIVE ) ;
864
    output = uniq_filename ( TDF_ARCHIVE_NAME, TDF_ARCHIVE, keep,
865
			     no_filename ) ;
866
    cmd_list ( exec_build_arch ) ;
867
    cmd_filename ( output ) ;
868
    cmd_filename ( input ) ;
869
    if ( opt_archive ) {
870
	cmd_string ( ARCHIVE_OPTION_START ) ;
871
	cmd_list ( opt_archive ) ;
872
    }
873
    output = execute ( input, output ) ;
874
    if ( output ) output->aux = input ;
875
    return ( output ) ;
876
}
877
 
878
 
879
/*
880
    BUILD AN ARCHIVE FILE
881
 
882
    This routine creates an archive file of type t from the input files
883
    and returns the result.  The aux field of the output contains the
884
    archive contents.
885
*/
886
 
887
filename *do_build_file
888
    PROTO_N ( ( input, t ) )
889
    PROTO_T ( filename *input X int t )
890
{
891
    int s ;
892
    filename *output ;
893
    if ( input == null ) return ( input ) ;
894
    if ( !( keeps [t] || keeps_aux [t] == 1 ) ) return ( input ) ;
895
    archive_type = t ;
896
    s = input->type ;
897
    input->type = UNKNOWN_TYPE ;
898
    output = make_filename ( input, t, where ( t ) ) ;
899
    input->type = s ;
900
    cmd_list ( exec_build_arch ) ;
901
    cmd_filename ( output ) ;
902
    cmd_filename ( input ) ;
903
    if ( allow_specs == 2 ) {
904
	cmd_string ( ARCHIVE_OPTION_START ) ;
905
	cmd_string ( "--2CS" ) ;
906
    }
907
    output = execute ( input, output ) ;
908
    if ( output ) output->aux = input ;
909
    return ( output ) ;
910
}
911
 
912
 
913
/*
914
    LINK A NUMBER OF C AND C++ SPECS
915
 
916
    This routine links a number of C++ specs, input, into one, which
917
    is then returned.  To avoid possible clashes with the input files,
918
    the output is firstly directed to a temporary file, which is then
919
    moved to the output file.  t is the dummy file type, C_SPEC_1,
920
    C_SPEC_2, CPP_SPEC_1 or CPP_SPEC_2.
921
*/
922
 
923
filename *do_link_specs
924
    PROTO_N ( ( input, t ) )
925
    PROTO_T ( filename *input X int t )
926
{
927
    int keep ;
928
    filename *output, *spec_file ;
929
    if ( input == null ) return ( input ) ;
930
    if ( t == C_SPEC_2 || t == CPP_SPEC_2 ) {
931
	/* Don't link in these cases */
932
	if ( stops [ BINARY_OBJ ] ) return ( input ) ;
933
    }
934
    if ( exec_error && !checker ) {
935
	last_return = 1 ;
936
	return ( null ) ;
937
    }
938
    keep = where ( t ) ;
939
    if ( allow_specs == 1 && dump_opts == null ) {
940
	output = make_filename ( no_filename, INDEP_TDF, TEMP_FILE ) ;
941
	if ( t == C_SPEC_1 || t == C_SPEC_2 ) {
942
	    spec_file = uniq_filename ( name_k_file, C_SPEC, keep, input ) ;
943
	    cmd_list ( exec_spec_link ) ;
944
	    cmd_list ( opt_spec_link ) ;
945
	} else {
946
	    spec_file = uniq_filename ( name_K_file, CPP_SPEC, keep, input ) ;
947
	    cmd_list ( exec_cpp_spec_link ) ;
948
	    cmd_list ( opt_cpp_spec_link ) ;
949
	}
950
	if ( checker ) cmd_string ( "-c" ) ;
951
	if ( make_pretty ) cmd_string ( "-t" ) ;
952
	cmd_string ( "-s" ) ;
953
	cmd_string ( uniq_tempfile->name ) ;
954
	cmd_filename ( input ) ;
955
	cmd_filename ( output ) ;
956
	output = execute ( input, output ) ;
957
	if ( checker ) output = null ;
958
	output = add_filename ( output, do_move ( uniq_tempfile, spec_file ) ) ;
959
    } else {
960
	if ( t == C_SPEC_1 || t == C_SPEC_2 ) {
961
	    output = uniq_filename ( name_k_file, C_SPEC, keep, input ) ;
962
	} else {
963
	    output = uniq_filename ( name_K_file, CPP_SPEC, keep, input ) ;
964
	}
965
	if ( allow_specs == 1 ) {
966
	    cmd_list ( exec_dump_link ) ;
967
	    cmd_list ( opt_dump_link ) ;
968
	    cmd_filename ( input ) ;
969
	    cmd_filename ( output ) ;
970
	    output = execute ( input, output ) ;
971
	} else {
972
	    cmd_list ( exec_touch ) ;
973
	    cmd_filename ( uniq_tempfile ) ;
974
	    cmd_string ( "-k" ) ;
975
	    output = execute ( no_filename, output ) ;
976
	}
977
    }
978
    return ( output ) ;
979
}
980
 
981
 
982
/*
983
    USE THE SYSTEM COMPILER
984
 
985
    tcc may optionally be used do invoke the system compiler, cc.  This
986
    routine applies cc to the input files, input, compiling as far as
987
    files of type t, and returning the output files.
988
*/
989
 
990
filename *do_cc
991
    PROTO_N ( ( input, t ) )
992
    PROTO_T ( filename *input X int t )
993
{
994
    char *flag ;
995
    filename *output ;
996
    if ( input == null ) return ( input ) ;
997
    output = make_filename ( input, t, where ( t ) ) ;
998
    if ( t == PREPROC_C ) {
999
	if ( keeps [t] ) {
1000
	    flag = "-P" ;
1001
	} else {
1002
	    flag = "-E" ;
1003
	    output = null ;
1004
	}
1005
    } else if ( t == AS_SOURCE ) {
1006
	flag = "-S" ;
1007
    } else {
1008
	flag = "-c" ;
1009
	output->type = BINARY_OBJ ;
1010
    }
1011
    cmd_list ( exec_cc ) ;
1012
    cmd_string ( flag ) ;
1013
    if ( flag_diag ) cmd_string ( "-g" ) ;
1014
    cmd_list ( opt_cc ) ;
1015
    if ( use_sparc_cc == 2 && output ) {
1016
	filename *real_output ;
1017
	real_output = make_filename ( input, output->type, PRESERVED_FILE ) ;
1018
	real_output->name = find_basename ( real_output->name ) ;
1019
	cmd_filename ( input ) ;
1020
	real_output = execute ( input, real_output ) ;
1021
	return ( do_move ( real_output, output ) ) ;
1022
    } else {
1023
	if ( output ) {
1024
	    cmd_string ( "-o" ) ;
1025
	    cmd_filename ( output ) ;
1026
	}
1027
	cmd_filename ( input ) ;
1028
	return ( execute ( input, output ) ) ;
1029
    }
1030
}