Quick Search:

Mode

Context

Displaying 3 lines of context. None | Less | More | Full

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.127
 
1.128
 
MAIN:ragge:20081025205535
 
cc.c
_><_1 -/*      $Id$    */
 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
 42 - * - Files that end with .s are passed as->ld
 43 - * - Files that end with .o are passed directly to ld
 44 - * - Multiple files may be given on the command line.
 45 - * - Unrecognized options are all sent directly to ld.
 46 - * -c or -S cannot be combined with -o if multiple files are given.
 47 - *
 48 - * This file should be rewritten readable.
 49 - */
 50 -#include "config.h"
 51 -
 52 -#include <sys/types.h>
 53 -#ifdef HAVE_SYS_WAIT_H
 54 -#include <sys/wait.h>
 55 -#endif
 56 -
 57 -#include <ctype.h>
 58 -#include <errno.h>
 59 -#include <fcntl.h>
 60 -#ifdef HAVE_LIBGEN_H
 61 -#include <libgen.h>
 62 -#endif
 63 -#include <signal.h>
 64 -#include <stdarg.h>
 65 -#include <stdio.h>
 66 -#include <stdlib.h>
 67 -#include <string.h>
 68 -#ifdef HAVE_UNISTD_H
 69 -#include <unistd.h>
 70 -#endif
 71 -
 72 -#ifdef WIN32
 73 -#include <windows.h>
 74 -#include <process.h>
 75 -#include <io.h>
 76 -#endif
 77 -
 78 -#include "compat.h"
 79 -
 80 -#include "ccconfig.h"
 81 -/* C command */
 82 -
 83 -#define MKS(x) _MKS(x)
 84 -#define _MKS(x) #x
 85 -
 86 -/*
 87 - * Many specific definitions, should be declared elsewhere.
 88 - */
 89 -
 90 -#ifndef STDINC
 91 -#define STDINC          "/usr/include/"
 92 -#endif
 93 -
 94 -#ifndef LIBDIR
 95 -#define LIBDIR          "/usr/lib/"
 96 -#endif
 97 -
 98 -#ifndef PREPROCESSOR
 99 -#define PREPROCESSOR    "cpp"
 100 -#endif
 101 -
 102 -#ifndef COMPILER
 103 -#define COMPILER        "ccom";
 104 -#endif
 105 -
 106 -#ifndef ASSEMBLER
 107 -#define ASSEMBLER       "as"
 108 -#endif
 109 -
 110 -#ifndef LINKER
 111 -#define LINKER          "ld"
 112 -#endif
 113 -
 114 -#define OS MKS(TARGOS)
 115 -#define MACH MKS(TARGMACH)
 116 -#ifndef PCCINCDIR
 117 -#define PCCINCDIR       LIBDIR "pcc/" MACH "-" OS "/" PACKAGE_VERSION "/include"
 118 -#endif
 119 -#ifndef PCCLIBDIR
 120 -#define PCCLIBDIR       LIBDIR "pcc/" MACH "-" OS "/" PACKAGE_VERSION "/lib"
 121 -#endif
 122 -
 123 -#define MAXFIL 10000
 124 -#define MAXLIB 10000
 125 -#define MAXAV  10000
 126 -#define MAXOPT 100
 127 -char    *tmp3;
 128 -char    *tmp4;
 129 -char    *outfile, *ermfile;
 130 -char *Bprefix(char *);
 131 -char *copy(char *, int),*setsuf(char *, char);
 132 -int getsuf(char *);
 133 -int main(int, char *[]);
 134 -void error(char *, ...);
 135 -void errorx(int, char *, ...);
 136 -int callsys(char [], char *[]);
 137 -int cunlink(char *);
 138 -void dexit(int);
 139 -void idexit(int);
 140 -char *gettmp(void);
 141 -void *ccmalloc(int size);
 142 -#ifdef WIN32
 143 -char *win32pathsubst(char *);
 144 -#endif
 145 -char    *av[MAXAV];
 146 -char    *clist[MAXFIL];
 147 -char    *llist[MAXLIB];
 148 -char    *aslist[MAXAV];
 149 -char    alist[20];
 150 -char    *xlist[100];
 151 -int     xnum;
 152 -char    *mlist[100];
 153 -char    *flist[100];
 154 -char    *wlist[100];
 155 -char    *idirafter;
 156 -int     nm;
 157 -int     nf;
 158 -int     nw;
 159 -int     sspflag;
 160 -int     Cflag;
 161 -int     dflag;
 162 -int     pflag;
 163 -int     sflag;
 164 -int     cflag;
 165 -int     eflag;
 166 -int     gflag;
 167 -int     vflag;
 168 -int     tflag;
 169 -int     Eflag;
 170 -int     Oflag;
 171 -int     kflag;  /* generate PIC/pic code */
 172 -#define F_PIC   1
 173 -#define F_pic   2
 174 -int     Mflag;  /* dependencies only */
 175 -int     pgflag;
 176 -int     exfail;
 177 -int     Xflag;
 178 -int     Wallflag;
 179 -int     Wflag;
 180 -int     nostartfiles, Bstatic, shared;
 181 -int     nostdinc, nostdlib;
 182 -int     onlyas;
 183 -int     pthreads;
 184 -int     xcflag;
 185 -int     ascpp;
 186 -
 187 -char    *passp = LIBEXECDIR PREPROCESSOR;
 188 -char    *pass0 = LIBEXECDIR COMPILER;
 189 -char    *as = ASSEMBLER;
 190 -char    *ld = LINKER;
 191 -char    *Bflag;
 192 -char *cppadd[] = CPPADD;
 193 -#ifdef DYNLINKER
 194 -char *dynlinker[] = DYNLINKER;
 195 -#endif
 196 -#ifdef CRT0FILE
 197 -char *crt0file = CRT0FILE;
 198 -#endif
 199 -#ifdef CRT0FILE_PROFILE
 200 -char *crt0file_profile = CRT0FILE_PROFILE;
 201 -#endif
 202 -#ifdef STARTFILES
 203 -char *startfiles[] = STARTFILES;
 204 -char *endfiles[] = ENDFILES;
 205 -#endif
 206 -#ifdef STARTFILES_T
 207 -char *startfiles_T[] = STARTFILES_T;
 208 -char *endfiles_T[] = ENDFILES_T;
 209 -#endif
 210 -#ifdef STARTFILES_S
 211 -char *startfiles_S[] = STARTFILES_S;
 212 -char *endfiles_S[] = ENDFILES_S;
 213 -#endif
 214 -#ifdef MULTITARGET
 215 -char *mach = DEFMACH;
 216 -struct cppmd {
 217 -        char *mach;
 218 -        char *cppmdadd[MAXCPPMDARGS];
 219 -};
 220 -
 221 -struct cppmd cppmds[] = CPPMDADDS;
 222 -#else
 223 -char *cppmdadd[] = CPPMDADD;
 224 -#endif
 225 -#ifdef LIBCLIBS
 226 -char *libclibs[] = LIBCLIBS;
 227 -#else
 228 -char *libclibs[] = { "-lc", NULL };
 229 -#endif
 230 -#ifdef LIBCLIBS_PROFILE
 231 -char *libclibs_profile[] = LIBCLIBS_PROFILE;
 232 -#else
 233 -char *libclibs_profile[] = { "-lc_p", NULL };
 234 -#endif
 235 -#ifndef STARTLABEL
 236 -#define STARTLABEL "__start"
 237 -#endif
 238 -char *incdir = STDINC;
 239 -char *pccincdir = PCCINCDIR;
 240 -char *pcclibdir = PCCLIBDIR;
 241 -
 242 -/* handle gcc warning emulations */
 243 -struct Wflags {
 244 -        char *name;
 245 -        int flags;
 246 -#define INWALL          1
 247 -#define NEGATIVE        2
 248 -} Wflags[] = {
 249 -        { "-Werror", 0 },
 250 -        { "-Wshadow", 0 },
 251 -        { "-Wno-shadow", NEGATIVE },
 252 -        { "-Wpointer-sign", INWALL },
 253 -        { "-Wno-pointer-sign", NEGATIVE },
 254 -        { "-Wsign-compare", 0 },
 255 -        { "-Wno-sign-compare", NEGATIVE },
 256 -        { "-Wunknown-pragmas", INWALL },
 257 -        { "-Wno-unknown-pragmas", NEGATIVE },
 258 -        { "-Wunreachable-code", 0 },
 259 -        { "-Wno-unreachable-code", NEGATIVE },
 260 -        { 0, 0 },
 261 -};
 262 -
 263 -#define SZWFL   (sizeof(Wflags)/sizeof(Wflags[0]))
 264 -
 265 -int
 266 -main(int argc, char *argv[])
 267 -{
 268 -        struct Wflags *Wf;
 269 -        char *t, *u;
 270 -        char *assource;
 271 -        char **pv, *ptemp[MAXOPT], **pvt;
 272 -        int nc, nl, nas, i, j, c, nxo, na;
 273 -#ifdef MULTITARGET
 274 -        int k;
 275 -#endif
 276 -
 277 -#ifdef WIN32
 278 -        /* have to prefix path early.  -B may override */
 279 -        incdir = win32pathsubst(incdir);
 280 -        pccincdir = win32pathsubst(pccincdir);
 281 -        pcclibdir = win32pathsubst(pcclibdir);
 282 -        passp = win32pathsubst(passp);
 283 -        pass0 = win32pathsubst(pass0);
 284 -#endif
 285 -
 286 -        i = nc = nl = nas = nxo = 0;
 287 -        pv = ptemp;
 288 -        while(++i < argc) {
 289 -                if (argv[i][0] == '-') {
 290 -                        switch (argv[i][1]) {
 291 -                        default:
 292 -                                goto passa;
 293 -#ifdef notyet
 294 -        /* must add library options first (-L/-l/...) */
 295 -                                error("unrecognized option `-%c'", argv[i][1]);
 296 -                                break;
 297 -#endif
 298 -
 299 -                        case '-': /* double -'s */
 300 -                                if (strcmp(argv[i], "--version") == 0)
 301 -                                        printf("%s\n", VERSSTR);
 302 -                                else if (strcmp(argv[i], "--param") == 0)
 303 -                                        /* NOTHING YET */;
 304 -                                else
 305 -                                        error("unrecognized option %s", argv[i]);
 306 -                                break;
 307 -
 308 -                        case 'B': /* other search paths for binaries */
 309 -                                Bflag = &argv[i][2];
 310 -                                break;
 311 -
 312 -#ifdef MULTITARGET
 313 -                        case 'b':
 314 -                                t = &argv[i][2];
 315 -                                if (*t == '\0' && i + 1 < argc) {
 316 -                                        t = argv[i+1];
 317 -                                        i++;
 318 -                                }
 319 -                                if (strncmp(t, "?", 1) == 0) {
 320 -                                        /* show machine targets */
 321 -                                        printf("Available machine targets:");
 322 -                                        for (j=0; cppmds[j].mach; j++)
 323 -                                                printf(" %s",cppmds[j].mach);
 324 -                                        printf("\n");
 325 -                                        exit(0);
 326 -                                }
 327 -                                for (j=0; cppmds[j].mach; j++)
 328 -                                        if (strcmp(t, cppmds[j].mach) == 0) {
 329 -                                                mach = cppmds[j].mach;
 330 -                                                break;
 331 -                                        }
 332 -                                if (cppmds[j].mach == NULL)
 333 -                                        errorx(1, "unknown target arch %s", t);
 334 -                                break;
 335 -#endif
 336 -
 337 -                        case 'X':
 338 -                                Xflag++;
 339 -                                break;
 340 -                        case 'W': /* Ignore (most of) W-flags */
 341 -                                if (strncmp(argv[i], "-Wl,", 4) == 0) {
 342 -                                        /* options to the linker */
 343 -                                        t = &argv[i][4];
 344 -                                        while ((u = strchr(t, ','))) {
 345 -                                                *u++ = 0;
 346 -                                                llist[nl++] = t;
 347 -                                                t = u;
 348 -                                        }
 349 -                                        llist[nl++] = t;
 350 -                                } else if (strncmp(argv[i], "-Wa,", 4) == 0) {
 351 -                                        /* options to the assembler */
 352 -                                        t = &argv[i][4];
 353 -                                        while ((u = strchr(t, ','))) {
 354 -                                                *u++ = 0;
 355 -                                                aslist[nas++] = t;
 356 -                                                t = u;
 357 -                                        }
 358 -                                        aslist[nas++] = t;
 359 -                                } else if (strncmp(argv[i], "-Wp,", 4) == 0) {
 360 -                                        /* preprocessor */
 361 -                                        if (!strncmp(argv[i], "-Wp,-C", 6))
 362 -                                                Cflag++;
 363 -                                } else if (strcmp(argv[i], "-Wall") == 0) {
 364 -                                        Wallflag = 1;
 365 -                                } else if (strcmp(argv[i], "-WW") == 0) {
 366 -                                        Wflag = 1;
 367 -                                } else {
 368 -                                        /* check and set if available */
 369 -                                        for (Wf = Wflags; Wf->name; Wf++) {
 370 -                                                if (strcmp(argv[i], Wf->name))
 371 -                                                        continue;
 372 -                                                wlist[nw++] = Wf->name;
 373 -                                        }
 374 -                                }
 375 -                                break;
 376 -
 377 -                        case 'f': /* GCC compatibility flags */
 378 -                                if (strcmp(argv[i], "-fPIC") == 0)
 379 -                                        kflag = F_PIC;
 380 -                                else if (strcmp(argv[i], "-fpic") == 0)
 381 -                                        kflag = F_pic;
 382 -                                else if (strcmp(argv[i],
 383 -                                    "-fsigned-char") == 0)
 384 -                                        flist[nf++] = argv[i];
 385 -                                else if (strcmp(argv[i],
 386 -                                    "-fno-signed-char") == 0)
 387 -                                        flist[nf++] = argv[i];
 388 -                                else if (strcmp(argv[i],
 389 -                                    "-funsigned-char") == 0)
 390 -                                        flist[nf++] = argv[i];
 391 -                                else if (strcmp(argv[i],
 392 -                                    "-fno-unsigned-char") == 0)
 393 -                                        flist[nf++] = argv[i];
 394 -                                else if (strcmp(argv[i],
 395 -                                    "-fstack-protector") == 0) {
 396 -                                        flist[nf++] = argv[i];
 397 -                                        sspflag++;
 398 -                                } else if (strcmp(argv[i],
 399 -                                    "-fstack-protector-all") == 0) {
 400 -                                        flist[nf++] = argv[i];
 401 -                                        sspflag++;
 402 -                                } else if (strcmp(argv[i],
 403 -                                    "-fno-stack-protector") == 0) {
 404 -                                        flist[nf++] = argv[i];
 405 -                                        sspflag = 0;
 406 -                                } else if (strcmp(argv[i],
 407 -                                    "-fno-stack-protector-all") == 0) {
 408 -                                        flist[nf++] = argv[i];
 409 -                                        sspflag = 0;
 410 -                                }
 411 -                                /* silently ignore the rest */
 412 -                                break;
 413 -
 414 -                        case 'g': /* create debug output */
 415 -                                gflag++;
 416 -                                break;
 417 -
 418 -                        case 'i':
 419 -                                if (strcmp(argv[i], "-isystem") == 0) {
 420 -                                        *pv++ = "-S";
 421 -                                        *pv++ = argv[++i];
 422 -                                } else if (strcmp(argv[i], "-include") == 0) {
 423 -                                        *pv++ = "-i";
 424 -                                        *pv++ = argv[++i];
 425 -                                } else if (strcmp(argv[i], "-idirafter") == 0) {
 426 -                                        idirafter = argv[++i];
 427 -                                } else
 428 -                                        goto passa;
 429 -                                break;
 430 -
 431 -                        case 'k': /* generate PIC code */
 432 -                                kflag = F_pic;
 433 -                                break;
 434 -
 435 -                        case 'm': /* target-dependent options */
 436 -                                mlist[nm++] = argv[i];
 437 -                                break;
 438 -
 439 -                        case 'n': /* handle -n flags */
 440 -                                if (strcmp(argv[i], "-nostdinc") == 0)
 441 -                                        nostdinc++;
 442 -                                else if (strcmp(argv[i], "-nostdlib") == 0) {
 443 -                                        nostdlib++;
 444 -                                        nostartfiles++;
 445 -                                } else if (strcmp(argv[i], "-nostartfiles") == 0)
 446 -                                        nostartfiles = 1;
 447 -                                else
 448 -                                        goto passa;
 449 -                                break;
 450 -
 451 -                        case 'p':
 452 -                                if (strcmp(argv[i], "-pg") == 0 ||
 453 -                                    strcmp(argv[i], "-p") == 0)
 454 -                                        pgflag++;
 455 -                                else if (strcmp(argv[i], "-pthread") == 0)
 456 -                                        pthreads++;
 457 -                                else if (strcmp(argv[i], "-pipe") == 0)
 458 -                                        /* NOTHING YET */;
 459 -                                else
 460 -                                        errorx(1, "unknown option %s", argv[i]);
 461 -                                break;
 462 -
 463 -                        case 'x':
 464 -                                t = &argv[i][2];
 465 -                                if (*t == 0)
 466 -                                        t = argv[++i];
 467 -                                if (strcmp(t, "c") == 0)
 468 -                                        xcflag = 1; /* default */
 469 -                                else if (strcmp(t, "assembler-with-cpp") == 0)
 470 -                                        ascpp = 1;
 471 -#ifdef notyet
 472 -                                else if (strcmp(t, "c++") == 0)
 473 -                                        cxxflag++;
 474 -#endif
 475 -                                else
 476 -                                        xlist[xnum++] = argv[i];
 477 -                                break;
 478 -                        case 't':
 479 -                                tflag++;
 480 -                                break;
 481 -                        case 'S':
 482 -                                sflag++;
 483 -                                cflag++;
 484 -                                break;
 485 -                        case 'o':
 486 -                                if (outfile)
 487 -                                        errorx(8, "too many -o");
 488 -                                outfile = argv[++i];
 489 -                                break;
 490 -                        case 'O':
 491 -                                if (argv[i][2] == '0')
 492 -                                        Oflag = 0;
 493 -                                else
 494 -                                        Oflag++;
 495 -                                break;
 496 -                        case 'E':
 497 -                                Eflag++;
 498 -                                break;
 499 -                        case 'P':
 500 -                                pflag++;
 501 -                                *pv++ = argv[i];
 502 -                        case 'c':
 503 -                                cflag++;
 504 -                                break;
 505 -
 506 -#if 0
 507 -                        case '2':
 508 -                                if(argv[i][2] == '\0')
 509 -                                        pref = "/lib/crt2.o";
 510 -                                else {
 511 -                                        pref = "/lib/crt20.o";
 512 -                                }
 513 -                                break;
 514 -#endif
 515 -                        case 'C':
 516 -                                Cflag = 1;
 517 -                                break;
 518 -                        case 'D':
 519 -                        case 'I':
 520 -                        case 'U':
 521 -                                *pv++ = argv[i];
 522 -                                if (argv[i][2] == 0)
 523 -                                        *pv++ = argv[++i];
 524 -                                if (pv >= ptemp+MAXOPT) {
 525 -                                        error("Too many DIU options");
 526 -                                        --pv;
 527 -                                }
 528 -                                break;
 529 -
 530 -                        case 'M':
 531 -                                Mflag++;
 532 -                                break;
 533 -
 534 -                        case 'd':
 535 -                                dflag++;
 536 -                                strlcpy(alist, argv[i], sizeof (alist));
 537 -                                break;
 538 -                        case 'v':
 539 -                                printf("%s\n", VERSSTR);
 540 -                                vflag++;
 541 -                                break;
 542 -
 543 -                        case 's':
 544 -                                if (strcmp(argv[i], "-static") == 0)
 545 -                                        Bstatic = 1;
 546 -                                else if (strcmp(argv[i], "-shared") == 0) {
 547 -                                        shared = 1;
 548 -#ifndef os_win32
 549 -                                        nostdlib = 1;
 550 -#endif
 551 -                                } else if (strncmp(argv[i], "-std", 4) == 0) {
 552 -                                        /* ignore gcc -std= */;
 553 -                                } else
 554 -                                        goto passa;
 555 -                                break;
 556 -                        }
 557 -                } else {
 558 -                passa:
 559 -                        t = argv[i];
 560 -                        if (*argv[i] == '-' && argv[i][1] == 'L')
 561 -                                ;
 562 -                        else if((c=getsuf(t))=='c' || c=='S' || c=='i' ||
 563 -                            c=='s'|| Eflag || xcflag) {
 564 -                                clist[nc++] = t;
 565 -                                if (nc>=MAXFIL) {
 566 -                                        error("Too many source files");
 567 -                                        exit(1);
 568 -                                }
 569 -                                t = setsuf(t, 'o');
 570 -                        }
 571 -
 572 -                        /* Check for duplicate .o files. */
 573 -                        for (j = getsuf(t) == 'o' ? 0 : nl; j < nl; j++) {
 574 -                                if (strcmp(llist[j], t) == 0)
 575 -                                        break;
 576 -                        }
 577 -                        if (j == nl) {
 578 -                                llist[nl++] = t;
 579 -                                if (nl >= MAXLIB) {
 580 -                                        error("Too many object/library files");
 581 -                                        exit(1);
 582 -                                }
 583 -                                if (getsuf(t)=='o')
 584 -                                        nxo++;
 585 -                        }
 586 -                }
 587 -        }
 588 -        /* Sanity checking */
 589 -        if (nc == 0 && nl == 0)
 590 -                errorx(8, "no input files");
 591 -        if (outfile && (cflag || sflag || Eflag) && nc > 1)
 592 -                errorx(8, "-o given with -c || -E || -S and more than one file");
 593 -        if (outfile && clist[0] && strcmp(outfile, clist[0]) == 0)
 594 -                errorx(8, "output file will be clobbered");
 595 -        if (gflag) Oflag = 0;
 596 -#if 0
 597 -        if (proflag)
 598 -                pref = "/lib/mcrt0.o";
 599 -#endif
 600 -        if(nc==0)
 601 -                goto nocom;
 602 -        if (pflag==0) {
 603 -                if (!sflag)
 604 -                        tmp3 = gettmp();
 605 -                tmp4 = gettmp();
 606 -        }
 607 -        if (Bflag) {
 608 -                incdir = Bflag;
 609 -                pccincdir = Bflag;
 610 -                pcclibdir = Bflag;
 611 -        }
 612 -        if (signal(SIGINT, SIG_IGN) != SIG_IGN/* interrupt */
 613 -                signal(SIGINT, idexit);
 614 -        if (signal(SIGTERM, SIG_IGN) != SIG_IGN)        /* terminate */
 615 -                signal(SIGTERM, idexit);
 616 -#ifdef MULTITARGET
 617 -        asprintf(&pass0, "%s%s%s", LIBEXECDIR, "ccom_", mach);
 618 -#endif
 619 -        pvt = pv;
 620 -        for (i=0; i<nc; i++) {
 621 -                /*
 622 -                 * C preprocessor
 623 -                 */
 624 -                if (nc>1 && !Eflag)
 625 -                        printf("%s:\n", clist[i]);
 626 -                onlyas = 0;
 627 -                assource = tmp3;
 628 -                if (getsuf(clist[i])=='S')
 629 -                        ascpp = 1;
 630 -                if (getsuf(clist[i])=='i') {
 631 -                        if(Eflag)
 632 -                                continue;
 633 -                        goto com;
 634 -                } else if (ascpp) {
 635 -                        onlyas = 1;
 636 -                } else if (getsuf(clist[i])=='s') {
 637 -                        assource = clist[i];
 638 -                        goto assemble;
 639 -                }
 640 -                if (pflag)
 641 -                        tmp4 = setsuf(clist[i], 'i');
 642 -                na = 0;
 643 -                av[na++] = "cpp";
 644 -                if (vflag)
 645 -                        av[na++] = "-v";
 646 -                av[na++] = "-D__PCC__=" MKS(PCC_MAJOR);
 647 -                av[na++] = "-D__PCC_MINOR__=" MKS(PCC_MINOR);
 648 -                av[na++] = "-D__PCC_MINORMINOR__=" MKS(PCC_MINORMINOR);
 649 -                if (ascpp)
 650 -                        av[na++] = "-D__ASSEMBLER__";
 651 -                if (sspflag)
 652 -                        av[na++] = "-D__SSP__=1";
 653 -                if (pthreads)
 654 -                        av[na++] = "-D_PTHREADS";
 655 -                if (Cflag)
 656 -                        av[na++] = "-C";
 657 -                if (Mflag)
 658 -                        av[na++] = "-M";
 659 -                if (dflag)
 660 -                        av[na++] = alist;
 661 -                for (j = 0; cppadd[j]; j++)
 662 -                        av[na++] = cppadd[j];
 663 -#ifdef MULTITARGET
 664 -                for (k = 0; cppmds[k].mach; k++) {
 665 -                        if (strcmp(cppmds[k].mach, mach) != 0)
 666 -                                continue;
 667 -                        for (j = 0; cppmds[k].cppmdadd[j]; j++)
 668 -                                av[na++] = cppmds[k].cppmdadd[j];
 669 -                        break;
 670 -                }
 671 -#else
 672 -                for (j = 0; cppmdadd[j]; j++)
 673 -                        av[na++] = cppmdadd[j];
 674 -#endif
 675 -                if (tflag)
 676 -                        av[na++] = "-t";
 677 -                for(pv=ptemp; pv <pvt; pv++)
 678 -                        av[na++] = *pv;
 679 -                if (!nostdinc)
 680 -                        av[na++] = "-S", av[na++] = incdir;
 681 -                av[na++] = "-I", av[na++] = pccincdir;
 682 -                if (idirafter) {
 683 -                        av[na++] = "-I";
 684 -                        av[na++] = idirafter;
 685 -                }
 686 -                av[na++] = clist[i];
 687 -                if (!Eflag && !Mflag)
 688 -                        av[na++] = tmp4;
 689 -                if (Eflag && outfile)
 690 -                         ermfile = av[na++] = outfile;
 691 -                av[na++]=0;
 692 -                if (callsys(passp, av))
 693 -                        {exfail++; eflag++;}
 694 -                if (Eflag || Mflag)
 695 -                        continue;
 696 -                if (onlyas) {
 697 -                        assource = tmp4;
 698 -                        goto assemble;
 699 -                }
 700 -
 701 -                /*
 702 -                 * C compiler
 703 -                 */
 704 -        com:
 705 -                na = 0;
 706 -                av[na++]= "ccom";
 707 -                if (Wallflag) {
 708 -                        /* Set only the same flags as gcc */
 709 -                        for (Wf = Wflags; Wf->name; Wf++) {
 710 -                                if (Wf->flags != INWALL)
 711 -                                        continue;
 712 -                                av[na++] = Wf->name;
 713 -                        }
 714 -                }
 715 -                if (Wflag) {
 716 -                        /* set all positive flags */
 717 -                        for (Wf = Wflags; Wf->name; Wf++) {
 718 -                                if (Wf->flags == NEGATIVE)
 719 -                                        continue;
 720 -                                av[na++] = Wf->name;
 721 -                        }
 722 -                }
 723 -                for (j = 0; j < nw; j++)
 724 -                        av[na++] = wlist[j];
 725 -                for (j = 0; j < nf; j++)
 726 -                        av[na++] = flist[j];
 727 -                if (vflag)
 728 -                        av[na++] = "-v";
 729 -                if (pgflag)
 730 -                        av[na++] = "-p";
 731 -                if (gflag)
 732 -                        av[na++] = "-g";
 733 -#ifdef os_darwin
 734 -                /* darwin always wants PIC compilation */
 735 -                if (!Bstatic)
 736 -                        av[na++] = "-k";
 737 -#else
 738 -                if (kflag)
 739 -                        av[na++] = "-k";
 740 -#endif
 741 -                if (Oflag) {
 742 -                        av[na++] = "-xtemps";
 743 -                        av[na++] = "-xdeljumps";
 744 -                }
 745 -                for (j = 0; j < xnum; j++)
 746 -                        av[na++] = xlist[j];
 747 -                for (j = 0; j < nm; j++)
 748 -                        av[na++] = mlist[j];
 749 -                if (getsuf(clist[i])=='i')
 750 -                        av[na++] = clist[i];
 751 -                else
 752 -                        av[na++] = tmp4; /* created by cpp */
 753 -                if (pflag || exfail)
 754 -                        {
 755 -                        cflag++;
 756 -                        continue;
 757 -                        }
 758 -                if(sflag) {
 759 -                        if (outfile)
 760 -                                tmp3 = outfile;
 761 -                        else
 762 -                                tmp3 = setsuf(clist[i], 's');
 763 -                }
 764 -                ermfile = av[na++] = tmp3;
 765 -#if 0
 766 -                if (proflag) {
 767 -                        av[3] = "-XP";
 768 -                        av[4] = 0;
 769 -                } else
 770 -                        av[3] = 0;
 771 -#endif
 772 -                av[na++] = NULL;
 773 -                if (callsys(pass0, av)) {
 774 -                        cflag++;
 775 -                        eflag++;
 776 -                        continue;
 777 -                }
 778 -                if (sflag)
 779 -                        continue;
 780 -
 781 -                /*
 782 -                 * Assembler
 783 -                 */
 784 -        assemble:
 785 -                na = 0;
 786 -                av[na++] = as;
 787 -                for (j = 0; j < nas; j++)
 788 -                        av[na++] = aslist[j];
 789 -#if defined(os_sunos) && defined(mach_sparc64)
 790 -                av[na++] = "-m64";
 791 -#endif
 792 -#if defined(os_darwin)
 793 -                if (Bstatic)
 794 -                        av[na++] = "-static";
 795 -#endif
 796 -                if (vflag)
 797 -                        av[na++] = "-v";
 798 -                if (kflag)
 799 -                        av[na++] = "-k";
 800 -                av[na++] = "-o";
 801 -                if (outfile && cflag)
 802 -                        ermfile = av[na++] = outfile;
 803 -                else
 804 -                        ermfile = av[na++] = setsuf(clist[i], 'o');
 805 -                av[na++] = assource;
 806 -                if (dflag)
 807 -                        av[na++] = alist;
 808 -                av[na++] = 0;
 809 -                if (callsys(as, av)) {
 810 -                        cflag++;
 811 -                        eflag++;
 812 -                        cunlink(tmp4);
 813 -                        continue;
 814 -                }
 815 -                cunlink(tmp4);
 816 -        }
 817 -
 818 -        if (Eflag || Mflag)
 819 -                dexit(eflag);
 820 -
 821 -        /*
 822 -         * Linker
 823 -         */
 824 -nocom:
 825 -        if (cflag==0 && nl!=0) {
 826 -                j = 0;
 827 -                av[j++] = ld;
 828 -#ifndef MSLINKER
 829 -                if (vflag)
 830 -                        av[j++] = "-v";
 831 -#endif
 832 -#if !defined(os_sunos) && !defined(os_win32)
 833 -                av[j++] = "-X";
 834 -#endif
 835 -                if (shared) {
 836 -                        av[j++] = "-shared";
 837 -#ifdef os_win32
 838 -                        av[j++] = "-Bdynamic";
 839 -#endif
 840 -#ifndef os_sunos
 841 -                } else {
 842 -#ifndef os_win32
 843 -#ifndef os_darwin
 844 -                        av[j++] = "-d";
 845 -#endif
 846 -                        av[j++] = "-e";
 847 -                        av[j++] = STARTLABEL;
 848 -#endif
 849 -#endif
 850 -                        if (Bstatic == 0) { /* Dynamic linkage */
 851 -#ifdef DYNLINKER
 852 -                                for (i = 0; dynlinker[i]; i++)
 853 -                                        av[j++] = dynlinker[i];
 854 -#endif
 855 -                        } else {
 856 -#ifdef os_darwin
 857 -                                av[j++] = "-static";
 858 -#else
 859 -                                av[j++] = "-Bstatic";
 860 -#endif
 861 -                        }
 862 -                }
 863 -                if (outfile) {
 864 -#ifdef MSLINKER
 865 -                        char *s = copy("/OUT:", strlen(outfile));
 866 -                        strcat(s, outfile);
 867 -                        av[j++] = s;
 868 -#else
 869 -                        av[j++] = "-o";
 870 -                        av[j++] = outfile;
 871 -#endif
 872 -                }
 873 -#ifdef STARTFILES_S
 874 -                if (shared) {
 875 -                        if (!nostartfiles) {
 876 -                                for (i = 0; startfiles_S[i]; i++)
 877 -                                        av[j++] = Bprefix(startfiles_S[i]);
 878 -                        }
 879 -                } else
 880 -#endif
 881 -                {
 882 -                        if (!nostartfiles) {
 883 -#ifdef CRT0FILE_PROFILE
 884 -                                if (pgflag) {
 885 -                                        av[j++] = Bprefix(crt0file_profile);
 886 -                                } else
 887 -#endif
 888 -                                {
 889 -#ifdef CRT0FILE
 890 -                                        av[j++] = Bprefix(crt0file);
 891 -#endif
 892 -                                }
 893 -#ifdef STARTFILES_T
 894 -                                if (Bstatic) {
 895 -                                        for (i = 0; startfiles_T[i]; i++)
 896 -                                                av[j++] = Bprefix(listartfiles_T[i]);
 897 -                                } else
 898 -#endif
 899 -                                {
 900 -#ifdef STARTFILES
 901 -                                        for (i = 0; startfiles[i]; i++)
 902 -                                                av[j++] = Bprefix(startfiles[i]);
 903 -#endif
 904 -                                }
 905 -                        }
 906 -                }
 907 -                i = 0;
 908 -                while(i<nl) {
 909 -                        av[j++] = llist[i++];
 910 -                        if (j >= MAXAV)
 911 -                                error("Too many ld options");
 912 -                }
 913 -#ifndef MACHOABI
 914 -                /* darwin assembler doesn't want -g */
 915 -                if (gflag)
 916 -                        av[j++] = "-g";
 917 -#endif
 918 -#if 0
 919 -                if (gflag)
 920 -                        av[j++] = "-lg";
 921 -#endif
 922 -                if (pthreads)
 923 -                        av[j++] = "-lpthread";
 924 -                if (!nostdlib) {
 925 -#ifdef MSLINKER
 926 -                        char *s = copy("/LIBPATH:", strlen(pcclibdir));
 927 -#else
 928 -                        char *s = copy("-L", strlen(pcclibdir));
 929 -#endif
 930 -                        strcat(s, pcclibdir);
 931 -                        av[j++] = s;
 932 -                        if (pgflag) {
 933 -                                for (i = 0; libclibs_profile[i]; i++)
 934 -                                        av[j++] = Bprefix(libclibs_profile[i]);
 935 -                        } else {
 936 -                                for (i = 0; libclibs[i]; i++)
 937 -                                        av[j++] = Bprefix(libclibs[i]);
 938 -                        }
 939 -                }
 940 -                if (!nostartfiles) {
 941 -#ifdef STARTFILES_S
 942 -                        if (shared) {
 943 -                                for (i = 0; endfiles_S[i]; i++)
 944 -                                        av[j++] = Bprefix(endfiles_S[i]);
 945 -                        } else
 946 -#endif
 947 -                        {
 948 -#ifdef STARTFILES_T
 949 -                                if (Bstatic) {
 950 -                                        for (i = 0; endfiles_T[i]; i++)
 951 -                                                av[j++] = Bprefix(endfiles_T[i]);
 952 -                                } else
 953 -#endif
 954 -                                {
 955 -#ifdef STARTFILES
 956 -                                        for (i = 0; endfiles[i]; i++)
 957 -                                                av[j++] = Bprefix(endfiles[i]);
 958 -#endif
 959 -                                }
 960 -                        }
 961 -                }
 962 -                av[j++] = 0;
 963 -                eflag |= callsys(ld, av);
 964 -                if (nc==1 && nxo==1 && eflag==0)
 965 -                        cunlink(setsuf(clist[0], 'o'));
 966 -                else if (nc > 0 && eflag == 0) {
 967 -                        /* remove .o files XXX ugly */
 968 -                        for (i = 0; i < nc; i++)
 969 -                                cunlink(setsuf(clist[i], 'o'));
 970 -                }
 971 -        }
 972 -        dexit(eflag);
 973 -        return 0;
 974 -}
 975 -
 976 -/*
 977 - * exit and cleanup after interrupt.
 978 - */
 979 -void
 980 -idexit(int arg)
 981 -{
 982 -        dexit(100);
 983 -}
 984 -
 985 -/*
 986 - * exit and cleanup.
 987 - */
 988 -void
 989 -dexit(int eval)
 990 -{
 991 -        if (!pflag && !Xflag) {
 992 -                if (sflag==0)
 993 -                        cunlink(tmp3);
 994 -                cunlink(tmp4);
 995 -        }
 996 -        if (exfail || eflag)
 997 -                cunlink(ermfile);
 998 -        if (eval == 100)
 999 -                _exit(eval);
 1000 -        exit(eval);
 1001 -}
 1002 -
 1003 -static void
 1004 -ccerror(char *s, va_list ap)
 1005 -{
 1006 -        vfprintf(Eflag ? stderr : stdout, s, ap);
 1007 -        putc('\n', Eflag? stderr : stdout);
 1008 -        exfail++;
 1009 -        cflag++;
 1010 -        eflag++;
 1011 -}
 1012 -
 1013 -/*
 1014 - * complain a bit.
 1015 - */
 1016 -void
 1017 -error(char *s, ...)
 1018 -{
 1019 -        va_list ap;
 1020 -
 1021 -        va_start(ap, s);
 1022 -        ccerror(s, ap);
 1023 -        va_end(ap);
 1024 -}
 1025 -
 1026 -/*
 1027 - * complain a bit and then exit.
 1028 - */
 1029 -void
 1030 -errorx(int eval, char *s, ...)
 1031 -{
 1032 -        va_list ap;
 1033 -
 1034 -        va_start(ap, s);
 1035 -        ccerror(s, ap);
 1036 -        va_end(ap);
 1037 -        dexit(eval);
 1038 -}
 1039 -
 1040 -char *
 1041 -Bprefix(char *s)
 1042 -{
 1043 -        char *suffix;
 1044 -        char *str;
 1045 -
 1046 -        if (Bflag == NULL || s[0] != '/')
 1047 -                return s;
 1048 -
 1049 -        suffix = strrchr(s, '/');
 1050 -        if (suffix == NULL)
 1051 -                suffix = s;
 1052 -
 1053 -        str = copy(Bflag, strlen(suffix));
 1054 -        strcat(str, suffix);
 1055 -        return str;
 1056 -}
 1057 -
 1058 -int
 1059 -getsuf(char *s)
 1060 -{
 1061 -        register char *p;
 1062 -
 1063 -        if ((p = strrchr(s, '.')) && p[1] != '\0' && p[2] == '\0')
 1064 -                return p[1];
 1065 -        return(0);
 1066 -}
 1067 -
 1068 -/*
 1069 - * Get basename of string s and change its suffix to ch.
 1070 - */
 1071 -char *
 1072 -setsuf(char *s, char ch)
 1073 -{
 1074 -        char *p;
 1075 -
 1076 -        s = copy(basename(s), 2);
 1077 -        if ((p = strrchr(s, '.')) == NULL) {
 1078 -                p = s + strlen(s);
 1079 -                p[0] = '.';
 1080 -        }
 1081 -        p[1] = ch;
 1082 -        p[2] = '\0';
 1083 -        return(s);
 1084 -}
 1085 -
 1086 -#ifdef WIN32
 1087 -int
 1088 -callsys(char *f, char *v[])
 1089 -{
 1090 -        char *s;
 1091 -        int t, status = 0;
 1092 -        char cmd[MAX_PATH];
 1093 -        int len;
 1094 -        STARTUPINFO si;
 1095 -        PROCESS_INFORMATION pi;
 1096 -        DWORD exitCode;
 1097 -        BOOL ok;
 1098 -
 1099 -        len = strlcpy(cmd, f, MAX_PATH);
 1100 -        for (t = 1; v[t] && len < MAX_PATH; t++) {
 1101 -                len = strlcat(cmd, " ", MAX_PATH);
 1102 -                len = strlcat(cmd, v[t], MAX_PATH);
 1103 -        }
 1104 -
 1105 -        if (vflag)
 1106 -                printf("%s\n", cmd);
 1107 -
 1108 -        ZeroMemory(&si, sizeof(STARTUPINFO));
 1109 -        si.cb = sizeof(STARTUPINFO);
 1110 -        ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
 1111 -
 1112 -        ok = CreateProcess(NULL// the executable program
 1113 -                cmd,   // the command line arguments
 1114 -                NULL,       // ignored
 1115 -                NULL,       // ignored
 1116 -                TRUE,       // inherit handles
 1117 -                HIGH_PRIORITY_CLASS,
 1118 -                NULL,       // ignored
 1119 -                NULL,       // ignored
 1120 -                &si,
 1121 -                &pi);
 1122 -
 1123 -        if (!ok) {
 1124 -                fprintf(stderr, "Can't find %s\n", f);
 1125 -                return 100;
 1126 -        }
 1127 -
 1128 -        WaitForSingleObject(pi.hProcess, INFINITE);
 1129 -        GetExitCodeProcess(pi.hProcess, &exitCode);
 1130 -        return (exitCode != 0);
 1131 -}
 1132 -
 1133 -#else
 1134 -
 1135 -int
 1136 -callsys(char *f, char *v[])
 1137 -{
 1138 -        int t, status = 0;
 1139 -        pid_t p;
 1140 -        char *s;
 1141 -
 1142 -        if (vflag) {
 1143 -                fprintf(stderr, "%s ", f);
 1144 -                for (t = 1; v[t]; t++)
 1145 -                        fprintf(stderr, "%s ", v[t]);
 1146 -                fprintf(stderr, "\n");
 1147 -        }
 1148 -
 1149 -        if ((p = fork()) == 0) {
 1150 -                if (Bflag) {
 1151 -                        size_t len = strlen(Bflag) + 8;
 1152 -                        char *a = malloc(len);
 1153 -                        if (a == NULL) {
 1154 -                                error("callsys: malloc failed");
 1155 -                                exit(1);
 1156 -                        }
 1157 -                        if ((s = strrchr(f, '/'))) {
 1158 -                                strlcpy(a, Bflag, len);
 1159 -                                strlcat(a, s, len);
 1160 -                                execv(a, v);
 1161 -                        }
 1162 -                }
 1163 -                execvp(f, v);
 1164 -                if ((s = strrchr(f, '/')))
 1165 -                        execvp(s+1, v);
 1166 -                fprintf(stderr, "Can't find %s\n", f);
 1167 -                _exit(100);
 1168 -        } else {
 1169 -                if (p == -1) {
 1170 -                        printf("Try again\n");
 1171 -                        return(100);
 1172 -                }
 1173 -        }
 1174 -        while (waitpid(p, &status, 0) == -1 && errno == EINTR)
 1175 -                ;
 1176 -        if (WIFEXITED(status))
 1177 -                return (WEXITSTATUS(status));
 1178 -        if (WIFSIGNALED(status))
 1179 -                dexit(eflag ? eflag : 1);
 1180 -        errorx(8, "Fatal error in %s", f);
 1181 -
 1182 -        return 0;
 1183 -}
 1184 -#endif
 1185 -
 1186 -/*
 1187 - * Make a copy of string as, mallocing extra bytes in the string.
 1188 - */
 1189 -char *
 1190 -copy(char *s, int extra)
 1191 -{
 1192 -        int len = strlen(s)+1;
 1193 -        char *rv;
 1194 -
 1195 -        rv = ccmalloc(len+extra);
 1196 -        strlcpy(rv, s, len);
 1197 -        return rv;
 1198 -}
 1199 -
 1200 -int
 1201 -cunlink(char *f)
 1202 -{
 1203 -        if (f==0 || Xflag)
 1204 -                return(0);
 1205 -        return (unlink(f));
 1206 -}
 1207 -
 1208 -#ifdef WIN32
 1209 -char *
 1210 -gettmp(void)
 1211 -{
 1212 -#define BUFFSIZE 1000
 1213 -        DWORD pathSize;
 1214 -        char pathBuffer[BUFFSIZE];
 1215 -        char tempFilename[MAX_PATH];
 1216 -        UINT uniqueNum;
 1217 -
 1218 -        pathSize = GetTempPath(BUFFSIZE, pathBuffer);
 1219 -        if (pathSize < BUFFSIZE)
 1220 -                pathBuffer[pathSize] = 0;
 1221 -        else
 1222 -                pathBuffer[0] = 0;
 1223 -        uniqueNum = GetTempFileName(pathBuffer, "ctm", 0, tempFilename);
 1224 -        if (uniqueNum == 0) {
 1225 -                fprintf(stderr, "%s:\n", pathBuffer);
 1226 -                exit(8);
 1227 -        }
 1228 -        return copy(tempFilename, 0);
 1229 -}
 1230 -
 1231 -#else
 1232 -
 1233 -char *
 1234 -gettmp(void)
 1235 -{
 1236 -        char *sfn = copy("/tmp/ctm.XXXXXX", 0);
 1237 -        int fd = -1;
 1238 -
 1239 -        if ((fd = mkstemp(sfn)) == -1) {
 1240 -                fprintf(stderr, "%s: %s\n", sfn, strerror(errno));
 1241 -                exit(8);
 1242 -        }
 1243 -        close(fd);
 1244 -        return sfn;
 1245 -}
 1246 -#endif
 1247 -
 1248 -void *
 1249 -ccmalloc(int size)
 1250 -{
 1251 -        void *rv;
 1252 -
 1253 -        if ((rv = malloc(size)) == NULL)
 1254 -                error("malloc failed");
 1255 -        return rv;
 1256 -}
 1257 -
 1258 -#ifdef WIN32
 1259 -
 1260 -char *
 1261 -win32pathsubst(char *s)
 1262 -{
 1263 -        char env[1024];
 1264 -        char *rv;
 1265 -        int len;
 1266 -
 1267 -        len = ExpandEnvironmentStrings(s, env, sizeof(env));
 1268 -        if (len <= 0)
 1269 -                return s;
 1270 -
 1271 -        len += 3;
 1272 -        rv = ccmalloc(len);
 1273 -        strlcpy(rv, "\"", len);
 1274 -        strlcat(rv, env, len);
 1275 -        strlcat(rv, "\"", len);
 1276 -
 1277 -        return rv;
 1278 -}
 1279 -
 1280 -#endif
  1+/*      $Id$    */
  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
  42+ * - Files that end with .s are passed as->ld
  43+ * - Files that end with .o are passed directly to ld
  44+ * - Multiple files may be given on the command line.
  45+ * - Unrecognized options are all sent directly to ld.
  46+ * -c or -S cannot be combined with -o if multiple files are given.
  47+ *
  48+ * This file should be rewritten readable.
  49+ */
  50+#include "config.h"
  51+
  52+#include <sys/types.h>
  53+#ifdef HAVE_SYS_WAIT_H
  54+#include <sys/wait.h>
  55+#endif
  56+
  57+#include <ctype.h>
  58+#include <errno.h>
  59+#include <fcntl.h>
  60+#ifdef HAVE_LIBGEN_H
  61+#include <libgen.h>
  62+#endif
  63+#include <signal.h>
  64+#include <stdarg.h>
  65+#include <stdio.h>
  66+#include <stdlib.h>
  67+#include <string.h>
  68+#ifdef HAVE_UNISTD_H
  69+#include <unistd.h>
  70+#endif
  71+
  72+#ifdef WIN32
  73+#include <windows.h>
  74+#include <process.h>
  75+#include <io.h>
  76+#endif
  77+
  78+#include "compat.h"
  79+
  80+#include "ccconfig.h"
  81+/* C command */
  82+
  83+#define MKS(x) _MKS(x)
  84+#define _MKS(x) #x
  85+
  86+/*
  87+ * Many specific definitions, should be declared elsewhere.
  88+ */
  89+
  90+#ifndef STDINC
  91+#define STDINC          "/usr/include/"
  92+#endif
  93+
  94+#ifndef LIBDIR
  95+#define LIBDIR          "/usr/lib/"
  96+#endif
  97+
  98+#ifndef PREPROCESSOR
  99+#define PREPROCESSOR    "cpp"
  100+#endif
  101+
  102+#ifndef COMPILER
  103+#define COMPILER        "ccom";
  104+#endif
  105+
  106+#ifndef ASSEMBLER
  107+#define ASSEMBLER       "as"
  108+#endif
  109+
  110+#ifndef LINKER
  111+#define LINKER          "ld"
  112+#endif
  113+
  114+#define OS MKS(TARGOS)
  115+#define MACH MKS(TARGMACH)
  116+#ifndef PCCINCDIR
  117+#define PCCINCDIR       LIBDIR "pcc/" MACH "-" OS "/" PACKAGE_VERSION "/include"
  118+#endif
  119+#ifndef PCCLIBDIR
  120+#define PCCLIBDIR       LIBDIR "pcc/" MACH "-" OS "/" PACKAGE_VERSION "/lib"
  121+#endif
  122+
  123+#define MAXFIL 10000
  124+#define MAXLIB 10000
  125+#define MAXAV  10000
  126+#define MAXOPT 100
  127+char    *tmp3;
  128+char    *tmp4;
  129+char    *outfile, *ermfile;
  130+char *Bprefix(char *);
  131+char *copy(char *, int),*setsuf(char *, char);
  132+int getsuf(char *);
  133+int main(int, char *[]);
  134+void error(char *, ...);
  135+void errorx(int, char *, ...);
  136+int callsys(char [], char *[]);
  137+int cunlink(char *);
  138+void dexit(int);
  139+void idexit(int);
  140+char *gettmp(void);
  141+void *ccmalloc(int size);
  142+#ifdef WIN32
  143+char *win32pathsubst(char *);
  144+#endif
  145+char    *av[MAXAV];
  146+char    *clist[MAXFIL];
  147+char    *llist[MAXLIB];
  148+char    *aslist[MAXAV];
  149+char    alist[20];
  150+char    *xlist[100];
  151+int     xnum;
  152+char    *mlist[100];
  153+char    *flist[100];
  154+char    *wlist[100];
  155+char    *idirafter;
  156+int     nm;
  157+int     nf;
  158+int     nw;
  159+int     sspflag;
  160+int     Cflag;
  161+int     dflag;
  162+int     pflag;
  163+int     sflag;
  164+int     cflag;
  165+int     eflag;
  166+int     gflag;
  167+int     vflag;
  168+int     tflag;
  169+int     Eflag;
  170+int     Oflag;
  171+int     kflag;  /* generate PIC/pic code */
  172+#define F_PIC   1
  173+#define F_pic   2
  174+int     Mflag;  /* dependencies only */
  175+int     pgflag;
  176+int     exfail;
  177+int     Xflag;
  178+int     Wallflag;
  179+int     Wflag;
  180+int     nostartfiles, Bstatic, shared;
  181+int     nostdinc, nostdlib;
  182+int     onlyas;
  183+int     pthreads;
  184+int     xcflag;
  185+int     ascpp;
  186+
  187+char    *passp = LIBEXECDIR PREPROCESSOR;
  188+char    *pass0 = LIBEXECDIR COMPILER;
  189+char    *as = ASSEMBLER;
  190+char    *ld = LINKER;
  191+char    *Bflag;
  192+char *cppadd[] = CPPADD;
  193+#ifdef DYNLINKER
  194+char *dynlinker[] = DYNLINKER;
  195+#endif
  196+#ifdef CRT0FILE
  197+char *crt0file = CRT0FILE;
  198+#endif
  199+#ifdef CRT0FILE_PROFILE
  200+char *crt0file_profile = CRT0FILE_PROFILE;
  201+#endif
  202+#ifdef STARTFILES
  203+char *startfiles[] = STARTFILES;
  204+char *endfiles[] = ENDFILES;
  205+#endif
  206+#ifdef STARTFILES_T
  207+char *startfiles_T[] = STARTFILES_T;
  208+char *endfiles_T[] = ENDFILES_T;
  209+#endif
  210+#ifdef STARTFILES_S
  211+char *startfiles_S[] = STARTFILES_S;
  212+char *endfiles_S[] = ENDFILES_S;
  213+#endif
  214+#ifdef MULTITARGET
  215+char *mach = DEFMACH;
  216+struct cppmd {
  217+        char *mach;
  218+        char *cppmdadd[MAXCPPMDARGS];
  219+};
  220+
  221+struct cppmd cppmds[] = CPPMDADDS;
  222+#else
  223+char *cppmdadd[] = CPPMDADD;
  224+#endif
  225+#ifdef LIBCLIBS
  226+char *libclibs[] = LIBCLIBS;
  227+#else
  228+char *libclibs[] = { "-lc", NULL };
  229+#endif
  230+#ifdef LIBCLIBS_PROFILE
  231+char *libclibs_profile[] = LIBCLIBS_PROFILE;
  232+#else
  233+char *libclibs_profile[] = { "-lc_p", NULL };
  234+#endif
  235+#ifndef STARTLABEL
  236+#define STARTLABEL "__start"
  237+#endif
  238+char *incdir = STDINC;
  239+char *pccincdir = PCCINCDIR;
  240+char *pcclibdir = PCCLIBDIR;
  241+
  242+/* handle gcc warning emulations */
  243+struct Wflags {
  244+        char *name;
  245+        int flags;
  246+#define INWALL          1
  247+#define NEGATIVE        2
  248+} Wflags[] = {
  249+        { "-Werror", 0 },
  250+        { "-Wshadow", 0 },
  251+        { "-Wno-shadow", NEGATIVE },
  252+        { "-Wpointer-sign", INWALL },
  253+        { "-Wno-pointer-sign", NEGATIVE },
  254+        { "-Wsign-compare", 0 },
  255+        { "-Wno-sign-compare", NEGATIVE },
  256+        { "-Wunknown-pragmas", INWALL },
  257+        { "-Wno-unknown-pragmas", NEGATIVE },
  258+        { "-Wunreachable-code", 0 },
  259+        { "-Wno-unreachable-code", NEGATIVE },
  260+        { 0, 0 },
  261+};
  262+
  263+#define SZWFL   (sizeof(Wflags)/sizeof(Wflags[0]))
  264+
  265+int
  266+main(int argc, char *argv[])
  267+{
  268+        struct Wflags *Wf;
  269+        char *t, *u;
  270+        char *assource;
  271+        char **pv, *ptemp[MAXOPT], **pvt;
  272+        int nc, nl, nas, i, j, c, nxo, na;
  273+#ifdef MULTITARGET
  274+        int k;
  275+#endif
  276+
  277+#ifdef WIN32
  278+        /* have to prefix path early.  -B may override */
  279+        incdir = win32pathsubst(incdir);
  280+        pccincdir = win32pathsubst(pccincdir);
  281+        pcclibdir = win32pathsubst(pcclibdir);
  282+        passp = win32pathsubst(passp);
  283+        pass0 = win32pathsubst(pass0);
  284+#endif
  285+
  286+        i = nc = nl = nas = nxo = 0;
  287+        pv = ptemp;
  288+        while(++i < argc) {
  289+                if (argv[i][0] == '-') {
  290+                        switch (argv[i][1]) {
  291+                        default:
  292+                                goto passa;
  293+#ifdef notyet
  294+        /* must add library options first (-L/-l/...) */
  295+                                error("unrecognized option `-%c'", argv[i][1]);
  296+                                break;
  297+#endif
  298+
  299+                        case '-': /* double -'s */
  300+                                if (strcmp(argv[i], "--version") == 0)
  301+                                        printf("%s\n", VERSSTR);
  302+                                else if (strcmp(argv[i], "--param") == 0)
  303+                                        /* NOTHING YET */;
  304+                                else
  305+                                        error("unrecognized option %s", argv[i]);
  306+                                break;
  307+
  308+                        case 'B': /* other search paths for binaries */
  309+                                Bflag = &argv[i][2];
  310+                                break;
  311+
  312+#ifdef MULTITARGET
  313+                        case 'b':
  314+                                t = &argv[i][2];
  315+                                if (*t == '\0' && i + 1 < argc) {
  316+                                        t = argv[i+1];
  317+                                        i++;
  318+                                }
  319+                                if (strncmp(t, "?", 1) == 0) {
  320+                                        /* show machine targets */
  321+                                        printf("Available machine targets:");
  322+                                        for (j=0; cppmds[j].mach; j++)
  323+                                                printf(" %s",cppmds[j].mach);
  324+                                        printf("\n");
  325+                                        exit(0);
  326+                                }
  327+                                for (j=0; cppmds[j].mach; j++)
  328+                                        if (strcmp(t, cppmds[j].mach) == 0) {
  329+                                                mach = cppmds[j].mach;
  330+                                                break;
  331+                                        }
  332+                                if (cppmds[j].mach == NULL)
  333+                                        errorx(1, "unknown target arch %s", t);
  334+                                break;
  335+#endif
  336+
  337+                        case 'X':
  338+                                Xflag++;
  339+                                break;
  340+                        case 'W': /* Ignore (most of) W-flags */
  341+                                if (strncmp(argv[i], "-Wl,", 4) == 0) {
  342+                                        /* options to the linker */
  343+                                        t = &argv[i][4];
  344+                                        while ((u = strchr(t, ','))) {
  345+                                                *u++ = 0;
  346+                                                llist[nl++] = t;
  347+                                                t = u;
  348+                                        }
  349+                                        llist[nl++] = t;
  350+                                } else if (strncmp(argv[i], "-Wa,", 4) == 0) {
  351+                                        /* options to the assembler */
  352+                                        t = &argv[i][4];
  353+                                        while ((u = strchr(t, ','))) {
  354+                                                *u++ = 0;
  355+                                                aslist[nas++] = t;
  356+                                                t = u;
  357+                                        }
  358+                                        aslist[nas++] = t;
  359+                                } else if (strncmp(argv[i], "-Wp,", 4) == 0) {
  360+                                        /* preprocessor */
  361+                                        if (!strncmp(argv[i], "-Wp,-C", 6))
  362+                                                Cflag++;
  363+                                } else if (strcmp(argv[i], "-Wall") == 0) {
  364+                                        Wallflag = 1;
  365+                                } else if (strcmp(argv[i], "-WW") == 0) {
  366+                                        Wflag = 1;
  367+                                } else {
  368+                                        /* check and set if available */
  369+                                        for (Wf = Wflags; Wf->name; Wf++) {
  370+                                                if (strcmp(argv[i], Wf->name))
  371+                                                        continue;
  372+                                                wlist[nw++] = Wf->name;
  373+                                        }
  374+                                }
  375+                                break;
  376+
  377+                        case 'f': /* GCC compatibility flags */
  378+                                if (strcmp(argv[i], "-fPIC") == 0)
  379+                                        kflag = F_PIC;
  380+                                else if (strcmp(argv[i], "-fpic") == 0)
  381+                                        kflag = F_pic;
  382+                                else if (strcmp(argv[i],
  383+                                    "-fsigned-char") == 0)
  384+                                        flist[nf++] = argv[i];
  385+                                else if (strcmp(argv[i],
  386+                                    "-fno-signed-char") == 0)
  387+                                        flist[nf++] = argv[i];
  388+                                else if (strcmp(argv[i],
  389+                                    "-funsigned-char") == 0)
  390+                                        flist[nf++] = argv[i];
  391+                                else if (strcmp(argv[i],
  392+                                    "-fno-unsigned-char") == 0)
  393+                                        flist[nf++] = argv[i];
  394+                                else if (strcmp(argv[i],
  395+                                    "-fstack-protector") == 0) {
  396+                                        flist[nf++] = argv[i];
  397+                                        sspflag++;
  398+                                } else if (strcmp(argv[i],
  399+                                    "-fstack-protector-all") == 0) {
  400+                                        flist[nf++] = argv[i];
  401+                                        sspflag++;
  402+                                } else if (strcmp(argv[i],
  403+                                    "-fno-stack-protector") == 0) {
  404+                                        flist[nf++] = argv[i];
  405+                                        sspflag = 0;
  406+                                } else if (strcmp(argv[i],
  407+                                    "-fno-stack-protector-all") == 0) {
  408+                                        flist[nf++] = argv[i];
  409+                                        sspflag = 0;
  410+                                }
  411+                                /* silently ignore the rest */
  412+                                break;
  413+
  414+                        case 'g': /* create debug output */
  415+                                gflag++;
  416+                                break;
  417+
  418+                        case 'i':
  419+                                if (strcmp(argv[i], "-isystem") == 0) {
  420+                                        *pv++ = "-S";
  421+                                        *pv++ = argv[++i];
  422+                                } else if (strcmp(argv[i], "-include") == 0) {
  423+                                        *pv++ = "-i";
  424+                                        *pv++ = argv[++i];
  425+                                } else if (strcmp(argv[i], "-idirafter") == 0) {
  426+                                        idirafter = argv[++i];
  427+                                } else
  428+                                        goto passa;
  429+                                break;
  430+
  431+                        case 'k': /* generate PIC code */
  432+                                kflag = F_pic;
  433+                                break;
  434+
  435+                        case 'm': /* target-dependent options */
  436+                                mlist[nm++] = argv[i];
  437+                                break;
  438+
  439+                        case 'n': /* handle -n flags */
  440+                                if (strcmp(argv[i], "-nostdinc") == 0)
  441+                                        nostdinc++;
  442+                                else if (strcmp(argv[i], "-nostdlib") == 0) {
  443+                                        nostdlib++;
  444+                                        nostartfiles++;
  445+                                } else if (strcmp(argv[i], "-nostartfiles") == 0)
  446+                                        nostartfiles = 1;
  447+                                else
  448+                                        goto passa;
  449+                                break;
  450+
  451+                        case 'p':
  452+                                if (strcmp(argv[i], "-pg") == 0 ||
  453+                                    strcmp(argv[i], "-p") == 0)
  454+                                        pgflag++;
  455+                                else if (strcmp(argv[i], "-pthread") == 0)
  456+                                        pthreads++;
  457+                                else if (strcmp(argv[i], "-pipe") == 0)
  458+                                        /* NOTHING YET */;
  459+                                else
  460+                                        errorx(1, "unknown option %s", argv[i]);
  461+                                break;
  462+
  463+                        case 'x':
  464+                                t = &argv[i][2];
  465+                                if (*t == 0)
  466+                                        t = argv[++i];
  467+                                if (strcmp(t, "c") == 0)
  468+                                        xcflag = 1; /* default */
  469+                                else if (strcmp(t, "assembler-with-cpp") == 0)
  470+                                        ascpp = 1;
  471+#ifdef notyet
  472+                                else if (strcmp(t, "c++") == 0)
  473+                                        cxxflag++;
  474+#endif
  475+                                else
  476+                                        xlist[xnum++] = argv[i];
  477+                                break;
  478+                        case 't':
  479+                                tflag++;
  480+                                break;
  481+                        case 'S':
  482+                                sflag++;
  483+                                cflag++;
  484+                                break;
  485+                        case 'o':
  486+                                if (outfile)
  487+                                        errorx(8, "too many -o");
  488+                                outfile = argv[++i];
  489+                                break;
  490+                        case 'O':
  491+                                if (argv[i][2] == '0')
  492+                                        Oflag = 0;
  493+                                else
  494+                                        Oflag++;
  495+                                break;
  496+                        case 'E':
  497+                                Eflag++;
  498+                                break;
  499+                        case 'P':
  500+                                pflag++;
  501+                                *pv++ = argv[i];
  502+                        case 'c':
  503+                                cflag++;
  504+                                break;
  505+
  506+#if 0
  507+                        case '2':
  508+                                if(argv[i][2] == '\0')
  509+                                        pref = "/lib/crt2.o";
  510+                                else {
  511+                                        pref = "/lib/crt20.o";
  512+                                }
  513+                                break;
  514+#endif
  515+                        case 'C':
  516+                                Cflag = 1;
  517+                                break;
  518+                        case 'D':
  519+                        case 'I':
  520+                        case 'U':
  521+                                *pv++ = argv[i];
  522+                                if (argv[i][2] == 0)
  523+                                        *pv++ = argv[++i];
  524+                                if (pv >= ptemp+MAXOPT) {
  525+                                        error("Too many DIU options");
  526+                                        --pv;
  527+                                }
  528+                                break;
  529+
  530+                        case 'M':
  531+                                Mflag++;
  532+                                break;
  533+
  534+                        case 'd':
  535+                                dflag++;
  536+                                strlcpy(alist, argv[i], sizeof (alist));
  537+                                break;
  538+                        case 'v':
  539+                                printf("%s\n", VERSSTR);
  540+                                vflag++;
  541+                                break;
  542+
  543+                        case 's':
  544+                                if (strcmp(argv[i], "-static") == 0)
  545+                                        Bstatic = 1;
  546+                                else if (strcmp(argv[i], "-shared") == 0) {
  547+                                        shared = 1;
  548+#ifndef os_win32
  549+                                        nostdlib = 1;
  550+#endif
  551+                                } else if (strncmp(argv[i], "-std", 4) == 0) {
  552+                                        /* ignore gcc -std= */;
  553+                                } else
  554+                                        goto passa;
  555+                                break;
  556+                        }
  557+                } else {
  558+                passa:
  559+                        t = argv[i];
  560+                        if (*argv[i] == '-' && argv[i][1] == 'L')
  561+                                ;
  562+                        else if((c=getsuf(t))=='c' || c=='S' || c=='i' ||
  563+                            c=='s'|| Eflag || xcflag) {
  564+                                clist[nc++] = t;
  565+                                if (nc>=MAXFIL) {
  566+                                        error("Too many source files");
  567+                                        exit(1);
  568+                                }
  569+                                t = setsuf(t, 'o');
  570+                        }
  571+
  572+                        /* Check for duplicate .o files. */
  573+                        for (j = getsuf(t) == 'o' ? 0 : nl; j < nl; j++) {
  574+                                if (strcmp(llist[j], t) == 0)
  575+                                        break;
  576+                        }
  577+                        if (j == nl) {
  578+                                llist[nl++] = t;
  579+                                if (nl >= MAXLIB) {
  580+                                        error("Too many object/library files");
  581+                                        exit(1);
  582+                                }
  583+                                if (getsuf(t)=='o')
  584+                                        nxo++;
  585+                        }
  586+                }
  587+        }
  588+        /* Sanity checking */
  589+        if (nc == 0 && nl == 0)
  590+                errorx(8, "no input files");
  591+        if (outfile && (cflag || sflag || Eflag) && nc > 1)
  592+                errorx(8, "-o given with -c || -E || -S and more than one file");
  593+        if (outfile && clist[0] && strcmp(outfile, clist[0]) == 0)
  594+                errorx(8, "output file will be clobbered");
  595+        if (gflag) Oflag = 0;
  596+#if 0
  597+        if (proflag)
  598+                pref = "/lib/mcrt0.o";
  599+#endif
  600+        if(nc==0)
  601+                goto nocom;
  602+        if (pflag==0) {
  603+                if (!sflag)
  604+                        tmp3 = gettmp();
  605+                tmp4 = gettmp();
  606+        }
  607+        if (Bflag) {
  608+                incdir = Bflag;
  609+                pccincdir = Bflag;
  610+                pcclibdir = Bflag;
  611+        }
  612+        if (signal(SIGINT, SIG_IGN) != SIG_IGN/* interrupt */
  613+                signal(SIGINT, idexit);
  614+        if (signal(SIGTERM, SIG_IGN) != SIG_IGN)        /* terminate */
  615+                signal(SIGTERM, idexit);
  616+#ifdef MULTITARGET
  617+        asprintf(&pass0, "%s%s%s", LIBEXECDIR, "ccom_", mach);
  618+#endif
  619+        pvt = pv;
  620+        for (i=0; i<nc; i++) {
  621+                /*
  622+                 * C preprocessor
  623+                 */
  624+                if (nc>1 && !Eflag)
  625+                        printf("%s:\n", clist[i]);
  626+                onlyas = 0;
  627+                assource = tmp3;
  628+                if (getsuf(clist[i])=='S')
  629+                        ascpp = 1;
  630+                if (getsuf(clist[i])=='i') {
  631+                        if(Eflag)
  632+                                continue;
  633+                        goto com;
  634+                } else if (ascpp) {
  635+                        onlyas = 1;
  636+                } else if (getsuf(clist[i])=='s') {
  637+                        assource = clist[i];
  638+                        goto assemble;
  639+                }
  640+                if (pflag)
  641+                        tmp4 = setsuf(clist[i], 'i');
  642+                na = 0;
  643+                av[na++] = "cpp";
  644+                if (vflag)
  645+                        av[na++] = "-v";
  646+                av[na++] = "-D__PCC__=" MKS(PCC_MAJOR);
  647+                av[na++] = "-D__PCC_MINOR__=" MKS(PCC_MINOR);
  648+                av[na++] = "-D__PCC_MINORMINOR__=" MKS(PCC_MINORMINOR);
  649+                if (ascpp)
  650+                        av[na++] = "-D__ASSEMBLER__";
  651+                if (sspflag)
  652+                        av[na++] = "-D__SSP__=1";
  653+                if (pthreads)
  654+                        av[na++] = "-D_PTHREADS";
  655+                if (Cflag)
  656+                        av[na++] = "-C";
  657+                if (Mflag)
  658+                        av[na++] = "-M";
  659+                if (dflag)
  660+                        av[na++] = alist;
  661+                for (j = 0; cppadd[j]; j++)
  662+                        av[na++] = cppadd[j];
  663+#ifdef MULTITARGET
  664+                for (k = 0; cppmds[k].mach; k++) {
  665+                        if (strcmp(cppmds[k].mach, mach) != 0)
  666+                                continue;
  667+                        for (j = 0; cppmds[k].cppmdadd[j]; j++)
  668+                                av[na++] = cppmds[k].cppmdadd[j];
  669+                        break;
  670+                }
  671+#else
  672+                for (j = 0; cppmdadd[j]; j++)
  673+                        av[na++] = cppmdadd[j];
  674+#endif
  675+                if (tflag)
  676+                        av[na++] = "-t";
  677+                for(pv=ptemp; pv <pvt; pv++)
  678+                        av[na++] = *pv;
  679+                if (!nostdinc)
  680+                        av[na++] = "-S", av[na++] = incdir;
  681+                av[na++] = "-I", av[na++] = pccincdir;
  682+                if (idirafter) {
  683+                        av[na++] = "-I";
  684+                        av[na++] = idirafter;
  685+                }
  686+                av[na++] = clist[i];
  687+                if (!Eflag && !Mflag)
  688+                        av[na++] = tmp4;
  689+                if (Eflag && outfile)
  690+                         ermfile = av[na++] = outfile;
  691+                av[na++]=0;
  692+                if (callsys(passp, av))
  693+                        {exfail++; eflag++;}
  694+                if (Eflag || Mflag)
  695+                        continue;
  696+                if (onlyas) {
  697+                        assource = tmp4;
  698+                        goto assemble;
  699+                }
  700+
  701+                /*
  702+                 * C compiler
  703+                 */
  704+        com:
  705+                na = 0;
  706+                av[na++]= "ccom";
  707+                if (Wallflag) {
  708+                        /* Set only the same flags as gcc */
  709+                        for (Wf = Wflags; Wf->name; Wf++) {
  710+                                if (Wf->flags != INWALL)
  711+                                        continue;
  712+                                av[na++] = Wf->name;
  713+                        }
  714+                }
  715+                if (Wflag) {
  716+                        /* set all positive flags */
  717+                        for (Wf = Wflags; Wf->name; Wf++) {
  718+                                if (Wf->flags == NEGATIVE)
  719+                                        continue;
  720+                                av[na++] = Wf->name;
  721+                        }
  722+                }
  723+                for (j = 0; j < nw; j++)
  724+                        av[na++] = wlist[j];
  725+                for (j = 0; j < nf; j++)
  726+                        av[na++] = flist[j];
  727+                if (vflag)
  728+                        av[na++] = "-v";
  729+                if (pgflag)
  730+                        av[na++] = "-p";
  731+                if (gflag)
  732+                        av[na++] = "-g";
  733+#ifdef os_darwin
  734+                /* darwin always wants PIC compilation */
  735+                if (!Bstatic)
  736+                        av[na++] = "-k";
  737+#else
  738+                if (kflag)
  739+                        av[na++] = "-k";
  740+#endif
  741+                if (Oflag) {
  742+                        av[na++] = "-xtemps";
  743+                        av[na++] = "-xdeljumps";
  744+                }
  745+                for (j = 0; j < xnum; j++)
  746+                        av[na++] = xlist[j];
  747+                for (j = 0; j < nm; j++)
  748+                        av[na++] = mlist[j];
  749+                if (getsuf(clist[i])=='i')
  750+                        av[na++] = clist[i];
  751+                else
  752+                        av[na++] = tmp4; /* created by cpp */
  753+                if (pflag || exfail)
  754+                        {
  755+                        cflag++;
  756+                        continue;
  757+                        }
  758+                if(sflag) {
  759+                        if (outfile)
  760+                                tmp3 = outfile;
  761+                        else
  762+                                tmp3 = setsuf(clist[i], 's');
  763+                }
  764+                ermfile = av[na++] = tmp3;
  765+#if 0
  766+                if (proflag) {
  767+                        av[3] = "-XP";
  768+                        av[4] = 0;
  769+                } else
  770+                        av[3] = 0;
  771+#endif
  772+                av[na++] = NULL;
  773+                if (callsys(pass0, av)) {
  774+                        cflag++;
  775+                        eflag++;
  776+                        continue;
  777+                }
  778+                if (sflag)
  779+                        continue;
  780+
  781+                /*
  782+                 * Assembler
  783+                 */
  784+        assemble:
  785+                na = 0;
  786+                av[na++] = as;
  787+                for (j = 0; j < nas; j++)
  788+                        av[na++] = aslist[j];
  789+#if defined(os_sunos) && defined(mach_sparc64)
  790+                av[na++] = "-m64";
  791+#endif
  792+#if defined(os_darwin)
  793+                if (Bstatic)
  794+                        av[na++] = "-static";
  795+#endif
  796+                if (vflag)
  797+                        av[na++] = "-v";
  798+                if (kflag)
  799+                        av[na++] = "-k";
  800+                av[na++] = "-o";
  801+                if (outfile && cflag)
  802+                        ermfile = av[na++] = outfile;
  803+                else
  804+                        ermfile = av[na++] = setsuf(clist[i], 'o');
  805+                av[na++] = assource;
  806+                if (dflag)
  807+                        av[na++] = alist;
  808+                av[na++] = 0;
  809+                if (callsys(as, av)) {
  810+                        cflag++;
  811+                        eflag++;
  812+                        cunlink(tmp4);
  813+                        continue;
  814+                }
  815+                cunlink(tmp4);
  816+        }
  817+
  818+        if (Eflag || Mflag)
  819+                dexit(eflag);
  820+
  821+        /*
  822+         * Linker
  823+         */
  824+nocom:
  825+        if (cflag==0 && nl!=0) {
  826+                j = 0;
  827+                av[j++] = ld;
  828+#ifndef MSLINKER
  829+                if (vflag)
  830+                        av[j++] = "-v";
  831+#endif
  832+#if !defined(os_sunos) && !defined(os_win32)
  833+                av[j++] = "-X";
  834+#endif
  835+                if (shared) {
  836+                        av[j++] = "-shared";
  837+#ifdef os_win32
  838+                        av[j++] = "-Bdynamic";
  839+#endif
  840+#ifndef os_sunos
  841+                } else {
  842+#ifndef os_win32
  843+#ifndef os_darwin
  844+                        av[j++] = "-d";
  845+#endif
  846+                        av[j++] = "-e";
  847+                        av[j++] = STARTLABEL;
  848+#endif
  849+#endif
  850+                        if (Bstatic == 0) { /* Dynamic linkage */
  851+#ifdef DYNLINKER
  852+                                for (i = 0; dynlinker[i]; i++)
  853+                                        av[j++] = dynlinker[i];
  854+#endif
  855+                        } else {
  856+#ifdef os_darwin
  857+                                av[j++] = "-static";
  858+#else
  859+                                av[j++] = "-Bstatic";
  860+#endif
  861+                        }
  862+                }
  863+                if (outfile) {
  864+#ifdef MSLINKER
  865+                        char *s = copy("/OUT:", strlen(outfile));
  866+                        strcat(s, outfile);
  867+                        av[j++] = s;
  868+#else
  869+                        av[j++] = "-o";
  870+                        av[j++] = outfile;
  871+#endif
  872+                }
  873+#ifdef STARTFILES_S
  874+                if (shared) {
  875+                        if (!nostartfiles) {
  876+                                for (i = 0; startfiles_S[i]; i++)
  877+                                        av[j++] = Bprefix(startfiles_S[i]);
  878+                        }
  879+                } else
  880+#endif
  881+                {
  882+                        if (!nostartfiles) {
  883+#ifdef CRT0FILE_PROFILE
  884+                                if (pgflag) {
  885+                                        av[j++] = Bprefix(crt0file_profile);
  886+                                } else
  887+#endif
  888+                                {
  889+#ifdef CRT0FILE
  890+                                        av[j++] = Bprefix(crt0file);
  891+#endif
  892+                                }
  893+#ifdef STARTFILES_T
  894+                                if (Bstatic) {
  895+                                        for (i = 0; startfiles_T[i]; i++)
  896+                                                av[j++] = Bprefix(listartfiles_T[i]);
  897+                                } else
  898+#endif
  899+                                {
  900+#ifdef STARTFILES
  901+                                        for (i = 0; startfiles[i]; i++)
  902+                                                av[j++] = Bprefix(startfiles[i]);
  903+#endif
  904+                                }
  905+                        }
  906+                }
  907+                i = 0;
  908+                while(i<nl) {
  909+                        av[j++] = llist[i++];
  910+                        if (j >= MAXAV)
  911+                                error("Too many ld options");
  912+                }
  913+#ifndef MACHOABI
  914+                /* darwin assembler doesn't want -g */
  915+                if (gflag)
  916+                        av[j++] = "-g";
  917+#endif
  918+#if 0
  919+                if (gflag)
  920+                        av[j++] = "-lg";
  921+#endif
  922+                if (pthreads)
  923+                        av[j++] = "-lpthread";
  924+                if (!nostdlib) {
  925+#ifdef MSLINKER
  926+                        char *s = copy("/LIBPATH:", strlen(pcclibdir));
  927+#else
  928+                        char *s = copy("-L", strlen(pcclibdir));
  929+#endif
  930+                        strcat(s, pcclibdir);
  931+                        av[j++] = s;
  932+                        if (pgflag) {
  933+                                for (i = 0; libclibs_profile[i]; i++)
  934+                                        av[j++] = Bprefix(libclibs_profile[i]);
  935+                        } else {
  936+                                for (i = 0; libclibs[i]; i++)
  937+                                        av[j++] = Bprefix(libclibs[i]);
  938+                        }
  939+                }
  940+                if (!nostartfiles) {
  941+#ifdef STARTFILES_S
  942+                        if (shared) {
  943+                                for (i = 0; endfiles_S[i]; i++)
  944+                                        av[j++] = Bprefix(endfiles_S[i]);
  945+                        } else
  946+#endif
  947+                        {
  948+#ifdef STARTFILES_T
  949+                                if (Bstatic) {
  950+                                        for (i = 0; endfiles_T[i]; i++)
  951+                                                av[j++] = Bprefix(endfiles_T[i]);
  952+                                } else
  953+#endif
  954+                                {
  955+#ifdef STARTFILES
  956+                                        for (i = 0; endfiles[i]; i++)
  957+                                                av[j++] = Bprefix(endfiles[i]);
  958+#endif
  959+                                }
  960+                        }
  961+                }
  962+                av[j++] = 0;
  963+                eflag |= callsys(ld, av);
  964+                if (nc==1 && nxo==1 && eflag==0)
  965+                        cunlink(setsuf(clist[0], 'o'));
  966+                else if (nc > 0 && eflag == 0) {
  967+                        /* remove .o files XXX ugly */
  968+                        for (i = 0; i < nc; i++)
  969+                                cunlink(setsuf(clist[i], 'o'));
  970+                }
  971+        }
  972+        dexit(eflag);
  973+        return 0;
  974+}
  975+
  976+/*
  977+ * exit and cleanup after interrupt.
  978+ */
  979+void
  980+idexit(int arg)
  981+{
  982+        dexit(100);
  983+}
  984+
  985+/*
  986+ * exit and cleanup.
  987+ */
  988+void
  989+dexit(int eval)
  990+{
  991+        if (!pflag && !Xflag) {
  992+                if (sflag==0)