Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20121026110439

Diff

Diff from 1.260 to:

Annotations

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

Annotated File View

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