Subversion Repositories tendra.SVN

Rev

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

Rev Author Line No. Line
2 7u83 1
/*
7 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
7 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:-
7 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
7 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;
7 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;
7 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 "filename.h"
63
#include "list.h"
64
#include "archive.h"
65
#include "environ.h"
66
#include "flags.h"
67
#include "compile.h"
68
#include "execute.h"
69
#include "options.h"
70
#include "stages.h"
71
#include "startup.h"
72
#include "suffix.h"
73
#include "utility.h"
74
 
7 7u83 75
static filename *apply_unjoin(filename *, int);
2 7u83 76
 
7 7u83 77
 
2 7u83 78
/*
7 7u83 79
 * CHECK IF ONE FILE IS THE C SPEC OF THE OTHER
80
 *
81
 * This macro checks if q is the C or C++ spec file corresponding to p.  q must
82
 * be of type C_SPEC and have the same uniq value as p.
83
 */
2 7u83 84
 
7 7u83 85
#define spec_of(p, q)	((q) &&\
86
			 ((q)->type == C_SPEC || (q)->type == CPP_SPEC) &&\
87
			 (q)->uniq == (p)->uniq)
2 7u83 88
 
89
 
90
/*
7 7u83 91
 * APPLY THE SYSTEM COMPILER
92
 *
93
 * This routine applies the system C compiler to the files, input, returning
94
 * the result.
95
 */
2 7u83 96
 
7 7u83 97
static filename *
98
apply_cc(filename *input)
2 7u83 99
{
7 7u83 100
	filename *p = input;
101
	filename *output = null;
102
	while (p != null) {
103
		filename *ps = null;
104
		filename *pn = p->next;
105
		p->next = null;
106
		switch (p->type) {
107
		case C_SOURCE:
108
			/* C source */
109
			if (make_preproc || keeps[PREPROC_C]) {
110
				p = do_cc(p, PREPROC_C);
111
				if (stops[PREPROC_C]) {
112
					break;
113
				}
114
			}
115
			goto preproc_c_lab;
116
		case PREPROC_C:
117
preproc_c_lab:
118
			/* Preprocessed C source */
119
			if (use_system_cc == 1) {
120
				ps = do_produce(p);
121
				if (ps == null) {
122
					p = null;
123
					break;
124
				} else {
125
					ps = ps->next;
126
				}
127
			}
128
			if (stops[DEP_TDF]) {
129
				if (ps != null) {
130
					p = null;
131
				}
132
				break;
133
			} else if (stops[AS_SOURCE]) {
134
				p = do_cc(p, AS_SOURCE);
135
				break;
136
			} else if (keeps[AS_SOURCE]) {
137
				p = do_cc(p, AS_SOURCE);
138
			} else {
139
				p = do_cc(p, binary_obj_type);
140
				break;
141
			}
142
			goto as_source_lab;
143
		case CPP_SOURCE:
144
			/* C++ source */
145
			if (make_preproc || keeps[PREPROC_CPP]) {
146
				p = do_cc(p, PREPROC_CPP);
147
				if (stops[PREPROC_CPP]) {
148
					break;
149
				}
150
			}
151
			goto preproc_cpp_lab;
152
		case PREPROC_CPP:
153
preproc_cpp_lab:
154
			/* Preprocessed C++ source */
155
			if (use_system_cc == 1) {
156
				ps = do_cpp_produce(p);
157
				if (ps == null) {
158
					p = null;
159
					break;
160
				} else {
161
					ps = ps->next;
162
				}
163
			}
164
			if (stops[DEP_TDF]) {
165
				if (ps != null) {
166
					p = null;
167
				}
168
				break;
169
			} else if (stops[AS_SOURCE]) {
170
				p = do_cc(p, AS_SOURCE);
171
				break;
172
			} else if (keeps[AS_SOURCE]) {
173
				p = do_cc(p, AS_SOURCE);
174
			} else {
175
				p = do_cc(p, binary_obj_type);
176
				break;
177
			}
178
			goto as_source_lab;
179
		case AS_SOURCE:
180
as_source_lab:
181
			/* Assembly source file */
182
			if (!stops[AS_SOURCE]) {
183
				p = do_cc(p, BINARY_OBJ);
184
			}
185
			break;
186
		case BINARY_OBJ:
187
			/* Binary object file */
188
			break;
189
		case C_SPEC:
190
			/* C spec file */
191
			if (!allow_specs) {
192
				error(WARNING, "'%s' is a C spec file",
193
				      p->name);
194
				p->type = DEFAULT_TYPE;
195
			} else {
196
				if (p->storage == INPUT_FILE &&
197
				    keeps_aux[BINARY_OBJ] == 1 &&
198
				    !stops[AS_SOURCE]) {
199
					p = do_build_file(p, BINARY_OBJ);
200
				}
201
			}
202
			break;
203
		case CPP_SPEC:
204
			/* C++ spec file */
205
			if (!allow_specs || !allow_cpp) {
206
				error(WARNING, "'%s' is a C++ spec file",
207
				      p->name);
208
				p->type = DEFAULT_TYPE;
209
			} else {
210
				if (p->storage == INPUT_FILE &&
211
				    keeps_aux[BINARY_OBJ] == 1 &&
212
				    !stops[AS_SOURCE]) {
213
					p = do_build_file(p, BINARY_OBJ);
214
				}
215
			}
216
			break;
217
		default:
218
			/* Other file types give an error */
219
			error(WARNING,
220
			      "TDF file '%s' not recognised in cc mode",
221
			      p->name);
222
			p->type = DEFAULT_TYPE;
223
			break;
2 7u83 224
		}
7 7u83 225
		if (p && p->storage != INPUT_FILE && p->aux == null) {
226
			boolean have_spec = 0;
227
			filename *p_archive = p;
228
			int t = p->type;
229
			if (t == BINARY_OBJ && keeps[t] &&
230
			    binary_obj_type != t) {
231
				if (spec_of(p_archive, ps)) {
232
					p_archive->next = ps;
233
					p_archive = p_archive->next;
234
					ps = ps->next;
235
					p_archive->next = null;
236
					have_spec = 1;
237
				}
238
				if (have_spec) {
239
					p = do_build_file(p, BINARY_OBJ);
240
				}
241
			}
2 7u83 242
		}
7 7u83 243
		output = add_filename(output, p);
244
		if (ps) {
245
			output = add_filename(output, ps);
2 7u83 246
		}
7 7u83 247
		p = pn;
248
	}
249
	return (output);
250
}
2 7u83 251
 
