Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

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