Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20120803082710

Diff

Diff from 1.223 to:

Annotations

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

Annotated File View

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