252
 
7 7u83 253
/*
254
 * APPLY THE TDF LINKER
255
 *
256
 * This routine applies the TDF linker to p, returning the result.
257
 */
2 7u83 258
 
7 7u83 259
static filename *
260
apply_tdf_link(filename *p)
261
{
262
	static boolean tried = 0;
263
	if (p == null || stops[INDEP_TDF]) {
264
		return (p);
2 7u83 265
	}
7 7u83 266
	if (tokdef_name && tokdef_output == null && !tried) {
267
		filename *q;
268
		if (!allow_notation) {
269
			read_env(TNC_ENV);
2 7u83 270
		}
7 7u83 271
		q = find_filename(tokdef_name, PRETTY_TDF);
272
		q = do_notation(q);
273
		if (q) {
274
			tokdef_output = q->name;
2 7u83 275
		}
7 7u83 276
		tried = 1;
2 7u83 277
	}
7 7u83 278
	return (do_tdf_link(p));
2 7u83 279
}
280
 
281
 
282
/*
7 7u83 283
 * APPLY THE MAIN COMPILATION STAGES
284
 *
285
 * This routine applies the main compilation phases to the input files input,
286
 * and returns the corresponding output files. If produce is true then the
287
 * compilation stops at the target independent TDF stage. This, and all the
288
 * routines in this module, needs to be kept in step with Table 1.
289
 */
2 7u83 290
 
