Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20120802180751

Diff

Diff from 1.222 to:

Annotations

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

Annotated File View

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