Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20120805181301

Diff

Diff from 1.229 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/cc/cc/cc.c

Annotated File View

ragge
1.229
1 /*      $Id: cc.c,v 1.229 2012/08/05 18:13:01 ragge Exp $       */
ragge
1.222
2
3 /*-
4  * Copyright (c) 2011 Joerg Sonnenberger <joerg@NetBSD.org>.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
22  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
24  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
28  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31
ragge
1.128
32 /*
33  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
34  *
35  * Redistribution and use in source and binary forms, with or without
36  * modification, are permitted provided that the following conditions
37  * are met:
38  *
39  * Redistributions of source code and documentation must retain the above
40  * copyright notice, this list of conditions and the following disclaimer.
41  * Redistributions in binary form must reproduce the above copyright
42  * notice, this list of conditionsand the following disclaimer in the
43  * documentation and/or other materials provided with the distribution.
44  * All advertising materials mentioning features or use of this software
45  * must display the following acknowledgement:
46  *      This product includes software developed or owned by Caldera
47  *      International, Inc.
48  * Neither the name of Caldera International, Inc. nor the names of other
49  * contributors may be used to endorse or promote products derived from
50  * this software without specific prior written permission.
51  *
52  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
53  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
54  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
55  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
56  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
57  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
61  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
62  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
63  * POSSIBILITY OF SUCH DAMAGE.
64  */
65
66 /*
67  * Front-end to the C compiler.
68  *
69  * Brief description of its syntax:
70  * - Files that end with .c are passed via cpp->ccom->as->ld
71  * - Files that end with .i are passed via ccom->as->ld
plunky
1.206
72  * - Files that end with .S are passed via cpp->as->ld
73  * - Files that end with .s are passed via as->ld
ragge
1.128
74  * - Files that end with .o are passed directly to ld
75  * - Multiple files may be given on the command line.
76  * - Unrecognized options are all sent directly to ld.
77  * -c or -S cannot be combined with -o if multiple files are given.
78  *
79  * This file should be rewritten readable.
80  */
81 #include "config.h"
82
83 #include <sys/types.h>
84 #ifdef HAVE_SYS_WAIT_H
85 #include <sys/wait.h>
86 #endif
87
88 #include <ctype.h>
89 #include <errno.h>
90 #include <fcntl.h>
91 #ifdef HAVE_LIBGEN_H
92 #include <libgen.h>
93 #endif
94 #include <signal.h>
95 #include <stdarg.h>
96 #include <stdio.h>
97 #include <stdlib.h>
98 #include <string.h>
99 #ifdef HAVE_UNISTD_H
100 #include <unistd.h>
101 #endif
ragge
1.222
102 #include <assert.h>
ragge
1.128
103
plunky
1.213
104 #ifdef os_win32
ragge
1.128
105 #include <windows.h>
106 #include <process.h>
107 #include <io.h>
gmcgarry
1.179
108 #define F_OK    0x00
109 #define R_OK    0x04
110 #define W_OK    0x02
111 #define X_OK    R_OK
ragge
1.128
112 #endif
113
114 #include "compat.h"
115
ragge
1.167
116 #include "macdefs.h"
ragge
1.218
117
118 #include "xalloc.h"
119 #include "strlist.h"
ragge
1.226
120
121 #include "ccconfig.h"
ragge
1.128
122 /* C command */
123
124 #define MKS(x) _MKS(x)
125 #define _MKS(x) #x
126
ragge
1.226
127 /* default program names in pcc */
128 /* May be overridden if cross-compiler is generated */
129 #ifndef CPPROGNAME
130 #define CPPROGNAME      "cpp"   /* cc used as cpp */
ragge
1.128
131 #endif
132 #ifndef PREPROCESSOR
ragge
1.226
133 #define PREPROCESSOR    "cpp"   /* "real" preprocessor name */
ragge
1.128
134 #endif
135 #ifndef COMPILER
gmcgarry
1.138
136 #define COMPILER        "ccom"
ragge
1.128
137 #endif
ragge
1.226
138 #ifndef CXXCOMPILER
139 #define CXXCOMPILER     "cxxcom"
140 #endif
ragge
1.128
141 #ifndef ASSEMBLER
142 #define ASSEMBLER       "as"
143 #endif
144 #ifndef LINKER
145 #define LINKER          "ld"
146 #endif
ragge
1.226
147 char    *passp = PREPROCESSOR;
148 char    *pass0 = COMPILER;
149 char    *passxx0 = CXXCOMPILER;
150 char    *as = ASSEMBLER;
151 char    *ld = LINKER;
152 char    *sysroot = "", *isysroot;
153
154
155 /* crt files using pcc default names */
156 #ifndef CRTBEGIN_S
157 #define CRTBEGIN_S      "crtbeginS.o"
158 #endif
159 #ifndef CRTEND_S
160 #define CRTEND_S        "crtendS.o"
161 #endif
162 #ifndef CRTBEGIN_T
163 #define CRTBEGIN_T      "crtbeginT.o"
164 #endif
165 #ifndef CRTEND_T
166 #define CRTEND_T        "crtendT.o"
167 #endif
168 #ifndef CRTBEGIN
169 #define CRTBEGIN        "crtbegin.o"
170 #endif
171 #ifndef CRTEND
172 #define CRTEND          "crtend.o"
173 #endif
174 #ifndef CRTI
175 #define CRTI            "crti.o"
176 #endif
177 #ifndef CRTN
178 #define CRTN            "crtn.o"
179 #endif
180 #ifndef CRT0
181 #define CRT0            "crt0.o"
182 #endif
183 #ifndef GCRT0
184 #define GCRT0           "gcrt0.o"
185 #endif
186
187 /* preprocessor stuff */
188 #ifndef STDINC
189 #define STDINC          "/usr/include/"
190 #endif
191
192 char *cppadd[] = CPPADD;
193 char *cppmdadd[] = CPPMDADD;
ragge
1.128
194
ragge
1.226
195 /* Dynamic linker definitions, per-target */
196 #ifndef DYNLINKER
197 #define DYNLINKER { 0 }
ragge
1.174
198 #endif
199
ragge
1.226
200 /* Default libraries and search paths */
201 #ifndef PCCLIBDIR       /* set by autoconf */
202 #define PCCLIBDIR       NULL
203 #endif
204 #ifndef DEFLIBDIRS      /* default library search paths */
205 #define DEFLIBDIRS      { "/usr/lib/", 0 }
206 #endif
207 #ifndef DEFLIBS         /* default libraries included */
208 #define DEFLIBS         { "-lpcc", "-lc", "-lpcc", 0 }
209 #endif
210 #ifndef DEFPROFLIBS     /* default profiling libraries */
211 #define DEFPROFLIBS     { "-lpcc", "-lc_p", "-lpcc", 0 }
212 #endif
213 #ifndef DEFCXXLIBS      /* default c++ libraries */
214 #define DEFCXXLIBS      { "-lp++", "-lpcc", "-lc", "-lpcc", 0 }
215 #endif
216 #ifndef STARTLABEL
217 #define STARTLABEL "__start"
218 #endif
ragge
1.174
219
ragge
1.226
220 char *dynlinker[] = DYNLINKER;
221 char *pcclibdir = PCCLIBDIR;
222 char *deflibdirs[] = DEFLIBDIRS;
223 char *deflibs[] = DEFLIBS;
224 char *defproflibs[] = DEFPROFLIBS;
225 char *defcxxlibs[] = DEFCXXLIBS;
226
227 char    *outfile;
ragge
1.220
228 static char **lav;
229 static int lac;
ragge
1.226
230 static char *find_file(const char *filestruct strlist *pathint mode);
231 static int preprocess_input(char *inputchar *outputint dodep);
232 static int compile_input(char *inputchar *output);
233 static int assemble_input(char *inputchar *output);
234 static int run_linker(void);
235 static int strlist_exec(struct strlist *l);
236
plunky
1.185
237 char *cat(const char *, const char *);
gmcgarry
1.150
238 char *setsuf(char *, char);
ragge
1.198
239 int cxxsuf(char *);
ragge
1.128
240 int getsuf(char *);
ragge
1.198
241 char *getsufp(char *s);
ragge
1.128
242 int main(intchar *[]);
243 void error(char *, ...);
244 void errorx(intchar *, ...);
245 int callsys(char [], char *[]);
246 int cunlink(char *);
ragge
1.226
247 void exandrm(char *);
ragge
1.128
248 void dexit(int);
249 void idexit(int);
250 char *gettmp(void);
ragge
1.218
251 void aerror(char *);
ragge
1.219
252 void oerror(char *);
ragge
1.223
253 void owarning(char *);
ragge
1.218
254 char *argnxt(char *, char *);
ragge
1.220
255 char *nxtopt(char *o);
ragge
1.222
256 void setup_cpp_flags(void);
ragge
1.226
257 void setup_ccom_flags(void);
258 void setup_as_flags(void);
259 void setup_ld_flags(void);
ragge
1.222
260 static void expand_sysroot(void);
plunky
1.213
261 #ifdef os_win32
ragge
1.128
262 char *win32pathsubst(char *);
gmcgarry
1.149
263 char *win32commandline(char *, char *[]);
ragge
1.128
264 #endif
265 int     sspflag;
plunky
1.214
266 int     freestanding;
ragge
1.226
267 int     Sflag;
ragge
1.128
268 int     cflag;
269 int     gflag;
gmcgarry
1.145
270 int     rflag;
ragge
1.128
271 int     vflag;
272 int     tflag;
273 int     Eflag;
274 int     Oflag;
275 int     kflag;  /* generate PIC/pic code */
276 #define F_PIC   1
277 #define F_pic   2
ragge
1.223
278 int     MflagneedM;   /* dependencies only */
ragge
1.128
279 int     pgflag;
280 int     Xflag;
281 int     Wallflag;
282 int     Wflag;
283 int     nostartfilesBstaticshared;
284 int     nostdincnostdlib;
285 int     pthreads;
plunky
1.217
286 int     xasmxcflagxgnu89xgnu99;
ragge
1.128
287 int     ascpp;
plunky
1.196
288 #ifdef CHAR_UNSIGNED
plunky
1.209
289 int     xuchar = 1;
plunky
1.196
290 #else
plunky
1.209
291 int     xuchar = 0;
plunky
1.196
292 #endif
ragge
1.198
293 int     cxxflag;
ragge
1.216
294 int     cppflag;
ragge
1.128
295
ragge
1.164
296 #ifdef mach_amd64
297 int amd64_i386;
298 #endif
ragge
1.128
299
ragge
1.218
300 #define match(a,b)      (strcmp(a,b) == 0)
301
ragge
1.128
302 /* handle gcc warning emulations */
303 struct Wflags {
304         char *name;
305         int flags;
306 #define INWALL          1
307 Wflags[] = {
plunky
1.215
308         { "truncate"0 },
309         { "strict-prototypes"0 },
310         { "missing-prototypes"0 },
311         { "implicit-int"INWALL },
312         { "implicit-function-declaration"INWALL },
313         { "shadow"0 },
314         { "pointer-sign"INWALL },
315         { "sign-compare"0 },
316         { "unknown-pragmas"INWALL },
317         { "unreachable-code"0 },
318         { NULL0 },
ragge
1.128
319 };
320
ragge
1.158
321 #ifndef USHORT
322 /* copied from mip/manifest.h */
323 #define USHORT          5
324 #define INT             6
325 #define UNSIGNED        7
326 #endif
327
ragge
1.157
328 /*
329  * Wide char defines.
330  */
331 #if WCHAR_TYPE == USHORT
332 #define WCT "short unsigned int"
333 #define WCM "65535U"
ragge
1.158
334 #if WCHAR_SIZE != 2
335 #error WCHAR_TYPE vs. WCHAR_SIZE mismatch
336 #endif
ragge
1.157
337 #elif WCHAR_TYPE == INT
338 #define WCT "int"
339 #define WCM "2147483647"
ragge
1.158
340 #if WCHAR_SIZE != 4
341 #error WCHAR_TYPE vs. WCHAR_SIZE mismatch
342 #endif
ragge
1.157
343 #elif WCHAR_TYPE == UNSIGNED
344 #define WCT "unsigned int"
ragge
1.158
345 #define WCM "4294967295U"
346 #if WCHAR_SIZE != 4
347 #error WCHAR_TYPE vs. WCHAR_SIZE mismatch
348 #endif
349 #else
350 #error WCHAR_TYPE not defined or invalid
ragge
1.157
351 #endif
352
ragge
1.160
353 #ifdef GCC_COMPAT
354 #ifndef REGISTER_PREFIX
355 #define REGISTER_PREFIX ""
356 #endif
357 #ifndef USER_LABEL_PREFIX
358 #define USER_LABEL_PREFIX ""
359 #endif
360 #endif
361
plunky
1.192
362 #ifndef PCC_WINT_TYPE
363 #define PCC_WINT_TYPE "unsigned int"
364 #endif
365
366 #ifndef PCC_SIZE_TYPE
367 #define PCC_SIZE_TYPE "unsigned long"
368 #endif
369
ragge
1.161
370 #ifndef PCC_PTRDIFF_TYPE
371 #define PCC_PTRDIFF_TYPE "long int"
372 #endif
373
ragge
1.216
374
ragge
1.218
375 struct strlist preprocessor_flags;
ragge
1.223
376 struct strlist depflags;
ragge
1.219
377 struct strlist incdirs;
ragge
1.221
378 struct strlist user_sysincdirs;
379 struct strlist includes;
ragge
1.222
380 struct strlist sysincdirs;
ragge
1.223
381 struct strlist dirafterdirs;
ragge
1.222
382 struct strlist crtdirs;
383 struct strlist libdirs;
384 struct strlist progdirs;
ragge
1.224
385 struct strlist early_linker_flags;
386 struct strlist middle_linker_flags;
387 struct strlist late_linker_flags;
388 struct strlist inputs;
ragge
1.225
389 struct strlist assembler_flags;
390 struct strlist temp_outputs;
ragge
1.226
391 struct strlist compiler_flags;
ragge
1.218
392
ragge
1.128
393 int
394 main(int argcchar *argv[])
395 {
396         struct Wflags *Wf;
ragge
1.226
397         struct string *s;
ragge
1.218
398         char *t, *u, *argp;
ragge
1.226
399         int ninputj;
ragge
1.222
400
ragge
1.220
401         lav = argv;
402         lac = argc;
ragge
1.128
403
ragge
1.222
404         strlist_init(&crtdirs);
405         strlist_init(&libdirs);
406         strlist_init(&progdirs);
ragge
1.218
407         strlist_init(&preprocessor_flags);
ragge
1.219
408         strlist_init(&incdirs);
ragge
1.221
409         strlist_init(&user_sysincdirs);
410         strlist_init(&includes);
ragge
1.222
411         strlist_init(&sysincdirs);
ragge
1.223
412         strlist_init(&dirafterdirs);
413         strlist_init(&depflags);
ragge
1.224
414         strlist_init(&early_linker_flags);
415         strlist_init(&middle_linker_flags);
416         strlist_init(&late_linker_flags);
417         strlist_init(&inputs);
ragge
1.225
418         strlist_init(&assembler_flags);
419         strlist_init(&temp_outputs);
ragge
1.226
420         strlist_init(&compiler_flags);
ragge
1.218
421
ragge
1.216
422         if ((t = strrchr(argv[0], '/')))
ragge
1.226
423                 t++;
ragge
1.229
424         else
425                 t = argv[0];
ragge
1.226
426
427         if (match(t"p++")) {
ragge
1.198
428                 cxxflag = 1;
ragge
1.226
429         } else if (match(t"cpp") || match(tCPPROGNAME)) {
430                 Eflag = cppflag = 1;
ragge
1.198
431         }
432
plunky
1.213
433 #ifdef os_win32
ragge
1.128
434         /* have to prefix path early.  -B may override */
435         incdir = win32pathsubst(incdir);
gmcgarry
1.153
436         altincdir = win32pathsubst(altincdir);
gmcgarry
1.136
437         libdir = win32pathsubst(libdir);
plunky
1.200
438 #ifdef PCCINCDIR
ragge
1.128
439         pccincdir = win32pathsubst(pccincdir);
plunky
1.199
440         pxxincdir = win32pathsubst(pxxincdir);
plunky
1.200
441 #endif
442 #ifdef PCCLIBDIR
ragge
1.128
443         pcclibdir = win32pathsubst(pcclibdir);
plunky
1.200
444 #endif
ragge
1.128
445         passp = win32pathsubst(passp);
446         pass0 = win32pathsubst(pass0);
gmcgarry
1.180
447 #ifdef STARTFILES
448         for (i = 0startfiles[i] != NULLi++)
449                 startfiles[i] = win32pathsubst(startfiles[i]);
450         for (i = 0endfiles[i] != NULLi++)
451                 endfiles[i] = win32pathsubst(endfiles[i]);
452 #endif
453 #ifdef STARTFILES_T
454         for (i = 0startfiles_T[i] != NULLi++)
455                 startfiles_T[i] = win32pathsubst(startfiles_T[i]);
456         for (i = 0endfiles_T[i] != NULLi++)
457                 endfiles_T[i] = win32pathsubst(endfiles_T[i]);
458 #endif
459 #ifdef STARTFILES_S
460         for (i = 0startfiles_S[i] != NULLi++)
461                 startfiles_S[i] = win32pathsubst(startfiles_S[i]);
462         for (i = 0endfiles_S[i] != NULLi++)
463                 endfiles_S[i] = win32pathsubst(endfiles_S[i]);
464 #endif
ragge
1.128
465 #endif
466
ragge
1.220
467         while (--lac) {
468                 ++lav;
469                 argp = *lav;
470
ragge
1.227
471 #ifdef EARLY_ARG_CHECK
472                 EARLY_ARG_CHECK;
473 #endif
474
ragge
1.225
475                 if (*argp != '-' || match(argp"-")) {
476                         /* Check for duplicate .o files. */
477                         if (getsuf(argp) == 'o') {
478                                 j = 0;
479                                 STRLIST_FOREACH(s, &inputs)
480                                         if (match(argps->value))
481                                                 j++;
482                                 if (j)
483                                         continue/* skip it */
484                         }
485                         strlist_append(&inputsargp);
486                         continue;
487                 }
ragge
1.220
488
489                 switch (argp[1]) {
490                 default:
ragge
1.224
491                         owarning(argp);
ragge
1.220
492                         break;
ragge
1.128
493
ragge
1.220
494                 case '-'/* double -'s */
495                         if (match(argp"--version")) {
496                                 printf("%s\n"VERSSTR);
497                                 return 0;
498                         } else if (strncmp(argp"--sysroot="10) == 0) {
499                                 sysroot = argp + 10;
500                         } else if (strcmp(argp"--param") == 0) {
501                                 /* NOTHING YET */;
502                                 (void)nxtopt(0); /* ignore arg */
503                         } else
ragge
1.225
504                                 owarning(argp);
ragge
1.220
505                         break;
ragge
1.128
506
ragge
1.220
507                 case 'B'/* other search paths for binaries */
ragge
1.224
508                         t = nxtopt("-B");
509                         strlist_append(&crtdirst);
510                         strlist_append(&libdirst);
511                         strlist_append(&progdirst);
ragge
1.220
512                         break;
ragge
1.128
513
ragge
1.220
514                 case 'C':
515                         if (match(argp"-C") || match(argp"-CC"))
516                                 strlist_append(&preprocessor_flagsargp);
517                         else
518                                 oerror(argp);
519                         break;
ragge
1.218
520
ragge
1.220
521                 case 'X':
522                         Xflag++;
523                         break;
524                 case 'W'/* Ignore (most of) W-flags */
ragge
1.225
525                         if ((t = argnxt(argp"-Wl,"))) {
526                                 u = strtok(t",");
527                                 do {
528                                         strlist_append(&middle_linker_flagsu);
529                                 } while ((u = strtok(NULL",")) != NULL);
530                         } else if ((t = argnxt(argp"-Wa,"))) {
531                                 u = strtok(t",");
532                                 do {
533                                         strlist_append(&assembler_flagsu);
534                                 } while ((u = strtok(NULL",")) != NULL);
ragge
1.226
535                         } else if ((t = argnxt(argp"-Wc,"))) {
536                                 u = strtok(t",");
537                                 do {
538                                         strlist_append(&compiler_flagsu);
539                                 } while ((u = strtok(NULL",")) != NULL);
ragge
1.220
540                         } else if ((t = argnxt(argp"-Wp,"))) {
541                                 u = strtok(t",");
542                                 do {
543                                         strlist_append(&preprocessor_flagsu);
544                                 } while ((u = strtok(NULL",")) != NULL);
545                         } else if (strcmp(argp"-Werror") == 0) {
ragge
1.226
546                                 strlist_append(&compiler_flags"-Werror");
ragge
1.220
547                         } else if (strcmp(argp"-Wall") == 0) {
548                                 Wallflag = 1;
549                         } else if (strcmp(argp"-WW") == 0) {
550                                 Wflag = 1;
551                         } else {
552                                 /* pass through, if supported */
553                                 t = &argp[2];
554                                 if (strncmp(t"no-"3) == 0)
555                                         t += 3;
556                                 if (strncmp(t"error="6) == 0)
557                                         t += 6;
558                                 for (Wf = WflagsWf->nameWf++) {
559                                         if (strcmp(tWf->name) == 0)
ragge
1.226
560                                                 strlist_append(&compiler_flags,
561                                                     argp);
ragge
1.128
562                                 }
ragge
1.220
563                         }
564                         break;
ragge
1.128
565
ragge
1.220
566                 case 'f'/* GCC compatibility flags */
567                         if (strcmp(argp"-fPIC") == 0)
568                                 kflag = F_PIC;
569                         else if (strcmp(argp"-fpic") == 0)
570                                 kflag = F_pic;
571                         else if (strcmp(argp"-ffreestanding") == 0)
572                                 freestanding = 1;
ragge
1.221
573                         else if (match(argp"-fsigned-char") ||
574                             match(argp"-fno-unsigned-char"))
ragge
1.220
575                                 xuchar = 0;
ragge
1.221
576                         else if (match(argp"-fno-signed-char") ||
577                             match(argp"-funsigned-char"))
ragge
1.220
578                                 xuchar = 1;
ragge
1.226
579                         else if (match(argp"-fstack-protector") ||
580                             match(argp"-fstack-protector-all")) {
ragge
1.220
581                                 sspflag++;
ragge
1.226
582                         } else if (match(argp"-fno-stack-protector") ||
583                             match(argp"-fno-stack-protector-all")) {
ragge
1.220
584                                 sspflag = 0;
585                         }
586                         /* silently ignore the rest */
587                         break;
ragge
1.128
588
ragge
1.220
589                 case 'g'/* create debug output */
590                         if (argp[2] == '0')
591                                 gflag = 0;
592                         else
593                                 gflag++;
594                         break;
ragge
1.128
595
ragge
1.220
596                 case 'D':
597                 case 'U':
ragge
1.221
598                         strlist_append(&preprocessor_flagsargp);
ragge
1.220
599                         if (argp[2] != 0)
ragge
1.219
600                                 break;
ragge
1.221
601                         strlist_append(&preprocessor_flagsnxtopt(argp));
602                         break;
603
604                 case 'I'/* Add include dirs */
605                         strlist_append(&incdirsnxtopt("-I"));
ragge
1.220
606                         break;
ragge
1.219
607
ragge
1.220
608                 case 'i':
ragge
1.221
609                         if (match(argp"-isystem")) {
610                                 strlist_append(&user_sysincdirsnxtopt(0));
611                         } else if (match(argp"-include")) {
612                                 strlist_append(&includesnxtopt(0));
ragge
1.222
613                         } else if (match(argp"-isysroot")) {
614                                 isysroot = nxtopt(0);
ragge
1.220
615                         } else if (strcmp(argp"-idirafter") == 0) {
ragge
1.223
616                                 strlist_append(&dirafterdirsnxtopt(0));
ragge
1.220
617                         } else
ragge
1.225
618                                 owarning(argp);
ragge
1.220
619                         break;
ragge
1.128
620
ragge
1.220
621                 case 'k'/* generate PIC code */
622                         kflag = F_pic;
623                         break;
ragge
1.128
624
ragge
1.224
625                 case 'l':
626                 case 'L':
627                         strlist_append(&late_linker_flagsargp);
ragge
1.226
628                         if (argp[2] == 0)
629                                 strlist_append(&late_linker_flagsnxtopt(0));
ragge
1.224
630                         break;
631
632
ragge
1.220
633                 case 'm'/* target-dependent options */
ragge
1.164
634 #ifdef mach_amd64
ragge
1.220
635                         /* need to call i386 ccom for this */
636                         if (strcmp(argp"-m32") == 0) {
637                                 pass0 = LIBEXECDIR "/ccom_i386";
638                                 amd64_i386 = 1;
639                                 break;
640                         }
ragge
1.164
641 #endif
ragge
1.225
642                         strlist_append(&middle_linker_flagsargp);
ragge
1.220
643                         if (argp[2] == 0) {
ragge
1.225
644                                 t = nxtopt(0);
645                                 strlist_append(&middle_linker_flagst);
ragge
1.220
646                         }
647                         break;
ragge
1.128
648
ragge
1.220
649                 case 'n'/* handle -n flags */
650                         if (strcmp(argp"-nostdinc") == 0)
651                                 nostdinc++;
652                         else if (strcmp(argp"-nostdlib") == 0) {
653                                 nostdlib++;
654                                 nostartfiles++;
655                         } else if (strcmp(argp"-nostartfiles") == 0)
656                                 nostartfiles = 1;
657                         else if (strcmp(argp"-nodefaultlibs") == 0)
658                                 nostdlib++;
659                         else
ragge
1.225
660                                 owarning(argp);
ragge
1.220
661                         break;
ragge
1.128
662
ragge
1.220
663                 case 'p':
664                         if (strcmp(argp"-pg") == 0 ||
665                             strcmp(argp"-p") == 0)
666                                 pgflag++;
667                         else if (strcmp(argp"-pthread") == 0)
668                                 pthreads++;
669                         else if (strcmp(argp"-pipe") == 0)
670                                 /* NOTHING YET */;
671                         else if (strcmp(argp"-pedantic") == 0)
672                                 /* NOTHING YET */;
673                         else if (strcmp(argp,
674                             "-print-prog-name=ld") == 0) {
675                                 printf("%s\n"LINKER);
676                                 return 0;
ragge
1.226
677 #ifdef notdef
678                         /* does not exist in gcc??? */
ragge
1.220
679                         } else if (strcmp(argp,
680                             "-print-multi-os-directory") == 0) {
681                                 printf("%s\n"MULTIOSDIR);
682                                 return 0;
ragge
1.226
683 #endif
ragge
1.220
684                         } else
685                                 oerror(argp);
686                         break;
ragge
1.128
687
ragge
1.220
688                 case 'r':
689                         rflag = 1;
690                         break;
gmcgarry
1.145
691
ragge
1.220
692                 case 'x':
693                         t = nxtopt("-x");
694                         if (match(t"c"))
695                                 xcflag = 1/* default */
696                         else if (match(t"assembler"))
697                                 xasm = 1;
698                         else if (match(t"assembler-with-cpp"))
699                                 ascpp = 1;
700                         else if (match(t"c++"))
701                                 cxxflag++;
ragge
1.226
702                         else {
703                                 strlist_append(&compiler_flags"-x");
704                                 strlist_append(&compiler_flagst);
705                         }
ragge
1.220
706                         break;
707                 case 't':
708                         tflag++;
709                         break;
710                 case 'S':
ragge
1.226
711                         Sflag++;
ragge
1.220
712                         cflag++;
713                         break;
714                 case 'o':
715                         if (outfile)
716                                 errorx(8"too many -o");
717                         outfile = nxtopt("-o");
718                         break;
719                 case 'O':
720                         if (argp[2] == '\0')
721                                 Oflag++;
ragge
1.226
722                         else if (argp[3] == '\0' &&
723                             isdigit((unsigned char)argp[2]))
ragge
1.220
724                                 Oflag = argp[2] - '0';
725                         else if (argp[3] == '\0' && argp[2] == 's')
726                                 Oflag = 1;      /* optimize for space only */
727                         else
728                                 oerror(argp);
729                         break;
730                 case 'E':
731                         Eflag++;
732                         break;
733                 case 'P':
ragge
1.221
734                         strlist_append(&preprocessor_flagsargp);
735                         break;
736
ragge
1.220
737                 case 'c':
ragge
1.227
738                         cflag++;
ragge
1.220
739                         break;
ragge
1.223
740
ragge
1.220
741                 case 'M':
742                         switch (argp[2]) {
ragge
1.223
743                         case '\0':
744                                 Mflag++;
745                                 strlist_append(&depflagsargp);
746                                 break;
747                         case 'P':
748                                 needM = 1;
749                                 strlist_append(&depflags"-xMP");
750                                 break;
751                         case 'F':
752                                 needM = 1;
753                                 outfile = nxtopt("-MF");
754                                 break;
ragge
1.220
755                         case 'T':
756                         case 'Q':
ragge
1.223
757                                 needM = 1;
ragge
1.226
758                                 t = cat("-xMT,"nxtopt("-MT"));
ragge
1.220
759                                 t[3] = argp[2];
ragge
1.223
760                                 strlist_append(&depflagst);
ragge
1.128
761                                 break;
ragge
1.220
762                         default:
763                                 oerror(argp);
764                         }
765                         break;
ragge
1.128
766
ragge
1.220
767                 case 'd':
ragge
1.227
768                         owarning(argp);
ragge
1.220
769                         break;
770                 case 'v':
771                         printf("%s\n"VERSSTR);
772                         vflag++;
773                         break;
ragge
1.128
774
ragge
1.220
775                 case 's':
776                         if (strcmp(argp"-shared") == 0) {
777                                 shared = 1;
ragge
1.227
778                         } else if (strcmp(argp"-static") == 0) {
ragge
1.220
779                                 Bstatic = 1;
ragge
1.225
780                         } else if (match(argp"-symbolic")) {
781                                 strlist_append(&middle_linker_flags,
782                                     "-Bsymbolic");
ragge
1.220
783                         } else if (strncmp(argp"-std"4) == 0) {
784                                 if (strcmp(&argp[5], "gnu99") == 0 ||
785                                     strcmp(&argp[5], "gnu9x") == 0)
786                                         xgnu99 = 1;
787                                 if (strcmp(&argp[5], "gnu89") == 0)
788                                         xgnu89 = 1;
789                         } else
ragge
1.225
790                                 owarning(argp);
ragge
1.220
791                         break;
792                 }
793                 continue;
794
ragge
1.128
795         }
ragge
1.222
796
ragge
1.128
797         /* Sanity checking */
ragge
1.224
798         ninput = 0;
799         STRLIST_FOREACH(s, &inputs)
800                 ninput++;
ragge
1.216
801         if (cppflag) {
ragge
1.224
802                 if (ninput == 0) {
803                         strlist_append(&inputs"-");
804                 } else if (ninput > 2 || (ninput == 2 && outfile)) {
ragge
1.216
805                         errorx(8"too many files");
ragge
1.224
806                 }
ragge
1.216
807         }
ragge
1.225
808         if (ninput == 0)
ragge
1.128
809                 errorx(8"no input files");
ragge
1.226
810         if (outfile && (cflag || Sflag || Eflag) && ninput > 1)
ragge
1.128
811                 errorx(8"-o given with -c || -E || -S and more than one file");
ragge
1.224
812 #if 0
ragge
1.128
813         if (outfile && clist[0] && strcmp(outfileclist[0]) == 0)
814                 errorx(8"output file will be clobbered");
ragge
1.224
815 #endif
ragge
1.223
816
817         if (needM && !Mflag)
818                 errorx(8"to make dependencies needs -M");
819
820
ragge
1.128
821         if (signal(SIGINTSIG_IGN) != SIG_IGN/* interrupt */
822                 signal(SIGINTidexit);
823         if (signal(SIGTERMSIG_IGN) != SIG_IGN)        /* terminate */
824                 signal(SIGTERMidexit);
ragge
1.222
825
ragge
1.226
826         /* after arg parsing */
827         strlist_append(&progdirsLIBEXECDIR);
828         if (pcclibdir)
829                 strlist_append(&crtdirspcclibdir);
830         for (j = 0deflibdirs[j]; j++)
831                 strlist_append(&crtdirsdeflibdirs[j]);
832
ragge
1.223
833         setup_cpp_flags();
ragge
1.226
834         setup_ccom_flags();
835         setup_as_flags();
ragge
1.223
836
837         if (isysroot == NULL)
838                 isysroot = sysroot;
839         expand_sysroot();
840
ragge
1.226
841         STRLIST_FOREACH(s, &inputs) {
842                 char *suffix;
843                 char *ifile, *ofile;
844
845                 ifile = s->value;
846                 if (ninput > 1 && !Eflag)
847                         printf("%s:\n"ifile);
848
849                 suffix = getsufp(ifile);
850                 if (xasm)
851                         suffix = "s";
852                 else if (ascpp)
853                         suffix = "S";
854                 else if (xcflag)
855                         suffix = "c";
ragge
1.128
856                 /*
857                  * C preprocessor
858                  */
ragge
1.226
859                 if (match(suffix"c") || match(suffix"S") ||
860                     cxxsuf(s->value)) {
861                         /* find out next output file */
862                         if (Eflag || Mflag) {
863                                 /* last pass */
864                                 ofile = outfile;
865                         } else {
866                                 /* to temp file */
867                                 strlist_append(&temp_outputsofile = gettmp());
868                         }
869                         if (Mflag /* || MDflag */)
870                                 if (preprocess_input(ifileofile1))
871                                         exandrm(ofile);
872                         if (Mflag)
873                                 continue;
874                         if (preprocess_input(ifileofile0))
875                                 exandrm(ofile);
876                         if (Eflag)
ragge
1.128
877                                 continue;
ragge
1.226
878                         ifile = ofile;
879                         suffix = match(suffix"S") ? "s" : "i";
ragge
1.128
880                 }
881
882                 /*
883                  * C compiler
884                  */
ragge
1.226
885                 if (match(suffix"i")) {
886                         /* find out next output file */
887                         if (Sflag) {
888                                 ofile = outfile;
889                                 if (outfile == NULL)
890                                         ofile = setsuf(s->value's');
891                         } else
892                                 strlist_append(&temp_outputsofile = gettmp());
893                         if (compile_input(ifileofile))
894                                 exandrm(ofile);
895                         if (Sflag)
896                                 continue;
897                         ifile = ofile;
898                         suffix = "s";
ragge
1.128
899                 }
900
901                 /*
902                  * Assembler
903                  */
ragge
1.226
904                 if (match(suffix"s")) {
905                         if (cflag) {
906                                 ofile = outfile;
907                                 if (ofile == NULL)
908                                         ofile = setsuf(s->value'o');
909                         } else {
910                                 strlist_append(&temp_outputsofile = gettmp());
911                                 /* strlist_append linker */
912                         }
913                         if (assemble_input(ifileofile))
914                                 exandrm(ofile);
915                         ifile = ofile;
ragge
1.225
916                 }
ragge
1.226
917                 strlist_append(&middle_linker_flagsifile);
ragge
1.128
918         }
919
ragge
1.226
920         if (cflag)
921                 dexit(0);
ragge
1.128
922
923         /*
924          * Linker
925          */
ragge
1.226
926         setup_ld_flags();
927         if (run_linker())
928                 exandrm(0);
ragge
1.224
929
ragge
1.219
930 #ifdef notdef
ragge
1.222
931         strlist_free(&crtdirs);
932         strlist_free(&libdirs);
933         strlist_free(&progdirs);
ragge
1.219
934         strlist_free(&incdirs);
935         strlist_free(&preprocessor_flags);
ragge
1.221
936         strlist_free(&user_sysincdirs);
937         strlist_free(&includes);
ragge
1.222
938         strlist_free(&sysincdirs);
ragge
1.223
939         strlist_free(&dirafterdirs);
940         strlist_free(&depflags);
ragge
1.224
941         strlist_free(&early_linker_flags);
942         strlist_free(&middle_linker_flags);
943         strlist_free(&late_linker_flags);
944         strlist_free(&inputs);
ragge
1.225
945         strlist_free(&assembler_flags);
946         strlist_free(&temp_outputs);
ragge
1.226
947         strlist_free(&compiler_flags);
ragge