7 7u83 291
static filename *
292
apply_compile(filename *input, int produce)
2 7u83 293
{
7 7u83 294
	filename *p = input;
295
	filename *output = null;
296
	if (use_system_cc) {
297
		return (apply_cc(input));
2 7u83 298
	}
7 7u83 299
	while (p != null) {
300
		filename *pc = p;
301
		filename *pn = p->next;
302
		p->next = null;
303
		switch (p->type) {
304
		case C_SOURCE:
305
			/* C source */
306
			if (keeps[PREPROC_C]) {
307
				p = do_preproc(p);
308
			} else {
309
				p = do_produce(p);
310
			}
311
			if (allow_specs && stops[C_SPEC]) {
312
				p = null;
313
			}
314
			if (p != pc) {
315
				p = apply_compile(p, produce);
316
			}
317
			break;
318
		case PREPROC_C:
319
			/* Preprocessed C source */
320
			if (stops[PREPROC_C]) {
321
				break;
322
			}
323
			p = do_produce(p);
324
			if (allow_specs && stops[C_SPEC]) {
325
				p = null;
326
			}
327
			if (p != pc) {
328
				p = apply_compile(p, produce);
329
			}
330
			break;
331
		case CPP_SOURCE:
332
			/* C++ source */
333
			if (allow_cpp) {
334
				if (keeps[PREPROC_CPP]) {
335
					p = do_cpp_preproc(p);
336
				} else {
337
					p = do_cpp_produce(p);
338
				}
339
				if (allow_specs && stops[CPP_SPEC]) {
340
					p = null;
341
				}
342
				if (p != pc) {
343
					p = apply_compile(p, produce);
344
				}
345
			} else {
346
				error(WARNING, "'%s' is a C++ source file",
347
				      p->name);
348
				p->type = DEFAULT_TYPE;
349
			}
350
			break;
351
		case PREPROC_CPP:
352
			/* Preprocessed C++ source */
353
			if (stops[PREPROC_CPP]) {
354
				break;
355
			}
356
			if (allow_cpp) {
357
				p = do_cpp_produce(p);
358
				if (allow_specs && stops[CPP_SPEC]) {
359
					p = null;
360
				}
361
				if (p != pc) {
362
					p = apply_compile(p, produce);
363
				}
364
			} else {
365
				error(WARNING,
366
				      "'%s' is a preprocessed C++ source file",
367
				      p->name);
368
				p->type = DEFAULT_TYPE;
369
			}
370
			break;
371
		case INDEP_TDF:
372
			/* Target independent TDF */
373
			if (!produce) {
374
				p = apply_tdf_link(p);
375
				if (p != pc) {
376
					p = apply_compile(p, produce);
377
				}
378
			}
379
			break;
380
		case DEP_TDF:
381
			/* Target dependent TDF */
382
			if (!produce) {
383
				p = do_translate(p);
384
				if (p != pc) {
385
					p = apply_compile(p, produce);
386
				}
387
			}
388
			break;
389
		case AS_SOURCE:
390
			/* Assembly source */
391
			if (!produce) {
392
				p = do_assemble(p);
393
				if (p != pc) {
394
					p = apply_compile(p, produce);
395
				}
396
			}
397
			break;
398
		case PRETTY_TDF:
399
			/* TDF notation source */
400
			if (allow_notation) {
401
				p = do_notation(p);
402
				if (p != pc) {
403
					p = apply_compile(p, produce);
404
				}
405
			} else {
406
				error(WARNING,
407
				      "'%s' is a TDF notation source file",
408
				      p->name);
409
				p->type = DEFAULT_TYPE;
410
			}
411
			break;
412
		case PL_TDF:
413
			/* PL_TDF source */
414
			if (allow_pl_tdf) {
415
				p = do_pl_tdf(p);
416
				if (p != pc) {
417
					p = apply_compile(p, produce);
418
				}
419
			} else {
420
				error(WARNING,
421
				      "'%s' is a PL_TDF source file", p->name);
422
				p->type = DEFAULT_TYPE;
423
			}
424
			break;
425
		case C_SPEC:
426
			/* C spec file */
427
			if (!allow_specs) {
428
				error(WARNING, "'%s' is a C spec file",
429
				      p->name);
430
				p->type = DEFAULT_TYPE;
431
			} else {
432
				if (p->storage == INPUT_FILE &&
433
				    keeps_aux[BINARY_OBJ] == 1 &&
434
				    !stops[AS_SOURCE]) {
435
					p = do_build_file(p, BINARY_OBJ);
436
				}
437
			}
438
			break;
439
		case CPP_SPEC:
440
			/* C++ spec file */
441
			if (!allow_specs || !allow_cpp) {
442
				error(WARNING, "'%s' is a C++ spec file",
443
				      p->name);
444
				p->type = DEFAULT_TYPE;
445
			} else {
446
				if (p->storage == INPUT_FILE &&
447
				    keeps_aux[BINARY_OBJ] == 1 &&
448
				    !stops[AS_SOURCE]) {
449
					p = do_build_file(p, BINARY_OBJ);
450
				}
451
			}
452
			break;
2 7u83 453
		}
7 7u83 454
		if (p && p->storage != INPUT_FILE && p->aux == null) {
455
			boolean have_spec = 0;
456
			filename *p_archive = p;
457
			if (spec_of(p_archive, p_archive->next)) {
458
				p_archive = p_archive->next;
459
				have_spec = 1;
460
			} else if (spec_of(p_archive, pn)) {
461
				p_archive->next = pn;
462
				p_archive = p_archive->next;
463
				pn = pn->next;
464
				p_archive->next = null;
465
				have_spec = 1;
466
			}
467
			if (have_spec) {
468
				int t = p->type;
469
				if (t == INDEP_TDF && checker && !stops[t]) {
470
					if (stops[BINARY_OBJ] ||
471
					    keeps_aux[BINARY_OBJ] == 1) {
472
						p = do_build_file(p->next,
473
								  BINARY_OBJ);
474
					}
475
				}
476
				if (t == BINARY_OBJ && keeps[t]) {
477
					p = do_build_file(p, BINARY_OBJ);
478
				}
479
			}
2 7u83 480
		}
7 7u83 481
		output = add_filename(output, p);
482
		p = pn;
2 7u83 483
	}
7 7u83 484
	return (output);
2 7u83 485
}
486
 
