Quick Search:

Mode

Context

Displaying the whole file. None | Less | More | Full

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.274
 
1.275
 
MAIN:plunky:20140606131903
 
cc.c
_>11 /*      $Id$    */
 22 
 33 /*-
 44  * Copyright (c) 2011 Joerg Sonnenberger <joerg@NetBSD.org>.
 55  * All rights reserved.
 66  *
 77  * Redistribution and use in source and binary forms, with or without
 88  * modification, are permitted provided that the following conditions
 99  * are met:
 1010  *
 1111  * 1. Redistributions of source code must retain the above copyright
 1212  *    notice, this list of conditions and the following disclaimer.
 1313  * 2. Redistributions in binary form must reproduce the above copyright
 1414  *    notice, this list of conditions and the following disclaimer in
 1515  *    the documentation and/or other materials provided with the
 1616  *    distribution.
 1717  *
 1818  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 1919  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 2020  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 2121  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 2222  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 2323  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
 2424  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 2525  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 2626  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 2727  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 2828  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 2929  * SUCH DAMAGE.
 3030  */
 3131 
 3232 /*
 3333  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
 3434  *
 3535  * Redistribution and use in source and binary forms, with or without
 3636  * modification, are permitted provided that the following conditions
 3737  * are met:
 3838  *
 3939  * Redistributions of source code and documentation must retain the above
 4040  * copyright notice, this list of conditions and the following disclaimer.
 4141  * Redistributions in binary form must reproduce the above copyright
 4242  * notice, this list of conditionsand the following disclaimer in the
 4343  * documentation and/or other materials provided with the distribution.
 4444  * All advertising materials mentioning features or use of this software
 4545  * must display the following acknowledgement:
 4646  *      This product includes software developed or owned by Caldera
 4747  *      International, Inc.
 4848  * Neither the name of Caldera International, Inc. nor the names of other
 4949  * contributors may be used to endorse or promote products derived from
 5050  * this software without specific prior written permission.
 5151  *
 5252  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
 5353  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
 5454  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 5555  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 5656  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
 5757  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 5858  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 5959  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 6060  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
 6161  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 6262  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 6363  * POSSIBILITY OF SUCH DAMAGE.
 6464  */
 6565 
 6666 /*
 6767  * Front-end to the C compiler.
 6868  *
 6969  * Brief description of its syntax:
 7070  * - Files that end with .c are passed via cpp->ccom->as->ld
 7171  * - Files that end with .i are passed via ccom->as->ld
 7272  * - Files that end with .S are passed via cpp->as->ld
 7373  * - Files that end with .s are passed via as->ld
 7474  * - Files that end with .o are passed directly to ld
 7575  * - Multiple files may be given on the command line.
 7676  * - Unrecognized options are all sent directly to ld.
 7777  * -c or -S cannot be combined with -o if multiple files are given.
 7878  *
 7979  * This file should be rewritten readable.
 8080  */
 8181 #include "config.h"
 8282 
 8383 #include <sys/types.h>
 8484 #ifdef HAVE_SYS_WAIT_H
 8585 #include <sys/wait.h>
 8686 #endif
 8787 
 8888 #include <ctype.h>
 8989 #include <errno.h>
 9090 #include <fcntl.h>
 9191 #ifdef HAVE_LIBGEN_H
 9292 #include <libgen.h>
 9393 #endif
 9494 #include <signal.h>
 9595 #include <stdarg.h>
 9696 #include <stdio.h>
 9797 #include <stdlib.h>
 9898 #include <string.h>
 9999 #ifdef HAVE_UNISTD_H
 100100 #include <unistd.h>
 101101 #endif
 102102 #include <assert.h>
 103103 
 104104 #ifdef os_win32
 105105 #include <windows.h>
 106106 #include <process.h>
 107107 #include <io.h>
 108108 #define F_OK    0x00
 109109 #define R_OK    0x04
 110110 #define W_OK    0x02
 111111 #define X_OK    R_OK
 112112 #endif
 113113 
 114114 #include "compat.h"
 115115 
 116116 #include "macdefs.h"
 117117 
 118118 #include "xalloc.h"
 119119 #include "strlist.h"
 120120 
 121121 #include "ccconfig.h"
 122122 /* C command */
 123123 
 124124 #define MKS(x) _MKS(x)
 125125 #define _MKS(x) #x
 126126 
 127127 /* default program names in pcc */
 128128 /* May be overridden if cross-compiler is generated */
 129129 #ifndef CPPROGNAME
 130130 #define CPPROGNAME      "cpp"   /* cc used as cpp */
 131131 #endif
 132132 #ifndef PREPROCESSOR
 133133 #define PREPROCESSOR    "cpp"   /* "real" preprocessor name */
 134134 #endif
 135135 #ifndef COMPILER
 136136 #define COMPILER        "ccom"
 137137 #endif
 138138 #ifndef CXXCOMPILER
 139139 #define CXXCOMPILER     "cxxcom"
 140140 #endif
 141141 #ifndef ASSEMBLER
 142142 #define ASSEMBLER       "as"
 143143 #endif
 144144 #ifndef LINKER
 145145 #define LINKER          "ld"
 146146 #endif
 147147 char    *passp = PREPROCESSOR;
 148148 char    *pass0 = COMPILER;
 149149 char    *passxx0 = CXXCOMPILER;
 150150 char    *as = ASSEMBLER;
 151151 char    *ld = LINKER;
 152152 char    *sysroot = "", *isysroot;
 153153 
 154154 
 155155 /* crt files using pcc default names */
 156156 #ifndef CRTBEGIN_S
 157157 #define CRTBEGIN_S      "crtbeginS.o"
 158158 #endif
 159159 #ifndef CRTEND_S
 160160 #define CRTEND_S        "crtendS.o"
 161161 #endif
 162162 #ifndef CRTBEGIN_T
 163163 #define CRTBEGIN_T      "crtbeginT.o"
 164164 #endif
 165165 #ifndef CRTEND_T
 166166 #define CRTEND_T        "crtendT.o"
 167167 #endif
 168168 #ifndef CRTBEGIN
 169169 #define CRTBEGIN        "crtbegin.o"
 170170 #endif
 171171 #ifndef CRTEND
 172172 #define CRTEND          "crtend.o"
 173173 #endif
 174174 #ifndef CRTI
 175175 #define CRTI            "crti.o"
 176176 #endif
 177177 #ifndef CRTN
 178178 #define CRTN            "crtn.o"
 179179 #endif
 180180 #ifndef CRT0
 181181 #define CRT0            "crt0.o"
 182182 #endif
 183183 #ifndef GCRT0
 184184 #define GCRT0           "gcrt0.o"
 185185 #endif
 186186 
 187187 /* preprocessor stuff */
 188188 #ifndef STDINC
 189189 #define STDINC          "/usr/include/"
 190190 #endif
 191191 
 192192 char *cppadd[] = CPPADD;
 193193 char *cppmdadd[] = CPPMDADD;
 194194 
 195195 /* Dynamic linker definitions, per-target */
 196196 #ifndef DYNLINKER
 197197 #define DYNLINKER { 0 }
 198198 #endif
 199199 
 200200 /* Default libraries and search paths */
 201201 #ifndef PCCLIBDIR       /* set by autoconf */
 202202 #define PCCLIBDIR       NULL
 203203 #endif
 204204 #ifndef DEFLIBDIRS      /* default library search paths */
 205205 #define DEFLIBDIRS      { "/usr/lib/", 0 }
 206206 #endif
 207207 #ifndef DEFLIBS         /* default libraries included */
 208208 #define DEFLIBS         { "-lpcc", "-lc", "-lpcc", 0 }
 209209 #endif
 210210 #ifndef DEFPROFLIBS     /* default profiling libraries */
 211211 #define DEFPROFLIBS     { "-lpcc", "-lc_p", "-lpcc", 0 }
 212212 #endif
 213213 #ifndef DEFCXXLIBS      /* default c++ libraries */
 214214 #define DEFCXXLIBS      { "-lp++", "-lpcc", "-lc", "-lpcc", 0 }
 215215 #endif
 216216 #ifndef STARTLABEL
 217217 #define STARTLABEL "__start"
 218218 #endif
 219219 
 220220 char *dynlinker[] = DYNLINKER;
 221221 char *pcclibdir = PCCLIBDIR;
 222222 char *deflibdirs[] = DEFLIBDIRS;
 223223 char *deflibs[] = DEFLIBS;
 224224 char *defproflibs[] = DEFPROFLIBS;
 225225 char *defcxxlibs[] = DEFCXXLIBS;
 226226 
 227227 char    *outfile, *MFfile, *fname;
 228228 static char **lav;
 229229 static int lac;
 230230 static char *find_file(const char *file, struct strlist *path, int mode);
 231231 static int preprocess_input(char *input, char *output, int dodep);
 232232 static int compile_input(char *input, char *output);
 233233 static int assemble_input(char *input, char *output);
 234234 static int run_linker(void);
 235235 static int strlist_exec(struct strlist *l);
 236236 
 237237 char *cat(const char *, const char *);
 238238 char *setsuf(char *, char);
 239239 int cxxsuf(char *);
 240240 int getsuf(char *);
 241241 char *getsufp(char *s);
 242242 int main(int, char *[]);
 243243 void errorx(int, char *, ...);
 244244 int cunlink(char *);
 245245 void exandrm(char *);
 246246 void dexit(int);
 247247 void idexit(int);
 248248 char *gettmp(void);
 249249 void oerror(char *);
 250250 char *argnxt(char *, char *);
 251251 char *nxtopt(char *o);
 252252 void setup_cpp_flags(void);
 253253 void setup_ccom_flags(void);
 254254 void setup_as_flags(void);
 255255 void setup_ld_flags(void);
 256256 static void expand_sysroot(void);
 257257 #ifdef os_win32
 258258 char *win32pathsubst(char *);
 259259 char *win32commandline(struct strlist *l);
 260260 #endif
 261261 int     sspflag;
 262262 int     freestanding;
 263263 int     Sflag;
 264264 int     cflag;
 265265 int     gflag;
 266266 int     rflag;
 267267 int     vflag;
 268268 int     tflag;
 269269 int     Eflag;
 270270 int     Oflag;
 271271 int     kflag;  /* generate PIC/pic code */
 272272 #define F_PIC   1
 273273 #define F_pic   2
 274274 int     Mflag, needM, MDflag;   /* dependencies only */
 275275 int     pgflag;
 276276 int     Xflag;
 277277 int     nostartfiles, Bstatic, shared;
 278278 int     nostdinc, nostdlib;
 279279 int     pthreads;
 280280 int     xgnu89, xgnu99;
 281281 int     ascpp;
 282282 #ifdef CHAR_UNSIGNED
 283283 int     xuchar = 1;
 284284 #else
 285285 int     xuchar = 0;
 286286 #endif
 287287 int     cxxflag;
 288288 int     cppflag;
 289289 int     printprogname, printfilename;
 290290 
 291291 #ifdef mach_amd64
 292292 int amd64_i386;
 293293 #endif
 294294 
 295295 #define match(a,b)      (strcmp(a,b) == 0)
 296296 
 297297 /* handle gcc warning emulations */
 298298 struct Wflags {
 299299         char *name;
 300300         int flags;
 301301 #define INWALL          1
 302302 } Wflags[] = {
 303303         { "truncate", 0 },
 304304         { "strict-prototypes", 0 },
 305305         { "missing-prototypes", 0 },
 306306         { "implicit-int", INWALL },
 307307         { "implicit-function-declaration", INWALL },
 308308         { "shadow", 0 },
 309309         { "pointer-sign", INWALL },
 310310         { "sign-compare", 0 },
 311311         { "unknown-pragmas", INWALL },
 312312         { "unreachable-code", 0 },
<> 313+        { "deprecated-declarations", 0 },
<_313314         { NULL, 0 },
 314315 };
 315316 
 316317 #ifndef USHORT
 317318 /* copied from mip/manifest.h */
 318319 #define USHORT          5
 319320 #define INT             6
 320321 #define UNSIGNED        7
 321322 #endif
 322323 
 323324 /*
 324325  * Wide char defines.
 325326  */
 326327 #if WCHAR_TYPE == USHORT
 327328 #define WCT "short unsigned int"
 328329 #define WCM "65535U"
 329330 #if WCHAR_SIZE != 2
 330331 #error WCHAR_TYPE vs. WCHAR_SIZE mismatch
 331332 #endif
 332333 #elif WCHAR_TYPE == INT
 333334 #define WCT "int"
 334335 #define WCM "2147483647"
 335336 #if WCHAR_SIZE != 4
 336337 #error WCHAR_TYPE vs. WCHAR_SIZE mismatch
 337338 #endif
 338339 #elif WCHAR_TYPE == UNSIGNED
 339340 #define WCT "unsigned int"
 340341 #define WCM "4294967295U"
 341342 #if WCHAR_SIZE != 4
 342343 #error WCHAR_TYPE vs. WCHAR_SIZE mismatch
 343344 #endif
 344345 #else
 345346 #error WCHAR_TYPE not defined or invalid
 346347 #endif
 347348 
 348349 #ifdef GCC_COMPAT
 349350 #ifndef REGISTER_PREFIX
 350351 #define REGISTER_PREFIX ""
 351352 #endif
 352353 #ifndef USER_LABEL_PREFIX
 353354 #define USER_LABEL_PREFIX ""
 354355 #endif
 355356 #endif
 356357 
 357358 #ifndef PCC_WINT_TYPE
 358359 #define PCC_WINT_TYPE "unsigned int"
 359360 #endif
 360361 
 361362 #ifndef PCC_SIZE_TYPE
 362363 #define PCC_SIZE_TYPE "unsigned long"
 363364 #endif
 364365 
 365366 #ifndef PCC_PTRDIFF_TYPE
 366367 #define PCC_PTRDIFF_TYPE "long int"
 367368 #endif
 368369 
 369370 
 370371 struct strlist preprocessor_flags;
 371372 struct strlist depflags;
 372373 struct strlist incdirs;
 373374 struct strlist user_sysincdirs;
 374375 struct strlist includes;
 375376 struct strlist sysincdirs;
 376377 struct strlist dirafterdirs;
 377378 struct strlist crtdirs;
 378379 struct strlist libdirs;
 379380 struct strlist progdirs;
 380381 struct strlist early_linker_flags;
 381382 struct strlist middle_linker_flags;
 382383 struct strlist late_linker_flags;
 383384 struct strlist inputs;
 384385 struct strlist assembler_flags;
 385386 struct strlist temp_outputs;
 386387 struct strlist compiler_flags;
 387388 
 388389 int
 389390 main(int argc, char *argv[])
 390391 {
 391392         struct Wflags *Wf;
 392393         struct string *s;
 393394         char *t, *u, *argp;
 394395         char *msuffix;
 395396         int ninput, j;
 396397 
 397398         lav = argv;
 398399         lac = argc;
 399400         ninput = 0;
 400401 
 401402         strlist_init(&crtdirs);
 402403         strlist_init(&libdirs);
 403404         strlist_init(&progdirs);
 404405         strlist_init(&preprocessor_flags);
 405406         strlist_init(&incdirs);
 406407         strlist_init(&user_sysincdirs);
 407408         strlist_init(&includes);
 408409         strlist_init(&sysincdirs);
 409410         strlist_init(&dirafterdirs);
 410411         strlist_init(&depflags);
 411412         strlist_init(&early_linker_flags);
 412413         strlist_init(&middle_linker_flags);
 413414         strlist_init(&late_linker_flags);
 414415         strlist_init(&inputs);
 415416         strlist_init(&assembler_flags);
 416417         strlist_init(&temp_outputs);
 417418         strlist_init(&compiler_flags);
 418419 
 419420         if ((t = strrchr(argv[0], '/')))
 420421                 t++;
 421422         else
 422423                 t = argv[0];
 423424 
 424425         if (match(t, "p++")) {
 425426                 cxxflag = 1;
 426427         } else if (match(t, "cpp") || match(t, CPPROGNAME)) {
 427428                 Eflag = cppflag = 1;
 428429         }
 429430 
 430431 #ifdef PCC_EARLY_SETUP
 431432         PCC_EARLY_SETUP
 432433 #endif
 433434 
 434435 #ifdef os_win32
 435436         /* have to prefix path early.  -B may override */
 436437         incdir = win32pathsubst(incdir);
 437438         altincdir = win32pathsubst(altincdir);
 438439         libdir = win32pathsubst(libdir);
 439440 #ifdef PCCINCDIR
 440441         pccincdir = win32pathsubst(pccincdir);
 441442         pxxincdir = win32pathsubst(pxxincdir);
 442443 #endif
 443444 #ifdef PCCLIBDIR
 444445         pcclibdir = win32pathsubst(pcclibdir);
 445446 #endif
 446447         passp = win32pathsubst(passp);
 447448         pass0 = win32pathsubst(pass0);
 448449 #ifdef STARTFILES
 449450         for (i = 0; startfiles[i] != NULL; i++)
 450451                 startfiles[i] = win32pathsubst(startfiles[i]);
 451452         for (i = 0; endfiles[i] != NULL; i++)
 452453                 endfiles[i] = win32pathsubst(endfiles[i]);
 453454 #endif
 454455 #ifdef STARTFILES_T
 455456         for (i = 0; startfiles_T[i] != NULL; i++)
 456457                 startfiles_T[i] = win32pathsubst(startfiles_T[i]);
 457458         for (i = 0; endfiles_T[i] != NULL; i++)
 458459                 endfiles_T[i] = win32pathsubst(endfiles_T[i]);
 459460 #endif
 460461 #ifdef STARTFILES_S
 461462         for (i = 0; startfiles_S[i] != NULL; i++)
 462463                 startfiles_S[i] = win32pathsubst(startfiles_S[i]);
 463464         for (i = 0; endfiles_S[i] != NULL; i++)
 464465                 endfiles_S[i] = win32pathsubst(endfiles_S[i]);
 465466 #endif
 466467 #endif
 467468 
 468469         while (--lac) {
 469470                 ++lav;
 470471                 argp = *lav;
 471472 
 472473 #ifdef PCC_EARLY_ARG_CHECK
 473474                 PCC_EARLY_ARG_CHECK
 474475 #endif
 475476 
 476477                 if (*argp != '-' || match(argp, "-")) {
 477478                         /* Check for duplicate .o files. */
 478479                         if (getsuf(argp) == 'o') {
 479480                                 j = 0;
 480481                                 STRLIST_FOREACH(s, &inputs)
 481482                                         if (match(argp, s->value))
 482483                                                 j++;
 483484                                 if (j)
 484485                                         continue; /* skip it */
 485486                         }
 486487                         strlist_append(&inputs, argp);
 487488                         ninput++;
 488489                         continue;
 489490                 }
 490491 
 491492                 switch (argp[1]) {
 492493                 default:
 493494                         oerror(argp);
 494495                         break;
 495496 
 496497                 case '-': /* double -'s */
 497498                         if (match(argp, "--version")) {
 498499                                 printf("%s\n", VERSSTR);
 499500                                 return 0;
 500501                         } else if (strncmp(argp, "--sysroot=", 10) == 0) {
 501502                                 sysroot = argp + 10;
 502503                         } else if (strcmp(argp, "--param") == 0) {
 503504                                 /* NOTHING YET */;
 504505                                 (void)nxtopt(0); /* ignore arg */
 505506                         } else
 506507                                 oerror(argp);
 507508                         break;
 508509 
 509510                 case 'B': /* other search paths for binaries */
 510511                         t = nxtopt("-B");
 511512                         strlist_append(&crtdirs, t);
 512513                         strlist_append(&libdirs, t);
 513514                         strlist_append(&progdirs, t);
 514515                         break;
 515516 
 516517                 case 'C':
 517518                         if (match(argp, "-C") || match(argp, "-CC"))
 518519                                 strlist_append(&preprocessor_flags, argp);
 519520                         else
 520521                                 oerror(argp);
 521522                         break;
 522523 
 523524                 case 'c':
 524525                         cflag++;
 525526                         break;
 526527 
 527528                 case 'd':
 528529                         oerror(argp);
 529530                         break;
 530531 
 531532                 case 'E':
 532533                         Eflag++;
 533534                         break;
 534535 
 535536                 case 'f': /* GCC compatibility flags */
 536537                         u = &argp[2];
 537538                         j = 0;
 538539                         if (strncmp(u, "no-", 3) == 0)
 539540                                 j = 1, u += 3;
 540541                         if (match(u, "PIC") || match(u, "pic")) {
 541542                                 kflag = j ? 0 : *u == 'P' ? F_PIC : F_pic;
 542543                         } else if (match(u, "freestanding")) {
 543544                                 freestanding = j ? 0 : 1;
 544545                         } else if (match(u, "signed-char")) {
 545546                                 xuchar = j ? 1 : 0;
 546547                         } else if (match(u, "unsigned-char")) {
 547548                                 xuchar = j ? 0 : 1;
 548549                         } else if (match(u, "stack-protector") ||
 549550                             match(u, "stack-protector-all")) {
 550551                                 sspflag = j ? 0 : 1;
 551552                         }
 552553                         /* silently ignore the rest */
 553554                         break;
 554555 
 555556                 case 'g': /* create debug output */
 556557                         if (argp[2] == '0')
 557558                                 gflag = 0;
 558559                         else
 559560                                 gflag++;
 560561                         break;
 561562 
 562563 
 563564                 case 'X':
 564565                         Xflag++;
 565566                         break;
 566567 
 567568                 case 'D':
 568569                 case 'U':
 569570                         strlist_append(&preprocessor_flags, argp);
 570571                         if (argp[2] != 0)
 571572                                 break;
 572573                         strlist_append(&preprocessor_flags, nxtopt(argp));
 573574                         break;
 574575 
 575576                 case 'I': /* Add include dirs */
 576577                         strlist_append(&incdirs, nxtopt("-I"));
 577578                         break;
 578579 
 579580                 case 'i':
 580581                         if (match(argp, "-isystem")) {
 581582                                 strlist_append(&user_sysincdirs, nxtopt(0));
 582583                         } else if (match(argp, "-include")) {
 583584                                 strlist_append(&includes, nxtopt(0));
 584585                         } else if (match(argp, "-isysroot")) {
 585586                                 isysroot = nxtopt(0);
 586587                         } else if (strcmp(argp, "-idirafter") == 0) {
 587588                                 strlist_append(&dirafterdirs, nxtopt(0));
 588589                         } else
 589590                                 oerror(argp);
 590591                         break;
 591592 
 592593                 case 'k': /* generate PIC code */
 593594                         kflag = argp[2] ? argp[2] - '0' : F_pic;
 594595                         break;
 595596 
 596597                 case 'l':
 597598                 case 'L':
 598599                         if (argp[2] == 0)
 599600                                 argp = cat(argp, nxtopt(0));
 600601                         strlist_append(&inputs, argp);
 601602                         break;
 602603 
 603604                 case 'm': /* target-dependent options */
 604605 #ifdef mach_amd64
 605606                         /* need to call i386 ccom for this */
 606607                         if (strcmp(argp, "-melf_i386") == 0) {
 607608                                 pass0 = LIBEXECDIR "/ccom_i386";
 608609                                 amd64_i386 = 1;
 609610                                 break;
 610611                         }
 611612 #endif
 612613                         strlist_append(&middle_linker_flags, argp);
 613614                         if (argp[2] == 0) {
 614615                                 t = nxtopt(0);
 615616                                 strlist_append(&middle_linker_flags, t);
 616617                         }
 617618                         break;
 618619 
 619620                 case 'n': /* handle -n flags */
 620621                         if (strcmp(argp, "-nostdinc") == 0)
 621622                                 nostdinc++;
 622623                         else if (strcmp(argp, "-nostdlib") == 0) {
 623624                                 nostdlib++;
 624625                                 nostartfiles++;
 625626                         } else if (strcmp(argp, "-nostartfiles") == 0)
 626627                                 nostartfiles = 1;
 627628                         else if (strcmp(argp, "-nodefaultlibs") == 0)
 628629                                 nostdlib++;
 629630                         else
 630631                                 oerror(argp);
 631632                         break;
 632633 
 633634                 case 'p':
 634635                         if (strcmp(argp, "-pg") == 0 ||
 635636                             strcmp(argp, "-p") == 0)
 636637                                 pgflag++;
 637638                         else if (strcmp(argp, "-pthread") == 0)
 638639                                 pthreads++;
 639640                         else if (strcmp(argp, "-pipe") == 0)
 640641                                 /* NOTHING YET */;
 641642                         else if (strcmp(argp, "-pedantic") == 0)
 642643                                 /* NOTHING YET */;
 643644                         else if ((t = argnxt(argp, "-print-prog-name="))) {
 644645                                 fname = t;
 645646                                 printprogname = 1;
 646647                         } else if ((t = argnxt(argp, "-print-file-name="))) {
 647648                                 fname = t;
 648649                                 printfilename = 1;
 649650                         } else if (match(argp, "-print-libgcc-file-name")) {
 650651                                 fname = "libpcc.a";
 651652                                 printfilename = 1;
 652653                         } else
 653654                                 oerror(argp);
 654655                         break;
 655656 
 656657                 case 'r':
 657658                         rflag = 1;
 658659                         break;
 659660 
 660661                 case 'T':
 661662                         strlist_append(&inputs, argp);
 662663                         if (argp[2] == 0 ||
 663664                             strcmp(argp, "-Ttext") == 0 ||
 664665                             strcmp(argp, "-Tdata") == 0 ||
 665666                             strcmp(argp, "-Tbss") == 0)
 666667                                 strlist_append(&inputs, nxtopt(0));
 667668                         break;
 668669 
 669670                 case 's':
 670671                         if (match(argp, "-shared")) {
 671672                                 shared = 1;
 672673                         } else if (match(argp, "-static")) {
 673674                                 Bstatic = 1;
 674675                         } else if (match(argp, "-symbolic")) {
 675676                                 strlist_append(&middle_linker_flags,
 676677                                     "-Bsymbolic");
 677678                         } else if (strncmp(argp, "-std", 4) == 0) {
 678679                                 if (strcmp(&argp[5], "gnu99") == 0 ||
 679680                                     strcmp(&argp[5], "gnu9x") == 0)
 680681                                         xgnu99 = 1;
 681682                                 if (strcmp(&argp[5], "gnu89") == 0)
 682683                                         xgnu89 = 1;
 683684                         } else
 684685                                 oerror(argp);
 685686                         break;
 686687 
 687688                 case 'S':
 688689                         Sflag++;
 689690                         cflag++;
 690691                         break;
 691692 
 692693                 case 't':
 693694                         tflag++;
 694695                         break;
 695696 
 696697                 case 'o':
 697698                         if (outfile)
 698699                                 errorx(8, "too many -o");
 699700                         outfile = nxtopt("-o");
 700701                         break;
 701702 
 702703                 case 'O':
 703704                         if (argp[2] == '\0')
 704705                                 Oflag++;
 705706                         else if (argp[3] == '\0' &&
 706707                             isdigit((unsigned char)argp[2]))
 707708                                 Oflag = argp[2] - '0';
 708709                         else if (argp[3] == '\0' && argp[2] == 's')
 709710                                 Oflag = 1;      /* optimize for space only */
 710711                         else
 711712                                 oerror(argp);
 712713                         break;
 713714 
 714715                 case 'P':
 715716                         strlist_append(&preprocessor_flags, argp);
 716717                         break;
 717718 
 718719                 case 'M':
 719720                         needM = 1;
 720721                         if (match(argp, "-M")) {
 721722                                 Mflag++;
 722723                                 strlist_append(&depflags, argp);
 723724                         } else if (match(argp, "-MP")) {
 724725                                 strlist_append(&depflags, "-xMP");
 725726                         } else if (match(argp, "-MF")) {
 726727                                 MFfile = nxtopt("-MF");
 727728                         } else if (match(argp, "-MT") || match(argp, "-MQ")) {
 728729                                 t = cat("-xMT,", nxtopt("-MT"));
 729730                                 t[3] = argp[2];
 730731                                 strlist_append(&depflags, t);
 731732                         } else if (match(argp, "-MD")) {
 732733                                 MDflag++;
 733734                                 needM = 0;
 734735                                 strlist_append(&depflags, "-M");
 735736                         } else
 736737                                 oerror(argp);
 737738                         break;
 738739 
 739740                 case 'v':
 740741                         printf("%s\n", VERSSTR);
 741742                         vflag++;
 742743                         break;
 743744 
 744745                 case 'W': /* Ignore (most of) W-flags */
 745746                         if ((t = argnxt(argp, "-Wl,"))) {
 746747                                 u = strtok(t, ",");
 747748                                 do {
 748749                                         strlist_append(&inputs, u);
 749750                                 } while ((u = strtok(NULL, ",")) != NULL);
 750751                         } else if ((t = argnxt(argp, "-Wa,"))) {
 751752                                 u = strtok(t, ",");
 752753                                 do {
 753754                                         strlist_append(&assembler_flags, u);
 754755                                 } while ((u = strtok(NULL, ",")) != NULL);
 755756                         } else if ((t = argnxt(argp, "-Wc,"))) {
 756757                                 u = strtok(t, ",");
 757758                                 do {
 758759                                         strlist_append(&compiler_flags, u);
 759760                                 } while ((u = strtok(NULL, ",")) != NULL);
 760761                         } else if ((t = argnxt(argp, "-Wp,"))) {
 761762                                 u = strtok(t, ",");
 762763                                 do {
 763764                                         strlist_append(&preprocessor_flags, u);
 764765                                 } while ((u = strtok(NULL, ",")) != NULL);
 765766                         } else if (strcmp(argp, "-Werror") == 0) {
 766767                                 strlist_append(&compiler_flags, "-Werror");
 767768                                 strlist_append(&preprocessor_flags, "-E");
 768769                         } else if (strcmp(argp, "-Wall") == 0) {
 769770                                 for (Wf = Wflags; Wf->name; Wf++)
 770771                                         if (Wf->flags & INWALL)
 771772                                                 strlist_append(&compiler_flags,
 772773                                                     cat("-W", Wf->name));
 773774                         } else if (strcmp(argp, "-WW") == 0) {
 774775                                 for (Wf = Wflags; Wf->name; Wf++)
 775776                                         strlist_append(&compiler_flags,
 776777                                             cat("-W", Wf->name));
 777778                         } else {
 778779                                 /* pass through, if supported */
 779780                                 t = &argp[2];
 780781                                 if (strncmp(t, "no-", 3) == 0)
 781782                                         t += 3;
 782783                                 if (strncmp(t, "error=", 6) == 0)
 783784                                         t += 6;
 784785                                 for (Wf = Wflags; Wf->name; Wf++) {
 785786                                         if (strcmp(t, Wf->name) == 0)
 786787                                                 strlist_append(&compiler_flags,
 787788                                                     argp);
 788789                                 }
 789790                         }
 790791                         break;
 791792 
 792793                 case 'x':
 793794                         t = nxtopt("-x");
 794795                         if (match(t, "none"))
 795796                                 strlist_append(&inputs, ")");
 796797                         else if (match(t, "c"))
 797798                                 strlist_append(&inputs, ")c");
 798799                         else if (match(t, "assembler"))
 799800                                 strlist_append(&inputs, ")s");
 800801                         else if (match(t, "assembler-with-cpp"))
 801802                                 strlist_append(&inputs, ")S");
 802803                         else if (match(t, "c++"))
 803804                                 strlist_append(&inputs, ")c++");
 804805                         else {
 805806                                 strlist_append(&compiler_flags, "-x");
 806807                                 strlist_append(&compiler_flags, t);
 807808                         }
 808809                         break;
 809810 
 810811                 }
 811812                 continue;
 812813 
 813814         }
 814815 
 815816         /* Sanity checking */
 816817         if (cppflag) {
 817818                 if (ninput == 0) {
 818819                         strlist_append(&inputs, "-");
 819820                         ninput++;
 820821                 } else if (ninput > 2 || (ninput == 2 && outfile)) {
 821822                         errorx(8, "too many files");
 822823                 } else if (ninput == 2) {
 823824                         outfile = STRLIST_NEXT(STRLIST_FIRST(&inputs))->value;
 824825                         STRLIST_FIRST(&inputs)->next = NULL;
 825826                         ninput--;
 826827                 }
 827828         }
 828829         if (ninput == 0 && !(printprogname || printfilename))
 829830                 errorx(8, "no input files");
 830831         if (outfile && (cflag || Sflag || Eflag) && ninput > 1)
 831832                 errorx(8, "-o given with -c || -E || -S and more than one file");
 832833 #if 0
 833834         if (outfile && clist[0] && strcmp(outfile, clist[0]) == 0)
 834835                 errorx(8, "output file will be clobbered");
 835836 #endif
 836837 
 837838         if (needM && !Mflag && !MDflag)
 838839                 errorx(8, "to make dependencies needs -M");
 839840 
 840841 
 841842         if (signal(SIGINT, SIG_IGN) != SIG_IGN/* interrupt */
 842843                 signal(SIGINT, idexit);
 843844         if (signal(SIGTERM, SIG_IGN) != SIG_IGN)        /* terminate */
 844845                 signal(SIGTERM, idexit);
 845846 
 846847         /* after arg parsing */
 847848         strlist_append(&progdirs, LIBEXECDIR);
 848849         if (pcclibdir)
 849850                 strlist_append(&crtdirs, pcclibdir);
 850851         for (j = 0; deflibdirs[j]; j++) {
 851852                 if (sysroot)
 852853                         deflibdirs[j] = cat(sysroot, deflibdirs[j]);
 853854                 strlist_append(&crtdirs, deflibdirs[j]);
 854855         }
 855856 
 856857         setup_cpp_flags();
 857858         setup_ccom_flags();
 858859         setup_as_flags();
 859860 
 860861         if (isysroot == NULL)
 861862                 isysroot = sysroot;
 862863         expand_sysroot();
 863864 
 864865         if (printprogname) {
 865866                 printf("%s\n", find_file(fname, &progdirs, X_OK));
 866867                 return 0;
 867868         } else if (printfilename) {
 868869                 printf("%s\n", find_file(fname, &crtdirs, R_OK));
 869870                 return 0;
 870871         }
 871872 
 872873         msuffix = NULL;
 873874         STRLIST_FOREACH(s, &inputs) {
 874875                 char *suffix;
 875876                 char *ifile, *ofile = NULL;
 876877 
 877878                 ifile = s->value;
 878879                 if (ifile[0] == ')') { /* -x source type given */
 879880                         msuffix = ifile[1] ? &ifile[1] : NULL;
 880881                         continue;
 881882                 }
 882883                 if (ifile[0] == '-' && ifile[1] == 0)
 883884                         suffix = msuffix ? msuffix : "c";
 884885                 else if (ifile[0] == '-')
 885886                         suffix = "o"; /* source files cannot begin with - */
 886887                 else if (msuffix)
 887888                         suffix = msuffix;
 888889                 else
 889890                         suffix = getsufp(ifile);
 890891                 /*
 891892                  * C preprocessor
 892893                  */
 893894                 ascpp = match(suffix, "S");
 894895                 if (ascpp || match(suffix, "c") || cxxsuf(suffix)) {
 895896                         /* find out next output file */
 896897                         if (Mflag || MDflag) {
 897898                                 char *Mofile = NULL;
 898899 
 899900                                 if (MFfile)
 900901                                         Mofile = MFfile;
 901902                                 else if (outfile)
 902903                                         Mofile = setsuf(outfile, 'd');
 903904                                 else if (MDflag)
 904905                                         Mofile = setsuf(ifile, 'd');
 905906                                 if (preprocess_input(ifile, Mofile, 1))
 906907                                         exandrm(Mofile);
 907908                         }
 908909                         if (Mflag)
 909910                                 continue;
 910911                         if (Eflag) {
 911912                                 /* last pass */
 912913                                 ofile = outfile;
 913914                         } else {
 914915                                 /* to temp file */
 915916                                 strlist_append(&temp_outputs, ofile = gettmp());
 916917                         }
 917918                         if (preprocess_input(ifile, ofile, 0))
 918919                                 exandrm(ofile);
 919920                         if (Eflag)
 920921                                 continue;
 921922                         ifile = ofile;
 922923                         suffix = match(suffix, "S") ? "s" : "i";
 923924                 }
 924925 
 925926                 /*
 926927                  * C compiler
 927928                  */
 928929                 if (match(suffix, "i")) {
 929930                         /* find out next output file */
 930931                         if (Sflag) {
 931932                                 ofile = outfile;
 932933                                 if (outfile == NULL)
 933934                                         ofile = setsuf(s->value, 's');
 934935                         } else
 935936                                 strlist_append(&temp_outputs, ofile = gettmp());
 936937                         if (compile_input(ifile, ofile))
 937938                                 exandrm(ofile);
 938939                         if (Sflag)
 939940                                 continue;
 940941                         ifile = ofile;
 941942                         suffix = "s";
 942943                 }
 943944 
 944945                 /*
 945946                  * Assembler
 946947                  */
 947948                 if (match(suffix, "s")) {
 948949                         if (cflag) {
 949950                                 ofile = outfile;
 950951                                 if (ofile == NULL)
 951952                                         ofile = setsuf(s->value, 'o');
 952953                         } else {
 953954                                 strlist_append(&temp_outputs, ofile = gettmp());
 954955                                 /* strlist_append linker */
 955956                         }
 956957                         if (assemble_input(ifile, ofile))
 957958                                 exandrm(ofile);
 958959                         ifile = ofile;
 959960                 }
 960961 
 961962                 if (ninput > 1 && !Eflag && ifile == ofile && ifile[0] != '-')
 962963                         printf("%s:\n", ifile);
 963964 
 964965                 strlist_append(&middle_linker_flags, ifile);
 965966         }
 966967 
 967968         if (cflag || Eflag || Mflag)
 968969                 dexit(0);
 969970 
 970971         /*
 971972          * Linker
 972973          */
 973974         setup_ld_flags();
 974975         if (run_linker())
 975976                 exandrm(0);
 976977 
 977978 #ifdef notdef
 978979         strlist_free(&crtdirs);
 979980         strlist_free(&libdirs);
 980981         strlist_free(&progdirs);
 981982         strlist_free(&incdirs);
 982983         strlist_free(&preprocessor_flags);
 983984         strlist_free(&user_sysincdirs);
 984985         strlist_free(&includes);
 985986         strlist_free(&sysincdirs);
 986987         strlist_free(&dirafterdirs);
 987988         strlist_free(&depflags);
 988989         strlist_free(&early_linker_flags);
 989990         strlist_free(&middle_linker_flags);
 990991         strlist_free(&late_linker_flags);
 991992         strlist_free(&inputs);
 992993         strlist_free(&assembler_flags);
 993994         strlist_free(&temp_outputs);
 994995         strlist_free(&compiler_flags);
 995996 #endif
 996997         dexit(0);
 997998         return 0;
 998999 }
 9991000 
 10001001 /*
 10011002  * exit and cleanup after interrupt.
 10021003  */
 10031004 void
 10041005 idexit(int arg)
 10051006 {
 10061007         dexit(100);
 10071008 }
 10081009 
 10091010 /*
 10101011  * exit and cleanup.
 10111012  */
 10121013 void
 10131014 dexit(int eval)
 10141015 {
 10151016         struct string *s;
 10161017 
 10171018         if (!Xflag) {
 10181019                 STRLIST_FOREACH(s, &temp_outputs)
 10191020                         cunlink(s->value);
 10201021         }
 10211022         exit(eval);
 10221023 }
 10231024 
 10241025 /*
 10251026  * Called when something failed.
 10261027  */
 10271028 void
 10281029 exandrm(char *s)
 10291030 {
 10301031         if (s && *s)
 10311032                 strlist_append(&temp_outputs, s);
 10321033         dexit(1);
 10331034 }
 10341035 
 10351036 /*
 10361037  * complain and exit.
 10371038  */
 10381039 void
 10391040 errorx(int eval, char *s, ...)
 10401041 {
 10411042         va_list ap;
 10421043 
 10431044         va_start(ap, s);
 10441045         fputs("error: ", stderr);
 10451046         vfprintf(stderr, s, ap);
 10461047         putc('\n', stderr);
 10471048         va_end(ap);
 10481049         dexit(eval);
 10491050 }
 10501051 
 10511052 static char *
 10521053 find_file(const char *file, struct strlist *path, int mode)
 10531054 {
 10541055         struct string *s;
 10551056         char *f;
 10561057         size_t lf, lp;
 10571058         int need_sep;
 10581059 
 10591060         lf = strlen(file);
 10601061         STRLIST_FOREACH(s, path) {
 10611062                 lp = strlen(s->value);
 10621063                 need_sep = (lp && s->value[lp - 1] != '/') ? 1 : 0;
 10631064                 f = xmalloc(lp + lf + need_sep + 1);
 10641065                 memcpy(f, s->value, lp);
 10651066                 if (need_sep)
 10661067                         f[lp] = '/';
 10671068                 memcpy(f + lp + need_sep, file, lf + 1);
 10681069                 if (access(f, mode) == 0)
 10691070                         return f;
 10701071                 free(f);
 10711072         }
 10721073         return xstrdup(file);
 10731074 }
 10741075 
 10751076 static int
 10761077 compile_input(char *input, char *output)
 10771078 {
 10781079         struct strlist args;
 10791080         int retval;
 10801081 
 10811082         strlist_init(&args);
 10821083         strlist_append_list(&args, &compiler_flags);
 10831084         strlist_append(&args, input);
 10841085         strlist_append(&args, output);
 10851086         strlist_prepend(&args,
 10861087             find_file(cxxflag ? passxx0 : pass0, &progdirs, X_OK));
 10871088         retval = strlist_exec(&args);
 10881089         strlist_free(&args);
 10891090         return retval;
 10901091 }
 10911092 
 10921093 static int
 10931094 assemble_input(char *input, char *output)
 10941095 {
 10951096         struct strlist args;
 10961097         int retval;
 10971098 
 10981099         strlist_init(&args);
 10991100 #ifdef PCC_EARLY_AS_ARGS
 11001101         PCC_EARLY_AS_ARGS
 11011102 #endif
 11021103         strlist_append_list(&args, &assembler_flags);
 11031104         strlist_append(&args, input);
 11041105         strlist_append(&args, "-o");
 11051106         strlist_append(&args, output);
 11061107         strlist_prepend(&args,
 11071108             find_file(as, &progdirs, X_OK));
 11081109 #ifdef PCC_LATE_AS_ARGS
 11091110         PCC_LATE_AS_ARGS
 11101111 #endif
 11111112         retval = strlist_exec(&args);
 11121113         strlist_free(&args);
 11131114         return retval;
 11141115 }
 11151116 
 11161117 static int
 11171118 preprocess_input(char *input, char *output, int dodep)
 11181119 {
 11191120         struct strlist args;
 11201121         struct string *s;
 11211122         int retval;
 11221123 
 11231124         strlist_init(&args);
 11241125         strlist_append_list(&args, &preprocessor_flags);
 11251126         if (ascpp) {
 11261127                 strlist_append(&args, "-A");
 11271128                 strlist_append(&args, "-D__ASSEMBLER__");
 11281129         }
 11291130         STRLIST_FOREACH(s, &includes) {
 11301131                 strlist_append(&args, "-i");
 11311132                 strlist_append(&args, s->value);
 11321133         }
 11331134         STRLIST_FOREACH(s, &incdirs) {
 11341135                 strlist_append(&args, "-I");
 11351136                 strlist_append(&args, s->value);
 11361137         }
 11371138         STRLIST_FOREACH(s, &user_sysincdirs) {
 11381139                 strlist_append(&args, "-S");
 11391140                 strlist_append(&args, s->value);
 11401141         }
 11411142         if (!nostdinc) {
 11421143                 STRLIST_FOREACH(s, &sysincdirs) {
 11431144                         strlist_append(&args, "-S");
 11441145                         strlist_append(&args, s->value);
 11451146                 }
 11461147         }
 11471148         if (dodep)
 11481149                 strlist_append_list(&args, &depflags);
 11491150         strlist_append(&args, input);
 11501151         if (output)
 11511152                 strlist_append(&args, output);
 11521153 
 11531154         strlist_prepend(&args, find_file(passp, &progdirs, X_OK));
 11541155         retval = strlist_exec(&args);
 11551156         strlist_free(&args);
 11561157         return retval;
 11571158 }
 11581159 
 11591160 static int
 11601161 run_linker(void)
 11611162 {
 11621163         struct strlist linker_flags;
 11631164         int retval;
 11641165 
 11651166         if (outfile) {
 11661167                 strlist_prepend(&early_linker_flags, outfile);
 11671168                 strlist_prepend(&early_linker_flags, "-o");
 11681169         }
 11691170         strlist_init(&linker_flags);
 11701171         strlist_append_list(&linker_flags, &early_linker_flags);
 11711172         strlist_append_list(&linker_flags, &middle_linker_flags);
 11721173         strlist_append_list(&linker_flags, &late_linker_flags);
 11731174         strlist_prepend(&linker_flags, find_file(ld, &progdirs, X_OK));
 11741175 
 11751176         retval = strlist_exec(&linker_flags);
 11761177 
 11771178         strlist_free(&linker_flags);
 11781179         return retval;
 11791180 }
 11801181 
 11811182 static char *cxxt[] = { "cc", "cp", "cxx", "cpp", "CPP", "c++", "C" };
 11821183 int
 11831184 cxxsuf(char *s)
 11841185 {
 11851186         unsigned i;
 11861187         for (i = 0; i < sizeof(cxxt)/sizeof(cxxt[0]); i++)
 11871188                 if (strcmp(s, cxxt[i]) == 0)
 11881189                         return 1;
 11891190         return 0;
 11901191 }
 11911192 
 11921193 char *
 11931194 getsufp(char *s)
 11941195 {
 11951196         register char *p;
 11961197 
 11971198         if ((p = strrchr(s, '.')) && p[1] != '\0')
 11981199                 return &p[1];
 11991200         return "";
 12001201 }
 12011202 
 12021203 int
 12031204 getsuf(char *s)
 12041205 {
 12051206         register char *p;
 12061207 
 12071208         if ((p = strrchr(s, '.')) && p[1] != '\0' && p[2] == '\0')
 12081209                 return p[1];
 12091210         return(0);
 12101211 }
 12111212 
 12121213 /*
 12131214  * Get basename of string s, copy it and change its suffix to ch.
 12141215  */
 12151216 char *
 12161217 setsuf(char *s, char ch)
 12171218 {
 12181219         char *e, *p, *rp;
 12191220 
 12201221         e = NULL;
 12211222         for (p = s; *p; p++) {
 12221223                 if (*p == '/')
 12231224                         s = p + 1;
 12241225                 if (*p == '.')
 12251226                         e = p;
 12261227         }
 12271228         if (s > e)
 12281229                 e = p;
 12291230 
 12301231         rp = p = xmalloc(e - s + 3);
 12311232         while (s < e)
 12321233                 *p++ = *s++;
 12331234 
 12341235         *p++ = '.';
 12351236         *p++ = ch;
 12361237         *p = '\0';
 12371238         return rp;
 12381239 }
 12391240 
 12401241 #ifdef os_win32
 12411242 
 12421243 static int
 12431244 strlist_exec(struct strlist *l)
 12441245 {
 12451246         char *cmd;
 12461247         STARTUPINFO si;
 12471248         PROCESS_INFORMATION pi;
 12481249         DWORD exitCode;
 12491250         BOOL ok;
 12501251 
 12511252         cmd = win32commandline(l);
 12521253         if (vflag)
 12531254                 printf("%s\n", cmd);
 12541255 
 12551256         ZeroMemory(&si, sizeof(STARTUPINFO));
 12561257         si.cb = sizeof(STARTUPINFO);
 12571258         ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
 12581259 
 12591260         ok = CreateProcess(NULL// the executable program
 12601261                 cmd,   // the command line arguments
 12611262                 NULL,       // ignored
 12621263                 NULL,       // ignored
 12631264                 TRUE,       // inherit handles
 12641265                 HIGH_PRIORITY_CLASS,
 12651266                 NULL,       // ignored
 12661267                 NULL,       // ignored
 12671268                 &si,
 12681269                 &pi);
 12691270 
 12701271         if (!ok)
 12711272                 errorx(100, "Can't find %s\n", STRLIST_FIRST(l)->value);
 12721273 
 12731274         WaitForSingleObject(pi.hProcess, INFINITE);
 12741275         GetExitCodeProcess(pi.hProcess, &exitCode);
 12751276         CloseHandle(pi.hProcess);
 12761277         CloseHandle(pi.hThread);
 12771278 
 12781279         return (exitCode != 0);
 12791280 }
 12801281 
 12811282 #else
 12821283 
 12831284 static int
 12841285 strlist_exec(struct strlist *l)
 12851286 {
 12861287         sig_atomic_t exit_now = 0;
 12871288         sig_atomic_t child;
 12881289         char **argv;
 12891290         size_t argc;
 12901291         int result;
 12911292 
 12921293         strlist_make_array(l, &argv, &argc);
 12931294         if (vflag) {
 12941295                 printf("Calling ");
 12951296                 strlist_print(l, stdout);
 12961297                 printf("\n");
 12971298         }
 12981299 
 12991300         switch ((child = fork())) {
 13001301         case 0:
 13011302                 execvp(argv[0], argv);
 13021303                 result = write(STDERR_FILENO, "Exec of ", 8);
 13031304                 result = write(STDERR_FILENO, argv[0], strlen(argv[0]));
 13041305                 result = write(STDERR_FILENO, "failed\n", 7);
 13051306                 (void)result;
 13061307                 _exit(127);
 13071308         case -1:
 13081309                 errorx(1, "fork failed");
 13091310         default:
 13101311                 while (waitpid(child, &result, 0) == -1 && errno == EINTR)
 13111312                         /* nothing */(void)0;
 13121313                 result = WEXITSTATUS(result);
 13131314                 if (result)
 13141315                         errorx(1, "%s terminated with status %d", argv[0], result);
 13151316                 while (argc-- > 0)
 13161317                         free(argv[argc]);
 13171318                 free(argv);
 13181319                 break;
 13191320         }
 13201321         return exit_now;
 13211322 }
 13221323 
 13231324 #endif
 13241325 
 13251326 /*
 13261327  * Catenate two (optional) strings together
 13271328  */
 13281329 char *
 13291330 cat(const char *a, const char *b)
 13301331 {
 13311332         size_t len;
 13321333         char *rv;
 13331334 
 13341335         len = (a ? strlen(a) : 0) + (b ? strlen(b) : 0) + 1;
 13351336         rv = xmalloc(len);
 13361337         snprintf(rv, len, "%s%s", (a ? a : ""), (b ? b : ""));
 13371338         return rv;
 13381339 }
 13391340 
 13401341 int
 13411342 cunlink(char *f)
 13421343 {
 13431344         if (f==0 || Xflag)
 13441345                 return(0);
 13451346         return (unlink(f));
 13461347 }
 13471348 
 13481349 #ifdef os_win32
 13491350 char *
 13501351 gettmp(void)
 13511352 {
 13521353         DWORD pathSize;
 13531354         char pathBuffer[MAX_PATH + 1];
 13541355         char tempFilename[MAX_PATH];
 13551356         UINT uniqueNum;
 13561357 
 13571358         pathSize = GetTempPath(sizeof(pathBuffer), pathBuffer);
 13581359         if (pathSize == 0 || pathSize > sizeof(pathBuffer))
 13591360                 pathBuffer[0] = '\0';
 13601361         uniqueNum = GetTempFileName(pathBuffer, "ctm", 0, tempFilename);
 13611362         if (uniqueNum == 0)
 13621363                 errorx(8, "GetTempFileName failed: path \"%s\"", pathBuffer);
 13631364 
 13641365         return xstrdup(tempFilename);
 13651366 }
 13661367 
 13671368 #else
 13681369 
 13691370 char *
 13701371 gettmp(void)
 13711372 {
 13721373         char *sfn = xstrdup("/tmp/ctm.XXXXXX");
 13731374         int fd = -1;
 13741375 
 13751376         if ((fd = mkstemp(sfn)) == -1)
 13761377                 errorx(8, "%s: %s\n", sfn, strerror(errno));
 13771378         close(fd);
 13781379         return sfn;
 13791380 }
 13801381 #endif
 13811382 
 13821383 static void
 13831384 expand_sysroot(void)
 13841385 {
 13851386         struct string *s;
 13861387         struct strlist *lists[] = { &crtdirs, &sysincdirs, &incdirs,
 13871388             &user_sysincdirs, &libdirs, &progdirs, &dirafterdirs, NULL };
 13881389         const char *sysroots[] = { sysroot, isysroot, isysroot, isysroot,
 13891390             sysroot, sysroot, isysroot, NULL };
 13901391         size_t i, sysroot_len, value_len;
 13911392         char *path;
 13921393 
 13931394         assert(sizeof(lists) / sizeof(lists[0]) ==
 13941395                sizeof(sysroots) / sizeof(sysroots[0]));
 13951396 
 13961397         for (i = 0; lists[i] != NULL; ++i) {
 13971398                 STRLIST_FOREACH(s, lists[i]) {
 13981399                         if (s->value[0] != '=')
 13991400                                 continue;
 14001401                         sysroot_len = strlen(sysroots[i]);
 14011402                         /* Skipped '=' compensates additional space for '\0' */
 14021403                         value_len = strlen(s->value);
 14031404                         path = xmalloc(sysroot_len + value_len);
 14041405                         memcpy(path, sysroots[i], sysroot_len);
 14051406                         memcpy(path + sysroot_len, s->value + 1, value_len);
 14061407                         free(s->value);
 14071408                         s->value = path;
 14081409                 }
 14091410         }
 14101411 }
 14111412 
 14121413 void
 14131414 oerror(char *s)
 14141415 {
 14151416         errorx(8, "unknown option '%s'", s);
 14161417 }
 14171418 
 14181419 /*
 14191420  * See if m matches the beginning of string str, if it does return the
 14201421  * remaining of str, otherwise NULL.
 14211422  */
 14221423 char *
 14231424 argnxt(char *str, char *m)
 14241425 {
 14251426         if (strncmp(str, m, strlen(m)))
 14261427                 return NULL; /* No match */
 14271428         return str + strlen(m);
 14281429 }
 14291430 
 14301431 /*
 14311432  * Return next argument to option, or complain.
 14321433  */
 14331434 char *
 14341435 nxtopt(char *o)
 14351436 {
 14361437         int l;
 14371438 
 14381439         if (o != NULL) {
 14391440                 l = strlen(o);
 14401441                 if (lav[0][l] != 0)
 14411442                         return &lav[0][l];
 14421443         }
 14431444         if (lac == 0)
 14441445                 errorx(8, "missing argument to '%s'", o);
 14451446         lav++;
 14461447         lac--;
 14471448         return lav[0];
 14481449 }
 14491450 
 14501451 struct flgcheck {
 14511452         int *flag;
 14521453         int set;
 14531454         char *def;
 14541455 } cppflgcheck[] = {
 14551456         { &vflag, 1, "-v" },
 14561457         { &freestanding, 1, "-D__STDC_HOSTED__=0" },
 14571458         { &freestanding, 0, "-D__STDC_HOSTED__=1" },
 14581459         { &cxxflag, 1, "-D__cplusplus" },
 14591460         { &xuchar, 1, "-D__CHAR_UNSIGNED__" },
 14601461         { &sspflag, 1, "-D__SSP__" },
 14611462         { &pthreads, 1, "-D_PTHREADS" },
 14621463         { &Oflag, 1, "-D__OPTIMIZE__" },
 14631464         { &tflag, 1, "-t" },
 14641465         { &kflag, 1, "-D__PIC__" },
 14651466         { 0 },
 14661467 };
 14671468 
 14681469 static void
 14691470 cksetflags(struct flgcheck *fs, struct strlist *sl, int which)
 14701471 {
 14711472         void (*fn)(struct strlist *, const char *);
 14721473 
 14731474         fn = which == 'p' ? strlist_prepend : strlist_append;
 14741475         for (; fs->flag; fs++) {
 14751476                 if (fs->set && *fs->flag)
 14761477                         fn(sl, fs->def);
 14771478                 if (!fs->set && !*fs->flag)
 14781479                         fn(sl, fs->def);
 14791480         }
 14801481 }
 14811482 
 14821483 static char *defflags[] = {
 14831484         "-D__PCC__=" MKS(PCC_MAJOR),
 14841485         "-D__PCC_MINOR__=" MKS(PCC_MINOR),
 14851486         "-D__PCC_MINORMINOR__=" MKS(PCC_MINORMINOR),
 14861487         "-D__VERSION__=" MKS(VERSSTR),
 14871488         "-D__SCHAR_MAX__=" MKS(MAX_CHAR),
 14881489         "-D__SHRT_MAX__=" MKS(MAX_SHORT),
 14891490         "-D__INT_MAX__=" MKS(MAX_INT),
 14901491         "-D__LONG_MAX__=" MKS(MAX_LONG),
 14911492         "-D__LONG_LONG_MAX__=" MKS(MAX_LONGLONG),
 14921493 
 14931494         "-D__STDC_ISO_10646__=200009L",
 14941495         "-D__WCHAR_TYPE__=" WCT,
 14951496         "-D__SIZEOF_WCHAR_T__=" MKS(WCHAR_SIZE),
 14961497         "-D__WCHAR_MAX__=" WCM,
 14971498         "-D__WINT_TYPE__=" PCC_WINT_TYPE,
 14981499         "-D__SIZE_TYPE__=" PCC_SIZE_TYPE,
 14991500         "-D__PTRDIFF_TYPE__=" PCC_PTRDIFF_TYPE,
 15001501         "-D__SIZEOF_WINT_T__=4",
 15011502 };
 15021503 
 15031504 static char *gcppflags[] = {
 15041505 #ifndef os_win32
 15051506 #ifdef GCC_COMPAT
 15061507         "-D__GNUC__=4",
 15071508         "-D__GNUC_MINOR__=3",
 15081509         "-D__GNUC_PATCHLEVEL__=1",
 15091510         "-D__REGISTER_PREFIX__=" REGISTER_PREFIX,
 15101511         "-D__USER_LABEL_PREFIX__=" USER_LABEL_PREFIX,
 15111512 #if SZLONG == 64
 15121513         "-D__SIZEOF_LONG__=8",
 15131514 #elif SZLONG == 32
 15141515         "-D__SIZEOF_LONG__=4",
 15151516 #endif
 15161517 #if SZPOINT(CHAR) == 64
 15171518         "-D__SIZEOF_POINTER__=8",
 15181519 #elif SZPOINT(CHAR) == 32
 15191520         "-D__SIZEOF_POINTER__=4",
 15201521 #endif
 15211522 #endif
 15221523 #endif
 15231524 };
 15241525 
 15251526 /* These should _not_ be defined here */
 15261527 static char *fpflags[] = {
 15271528 #ifdef TARGET_FLT_EVAL_METHOD
 15281529         "-D__FLT_EVAL_METHOD__=" MKS(TARGET_FLT_EVAL_METHOD),
 15291530 #endif
 15301531 #if defined(os_darwin) || defined(os_netbsd)
 15311532         "-D__FLT_RADIX__=2",
 15321533 #if defined(mach_vax)
 15331534         "-D__FLT_DIG__=6",
 15341535         "-D__FLT_EPSILON__=1.19209290e-07F",
 15351536         "-D__FLT_MANT_DIG__=24",
 15361537         "-D__FLT_MAX_10_EXP__=38",
 15371538         "-D__FLT_MAX_EXP__=127",
 15381539         "-D__FLT_MAX__=1.70141173e+38F",
 15391540         "-D__FLT_MIN_10_EXP__=(-38)",
 15401541         "-D__FLT_MIN_EXP__=(-127)",
 15411542         "-D__FLT_MIN__=2.93873588e-39F",
 15421543         "-D__DBL_DIG__=16",
 15431544         "-D__DBL_EPSILON__=2.77555756156289135e-17",
 15441545         "-D__DBL_MANT_DIG__=56",
 15451546         "-D__DBL_MAX_10_EXP__=38",
 15461547         "-D__DBL_MAX_EXP__=127",
 15471548         "-D__DBL_MAX__=1.701411834604692294e+38",
 15481549         "-D__DBL_MIN_10_EXP__=(-38)",
 15491550         "-D__DBL_MIN_EXP__=(-127)",
 15501551         "-D__DBL_MIN__=2.938735877055718770e-39",
 15511552 #else
 15521553         "-D__FLT_DIG__=6",
 15531554         "-D__FLT_EPSILON__=1.19209290e-07F",
 15541555         "-D__FLT_MANT_DIG__=24",
 15551556         "-D__FLT_MAX_10_EXP__=38",
 15561557         "-D__FLT_MAX_EXP__=128",
 15571558         "-D__FLT_MAX__=3.40282347e+38F",
 15581559         "-D__FLT_MIN_10_EXP__=(-37)",
 15591560         "-D__FLT_MIN_EXP__=(-125)",
 15601561         "-D__FLT_MIN__=1.17549435e-38F",
 15611562         "-D__DBL_DIG__=15",
 15621563         "-D__DBL_EPSILON__=2.2204460492503131e-16",
 15631564         "-D__DBL_MANT_DIG__=53",
 15641565         "-D__DBL_MAX_10_EXP__=308",
 15651566         "-D__DBL_MAX_EXP__=1024",
 15661567         "-D__DBL_MAX__=1.7976931348623157e+308",
 15671568         "-D__DBL_MIN_10_EXP__=(-307)",
 15681569         "-D__DBL_MIN_EXP__=(-1021)",
 15691570         "-D__DBL_MIN__=2.2250738585072014e-308",
 15701571 #endif
 15711572 #if defined(mach_i386) || defined(mach_amd64)
 15721573         "-D__LDBL_DIG__=18",
 15731574         "-D__LDBL_EPSILON__=1.08420217248550443401e-19L",
 15741575         "-D__LDBL_MANT_DIG__=64",
 15751576         "-D__LDBL_MAX_10_EXP__=4932",
 15761577         "-D__LDBL_MAX_EXP__=16384",
 15771578         "-D__LDBL_MAX__=1.18973149535723176502e+4932L",
 15781579         "-D__LDBL_MIN_10_EXP__=(-4931)",
 15791580         "-D__LDBL_MIN_EXP__=(-16381)",
 15801581         "-D__LDBL_MIN__=3.36210314311209350626e-4932L",
 15811582 #elif defined(mach_vax)
 15821583         "-D__LDBL_DIG__=16",
 15831584         "-D__LDBL_EPSILON__=2.77555756156289135e-17",
 15841585         "-D__LDBL_MANT_DIG__=56",
 15851586         "-D__LDBL_MAX_10_EXP__=38",
 15861587         "-D__LDBL_MAX_EXP__=127",
 15871588         "-D__LDBL_MAX__=1.701411834604692294e+38",
 15881589         "-D__LDBL_MIN_10_EXP__=(-38)",
 15891590         "-D__LDBL_MIN_EXP__=(-127)",
 15901591         "-D__LDBL_MIN__=2.938735877055718770e-39",
 15911592 #else
 15921593         "-D__LDBL_DIG__=15",
 15931594         "-D__LDBL_EPSILON__=2.2204460492503131e-16",
 15941595         "-D__LDBL_MANT_DIG__=53",
 15951596         "-D__LDBL_MAX_10_EXP__=308",
 15961597         "-D__LDBL_MAX_EXP__=1024",
 15971598         "-D__LDBL_MAX__=1.7976931348623157e+308",
 15981599         "-D__LDBL_MIN_10_EXP__=(-307)",
 15991600         "-D__LDBL_MIN_EXP__=(-1021)",
 16001601         "-D__LDBL_MIN__=2.2250738585072014e-308",
 16011602 #endif
 16021603 #endif
 16031604 };
 16041605 
 16051606 /*
 16061607  * Configure the standard cpp flags.
 16071608  */
 16081609 void
 16091610 setup_cpp_flags(void)
 16101611 {
 16111612         int i;
 16121613 
 16131614         /* a bunch of misc defines */
 16141615         for (i = 0; i < (int)sizeof(defflags)/(int)sizeof(char *); i++)
 16151616                 strlist_prepend(&preprocessor_flags, defflags[i]);
 16161617 
 16171618         for (i = 0; i < (int)sizeof(gcppflags)/(int)sizeof(char *); i++)
 16181619                 strlist_prepend(&preprocessor_flags, gcppflags[i]);
 16191620         strlist_prepend(&preprocessor_flags, xgnu89 ?
 16201621             "-D__GNUC_GNU_INLINE__" : "-D__GNUC_STDC_INLINE__");
 16211622 
 16221623         cksetflags(cppflgcheck, &preprocessor_flags, 'p');
 16231624 
 16241625         for (i = 0; i < (int)sizeof(fpflags)/(int)sizeof(char *); i++)
 16251626                 strlist_prepend(&preprocessor_flags, fpflags[i]);
 16261627 
 16271628         for (i = 0; cppadd[i]; i++)
 16281629                 strlist_prepend(&preprocessor_flags, cppadd[i]);
 16291630         for (i = 0; cppmdadd[i]; i++)
 16301631                 strlist_prepend(&preprocessor_flags, cppmdadd[i]);
 16311632 
 16321633         /* Include dirs */
 16331634         strlist_append(&sysincdirs, "=" INCLUDEDIR "pcc/");
 16341635         strlist_append(&sysincdirs, "=" STDINC);
 16351636 #ifdef PCCINCDIR
 16361637         if (cxxflag)
 16371638                 strlist_append(&sysincdirs, "=" PCCINCDIR "/c++");
 16381639         strlist_append(&sysincdirs, "=" PCCINCDIR);
 16391640 #endif
 16401641 }
 16411642 
 16421643 struct flgcheck ccomflgcheck[] = {
 16431644         { &Oflag, 1, "-xtemps" },
 16441645         { &Oflag, 1, "-xdeljumps" },
 16451646         { &Oflag, 1, "-xinline" },
 16461647         { &Oflag, 1, "-xdce" },
 16471648 #ifdef notyet
 16481649         { &Oflag, 1, "-xssa" },
 16491650 #endif
 16501651         { &freestanding, 1, "-ffreestanding" },
 16511652         { &pgflag, 1, "-p" },
 16521653         { &gflag, 1, "-g" },
 16531654         { &xgnu89, 1, "-xgnu89" },
 16541655         { &xgnu99, 1, "-xgnu99" },
 16551656         { &xuchar, 1, "-xuchar" },
 16561657 #if !defined(os_sunos) && !defined(mach_i386)
 16571658         { &vflag, 1, "-v" },
 16581659 #endif
 16591660 #ifdef os_darwin
 16601661         { &Bstatic, 0, "-k" },
 16611662 #elif defined(os_sunos) && defined(mach_i386)
 16621663         { &kflag, 1, "-K" },
 16631664         { &kflag, 1, "pic" },
 16641665 #else
 16651666         { &kflag, 1, "-k" },
 16661667 #endif
 16671668         { &sspflag, 1, "-fstack-protector" },
 16681669         { 0 }
 16691670 };
 16701671 
 16711672 void
 16721673 setup_ccom_flags(void)
 16731674 {
 16741675 
 16751676         cksetflags(ccomflgcheck, &compiler_flags, 'a');
 16761677 }
 16771678 
 16781679 static int one = 1;
 16791680 
 16801681 struct flgcheck asflgcheck[] = {
 16811682 #if defined(USE_YASM)
 16821683         { &one, 1, "-p" },
 16831684         { &one, 1, "gnu" },
 16841685         { &one, 1, "-f" },
 16851686 #if defined(os_win32)
 16861687         { &one, 1, "win32" },
 16871688 #elif defined(os_darwin)
 16881689         { &one, 1, "macho" },
 16891690 #else
 16901691         { &one, 1, "elf" },
 16911692 #endif
 16921693 #endif
 16931694 #if defined(os_sunos) && defined(mach_sparc64)
 16941695         { &one, 1, "-m64" },
 16951696 #endif
 16961697 #if defined(os_darwin)
 16971698         { &Bstatic, 1, "-static" },
 16981699 #endif
 16991700 #if !defined(USE_YASM)
 17001701         { &vflag, 1, "-v" },
 17011702 #endif
 17021703         { &kflag, 1, "-k" },
 17031704 #ifdef os_darwin
 17041705         { &one, 1, "-arch" },
 17051706 #if mach_amd64
 17061707         { &amd64_i386, 1, "i386" },
 17071708         { &amd64_i386, 0, "x86_64" },
 17081709 #else
 17091710         { &one, 1, "i386" },
 17101711 #endif
 17111712 #else
 17121713 #ifdef mach_amd64
 17131714         { &amd64_i386, 1, "--32" },
 17141715 #endif
 17151716 #endif
 17161717         { 0 }
 17171718 };
 17181719 void
 17191720 setup_as_flags(void)
 17201721 {
 17211722         one = one;
 17221723 #ifdef PCC_SETUP_AS_ARGS
 17231724         PCC_SETUP_AS_ARGS
 17241725 #endif
 17251726         cksetflags(asflgcheck, &assembler_flags, 'a');
 17261727 }
 17271728 
 17281729 struct flgcheck ldflgcheck[] = {
 17291730 #ifndef MSLINKER
 17301731         { &vflag, 1, "-v" },
 17311732 #endif
 17321733 #ifdef os_darwin
 17331734         { &shared, 1, "-dylib" },
 17341735 #elif defined(os_win32)
 17351736         { &shared, 1, "-Bdynamic" },
 17361737 #else
 17371738         { &shared, 1, "-shared" },
 17381739 #endif
 17391740 #if !defined(os_sunos) && !defined(os_win32)
 17401741 #ifndef os_darwin
 17411742         { &shared, 0, "-d" },
 17421743 #endif
 17431744 #endif
 17441745 #ifdef os_darwin
 17451746         { &Bstatic, 1, "-static" },
 17461747 #else
 17471748         { &Bstatic, 1, "-Bstatic" },
 17481749 #endif
 17491750 #if !defined(os_darwin) && !defined(os_sunos)
 17501751         { &gflag, 1, "-g" },
 17511752 #endif
 17521753         { &pthreads, 1, "-lpthread" },
 17531754         { 0 },
 17541755 };
 17551756 
 17561757 static void
 17571758 strap(struct strlist *sh, struct strlist *cd, char *n, int where)
 17581759 {
 17591760         void (*fn)(struct strlist *, const char *);
 17601761         char *fil;
 17611762 
 17621763         if (n == 0)
 17631764                 return; /* no crtfile */
 17641765 
 17651766         fn = where == 'p' ? strlist_prepend : strlist_append;
 17661767         fil = find_file(n, cd, R_OK);
 17671768         (*fn)(sh, fil);
 17681769 }
 17691770 
 17701771 void
 17711772 setup_ld_flags(void)
 17721773 {
 17731774         char *b, *e;
 17741775         int i;
 17751776 
 17761777         cksetflags(ldflgcheck, &early_linker_flags, 'a');
 17771778         if (Bstatic == 0 && shared == 0 && rflag == 0) {
 17781779                 for (i = 0; dynlinker[i]; i++)
 17791780                         strlist_append(&early_linker_flags, dynlinker[i]);
 17801781                 strlist_append(&early_linker_flags, "-e");
 17811782                 strlist_append(&early_linker_flags, STARTLABEL);
 17821783         }
 17831784         if (shared == 0 && rflag)
 17841785                 strlist_append(&early_linker_flags, "-r");
 17851786         if (sysroot && *sysroot)
 17861787                 strlist_append(&early_linker_flags, cat("--sysroot=", sysroot));
 17871788         if (!nostdlib) {
 17881789                 /* library search paths */
 17891790                 if (pcclibdir)
 17901791                         strlist_append(&late_linker_flags,
 17911792                             cat("-L", pcclibdir));
 17921793                 for (i = 0; deflibdirs[i]; i++)
 17931794                         strlist_append(&late_linker_flags,
 17941795                             cat("-L", deflibdirs[i]));
 17951796                 /* standard libraries */
 17961797                 if (pgflag) {
 17971798                         for (i = 0; defproflibs[i]; i++)
 17981799                                 strlist_append(&late_linker_flags,
 17991800                                      defproflibs[i]);
 18001801                 } else if (cxxflag) {
 18011802                         for (i = 0; defcxxlibs[i]; i++)
 18021803                                 strlist_append(&late_linker_flags,
 18031804                                     defcxxlibs[i]);
 18041805                 } else {
 18051806                         for (i = 0; deflibs[i]; i++)
 18061807                                 strlist_append(&late_linker_flags, deflibs[i]);
 18071808                 }
 18081809         }
 18091810         if (!nostartfiles) {
 18101811                 if (Bstatic) {
 18111812                         b = CRTBEGIN_T;
 18121813                         e = CRTEND_T;
 18131814                 } else if (shared /* || pieflag */) {
 18141815                         b = CRTBEGIN_S;
 18151816                         e = CRTEND_S;
 18161817                 }  else {
 18171818                         b = CRTBEGIN;
 18181819                         e = CRTEND;
 18191820                 }
 18201821                 strap(&middle_linker_flags, &crtdirs, b, 'p');
 18211822                 strap(&late_linker_flags, &crtdirs, e, 'a');
 18221823                 strap(&middle_linker_flags, &crtdirs, CRTI, 'p');
 18231824                 strap(&late_linker_flags, &crtdirs, CRTN, 'a');
 18241825                 if (shared == 0) {
 18251826                         if (pgflag)
 18261827                                 b = GCRT0;
 18271828 #ifdef notyet
 18281829                         else if (pieflag)
 18291830                                 b = SCRT0;
 18301831 #endif
 18311832                         else
 18321833                                 b = CRT0;
 18331834                         strap(&middle_linker_flags, &crtdirs, b, 'p');
 18341835                 }
 18351836         }
 18361837 }
 18371838 
 18381839 #ifdef os_win32
 18391840 char *
 18401841 win32pathsubst(char *s)
 18411842 {
 18421843         char env[1024];
 18431844         DWORD len;
 18441845 
 18451846         len = ExpandEnvironmentStrings(s, env, sizeof(env));
 18461847         if (len == 0 || len > sizeof(env))
 18471848                 errorx(8, "ExpandEnvironmentStrings failed, len %lu", len);
 18481849 
 18491850         len--;  /* skip nil */
 18501851         while (len-- > 0 && (env[len] == '/' || env[len] == '\\'))
 18511852                 env[len] = '\0';
 18521853 
 18531854         return xstrdup(env);
 18541855 }
 18551856 
 18561857 char *
 18571858 win32commandline(struct strlist *l)
 18581859 {
 18591860         const struct string *s;
 18601861         char *cmd;
 18611862         char *p;
 18621863         int len;
 18631864         int j, k;
 18641865 
 18651866         len = 0;
 18661867         STRLIST_FOREACH(s, l) {
 18671868                 len++;
 18681869                 for (j = 0; s->value[j] != '\0'; j++) {
 18691870                         if (s->value[j] == '\"') {
 18701871                                 for (k = j-1; k >= 0 && s->value[k] == '\\'; k--)
 18711872                                         len++;
 18721873                                 len++;
 18731874                         }
 18741875                         len++;
 18751876                 }
 18761877                 for (k = j-1; k >= 0 && s->value[k] == '\\'; k--)
 18771878                         len++;
 18781879                 len++;
 18791880                 len++;
 18801881         }
 18811882 
 18821883         p = cmd = xmalloc(len);
 18831884 
 18841885         STRLIST_FOREACH(s, l) {
 18851886                 *p++ = '\"';
 18861887                 for (j = 0; s->value[j] != '\0'; j++) {
 18871888                         if (s->value[j] == '\"') {
 18881889                                 for (k = j-1; k >= 0 && s->value[k] == '\\'; k--)
 18891890                                         *p++ = '\\';
 18901891                                 *p++ = '\\';
 18911892                         }
 18921893                         *p++ = s->value[j];
 18931894                 }
 18941895                 for (k = j-1; k >= 0 && s->value[k] == '\\'; k--)
 18951896                         *p++ = '\\';
 18961897                 *p++ = '\"';
 18971898                 *p++ = ' ';
 18981899         }
 18991900         p[-1] = '\0';
 19001901 
 19011902         return cmd;
 19021903 }
 19031904 #endif
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-11-01 13:31 +0100