Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20120803124205

Diff

Diff from 1.224 to:

Annotations

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

Annotated File View

ragge
1.224
1 /*      $Id: cc.c,v 1.224 2012/08/03 12:42:05 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
116 #include "ccconfig.h"
ragge
1.167
117 #include "macdefs.h"
ragge
1.218
118
119 #include "xalloc.h"
120 #include "strlist.h"
ragge
1.128
121 /* C command */
122
123 #define MKS(x) _MKS(x)
124 #define _MKS(x) #x
125
126 /*
127  * Many specific definitions, should be declared elsewhere.
128  */
129
130 #ifndef STDINC
131 #define STDINC          "/usr/include/"
132 #endif
133
134 #ifndef LIBDIR
135 #define LIBDIR          "/usr/lib/"
136 #endif
137
138 #ifndef PREPROCESSOR
139 #define PREPROCESSOR    "cpp"
140 #endif
141
142 #ifndef COMPILER
gmcgarry
1.138
143 #define COMPILER        "ccom"
ragge
1.128
144 #endif
145
146 #ifndef ASSEMBLER
147 #define ASSEMBLER       "as"
148 #endif
149
150 #ifndef LINKER
151 #define LINKER          "ld"
152 #endif
153
ragge
1.174
154 #ifndef MULTIOSDIR
155 #define MULTIOSDIR      "."
156 #endif
157
158
ragge
1.128
159 #define MAXFIL 10000
160 #define MAXLIB 10000
161 #define MAXAV  10000
162 char    *tmp3;
163 char    *tmp4;
164 char    *outfile, *ermfile;
ragge
1.220
165 static char **lav;
166 static int lac;
ragge
1.175
167 static void add_prefix(const char *);
168 static char *find_file(const char *, int);
ragge
1.224
169 static char *find_file2(const char *filestruct strlist *pathint mode);
plunky
1.183
170 char *copy(const char *, int);
plunky
1.185
171 char *cat(const char *, const char *);
gmcgarry
1.150
172 char *setsuf(char *, char);
ragge
1.198
173 int cxxsuf(char *);
ragge
1.128
174 int getsuf(char *);
ragge
1.198
175 char *getsufp(char *s);
ragge
1.128
176 int main(intchar *[]);
177 void error(char *, ...);
178 void errorx(intchar *, ...);
179 int callsys(char [], char *[]);
180 int cunlink(char *);
181 void dexit(int);
182 void idexit(int);
183 char *gettmp(void);
184 void *ccmalloc(int size);
ragge
1.218
185 void aerror(char *);
ragge
1.219
186 void oerror(char *);
ragge
1.223
187 void owarning(char *);
ragge
1.218
188 char *argnxt(char *, char *);
ragge
1.220
189 char *nxtopt(char *o);
ragge
1.222
190 void setup_cpp_flags(void);
191 static void expand_sysroot(void);
plunky
1.213
192 #ifdef os_win32
ragge
1.128
193 char *win32pathsubst(char *);
gmcgarry
1.149
194 char *win32commandline(char *, char *[]);
ragge
1.128
195 #endif
196 char    *av[MAXAV];
197 char    *llist[MAXLIB];
198 char    *aslist[MAXAV];
199 char    *xlist[100];
200 int     xnum;
201 char    *mlist[100];
202 char    *flist[100];
203 char    *wlist[100];
204 int     nm;
205 int     nf;
206 int     nw;
207 int     sspflag;
plunky
1.214
208 int     freestanding;
ragge
1.128
209 int     pflag;
210 int     sflag;
211 int     cflag;
212 int     eflag;
213 int     gflag;
gmcgarry
1.145
214 int     rflag;
ragge
1.128
215 int     vflag;
216 int     tflag;
217 int     Eflag;
218 int     Oflag;
219 int     kflag;  /* generate PIC/pic code */
220 #define F_PIC   1
221 #define F_pic   2
ragge
1.223
222 int     MflagneedM;   /* dependencies only */
ragge
1.128
223 int     pgflag;
224 int     exfail;
225 int     Xflag;
226 int     Wallflag;
227 int     Wflag;
228 int     nostartfilesBstaticshared;
229 int     nostdincnostdlib;
230 int     onlyas;
231 int     pthreads;
plunky
1.217
232 int     xasmxcflagxgnu89xgnu99;
ragge
1.128
233 int     ascpp;
plunky
1.196
234 #ifdef CHAR_UNSIGNED
plunky
1.209
235 int     xuchar = 1;
plunky
1.196
236 #else
plunky
1.209
237 int     xuchar = 0;
plunky
1.196
238 #endif
ragge
1.198
239 int     cxxflag;
ragge
1.216
240 int     cppflag;
ragge
1.128
241
242 char    *passp = LIBEXECDIR PREPROCESSOR;
243 char    *pass0 = LIBEXECDIR COMPILER;
ragge
1.212
244 char    *passxx0 = LIBEXECDIR "cxxcom";
ragge
1.128
245 char    *as = ASSEMBLER;
246 char    *ld = LINKER;
ragge
1.222
247 char    *sysroot = "", *isysroot;
ragge
1.128
248 char *cppadd[] = CPPADD;
249 #ifdef DYNLINKER
250 char *dynlinker[] = DYNLINKER;
251 #endif
252 #ifdef CRT0FILE
253 char *crt0file = CRT0FILE;
254 #endif
255 #ifdef CRT0FILE_PROFILE
256 char *crt0file_profile = CRT0FILE_PROFILE;
257 #endif
258 #ifdef STARTFILES
259 char *startfiles[] = STARTFILES;
260 char *endfiles[] = ENDFILES;
261 #endif
262 #ifdef STARTFILES_T
263 char *startfiles_T[] = STARTFILES_T;
264 char *endfiles_T[] = ENDFILES_T;
265 #endif
266 #ifdef STARTFILES_S
267 char *startfiles_S[] = STARTFILES_S;
268 char *endfiles_S[] = ENDFILES_S;
269 #endif
270 char *cppmdadd[] = CPPMDADD;
271 #ifdef LIBCLIBS
272 char *libclibs[] = LIBCLIBS;
273 #else
274 char *libclibs[] = { "-lc"NULL };
275 #endif
276 #ifdef LIBCLIBS_PROFILE
277 char *libclibs_profile[] = LIBCLIBS_PROFILE;
278 #else
279 char *libclibs_profile[] = { "-lc_p"NULL };
280 #endif
281 #ifndef STARTLABEL
282 #define STARTLABEL "__start"
283 #endif
plunky
1.200
284 #ifdef PCCLIBDIR
ragge
1.128
285 char *pcclibdir = PCCLIBDIR;
plunky
1.200
286 #endif
ragge
1.164
287 #ifdef mach_amd64
288 int amd64_i386;
289 #endif
ragge
1.128
290
ragge
1.218
291 #define match(a,b)      (strcmp(a,b) == 0)
292
ragge
1.128
293 /* handle gcc warning emulations */
294 struct Wflags {
295         char *name;
296         int flags;
297 #define INWALL          1
298 Wflags[] = {
plunky
1.215
299         { "truncate"0 },
300         { "strict-prototypes"0 },
301         { "missing-prototypes"0 },
302         { "implicit-int"INWALL },
303         { "implicit-function-declaration"INWALL },
304         { "shadow"0 },
305         { "pointer-sign"INWALL },
306         { "sign-compare"0 },
307         { "unknown-pragmas"INWALL },
308         { "unreachable-code"0 },
309         { NULL0 },
ragge
1.128
310 };
311
ragge
1.158
312 #ifndef USHORT
313 /* copied from mip/manifest.h */
314 #define USHORT          5
315 #define INT             6
316 #define UNSIGNED        7
317 #endif
318
ragge
1.157
319 /*
320  * Wide char defines.
321  */
322 #if WCHAR_TYPE == USHORT
323 #define WCT "short unsigned int"
324 #define WCM "65535U"
ragge
1.158
325 #if WCHAR_SIZE != 2
326 #error WCHAR_TYPE vs. WCHAR_SIZE mismatch
327 #endif
ragge
1.157
328 #elif WCHAR_TYPE == INT
329 #define WCT "int"
330 #define WCM "2147483647"
ragge
1.158
331 #if WCHAR_SIZE != 4
332 #error WCHAR_TYPE vs. WCHAR_SIZE mismatch
333 #endif
ragge
1.157
334 #elif WCHAR_TYPE == UNSIGNED
335 #define WCT "unsigned int"
ragge
1.158
336 #define WCM "4294967295U"
337 #if WCHAR_SIZE != 4
338 #error WCHAR_TYPE vs. WCHAR_SIZE mismatch
339 #endif
340 #else
341 #error WCHAR_TYPE not defined or invalid
ragge
1.157
342 #endif
343
ragge
1.160
344 #ifdef GCC_COMPAT
345 #ifndef REGISTER_PREFIX
346 #define REGISTER_PREFIX ""
347 #endif
348 #ifndef USER_LABEL_PREFIX
349 #define USER_LABEL_PREFIX ""
350 #endif
351 #endif
352
plunky
1.192
353 #ifndef PCC_WINT_TYPE
354 #define PCC_WINT_TYPE "unsigned int"
355 #endif
356
357 #ifndef PCC_SIZE_TYPE
358 #define PCC_SIZE_TYPE "unsigned long"
359 #endif
360
ragge
1.161
361 #ifndef PCC_PTRDIFF_TYPE
362 #define PCC_PTRDIFF_TYPE "long int"
363 #endif
364
ragge
1.216
365 #ifndef CPPROGNAME
366 #define CPPROGNAME      "cpp"
367 #endif
368
ragge
1.218
369 struct strlist preprocessor_flags;
ragge
1.223
370 struct strlist depflags;
ragge
1.219
371 struct strlist incdirs;
ragge
1.221
372 struct strlist user_sysincdirs;
373 struct strlist includes;
ragge
1.222
374 struct strlist sysincdirs;
ragge
1.223
375 struct strlist dirafterdirs;
ragge
1.222
376 struct strlist crtdirs;
377 struct strlist libdirs;
378 struct strlist progdirs;
ragge
1.224
379 struct strlist early_linker_flags;
380 struct strlist middle_linker_flags;
381 struct strlist late_linker_flags;
382 struct strlist inputs;
ragge
1.218
383
ragge
1.128
384 int
385 main(int argcchar *argv[])
386 {
ragge
1.224
387         struct string *s, *ss;
ragge
1.128
388         struct Wflags *Wf;
ragge
1.218
389         char *t, *u, *argp;
ragge
1.128
390         char *assource;
ragge
1.224
391         int ninputnlnasijcnxona;
ragge
1.222
392
ragge
1.220
393         lav = argv;
394         lac = argc;
ragge
1.128
395
ragge
1.222
396         strlist_init(&crtdirs);
397         strlist_init(&libdirs);
398         strlist_init(&progdirs);
ragge
1.218
399         strlist_init(&preprocessor_flags);
ragge
1.219
400         strlist_init(&incdirs);
ragge
1.221
401         strlist_init(&user_sysincdirs);
402         strlist_init(&includes);
ragge
1.222
403         strlist_init(&sysincdirs);
ragge
1.223
404         strlist_init(&dirafterdirs);
405         strlist_init(&depflags);
ragge
1.224
406         strlist_init(&early_linker_flags);
407         strlist_init(&middle_linker_flags);
408         strlist_init(&late_linker_flags);
409         strlist_init(&inputs);
ragge
1.218
410
ragge
1.216
411         if ((t = strrchr(argv[0], '/')))
412                 t = copy(t+10);
413         else
414                 t = argv[0];
415         if (strcmp(t"p++") == 0) {
ragge
1.198
416                 cxxflag = 1;
417                 pass0 = passxx0;
ragge
1.216
418         } else if (strcmp(t"cpp") == 0 || strcmp(tCPPROGNAME) == 0) {
419                 cppflag = 1;
420                 Eflag = 1;
ragge
1.198
421         }
422
plunky
1.213
423 #ifdef os_win32
ragge
1.128
424         /* have to prefix path early.  -B may override */
425         incdir = win32pathsubst(incdir);
gmcgarry
1.153
426         altincdir = win32pathsubst(altincdir);
gmcgarry
1.136
427         libdir = win32pathsubst(libdir);
plunky
1.200
428 #ifdef PCCINCDIR
ragge
1.128
429         pccincdir = win32pathsubst(pccincdir);
plunky
1.199
430         pxxincdir = win32pathsubst(pxxincdir);
plunky
1.200
431 #endif
432 #ifdef PCCLIBDIR
ragge
1.128
433         pcclibdir = win32pathsubst(pcclibdir);
plunky
1.200
434 #endif
ragge
1.128
435         passp = win32pathsubst(passp);
436         pass0 = win32pathsubst(pass0);
gmcgarry
1.180
437 #ifdef STARTFILES
438         for (i = 0startfiles[i] != NULLi++)
439                 startfiles[i] = win32pathsubst(startfiles[i]);
440         for (i = 0endfiles[i] != NULLi++)
441                 endfiles[i] = win32pathsubst(endfiles[i]);
442 #endif
443 #ifdef STARTFILES_T
444         for (i = 0startfiles_T[i] != NULLi++)
445                 startfiles_T[i] = win32pathsubst(startfiles_T[i]);
446         for (i = 0endfiles_T[i] != NULLi++)
447                 endfiles_T[i] = win32pathsubst(endfiles_T[i]);
448 #endif
449 #ifdef STARTFILES_S
450         for (i = 0startfiles_S[i] != NULLi++)
451                 startfiles_S[i] = win32pathsubst(startfiles_S[i]);
452         for (i = 0endfiles_S[i] != NULLi++)
453                 endfiles_S[i] = win32pathsubst(endfiles_S[i]);
454 #endif
ragge
1.128
455 #endif
456
ragge
1.224
457         nl = nas = nxo = 0;
ragge
1.220
458         while (--lac) {
459                 ++lav;
460                 argp = *lav;
461
462                 if (*argp != '-' || match(argp"-"))
463                         goto passa;
464
465                 switch (argp[1]) {
466                 default:
ragge
1.224
467                         owarning(argp);
ragge
1.220
468                         break;
ragge
1.128
469
ragge
1.220
470                 case '-'/* double -'s */
471                         if (match(argp"--version")) {
472                                 printf("%s\n"VERSSTR);
473                                 return 0;
474                         } else if (strncmp(argp"--sysroot="10) == 0) {
475                                 sysroot = argp + 10;
476                         } else if (strcmp(argp"--param") == 0) {
477                                 /* NOTHING YET */;
478                                 (void)nxtopt(0); /* ignore arg */
479                         } else
480                                 goto passa;
481                         break;
ragge
1.128
482
ragge
1.220
483                 case 'B'/* other search paths for binaries */
ragge
1.224
484                         t = nxtopt("-B");
485                         strlist_append(&crtdirst);
486                         strlist_append(&libdirst);
487                         strlist_append(&progdirst);
488                         add_prefix(t);
ragge
1.220
489                         break;
ragge
1.128
490
ragge
1.220
491                 case 'C':
492                         if (match(argp"-C") || match(argp"-CC"))
493                                 strlist_append(&preprocessor_flagsargp);
494                         else
495                                 oerror(argp);
496                         break;
ragge
1.218
497
ragge
1.220
498                 case 'X':
499                         Xflag++;
500                         break;
501                 case 'W'/* Ignore (most of) W-flags */
502                         if (strncmp(argp"-Wl,"4) == 0) {
503                                 /* options to the linker */
504                                 t = &argp[4];
505                                 while ((u = strchr(t','))) {
506                                         *u++ = 0;
ragge
1.128
507                                         llist[nl++] = t;
ragge
1.220
508                                         t = u;
509                                 }
510                                 llist[nl++] = t;
511                         } else if (strncmp(argp"-Wa,"4) == 0) {
512                                 /* options to the assembler */
513                                 t = &argp[4];
514                                 while ((u = strchr(t','))) {
515                                         *u++ = 0;
ragge
1.128
516                                         aslist[nas++] = t;
ragge
1.220
517                                         t = u;
518                                 }
519                                 aslist[nas++] = t;
520                         } else if (strncmp(argp"-Wc,"4) == 0) {
521                                 /* options to ccom */
522                                 t = &argp[4];
523                                 while ((u = strchr(t','))) {
524                                         *u++ = 0;
ragge
1.137
525                                         wlist[nw++] = t;
ragge
1.220
526                                         t = u;
527                                 }
528                                 wlist[nw++] = t;
529                         } else if ((t = argnxt(argp"-Wp,"))) {
530                                 u = strtok(t",");
531                                 do {
532                                         strlist_append(&preprocessor_flagsu);
533                                 } while ((u = strtok(NULL",")) != NULL);
534                         } else if (strcmp(argp"-Werror") == 0) {
535                                 wlist[nw++] = argp;
536                         } else if (strcmp(argp"-Wall") == 0) {
537                                 Wallflag = 1;
538                         } else if (strcmp(argp"-WW") == 0) {
539                                 Wflag = 1;
540                         } else {
541                                 /* pass through, if supported */
542                                 t = &argp[2];
543                                 if (strncmp(t"no-"3) == 0)
544                                         t += 3;
545                                 if (strncmp(t"error="6) == 0)
546                                         t += 6;
547                                 for (Wf = WflagsWf->nameWf++) {
548                                         if (strcmp(tWf->name) == 0)
549                                                 wlist[nw++] = argp;
ragge
1.128
550                                 }
ragge
1.220
551                         }
552                         break;
ragge
1.128
553
ragge
1.220
554                 case 'f'/* GCC compatibility flags */
555                         if (strcmp(argp"-fPIC") == 0)
556                                 kflag = F_PIC;
557                         else if (strcmp(argp"-fpic") == 0)
558                                 kflag = F_pic;
559                         else if (strcmp(argp"-ffreestanding") == 0)
560                                 freestanding = 1;
ragge
1.221
561                         else if (match(argp"-fsigned-char") ||
562                             match(argp"-fno-unsigned-char"))
ragge
1.220
563                                 xuchar = 0;
ragge
1.221
564                         else if (match(argp"-fno-signed-char") ||
565                             match(argp"-funsigned-char"))
ragge
1.220
566                                 xuchar = 1;
ragge
1.221
567                         else if (strcmp(argp"-fstack-protector") == 0) {
ragge
1.220
568                                 flist[nf++] = argp;
569                                 sspflag++;
ragge
1.221
570                         } else if (strcmp(argp"-fstack-protector-all") == 0) {
ragge
1.220
571                                 flist[nf++] = argp;
572                                 sspflag++;
ragge
1.221
573                         } else if (strcmp(argp"-fno-stack-protector") == 0) {
ragge
1.220
574                                 flist[nf++] = argp;
575                                 sspflag = 0;
ragge
1.221
576                         } else if (strcmp(argp"-fno-stack-protector-all") == 0) {
ragge
1.220
577                                 flist[nf++] = argp;
578                                 sspflag = 0;
579                         }
580                         /* silently ignore the rest */
581                         break;
ragge
1.128
582
ragge
1.220
583                 case 'g'/* create debug output */
584                         if (argp[2] == '0')
585                                 gflag = 0;
586                         else
587                                 gflag++;
588                         break;
ragge
1.128
589
ragge
1.220
590                 case 'D':
591                 case 'U':
ragge
1.221
592                         strlist_append(&preprocessor_flagsargp);
ragge
1.220
593                         if (argp[2] != 0)
ragge
1.219
594                                 break;
ragge
1.221
595                         strlist_append(&preprocessor_flagsnxtopt(argp));
596                         break;
597
598                 case 'I'/* Add include dirs */
599                         strlist_append(&incdirsnxtopt("-I"));
ragge
1.220
600                         break;
ragge
1.219
601
ragge
1.220
602                 case 'i':
ragge
1.221
603                         if (match(argp"-isystem")) {
604                                 strlist_append(&user_sysincdirsnxtopt(0));
605                         } else if (match(argp"-include")) {
606                                 strlist_append(&includesnxtopt(0));
ragge
1.222
607                         } else if (match(argp"-isysroot")) {
608                                 isysroot = nxtopt(0);
ragge
1.220
609                         } else if (strcmp(argp"-idirafter") == 0) {
ragge
1.223
610                                 strlist_append(&dirafterdirsnxtopt(0));
gmcgarry
1.172
611 #ifdef os_darwin
ragge
1.220
612                         } else if (strcmp(argp"-install_name") == 0) {
613                                 llist[nl++] = argp;
614                                 llist[nl++] = nxtopt("-install_name");
gmcgarry
1.172
615 #endif
ragge
1.220
616                         } else
617                                 goto passa;
618                         break;
ragge
1.128
619
ragge
1.220
620                 case 'k'/* generate PIC code */
621                         kflag = F_pic;
622                         break;
ragge
1.128
623
ragge
1.224
624                 case 'l':
625                 case 'L':
626                         strlist_append(&late_linker_flagsargp);
627                         break;
628
629
ragge
1.220
630                 case 'm'/* target-dependent options */
ragge
1.164
631 #ifdef mach_amd64
ragge
1.220
632                         /* need to call i386 ccom for this */
633                         if (strcmp(argp"-m32") == 0) {
634                                 pass0 = LIBEXECDIR "/ccom_i386";
635                                 amd64_i386 = 1;
636                                 break;
637                         }
ragge
1.164
638 #endif
ragge
1.220
639                         mlist[nm++] = argp;
640                         if (argp[2] == 0) {
641                                 /* separate second arg */
642                                 /* give also to linker */
643                                 llist[nl++] = argp;
644                                 lav++, lac--;
645                                 mlist[nm++] = lav[0];
646                                 llist[nl++] = lav[0];
647                         }
648                         break;
ragge
1.128
649
ragge
1.220
650                 case 'n'/* handle -n flags */
651                         if (strcmp(argp"-nostdinc") == 0)
652                                 nostdinc++;
653                         else if (strcmp(argp"-nostdlib") == 0) {
654                                 nostdlib++;
655                                 nostartfiles++;
656                         } else if (strcmp(argp"-nostartfiles") == 0)
657                                 nostartfiles = 1;
658                         else if (strcmp(argp"-nodefaultlibs") == 0)
659                                 nostdlib++;
660                         else
661                                 goto passa;
662                         break;
ragge
1.128
663
ragge
1.220
664                 case 'p':
665                         if (strcmp(argp"-pg") == 0 ||
666                             strcmp(argp"-p") == 0)
667                                 pgflag++;
668                         else if (strcmp(argp"-pthread") == 0)
669                                 pthreads++;
670                         else if (strcmp(argp"-pipe") == 0)
671                                 /* NOTHING YET */;
672                         else if (strcmp(argp"-pedantic") == 0)
673                                 /* NOTHING YET */;
674                         else if (strcmp(argp,
675                             "-print-prog-name=ld") == 0) {
676                                 printf("%s\n"LINKER);
677                                 return 0;
678                         } else if (strcmp(argp,
679                             "-print-multi-os-directory") == 0) {
680                                 printf("%s\n"MULTIOSDIR);
681                                 return 0;
682                         } else
683                                 oerror(argp);
684                         break;
ragge
1.128
685
ragge
1.220
686                 case 'r':
687                         rflag = 1;
688                         break;
gmcgarry
1.145
689
ragge
1.220
690                 case 'x':
691                         t = nxtopt("-x");
692                         if (match(t"c"))
693                                 xcflag = 1/* default */
694                         else if (match(t"assembler"))
695                                 xasm = 1;
696                         else if (match(t"assembler-with-cpp"))
697                                 ascpp = 1;
698                         else if (match(t"c++"))
699                                 cxxflag++;
700                         else if (argp[2])
701                                 xlist[xnum++] = argp;
702                         else
703                                 xlist[xnum++] = "-x"xlist[xnum++] = t;
704                         break;
705                 case 't':
706                         tflag++;
707                         break;
708                 case 'S':
709                         sflag++;
710                         cflag++;
711                         break;
712                 case 'o':
713                         if (outfile)
714                                 errorx(8"too many -o");
715                         outfile = nxtopt("-o");
716                         break;
717                 case 'O':
718                         if (argp[2] == '\0')
719                                 Oflag++;
720                         else if (argp[3] == '\0' && isdigit((unsigned char)argp[2]))
721                                 Oflag = argp[2] - '0';
722                         else if (argp[3] == '\0' && argp[2] == 's')
723                                 Oflag = 1;      /* optimize for space only */
724                         else
725                                 oerror(argp);
726                         break;
727                 case 'E':
728                         Eflag++;
729                         break;
730                 case 'P':
731                         pflag++;
ragge
1.221
732                         strlist_append(&preprocessor_flagsargp);
733                         break;
734
ragge
1.220
735                 case 'c':
gmcgarry
1.172
736 #ifdef os_darwin
ragge
1.220
737                         if (strcmp(argp"-compatibility_version") == 0) {
738                                 llist[nl++] = argp;
739                                 llist[nl++] = nxtopt(0);
740                         } else if (strcmp(argp"-current_version") == 0) {
741                                 llist[nl++] = argp;
742                                 llist[nl++] = nxtopt(0);
743                         } else
gmcgarry
1.172
744 #endif
ragge
1.220
745                                 cflag++;
746                         break;
ragge
1.223
747
ragge
1.220
748                 case 'M':
749                         switch (argp[2]) {
ragge
1.223
750                         case '\0':
751                                 Mflag++;
752                                 strlist_append(&depflagsargp);
753                                 break;
754                         case 'P':
755                                 needM = 1;
756                                 strlist_append(&depflags"-xMP");
757                                 break;
758                         case 'F':
759                                 needM = 1;
760                                 outfile = nxtopt("-MF");
761                                 break;
ragge
1.220
762                         case 'T':
763                         case 'Q':
ragge
1.223
764                                 needM = 1;
765                                 j = strlen(u = nxtopt("-MT"));
766                                 t = copy("-xMT,"j);
ragge
1.220
767                                 strlcat(tuj+6);
768                                 t[3] = argp[2];
ragge
1.223
769                                 strlist_append(&depflagst);
ragge
1.128
770                                 break;
ragge
1.220
771                         default:
772                                 oerror(argp);
773                         }
774                         break;
ragge
1.128
775
ragge
1.220
776                 case 'd':
gmcgarry
1.144
777 #ifdef os_darwin
ragge
1.220
778                         if (strcmp(argp"-dynamiclib") == 0) {
779                                 shared = 1;
780                         } else
gmcgarry
1.144
781 #endif
ragge
1.220
782                         break;
783                 case 'v':
784                         printf("%s\n"VERSSTR);
785                         vflag++;
786                         break;
ragge
1.128
787
ragge
1.220
788                 case 's':
gmcgarry
1.144
789 #ifndef os_darwin
ragge
1.220
790                         if (strcmp(argp"-shared") == 0) {
791                                 shared = 1;
792                         } else
793 #endif
794                         if (strcmp(argp"-static") == 0) {
795                                 Bstatic = 1;
796                         } else if (strcmp(argp"-symbolic") == 0) {
797                                 llist[nl++] = "-Bsymbolic";
798                         } else if (strncmp(argp"-std"4) == 0) {
799                                 if (strcmp(&argp[5], "gnu99") == 0 ||
800                                     strcmp(&argp[5], "gnu9x") == 0)
801                                         xgnu99 = 1;
802                                 if (strcmp(&argp[5], "gnu89") == 0)
803                                         xgnu89 = 1;
804                         } else
805                                 goto passa;
806                         break;
807                 }
808                 continue;
809
810         passa:
811                 t = argp;
ragge
1.224
812                 if ((cxxsuf(getsufp(t)) && cxxflag) ||
ragge
1.220
813                     (c=getsuf(t))=='c' || c=='S' || c=='i' ||
814                     c=='s'|| Eflag || xcflag || xasm) {
ragge
1.224
815                         strlist_append(&inputst);
ragge
1.220
816                 }
ragge
1.128
817
ragge
1.220
818                 /* Check for duplicate .o files. */
819                 for (j = getsuf(t) == 'o' ? 0 : nlj < nlj++) {
820                         if (strcmp(llist[j], t) == 0)
821                                 break;
822                 }
823                 if ((c=getsuf(t))!='c' && c!='S' &&
824                     c!='s' && c!='i' && j==nl &&
825                     !(cxxsuf(getsufp(t)) && cxxflag) && !xasm) {
826                         llist[nl++] = t;
827                         if (nl >= MAXLIB) {
828                                 error("Too many object/library files");
829                                 exit(1);
ragge
1.128
830                         }
ragge
1.220
831                         if (getsuf(t)=='o')
832                                 nxo++;
ragge
1.128
833                 }
834         }
ragge
1.222
835
ragge
1.128
836         /* Sanity checking */
ragge
1.224
837         ninput = 0;
838         STRLIST_FOREACH(s, &inputs)
839                 ninput++;
ragge
1.216
840         if (cppflag) {
ragge
1.224
841                 if (ninput == 0) {
842                         strlist_append(&inputs"-");
843                 } else if (ninput > 2 || (ninput == 2 && outfile)) {
ragge
1.216
844                         errorx(8"too many files");
ragge
1.224
845 #if 0
846                 } else if (ninput == 2) {
ragge
1.216
847                         outfile = clist[--nc];
ragge
1.224
848 #endif
849                 }
ragge
1.216
850         }
ragge
1.224
851         if (ninput == 0 && nl == 0)
ragge
1.128
852                 errorx(8"no input files");
ragge
1.224
853         if (outfile && (cflag || sflag || Eflag) && ninput > 1)
ragge
1.128
854                 errorx(8"-o given with -c || -E || -S and more than one file");
ragge
1.224
855 #if 0
ragge
1.128
856         if (outfile && clist[0] && strcmp(outfileclist[0]) == 0)
857                 errorx(8"output file will be clobbered");
ragge
1.224
858 #endif
ragge
1.223
859
860         if (needM && !Mflag)
861                 errorx(8"to make dependencies needs -M");
862
863
ragge
1.224
864         if (ninput == 0)
ragge
1.128
865                 goto nocom;
866         if (pflag==0) {
867                 if (!sflag)
868                         tmp3 = gettmp();
869                 tmp4 = gettmp();
870         }
871         if (signal(SIGINTSIG_IGN) != SIG_IGN/* interrupt */
872                 signal(SIGINTidexit);
873         if (signal(SIGTERMSIG_IGN) != SIG_IGN)        /* terminate */
874                 signal(SIGTERMidexit);
ragge
1.222
875
ragge
1.223
876         setup_cpp_flags();
877
878         if (isysroot == NULL)
879                 isysroot = sysroot;
880         expand_sysroot();
881
ragge
1.224
882         STRLIST_FOREACH(ss, &inputs) {
ragge
1.128
883                 /*
884                  * C preprocessor
885                  */
ragge
1.224
886                 if (ninput > 1 && !Eflag)
887                         printf("%s:\n"ss->value);
ragge
1.128
888                 onlyas = 0;
889                 assource = tmp3;
ragge
1.224
890                 if (getsuf(ss->value)=='S')
ragge
1.128
891                         ascpp = 1;
ragge
1.224
892                 if (getsuf(ss->value)=='i') {
ragge
1.128
893                         if(Eflag)
894                                 continue;
895                         goto com;
896                 } else if (ascpp) {
897                         onlyas = 1;
ragge
1.224
898                 } else if (xasm || getsuf(ss->value)=='s') {
899                         assource = ss->value;
ragge
1.128
900                         goto assemble;
901                 }
ragge
1.222
902
903
ragge
1.128
904                 if (pflag)
ragge
1.224
905                         tmp4 = setsuf(s->value'i');
ragge
1.128
906                 na = 0;
907                 av[na++] = "cpp";
ragge
1.222
908
ragge
1.223
909                 STRLIST_FOREACH(s, &depflags) {
910                         av[na++] = s->value;
911                 }
ragge
1.218
912                 STRLIST_FOREACH(s, &preprocessor_flags) {
913                         av[na++] = s->value;
914                 }
ragge
1.221
915                 STRLIST_FOREACH(s, &includes) {
916                         av[na++] = "-i";
917                         av[na++] = s->value;
918                 }
ragge
1.219
919                 STRLIST_FOREACH(s, &incdirs) {
ragge
1.221
920                         av[na++] = "-I";
921                         av[na++] = s->value;
922                 }
923                 STRLIST_FOREACH(s, &user_sysincdirs) {
924                         av[na++] = "-S";
ragge
1.219
925                         av[na++] = s->value;
926                 }
gmcgarry
1.153
927                 if (!nostdinc) {
ragge
1.222
928                         STRLIST_FOREACH(s, &sysincdirs) {
929                                 av[na++] = "-S";
930                                 av[na++] = s->value;
931                         }
gmcgarry
1.153
932                 }
ragge
1.223
933                 STRLIST_FOREACH(s, &dirafterdirs) {
934                         av[na++] = "-S";
935                         av[na++] = s->value;
936                 }
ragge
1.222
937
ragge
1.224
938                 av[na++] = ss->value;
ragge
1.128
939                 if (!Eflag && !Mflag)
940                         av[na++] = tmp4;
ragge
1.141
941                 if ((Eflag || Mflag) && outfile)
ragge
1.128
942                          ermfile = av[na++] = outfile;
943                 av[na++]=0;
gmcgarry
1.140
944                 if (callsys(passpav)) {
945                         exfail++;
946                         eflag++;
947                 }
ragge
1.128
948                 if (Eflag || Mflag)
949                         continue;
950                 if (onlyas) {
951                         assource = tmp4;
952                         goto assemble;
953                 }
954
955                 /*
956                  * C compiler
957                  */
958         com:
959