487
 
488
/*
7 7u83 489
 * FILTER OUT LIST OF BINARY OBJECT FILES
490
 *
491
 * This routine picks out the TDF capsules from the input files, input,
492
 * compiles them to binary object files, and returns them.
493
 */
2 7u83 494
 
7 7u83 495
static filename *
496
filter_ofiles(filename *input)
2 7u83 497
{
7 7u83 498
	filename *p = input;
499
	filename *links = null;
500
	while (p != null) {
501
		filename *pn = p->next;
502
		p->next = null;
503
		p->aux = pn;
504
		if (p->type == INDEP_TDF) {
505
			filename *q = apply_compile(p, 0);
506
			if (q && q->type == BINARY_OBJ) {
507
				links = add_filename(links, q);
508
			}
509
		}
510
		p = pn;
2 7u83 511
	}
7 7u83 512
	return (links);
2 7u83 513
}
514
 
515
 
516
/*
7 7u83 517
 * APPLY THE SYSTEM LINKER
518
 *
519
 * This routine applies the system linker to the input files, input, and
520
 * returns the corresponding output files.
521
 */
2 7u83 522
 
7 7u83 523
static filename *
524
apply_link(filename *input)
2 7u83 525
{
7 7u83 526
	filename *p = input;
527
	int spec_out = C_SPEC_2;
528
	filename *links = null, *links_out = null;
529
	filename *specs = null, *specs_out;
530
	filename *others = null;
531
	while (p != null) {
532
		filename *pn = p->next;
533
		p->next = null;
534
		p->aux = pn;
535
		if (p->type == BINARY_OBJ) {
536
			links = add_filename(links, p);
537
		} else if (p->type == C_SPEC) {
538
			specs = add_filename(specs, p);
539
		} else if (p->type == CPP_SPEC) {
540
			specs = add_filename(specs, p);
541
			spec_out = CPP_SPEC_2;
2 7u83 542
		} else {
7 7u83 543
			others = add_filename(others, p);
2 7u83 544
		}
7 7u83 545
		p = pn;
2 7u83 546
	}
7 7u83 547
	last_return = 0;
548
	keeps[binary_obj_type] = 0;
549
	specs_out = do_link_specs(specs, spec_out);
550
	links = add_filename(links, filter_ofiles(specs_out));
551
	if (use_dynlink != 0 && use_system_cc == 0) {
552
		links = do_dynlink(links);
553
	}
554
	if (links) {
555
		links_out = do_link(links);
556
	}
557
	if (specs_out && links_out) {
558
		specs_out->uniq = links_out->uniq;
559
	}
560
	p = add_filename(links_out, specs_out);
561
	p = add_filename(p, others);
562
	if (last_return) {
563
		/* If the linking failed, keep the .o files */
564
		filename *q = input;
565
		boolean b = keeps[BINARY_OBJ];
566
		keeps[BINARY_OBJ] = 1;
567
		p = null;
568
		while (q != null) {
569
			filename *qa = q->aux;
570
			q->next = null;
571
			if (q->type == C_SPEC || q->type == CPP_SPEC) {
572
				q = null;
573
			} else if (q->type == BINARY_OBJ) {
574
				if (q->storage == INPUT_FILE || b) {
575
					q = null;
576
				} else if (allow_specs) {
577
					if (link_specs) {
578
						q = do_keep(q);
579
					}
580
					if (spec_of(q, qa)) {
581
						q->next = qa;
582
						qa->next = null;
583
						qa = qa->aux;
584
						if (link_specs) {
585
							q->next =
586
							    do_keep(q->next);
587
						}
588
					}
589
					q = do_build_file(q, BINARY_OBJ);
590
				} else {
591
					q = do_keep(q);
592
				}
593
			}
594
			p = add_filename(p, q);
595
			q = qa;
596
		}
597
	}
598
	return (p);
2 7u83 599
}
600
 
