Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20120802100909

Diff

Diff from 1.218 to:

Annotations

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

Annotated File View

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