Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20120802132736

Diff

Diff from 1.220 to:

Annotations

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

Annotated File View

ragge
1.220
1 /*      $Id: cc.c,v 1.220 2012/08/02 13:27:36 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.220
135 static char **lav;
136 static int lac;
ragge
1.175
137 static void add_prefix(const char *);
138 static char *find_file(const char *, int);
plunky
1.183
139 char *copy(const char *, int);
plunky
1.185
140 char *cat(const char *, const char *);
gmcgarry
1.150
141 char *setsuf(char *, char);
ragge
1.198
142 int cxxsuf(char *);
ragge
1.128
143 int getsuf(char *);
ragge
1.198
144 char *getsufp(char *s);
ragge
1.128
145 int main(intchar *[]);
146 void error(char *, ...);
147 void errorx(intchar *, ...);
148 int callsys(char [], char *[]);
149 int cunlink(char *);
150 void dexit(int);
151 void idexit(int);
152 char *gettmp(void);
153 void *ccmalloc(int size);
ragge
1.218
154 void aerror(char *);
ragge
1.219
155 void oerror(char *);
ragge
1.218
156 char *argnxt(char *, char *);
ragge
1.220
157 char *nxtopt(char *o);
plunky
1.213
158 #ifdef os_win32
ragge
1.128
159 char *win32pathsubst(char *);
gmcgarry
1.149
160 char *win32commandline(char *, char *[]);
ragge
1.128
161 #endif
162 char    *av[MAXAV];
163 char    *clist[MAXFIL];
gmcgarry
1.150
164 char    *olist[MAXFIL];
ragge
1.128
165 char    *llist[MAXLIB];
166 char    *aslist[MAXAV];
167 char    *xlist[100];
168 int     xnum;
169 char    *mlist[100];
170 char    *flist[100];
171 char    *wlist[100];
172 char    *idirafter;
173 int     nm;
174 int     nf;
175 int     nw;
176 int     sspflag;
plunky
1.214
177 int     freestanding;
ragge
1.128
178 int     pflag;
179 int     sflag;
180 int     cflag;
181 int     eflag;
182 int     gflag;
gmcgarry
1.145
183 int     rflag;
ragge
1.128
184 int     vflag;
185 int     tflag;
186 int     Eflag;
187 int     Oflag;
188 int     kflag;  /* generate PIC/pic code */
189 #define F_PIC   1
190 #define F_pic   2
ragge
1.216
191 int     MflagMPflagnMfiles/* dependencies only */
192 char    *Mfiles[10];
ragge
1.128
193 int     pgflag;
194 int     exfail;
195 int     Xflag;
196 int     Wallflag;
197 int     Wflag;
198 int     nostartfilesBstaticshared;
199 int     nostdincnostdlib;
200 int     onlyas;
201 int     pthreads;
plunky
1.217
202 int     xasmxcflagxgnu89xgnu99;
ragge
1.128
203 int     ascpp;
plunky
1.196
204 #ifdef CHAR_UNSIGNED
plunky
1.209
205 int     xuchar = 1;
plunky
1.196
206 #else
plunky
1.209
207 int     xuchar = 0;
plunky
1.196
208 #endif
ragge
1.198
209 int     cxxflag;
ragge
1.216
210 int     cppflag;
ragge
1.128
211
212 char    *passp = LIBEXECDIR PREPROCESSOR;
213 char    *pass0 = LIBEXECDIR COMPILER;
ragge
1.212
214 char    *passxx0 = LIBEXECDIR "cxxcom";
ragge
1.128
215 char    *as = ASSEMBLER;
216 char    *ld = LINKER;
ragge
1.175
217 char    *sysroot;
ragge
1.128
218 char *cppadd[] = CPPADD;
219 #ifdef DYNLINKER
220 char *dynlinker[] = DYNLINKER;
221 #endif
222 #ifdef CRT0FILE
223 char *crt0file = CRT0FILE;
224 #endif
225 #ifdef CRT0FILE_PROFILE
226 char *crt0file_profile = CRT0FILE_PROFILE;
227 #endif
228 #ifdef STARTFILES
229 char *startfiles[] = STARTFILES;
230 char *endfiles[] = ENDFILES;
231 #endif
232 #ifdef STARTFILES_T
233 char *startfiles_T[] = STARTFILES_T;
234 char *endfiles_T[] = ENDFILES_T;
235 #endif
236 #ifdef STARTFILES_S
237 char *startfiles_S[] = STARTFILES_S;
238 char *endfiles_S[] = ENDFILES_S;
239 #endif
240 #ifdef MULTITARGET
241 char *mach = DEFMACH;
242 struct cppmd {
243         char *mach;
244         char *cppmdadd[MAXCPPMDARGS];
245 };
246
247 struct cppmd cppmds[] = CPPMDADDS;
248 #else
249 char *cppmdadd[] = CPPMDADD;
250 #endif
251 #ifdef LIBCLIBS
252 char *libclibs[] = LIBCLIBS;
253 #else
254 char *libclibs[] = { "-lc"NULL };
255 #endif
256 #ifdef LIBCLIBS_PROFILE
257 char *libclibs_profile[] = LIBCLIBS_PROFILE;
258 #else
259 char *libclibs_profile[] = { "-lc_p"NULL };
260 #endif
261 #ifndef STARTLABEL
262 #define STARTLABEL "__start"
263 #endif
264 char *incdir = STDINC;
gmcgarry
1.153
265 char *altincdir = INCLUDEDIR "pcc/";
gmcgarry
1.136
266 char *libdir = LIBDIR;
plunky
1.200
267 #ifdef PCCINCDIR
ragge
1.128
268 char *pccincdir = PCCINCDIR;
ragge
1.198
269 char *pxxincdir = PCCINCDIR "/c++";
plunky
1.200
270 #endif
271 #ifdef PCCLIBDIR
ragge
1.128
272 char *pcclibdir = PCCLIBDIR;
plunky
1.200
273 #endif
ragge
1.164
274 #ifdef mach_amd64
275 int amd64_i386;
276 #endif
ragge
1.128
277
ragge
1.218
278 #define match(a,b)      (strcmp(a,b) == 0)
279
ragge
1.128
280 /* handle gcc warning emulations */
281 struct Wflags {
282         char *name;
283         int flags;
284 #define INWALL          1
285 Wflags[] = {
plunky
1.215
286         { "truncate"0 },
287         { "strict-prototypes"0 },
288         { "missing-prototypes"0 },
289         { "implicit-int"INWALL },
290         { "implicit-function-declaration"INWALL },
291         { "shadow"0 },
292         { "pointer-sign"INWALL },
293         { "sign-compare"0 },
294         { "unknown-pragmas"INWALL },
295         { "unreachable-code"0 },
296         { NULL0 },
ragge
1.128
297 };
298
ragge
1.158
299 #ifndef USHORT
300 /* copied from mip/manifest.h */
301 #define USHORT          5
302 #define INT             6
303 #define UNSIGNED        7
304 #endif
305
ragge
1.157
306 /*
307  * Wide char defines.
308  */
309 #if WCHAR_TYPE == USHORT
310 #define WCT "short unsigned int"
311 #define WCM "65535U"
ragge
1.158
312 #if WCHAR_SIZE != 2
313 #error WCHAR_TYPE vs. WCHAR_SIZE mismatch
314 #endif
ragge
1.157
315 #elif WCHAR_TYPE == INT
316 #define WCT "int"
317 #define WCM "2147483647"
ragge
1.158
318 #if WCHAR_SIZE != 4
319 #error WCHAR_TYPE vs. WCHAR_SIZE mismatch
320 #endif
ragge
1.157
321 #elif WCHAR_TYPE == UNSIGNED
322 #define WCT "unsigned int"
ragge
1.158
323 #define WCM "4294967295U"
324 #if WCHAR_SIZE != 4
325 #error WCHAR_TYPE vs. WCHAR_SIZE mismatch
326 #endif
327 #else
328 #error WCHAR_TYPE not defined or invalid
ragge
1.157
329 #endif
330
ragge
1.160
331 #ifdef GCC_COMPAT
332 #ifndef REGISTER_PREFIX
333 #define REGISTER_PREFIX ""
334 #endif
335 #ifndef USER_LABEL_PREFIX
336 #define USER_LABEL_PREFIX ""
337 #endif
338 #endif
339
plunky
1.192
340 #ifndef PCC_WINT_TYPE
341 #define PCC_WINT_TYPE "unsigned int"
342 #endif
343
344 #ifndef PCC_SIZE_TYPE
345 #define PCC_SIZE_TYPE "unsigned long"
346 #endif
347
ragge
1.161
348 #ifndef PCC_PTRDIFF_TYPE
349 #define PCC_PTRDIFF_TYPE "long int"
350 #endif
351
ragge
1.216
352 #ifndef CPPROGNAME
353 #define CPPROGNAME      "cpp"
354 #endif
355
ragge
1.218
356 struct strlist preprocessor_flags;
ragge
1.219
357 struct strlist incdirs;
ragge
1.218
358
ragge
1.128
359 int
360 main(int argcchar *argv[])
361 {
ragge
1.218
362         struct string *s;
ragge
1.219
363         struct strlist *sl;
ragge
1.128
364         struct Wflags *Wf;
ragge
1.218
365         char *t, *u, *argp;
ragge
1.128
366         char *assource;
367         char **pv, *ptemp[MAXOPT], **pvt;
gmcgarry
1.163
368         int ncnlnasncppijcnxona;
ragge
1.128
369 #ifdef MULTITARGET
370         int k;
371 #endif
ragge
1.220
372         lav = argv;
373         lac = argc;
ragge
1.128
374
ragge
1.218
375         strlist_init(&preprocessor_flags);
ragge
1.219
376         strlist_init(&incdirs);
ragge
1.218
377
ragge
1.216
378         if ((t = strrchr(argv[0], '/')))
379                 t = copy(t+10);
380         else
381                 t = argv[0];
382         if (strcmp(t"p++") == 0) {
ragge
1.198
383                 cxxflag = 1;
384                 pass0 = passxx0;
ragge
1.216
385         } else if (strcmp(t"cpp") == 0 || strcmp(tCPPROGNAME) == 0) {
386                 cppflag = 1;
387                 Eflag = 1;
ragge
1.198
388         }
389
plunky
1.213
390 #ifdef os_win32
ragge
1.128
391         /* have to prefix path early.  -B may override */
392         incdir = win32pathsubst(incdir);
gmcgarry
1.153
393         altincdir = win32pathsubst(altincdir);
gmcgarry
1.136
394         libdir = win32pathsubst(libdir);
plunky
1.200
395 #ifdef PCCINCDIR
ragge
1.128
396         pccincdir = win32pathsubst(pccincdir);
plunky
1.199
397         pxxincdir = win32pathsubst(pxxincdir);
plunky
1.200
398 #endif
399 #ifdef PCCLIBDIR
ragge
1.128
400         pcclibdir = win32pathsubst(pcclibdir);
plunky
1.200
401 #endif
ragge
1.128
402         passp = win32pathsubst(passp);
403         pass0 = win32pathsubst(pass0);
gmcgarry
1.180
404 #ifdef STARTFILES
405         for (i = 0startfiles[i] != NULLi++)
406                 startfiles[i] = win32pathsubst(startfiles[i]);
407         for (i = 0endfiles[i] != NULLi++)
408                 endfiles[i] = win32pathsubst(endfiles[i]);
409 #endif
410 #ifdef STARTFILES_T
411         for (i = 0startfiles_T[i] != NULLi++)
412                 startfiles_T[i] = win32pathsubst(startfiles_T[i]);
413         for (i = 0endfiles_T[i] != NULLi++)
414                 endfiles_T[i] = win32pathsubst(endfiles_T[i]);
415 #endif
416 #ifdef STARTFILES_S
417         for (i = 0startfiles_S[i] != NULLi++)
418                 startfiles_S[i] = win32pathsubst(startfiles_S[i]);
419         for (i = 0endfiles_S[i] != NULLi++)
420                 endfiles_S[i] = win32pathsubst(endfiles_S[i]);
421 #endif
ragge
1.128
422 #endif
423
ragge
1.220
424         nc = nl = nas = ncpp = nxo = 0;
ragge
1.128
425         pv = ptemp;
ragge
1.220
426         while (--lac) {
427                 ++lav;
428                 argp = *lav;
429
430                 if (*argp != '-' || match(argp"-"))
431                         goto passa;
432
433                 switch (argp[1]) {
434                 default:
435                         goto passa;
ragge
1.128
436 #ifdef notyet
437         /* must add library options first (-L/-l/...) */
ragge
1.220
438                         oerror(argp);
439                         break;
ragge
1.128
440 #endif
441
ragge
1.220
442                 case '-'/* double -'s */
443                         if (match(argp"--version")) {
444                                 printf("%s\n"VERSSTR);
445                                 return 0;
446                         } else if (strncmp(argp"--sysroot="10) == 0) {
447                                 sysroot = argp + 10;
448                         } else if (strcmp(argp"--param") == 0) {
449                                 /* NOTHING YET */;
450                                 (void)nxtopt(0); /* ignore arg */
451                         } else
452                                 goto passa;
453                         break;
ragge
1.128
454
ragge
1.220
455                 case 'B'/* other search paths for binaries */
456                         add_prefix(argp + 2);
457                         break;
ragge
1.128
458
459 #ifdef MULTITARGET
ragge
1.220
460                 case 'b':
461                         t = &argp[2];
462                         if (*t == '\0' && i + 1 < argc) {
463                                 t = nxtopt(0);
464                         }
465                         if (strncmp(t"?"1) == 0) {
466                                 /* show machine targets */
467                                 printf("Available machine targets:");
468                                 for (j=0cppmds[j].machj++)
469                                         printf(" %s",cppmds[j].mach);
470                                 printf("\n");
471                                 exit(0);
472                         }
473                         for (j=0cppmds[j].machj++)
474                                 if (strcmp(tcppmds[j].mach) == 0) {
475                                         mach = cppmds[j].mach;
476                                         break;
ragge
1.128
477                                 }
ragge
1.220
478                         if (cppmds[j].mach == NULL)
479                                 errorx(1"unknown target arch %s"t);
480                         break;
ragge
1.128
481 #endif
482
ragge
1.220
483                 case 'C':
484                         if (match(argp"-C") || match(argp"-CC"))
485                                 strlist_append(&preprocessor_flagsargp);
486                         else
487                                 oerror(argp);
488                         break;
ragge
1.218
489
ragge
1.220
490                 case 'X':
491                         Xflag++;
492                         break;
493                 case 'W'/* Ignore (most of) W-flags */
494                         if (strncmp(argp"-Wl,"4) == 0) {
495                                 /* options to the linker */
496                                 t = &argp[4];
497                                 while ((u = strchr(t','))) {
498                                         *u++ = 0;
ragge
1.128
499                                         llist[nl++] = t;
ragge
1.220
500                                         t = u;
501                                 }
502                                 llist[nl++] = t;
503                         } else if (strncmp(argp"-Wa,"4) == 0) {
504                                 /* options to the assembler */
505                                 t = &argp[4];
506                                 while ((u = strchr(t','))) {
507                                         *u++ = 0;
ragge
1.128
508                                         aslist[nas++] = t;
ragge
1.220
509                                         t = u;
510                                 }
511                                 aslist[nas++] = t;
512                         } else if (strncmp(argp"-Wc,"4) == 0) {
513                                 /* options to ccom */
514                                 t = &argp[4];
515                                 while ((u = strchr(t','))) {
516                                         *u++ = 0;
ragge
1.137
517                                         wlist[nw++] = t;
ragge
1.220
518                                         t = u;
519                                 }
520                                 wlist[nw++] = t;
521                         } else if ((t = argnxt(argp"-Wp,"))) {
522                                 u = strtok(t",");
523                                 do {
524                                         strlist_append(&preprocessor_flagsu);
525                                 } while ((u = strtok(NULL",")) != NULL);
526                         } else if (strcmp(argp"-Werror") == 0) {
527                                 wlist[nw++] = argp;
528                         } else if (strcmp(argp"-Wall") == 0) {
529                                 Wallflag = 1;
530                         } else if (strcmp(argp"-WW") == 0) {
531                                 Wflag = 1;
532                         } else {
533                                 /* pass through, if supported */
534                                 t = &argp[2];
535                                 if (strncmp(t"no-"3) == 0)
536                                         t += 3;
537                                 if (strncmp(t"error="6) == 0)
538                                         t += 6;
539                                 for (Wf = WflagsWf->nameWf++) {
540                                         if (strcmp(tWf->name) == 0)
541                                                 wlist[nw++] = argp;
ragge
1.128
542                                 }
ragge
1.220
543                         }
544                         break;
ragge
1.128
545
ragge
1.220
546                 case 'f'/* GCC compatibility flags */
547                         if (strcmp(argp"-fPIC") == 0)
548                                 kflag = F_PIC;
549                         else if (strcmp(argp"-fpic") == 0)
550                                 kflag = F_pic;
551                         else if (strcmp(argp"-ffreestanding") == 0)
552                                 freestanding = 1;
553                         else if (strcmp(argp,
554                             "-fsigned-char") == 0)
555                                 xuchar = 0;
556                         else if (strcmp(argp,
557                             "-fno-signed-char") == 0)
558                                 xuchar = 1;
559                         else if (strcmp(argp,
560                             "-funsigned-char") == 0)
561                                 xuchar = 1;
562                         else if (strcmp(argp,
563                             "-fno-unsigned-char") == 0)
564                                 xuchar = 0;
565                         else if (strcmp(argp,
566                             "-fstack-protector") == 0) {
567                                 flist[nf++] = argp;
568                                 sspflag++;
569                         } else if (strcmp(argp,
570                             "-fstack-protector-all") == 0) {
571                                 flist[nf++] = argp;
572                                 sspflag++;
573                         } else if (strcmp(argp,
574                             "-fno-stack-protector") == 0) {
575                                 flist[nf++] = argp;
576                                 sspflag = 0;
577                         } else if (strcmp(argp,
578                             "-fno-stack-protector-all") == 0) {
579                                 flist[nf++] = argp;
580                                 sspflag = 0;
581                         }
582                         /* silently ignore the rest */
583                         break;
ragge
1.128
584
ragge
1.220
585                 case 'g'/* create debug output */
586                         if (argp[2] == '0')
587                                 gflag = 0;
588                         else
589                                 gflag++;
590                         break;
ragge
1.128
591
ragge
1.220
592                 case 'D':
593                 case 'U':
594                 case 'I'/* Add include dirs */
595                         sl = argp[1] == 'I' ? &incdirs : &preprocessor_flags;
596                         strlist_append(slargp);
597                         if (argp[2] != 0)
ragge
1.219
598                                 break;
ragge
1.220
599                         strlist_append(slnxtopt(argp));
600                         break;
ragge
1.219
601
ragge
1.220
602                 case 'i':
603                         if (strcmp(argp"-isystem") == 0) {
604                                 *pv++ = "-S";
605                                 *pv++ = nxtopt("-isystem");
606                         } else if (strcmp(argp"-include") == 0) {
607                                 *pv++ = "-i";
608                                 *pv++ = nxtopt("-include");
609                         } else if (strcmp(argp"-idirafter") == 0) {
610                                 idirafter = nxtopt("-idirafter");
gmcgarry
1.172
611 #ifdef os_darwin
ragge
1.220
612                         } else if (strcmp(argp"-install_name") == 0) {
613                                 llist[nl++] = argp;
614                                 llist[nl++] = nxtopt("-install_name");
gmcgarry
1.172
615 #endif
ragge
1.220
616                         } else
617                                 goto passa;
618                         break;
ragge
1.128
619
ragge
1.220
620                 case 'k'/* generate PIC code */
621                         kflag = F_pic;
622                         break;
ragge
1.128
623
ragge
1.220
624                 case 'm'/* target-dependent options */
ragge
1.164
625 #ifdef mach_amd64
ragge
1.220
626                         /* need to call i386 ccom for this */
627                         if (strcmp(argp"-m32") == 0) {
628                                 pass0 = LIBEXECDIR "/ccom_i386";
629                                 amd64_i386 = 1;
630                                 break;
631                         }
ragge
1.164
632 #endif
ragge
1.220
633                         mlist[nm++] = argp;
634                         if (argp[2] == 0) {
635                                 /* separate second arg */
636                                 /* give also to linker */
637                                 llist[nl++] = argp;
638                                 lav++, lac--;
639                                 mlist[nm++] = lav[0];
640                                 llist[nl++] = lav[0];
641                         }
642                         break;
ragge
1.128
643
ragge
1.220
644                 case 'n'/* handle -n flags */
645                         if (strcmp(argp"-nostdinc") == 0)
646                                 nostdinc++;
647                         else if (strcmp(argp"-nostdlib") == 0) {
648                                 nostdlib++;
649                                 nostartfiles++;
650                         } else if (strcmp(argp"-nostartfiles") == 0)
651                                 nostartfiles = 1;
652                         else if (strcmp(argp"-nodefaultlibs") == 0)
653                                 nostdlib++;
654                         else
655                                 goto passa;
656                         break;
ragge
1.128
657
ragge
1.220
658                 case 'p':
659                         if (strcmp(argp"-pg") == 0 ||
660                             strcmp(argp"-p") == 0)
661                                 pgflag++;
662                         else if (strcmp(argp"-pthread") == 0)
663                                 pthreads++;
664                         else if (strcmp(argp"-pipe") == 0)
665                                 /* NOTHING YET */;
666                         else if (strcmp(argp"-pedantic") == 0)
667                                 /* NOTHING YET */;
668                         else if (strcmp(argp,
669                             "-print-prog-name=ld") == 0) {
670                                 printf("%s\n"LINKER);
671                                 return 0;
672                         } else if (strcmp(argp,
673                             "-print-multi-os-directory") == 0) {
674                                 printf("%s\n"MULTIOSDIR);
675                                 return 0;
676                         } else
677                                 oerror(argp);
678                         break;
ragge
1.128
679
ragge
1.220
680                 case 'r':
681                         rflag = 1;
682                         break;
gmcgarry
1.145
683
ragge
1.220
684                 case 'x':
685                         t = nxtopt("-x");
686                         if (match(t"c"))
687                                 xcflag = 1/* default */
688                         else if (match(t"assembler"))
689                                 xasm = 1;
690                         else if (match(t"assembler-with-cpp"))
691                                 ascpp = 1;
692                         else if (match(t"c++"))
693                                 cxxflag++;
694                         else if (argp[2])
695                                 xlist[xnum++] = argp;
696                         else
697                                 xlist[xnum++] = "-x"xlist[xnum++] = t;
698                         break;
699                 case 't':
700                         tflag++;
701                         break;
702                 case 'S':
703                         sflag++;
704                         cflag++;
705                         break;
706                 case 'o':
707                         if (outfile)
708                                 errorx(8"too many -o");
709                         outfile = nxtopt("-o");
710                         break;
711                 case 'O':
712                         if (argp[2] == '\0')
713                                 Oflag++;
714                         else if (argp[3] == '\0' && isdigit((unsigned char)argp[2]))
715                                 Oflag = argp[2] - '0';
716                         else if (argp[3] == '\0' && argp[2] == 's')
717                                 Oflag = 1;      /* optimize for space only */
718                         else
719                                 oerror(argp);
720                         break;
721                 case 'E':
722                         Eflag++;
723                         break;
724                 case 'P':
725                         pflag++;
726                         *pv++ = argp;
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         }
831         /* Sanity checking */
ragge
1.216
832         if (cppflag) {
833                 if (nc == 0)
834                         clist[nc++] = "-";
835                 else if (nc > 2 || (nc == 2 && outfile))
836                         errorx(8"too many files");
837                 else if (nc == 2)
838                         outfile = clist[--nc];
839         }
ragge
1.128
840         if (nc == 0 && nl == 0)
841                 errorx(8"no input files");
842         if (outfile && (cflag || sflag || Eflag) && nc > 1)
843                 errorx(8"-o given with -c || -E || -S and more than one file");
844         if (outfile && clist[0] && strcmp(outfileclist[0]) == 0)
845                 errorx(8"output file will be clobbered");
gmcgarry
1.150
846         if (nc==0)
ragge
1.128
847                 goto nocom;
848         if (pflag==0) {
849                 if (!sflag)
850                         tmp3 = gettmp();
851                 tmp4 = gettmp();
852         }
853         if (signal(SIGINTSIG_IGN) != SIG_IGN/* interrupt */
854                 signal(SIGINTidexit);
855         if (signal(SIGTERMSIG_IGN) != SIG_IGN)        /* terminate */
856                 signal(SIGTERMidexit);
857 #ifdef MULTITARGET
plunky
1.186
858         pass0 = cat(LIBEXECDIR "/ccom_"mach);
ragge
1.128
859 #endif
860         pvt = pv;
861         for (i=0i<nci++) {
862                 /*
863                  * C preprocessor
864                  */
865                 if (nc>1 && !Eflag)
866                         printf("%s:\n"clist[i]);
867                 onlyas = 0;
868                 assource = tmp3;
869                 if (getsuf(clist[i])=='S')
870                         ascpp = 1;
871                 if (getsuf(clist[i])=='i') {
872                         if(Eflag)
873                                 continue;
874                         goto com;
875                 } else if (ascpp) {
876                         onlyas = 1;
plunky
1.217
877                 } else if (xasm || getsuf(clist[i])=='s') {
ragge
1.128
878                         assource = clist[i];
879                         goto assemble;
880                 }
881                 if (pflag)
882                         tmp4 = setsuf(clist[i], 'i');
883                 na = 0;
884                 av[na++] = "cpp";
885                 if (vflag)
886                         av[na++] = "-v";
887                 av[na++] = "-D__PCC__=" MKS(PCC_MAJOR);
888                 av[na++] = "-D__PCC_MINOR__=" MKS(PCC_MINOR);
889                 av[na++] = "-D__PCC_MINORMINOR__=" MKS(PCC_MINORMINOR);
gmcgarry
1.156
890 #ifndef os_win32
ragge
1.155
891 #ifdef GCC_COMPAT
892                 av[na++] = "-D__GNUC__=4";
893                 av[na++] = "-D__GNUC_MINOR__=3";
894                 av[na++] = "-D__GNUC_PATCHLEVEL__=1";
ragge
1.198
895                 if (xgnu89)
plunky
1.208
896                         av[na++] = "-D__GNUC_GNU_INLINE__";
ragge
1.191
897                 else
plunky
1.208
898                         av[na++] = "-D__GNUC_STDC_INLINE__";
ragge
1.170
899 #endif
900 #endif
ragge
1.166
901                 av[na++] = "-D__VERSION__=" MKS(VERSSTR);
ragge
1.167
902                 av[na++] = "-D__SCHAR_MAX__=" MKS(MAX_CHAR);
903                 av[na++] = "-D__SHRT_MAX__=" MKS(MAX_SHORT);
904                 av[na++] = "-D__INT_MAX__=" MKS(MAX_INT);
905                 av[na++] = "-D__LONG_MAX__=" MKS(MAX_LONG);
906                 av[na++] = "-D__LONG_LONG_MAX__=" MKS(MAX_LONGLONG);
plunky
1.214
907                 if (freestanding)
908                         av[na++] = "-D__STDC_HOSTED__=0";
909                 else
910                         av[na++] = "-D__STDC_HOSTED__=1";
ragge
1.212
911                 if (cxxflag)
912                         av[na++] = "-D__cplusplus";
plunky
1.209
913                 if (xuchar)
plunky
1.196
914                         av[na++] = "-D__CHAR_UNSIGNED__";
ragge
1.128
915                 if (ascpp)
916                         av[na++] = "-D__ASSEMBLER__";
917                 if (sspflag)
plunky
1.208
918                         av[na++] = "-D__SSP__";
ragge
1.128
919                 if (pthreads)
920                         av[na++] = "-D_PTHREADS";
921                 if (Mflag)
922                         av[na++] = "-M";
ragge
1.216
923                 if (MPflag)
924                         av[na++] = "-xMP";
925                 for (j = 0j < nMfilesj++)
926                         av[na++] = Mfiles[j];
ragge
1.160
927                 if (Oflag)
928                         av[na++] = "-D__OPTIMIZE__";
929 #ifdef GCC_COMPAT
930                 av[na++] = "-D__REGISTER_PREFIX__=" REGISTER_PREFIX;
931                 av[na++] = "-D__USER_LABEL_PREFIX__=" USER_LABEL_PREFIX;
932 #endif
ragge
1.128
933                 for (j = 0cppadd[j]; j++)
934                         av[na++] = cppadd[j];
ragge
1.218
935                 STRLIST_FOREACH(s, &preprocessor_flags) {
936                         av[na++] = s->value;
937                 }
ragge
1.219
938                 STRLIST_FOREACH(s, &incdirs) {
939                         av[na++] = s->value;
940                 }
gmcgarry
1.149
941                 av[na++] = "-D__STDC_ISO_10646__=200009L";
ragge
1.157
942                 av[na++] = "-D__WCHAR_TYPE__=" WCT;
943                 av[na++] = "-D__SIZEOF_WCHAR_T__=" MKS(WCHAR_SIZE);
944                 av[na++] = "-D__WCHAR_MAX__=" WCM;
plunky
1.192
945                 av[na++] = "-D__WINT_TYPE__=" PCC_WINT_TYPE;
946                 av[na++] = "-D__SIZE_TYPE__=" PCC_SIZE_TYPE;
ragge
1.161
947                 av[na++] = "-D__PTRDIFF_TYPE__=" PCC_PTRDIFF_TYPE;
gmcgarry
1.142
948                 av[na++] = "-D__SIZEOF_WINT_T__=4";
plunky
1.201
949 #if defined(os_darwin) || defined(os_netbsd)
950                 av[na++] = "-D__FLT_RADIX__=2";
951                 av[na++] = "-D__FLT_DIG__=6";
952                 av[na++] = "-D__FLT_EPSILON__=1.19209290e-07F";
953                 av[na++] = "-D__FLT_MANT_DIG__=24";
954                 av[na++] = "-D__FLT_MAX_10_EXP__=38";
955                 av[na++] = "-D__FLT_MAX_EXP__=128";
956                 av[na++] = "-D__FLT_MAX__=3.40282347e+38F";
957                 av[na++] = "-D__FLT_MIN_10_EXP__=(-37)";
958                 av[na++] = "-D__FLT_MIN_EXP__=(-125)";
gmcgarry
1.171
959                 av[na++] = "-D__FLT_MIN__=1.17549435e-38F";
plunky
1.201
960                 av[na++] = "-D__DBL_DIG__=15";
961                 av[na++] = "-D__DBL_EPSILON__=2.2204460492503131e-16";
962                 av[na++] = "-D__DBL_MANT_DIG__=53";
963                 av[na++] = "-D__DBL_MAX_10_EXP__=308";
964                 av[na++] = "-D__DBL_MAX_EXP__=1024";
965                 av[na++] = "-D__DBL_MAX__=1.7976931348623157e+308";
966                 av[na++] = "-D__DBL_MIN_10_EXP__=(-307)";
967                 av[na++] = "-D__DBL_MIN_EXP__=(-1021)";
gmcgarry
1.171
968                 av[na++] = "-D__DBL_MIN__=2.2250738585072014e-308";
plunky
1.201
969 #if defined(mach_i386) || defined(mach_amd64)
970                 av[na++] = "-D__LDBL_DIG__=18";
971                 av[na++] = "-D__LDBL_EPSILON__=1.08420217248550443401e-19L";
972