601
 
602
/*
7 7u83 603
 * SPLIT ALL TDF ARCHIVES
604
 *
605
 * This routine splits any TDF archives in the input files, input, and returns
606
 * the corresponding output files.
607
 */
2 7u83 608
 
7 7u83 609
static filename *
610
apply_split_arch(filename *input)
2 7u83 611
{
7 7u83 612
	filename *p = input;
613
	filename *output = null;
614
	archive_type = TDF_ARCHIVE;
615
	while (p != null) {
616
		filename *pn = p->next;
617
		p->next = null;
618
		if (p->type == TDF_ARCHIVE) {
619
			if (use_system_cc) {
620
				error(WARNING, "'%s' is a TDF archive",
621
				      p->name);
622
				p->type = DEFAULT_TYPE;
623
			} else {
624
				p = do_split_arch(p);
625
			}
626
		}
627
		output = add_filename(output, p);
628
		p = pn;
2 7u83 629
	}
7 7u83 630
	return (output);
2 7u83 631
}
632
 
633
 
634
/*
7 7u83 635
 * BUILD A TDF ARCHIVE
636
 *
637
 * This routine creates a TDF archive from the input files, input, and returns
638
 * the corresponding output files.
639
 */
2 7u83 640
 
7 7u83 641
static filename *
642
apply_build_arch(filename *input)
2 7u83 643
{
7 7u83 644
	filename *p = input;
645
	filename *links = null;
646
	filename *specs = null;
647
	filename *others = null;
648
	int spec_out = C_SPEC_1;
649
	while (p != null) {
650
		filename *pn = p->next;
651
		p->next = null;
652
		if (p->type == INDEP_TDF) {
653
			links = add_filename(links, p);
654
		} else if (p->type == C_SPEC) {
655
			specs = add_filename(specs, p);
656
		} else if (p->type == CPP_SPEC) {
657
			specs = add_filename(specs, p);
658
			spec_out = CPP_SPEC_1;
659
		} else {
660
			others = add_filename(others, p);
661
		}
662
		p = pn;
2 7u83 663
	}
7 7u83 664
	specs = do_link_specs(specs, spec_out);
665
	links = do_build_arch(links);
666
	if (specs && links) {
667
		specs->uniq = links->uniq;
668
	}
669
	p = add_filename(links, specs);
670
	p = add_filename(p, others);
671
	return (p);
2 7u83 672
}
673
 
674
 
675
/*
7 7u83 676
 * BUILD A TDF COMPLEX
677
 *
678
 * This routine creates a complex TDF capsule from the input files, input, and
679
 * returns the corresponding output files.
680
 */
2 7u83 681
 
7 7u83 682
static filename *
683
apply_build(filename *input)
2 7u83 684
{
7 7u83 685
	filename *p = input;
686
	filename *links = null;
687
	filename *specs = null;
688
	filename *others = null;
689
	int spec_out = C_SPEC_1;
690
	while (p != null) {
691
		filename *pn = p->next;
692
		p->next = null;
693
		if (p->type == INDEP_TDF) {
694
			links = add_filename(links, p);
695
		} else if (p->type == C_SPEC) {
696
			specs = add_filename(specs, p);
697
		} else if (p->type == CPP_SPEC) {
698
			specs = add_filename(specs, p);
699
			spec_out = CPP_SPEC_1;
700
		} else {
701
			others = add_filename(others, p);
702
		}
703
		p = pn;
2 7u83 704
	}
7 7u83 705
	specs = do_link_specs(specs, spec_out);
706
	links = do_tdf_build(links);
707
	if (specs && links) {
708
		specs->uniq = links->uniq;
709
	}
710
	p = add_filename(links, specs);
711
	p = add_filename(p, others);
712
	return (p);
2 7u83 713
}
714
 
715
 
716
/*
7 7u83 717
 * APPLY THE PREPROCESSOR
718
 *
719
 * This routine applies the preprocessor to the input files, input, and returns
720
 * the corresponding output files.
721
 */
2 7u83 722
 
7 7u83 723
static filename *
724
apply_preproc(filename *input)
2 7u83 725
{
7 7u83 726
	filename *p = input;
727
	filename *output = null;
728
	if (use_system_cc) {
729
		return (apply_cc(input));
730
	}
731
	while (p != null) {
732
		filename *pn = p->next;
733
		p->next = null;
734
		if (p->type == C_SOURCE) {
735
			p = do_preproc(p);
736
		} else if (p->type == CPP_SOURCE) {
737
			p = do_cpp_preproc(p);
738
		}
739
		output = add_filename(output, p);
740
		p = pn;
741
	}
742
	return (output);
2 7u83 743
}
744
 
745
 
746
/*
7 7u83 747
 * APPLY THE TDF PRETTY PRINTER
748
 *
749
 * This routine applies the TDF pretty printer to the input files, input, and
750
 * returns the corresponding output files.
751
 */
2 7u83 752
 
7 7u83 753
static filename *
754
apply_pretty(filename *input)
2 7u83 755
{
7 7u83 756
	filename *p = input;
757
	filename *output = null;
758
	while (p != null) {
759
		filename *pn = p->next;
760
		p->next = null;
761
		if (make_tspec) {
762
			if (p->type == C_SPEC) {
763
				p = do_pretty(p);
764
			}
765
		} else if (p->type == INDEP_TDF) {
766
			if (make_pretty == 2) {
767
				p = apply_tdf_link(p);
768
			}
769
			p = do_pretty(p);
770
		} else if (p->type == DEP_TDF) {
771
			p = do_pretty(p);
772
		}
773
		output = add_filename(output, p);
774
		p = pn;
2 7u83 775
	}
7 7u83 776
	return (output);
2 7u83 777
}
778
 
779
 
780
/*
7 7u83 781
 * APPLY THE ARCHIVER TO UNJOIN C SPEC FILES
782
 *
783
 * This routine scans input for input archives of type t. It splits these into
784
 * their component files. For internal archives the contents are in the aux
785
 * field.
786
 */
2 7u83 787
 
7 7u83 788
static filename *
789
apply_unjoin(filename *input, int t)
2 7u83 790
{
7 7u83 791
	filename *p = input;
792
	filename *output = null;
793
	archive_type = t;
794
	while (p != null) {
795
		filename *pn = p->next;
796
		p->next = null;
797
		if (p->type == t) {
798
			if (p->storage == INPUT_FILE) {
799
				if (is_archive(p->name)) {
800
					p = do_split_arch(p);
801
				}
802
			} else if (p->aux != null) {
803
				p = p->aux;
804
			}
805
		}
806
		output = add_filename(output, p);
807
		p = pn;
2 7u83 808
	}
7 7u83 809
	return (output);
2 7u83 810
}
811
 
812
 
813
/*
7 7u83 814
 * APPLY ALL THE COMPILATION STAGES
815
 *
816
 * This routine applies all the compilation stages to the input files, input,
817
 * and returns the corresponding output files.
818
 */
2 7u83 819
 
7 7u83 820
filename *
821
apply_all(filename *input)
2 7u83 822
{
7 7u83 823
	filename *p = input;
2 7u83 824
 
7 7u83 825
	/* Set up file types */
826
	if (allow_specs) {
827
		binary_obj_type = BINARY_OBJ_AUX;
828
	}
2 7u83 829
 
7 7u83 830
	/* Preprocessing is a special case */
831
	if (make_preproc) {
832
		return (apply_preproc(p));
833
	}
2 7u83 834
 
7 7u83 835
	/* Any TDF archives are split immediately */
836
	p = apply_split_arch(input);
2 7u83 837
 
7 7u83 838
	/* Deal with building TDF archive case */
839
	if (make_archive) {
840
		p = apply_compile(p, 1);
841
		if (make_complex) {
842
			p = apply_build(p);
843
		}
844
		return (apply_build_arch(p));
845
	}
2 7u83 846
 
7 7u83 847
	/* Deal with pretty printing case */
848
	if (make_pretty) {
849
		p = apply_compile(p, 1);
850
		if (make_complex) {
851
			p = apply_build(p);
852
		}
853
		return (apply_pretty(p));
854
	}
2 7u83 855
 
7 7u83 856
	/* Deal with building TDF complex */
857
	if (make_complex) {
858
		p = apply_compile(p, 1);
859
		p = apply_build(p);
860
	}
2 7u83 861
 
7 7u83 862
	/* Main compilation phases */
863
	p = apply_compile(p, (int)checker);
864
	if (allow_specs && !stops[BINARY_OBJ]) {
865
		p = apply_unjoin(p, BINARY_OBJ);
866
	}
867
	p = apply_link(p);
868
	return (p);
2 7u83 869
}