Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.272
 
1.273
 
MAIN:gmcgarry:20140604064349
 
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 error(char *, ...);
 244244 void errorx(int, char *, ...);
 245245 int cunlink(char *);
 246246 void exandrm(char *);
 247247 void dexit(int);
 248248 void idexit(int);
 249249 char *gettmp(void);
 250250 void aerror(char *);
 251251 void oerror(char *);
 252252 char *argnxt(char *, char *);
 253253 char *nxtopt(char *o);
 254254 void setup_cpp_flags(void);
 255255 void setup_ccom_flags(void);
 256256 void setup_as_flags(void);
 257257 void setup_ld_flags(void);
 258258 static void expand_sysroot(void);
 259259 #ifdef os_win32
 260260 char *win32pathsubst(char *);
 261261 char *win32commandline(struct strlist *l);
 262262 #endif
 263263 int     sspflag;
 264264 int     freestanding;
 265265 int     Sflag;
 266266 int     cflag;
 267267 int     gflag;
 268268 int     rflag;
 269269 int     vflag;
 270270 int     tflag;
 271271 int     Eflag;
 272272 int     Oflag;
 273273 int     kflag;  /* generate PIC/pic code */
 274274 #define F_PIC   1
 275275 #define F_pic   2
 276276 int     Mflag, needM, MDflag;   /* dependencies only */
 277277 int     pgflag;
 278278 int     Xflag;
 279279 int     nostartfiles, Bstatic, shared;
 280280 int     nostdinc, nostdlib;
 281281 int     pthreads;
 282282 int     xgnu89, xgnu99;
 283283 int     ascpp;
 284284 #ifdef CHAR_UNSIGNED
 285285 int     xuchar = 1;
 286286 #else
 287287 int     xuchar = 0;
 288288 #endif
 289289 int     cxxflag;
 290290 int     cppflag;
 291291 int     printprogname, printfilename;
 292292 
 293293 #ifdef mach_amd64
 294294 int amd64_i386;
 295295 #endif
 296296 
 297297 #define match(a,b)      (strcmp(a,b) == 0)
 298298 
 299299 /* handle gcc warning emulations */
 300300 struct Wflags {
 301301         char *name;
 302302         int flags;
 303303 #define INWALL          1
 304304 } Wflags[] = {
 305305         { "truncate", 0 },
 306306         { "strict-prototypes", 0 },
 307307         { "missing-prototypes", 0 },
 308308         { "implicit-int", INWALL },
 309309         { "implicit-function-declaration", INWALL },
 310310         { "shadow", 0 },
 311311         { "pointer-sign", INWALL },
 312312         { "sign-compare", 0 },
 313313         { "unknown-pragmas", INWALL },
 314314         { "unreachable-code", 0 },
 315315         { NULL, 0 },
 316316 };
 317317 
 318318 #ifndef USHORT
 319319 /* copied from mip/manifest.h */
 320320 #define USHORT          5
 321321 #define INT             6
 322322 #define UNSIGNED        7
 323323 #endif
 324324 
 325325 /*
 326326  * Wide char defines.
 327327  */
 328328 #if WCHAR_TYPE == USHORT
 329329 #define WCT "short unsigned int"
 330330 #define WCM "65535U"
 331331 #if WCHAR_SIZE != 2
 332332 #error WCHAR_TYPE vs. WCHAR_SIZE mismatch
 333333 #endif
 334334 #elif WCHAR_TYPE == INT
 335335 #define WCT "int"
 336336 #define WCM "2147483647"
 337337 #if WCHAR_SIZE != 4
 338338 #error WCHAR_TYPE vs. WCHAR_SIZE mismatch
 339339 #endif
 340340 #elif WCHAR_TYPE == UNSIGNED
 341341 #define WCT "unsigned int"
 342342 #define WCM "4294967295U"
 343343 #if WCHAR_SIZE != 4
 344344 #error WCHAR_TYPE vs. WCHAR_SIZE mismatch
 345345 #endif
 346346 #else
 347347 #error WCHAR_TYPE not defined or invalid
 348348 #endif
 349349 
 350350 #ifdef GCC_COMPAT
 351351 #ifndef REGISTER_PREFIX
 352352 #define REGISTER_PREFIX ""
 353353 #endif
 354354 #ifndef USER_LABEL_PREFIX
 355355 #define USER_LABEL_PREFIX ""
 356356 #endif
 357357 #endif
 358358 
 359359 #ifndef PCC_WINT_TYPE
 360360 #define PCC_WINT_TYPE "unsigned int"
 361361 #endif
 362362 
 363363 #ifndef PCC_SIZE_TYPE
 364364 #define PCC_SIZE_TYPE "unsigned long"
 365365 #endif
 366366 
 367367 #ifndef PCC_PTRDIFF_TYPE
 368368 #define PCC_PTRDIFF_TYPE "long int"
 369369 #endif
 370370 
 371371 
 372372 struct strlist preprocessor_flags;
 373373 struct strlist depflags;
 374374 struct strlist incdirs;
 375375 struct strlist user_sysincdirs;
 376376 struct strlist includes;
 377377 struct strlist sysincdirs;
 378378 struct strlist dirafterdirs;
 379379 struct strlist crtdirs;
 380380 struct strlist libdirs;
 381381 struct strlist progdirs;
 382382 struct strlist early_linker_flags;
 383383 struct strlist middle_linker_flags;
 384384 struct strlist late_linker_flags;
 385385 struct strlist inputs;
 386386 struct strlist assembler_flags;
 387387 struct strlist temp_outputs;
 388388 struct strlist compiler_flags;
 389389 
 390390 int
 391391 main(int argc, char *argv[])
 392392 {
 393393         struct Wflags *Wf;
 394394         struct string *s;
 395395         char *t, *u, *argp;
 396396         char *msuffix;
 397397         int ninput, j;
 398398 
 399399         lav = argv;
 400400         lac = argc;
 401401         ninput = 0;
 402402 
 403403         strlist_init(&crtdirs);
 404404         strlist_init(&libdirs);
 405405         strlist_init(&progdirs);
 406406         strlist_init(&preprocessor_flags);
 407407         strlist_init(&incdirs);
 408408         strlist_init(&user_sysincdirs);
 409409         strlist_init(&includes);
 410410         strlist_init(&sysincdirs);
 411411         strlist_init(&dirafterdirs);
 412412         strlist_init(&depflags);
 413413         strlist_init(&early_linker_flags);
 414414         strlist_init(&middle_linker_flags);
 415415         strlist_init(&late_linker_flags);
 416416         strlist_init(&inputs);
 417417         strlist_init(&assembler_flags);
 418418         strlist_init(&temp_outputs);
 419419         strlist_init(&compiler_flags);
 420420 
 421421         if ((t = strrchr(argv[0], '/')))
 422422                 t++;
 423423         else
 424424                 t = argv[0];
 425425 
 426426         if (match(t, "p++")) {
 427427                 cxxflag = 1;
 428428         } else if (match(t, "cpp") || match(t, CPPROGNAME)) {
 429429                 Eflag = cppflag = 1;
 430430         }
 431431 
 432432 #ifdef PCC_EARLY_SETUP
 433433         PCC_EARLY_SETUP
 434434 #endif
 435435 
 436436 #ifdef os_win32
 437437         /* have to prefix path early.  -B may override */
 438438         incdir = win32pathsubst(incdir);
 439439         altincdir = win32pathsubst(altincdir);
 440440         libdir = win32pathsubst(libdir);
 441441 #ifdef PCCINCDIR
 442442         pccincdir = win32pathsubst(pccincdir);
 443443         pxxincdir = win32pathsubst(pxxincdir);
 444444 #endif
 445445 #ifdef PCCLIBDIR
 446446         pcclibdir = win32pathsubst(pcclibdir);
 447447 #endif
 448448         passp = win32pathsubst(passp);
 449449         pass0 = win32pathsubst(pass0);
 450450 #ifdef STARTFILES
 451451         for (i = 0; startfiles[i] != NULL; i++)
 452452                 startfiles[i] = win32pathsubst(startfiles[i]);
 453453         for (i = 0; endfiles[i] != NULL; i++)
 454454                 endfiles[i] = win32pathsubst(endfiles[i]);
 455455 #endif
 456456 #ifdef STARTFILES_T
 457457         for (i = 0; startfiles_T[i] != NULL; i++)
 458458                 startfiles_T[i] = win32pathsubst(startfiles_T[i]);
 459459         for (i = 0; endfiles_T[i] != NULL; i++)
 460460                 endfiles_T[i] = win32pathsubst(endfiles_T[i]);
 461461 #endif
 462462 #ifdef STARTFILES_S
 463463         for (i = 0; startfiles_S[i] != NULL; i++)
 464464                 startfiles_S[i] = win32pathsubst(startfiles_S[i]);
 465465         for (i = 0; endfiles_S[i] != NULL; i++)
 466466                 endfiles_S[i] = win32pathsubst(endfiles_S[i]);
 467467 #endif
 468468 #endif
 469469 
 470470         while (--lac) {
 471471                 ++lav;
 472472                 argp = *lav;
 473473 
 474474 #ifdef PCC_EARLY_ARG_CHECK
 475475                 PCC_EARLY_ARG_CHECK
 476476 #endif
 477477 
 478478                 if (*argp != '-' || match(argp, "-")) {
 479479                         /* Check for duplicate .o files. */
 480480                         if (getsuf(argp) == 'o') {
 481481                                 j = 0;
 482482                                 STRLIST_FOREACH(s, &inputs)
 483483                                         if (match(argp, s->value))
 484484                                                 j++;
 485485                                 if (j)
 486486                                         continue; /* skip it */
 487487                         }
 488488                         strlist_append(&inputs, argp);
 489489                         ninput++;
 490490                         continue;
 491491                 }
 492492 
 493493                 switch (argp[1]) {
 494494                 default:
 495495                         oerror(argp);
 496496                         break;
 497497 
 498498                 case '-': /* double -'s */
 499499                         if (match(argp, "--version")) {
 500500                                 printf("%s\n", VERSSTR);
 501501                                 return 0;
 502502                         } else if (strncmp(argp, "--sysroot=", 10) == 0) {
 503503                                 sysroot = argp + 10;
 504504                         } else if (strcmp(argp, "--param") == 0) {
 505505                                 /* NOTHING YET */;
 506506                                 (void)nxtopt(0); /* ignore arg */
 507507                         } else
 508508                                 oerror(argp);
 509509                         break;
 510510 
 511511                 case 'B': /* other search paths for binaries */
 512512                         t = nxtopt("-B");
 513513                         strlist_append(&crtdirs, t);
 514514                         strlist_append(&libdirs, t);
 515515                         strlist_append(&progdirs, t);
 516516                         break;
 517517 
 518518                 case 'C':
 519519                         if (match(argp, "-C") || match(argp, "-CC"))
 520520                                 strlist_append(&preprocessor_flags, argp);
 521521                         else
 522522                                 oerror(argp);
 523523                         break;
 524524 
 525525                 case 'c':
 526526                         cflag++;
 527527                         break;
 528528 
 529529                 case 'd':
 530530                         oerror(argp);
 531531                         break;
 532532 
 533533                 case 'E':
 534534                         Eflag++;
 535535                         break;
 536536 
 537537                 case 'f': /* GCC compatibility flags */
 538538                         u = &argp[2];
 539539                         j = 0;
 540540                         if (strncmp(u, "no-", 3) == 0)
 541541                                 j = 1, u += 3;
 542542                         if (match(u, "PIC") || match(u, "pic")) {
 543543                                 kflag = j ? 0 : *u == 'P' ? F_PIC : F_pic;
 544544                         } else if (match(u, "freestanding")) {
 545545                                 freestanding = j ? 0 : 1;
 546546                         } else if (match(u, "signed-char")) {
 547547                                 xuchar = j ? 1 : 0;
 548548                         } else if (match(u, "unsigned-char")) {
 549549                                 xuchar = j ? 0 : 1;
 550550                         } else if (match(u, "stack-protector") ||
 551551                             match(u, "stack-protector-all")) {
 552552                                 sspflag = j ? 0 : 1;
<>553 -#ifdef os_darwin
 554 -                        } else if (match(u, "ramework")) {
 555 -                                strlist_append(&middle_linker_flags, argp);
 556 -                                strlist_append(&middle_linker_flags, nxtopt(0));
 557 -#endif
<_558553                         }
 559554                         /* silently ignore the rest */
 560555                         break;
 561556 
 562557                 case 'g': /* create debug output */
 563558                         if (argp[2] == '0')
 564559                                 gflag = 0;
 565560                         else
 566561                                 gflag++;
 567562                         break;
 568563 
 569564 
 570565                 case 'X':
 571566                         Xflag++;
 572567                         break;
 573568 
 574569                 case 'D':
 575570                 case 'U':
 576571                         strlist_append(&preprocessor_flags, argp);
 577572                         if (argp[2] != 0)
 578573                                 break;
 579574                         strlist_append(&preprocessor_flags, nxtopt(argp));
 580575                         break;
 581576 
 582577                 case 'I': /* Add include dirs */
 583578                         strlist_append(&incdirs, nxtopt("-I"));
 584579                         break;
 585580 
 586581                 case 'i':
 587582                         if (match(argp, "-isystem")) {
 588583                                 strlist_append(&user_sysincdirs, nxtopt(0));
 589584                         } else if (match(argp, "-include")) {
 590585                                 strlist_append(&includes, nxtopt(0));
 591586                         } else if (match(argp, "-isysroot")) {
 592587                                 isysroot = nxtopt(0);
 593588                         } else if (strcmp(argp, "-idirafter") == 0) {
 594589                                 strlist_append(&dirafterdirs, nxtopt(0));
 595590                         } else
 596591                                 oerror(argp);
 597592                         break;
 598593 
 599594                 case 'k': /* generate PIC code */
 600595                         kflag = argp[2] ? argp[2] - '0' : F_pic;
 601596                         break;
 602597 
 603598                 case 'l':
 604599                 case 'L':
 605600                         if (argp[2] == 0)
 606601                                 argp = cat(argp, nxtopt(0));
 607602                         strlist_append(&inputs, argp);
 608603                         break;
 609604 
 610605                 case 'm': /* target-dependent options */
 611606 #ifdef mach_amd64
 612607                         /* need to call i386 ccom for this */
 613608                         if (strcmp(argp, "-melf_i386") == 0) {
 614609                                 pass0 = LIBEXECDIR "/ccom_i386";
 615610                                 amd64_i386 = 1;
 616611                                 break;
 617612                         }
 618613 #endif
 619614                         strlist_append(&middle_linker_flags, argp);
 620615                         if (argp[2] == 0) {
 621616                                 t = nxtopt(0);
 622617                                 strlist_append(&middle_linker_flags, t);
 623618                         }
 624619                         break;
 625620 
 626621                 case 'n': /* handle -n flags */
 627622                         if (strcmp(argp, "-nostdinc") == 0)
 628623                                 nostdinc++;
 629624                         else if (strcmp(argp, "-nostdlib") == 0) {
 630625                                 nostdlib++;
 631626                                 nostartfiles++;
 632627                         } else if (strcmp(argp, "-nostartfiles") == 0)
 633628                                 nostartfiles = 1;
 634629                         else if (strcmp(argp, "-nodefaultlibs") == 0)
 635630                                 nostdlib++;
 636631                         else
 637632                                 oerror(argp);
 638633                         break;
 639634 
 640635                 case 'p':
 641636                         if (strcmp(argp, "-pg") == 0 ||
 642637                             strcmp(argp, "-p") == 0)
 643638                                 pgflag++;
 644639                         else if (strcmp(argp, "-pthread") == 0)
 645640                                 pthreads++;
 646641                         else if (strcmp(argp, "-pipe") == 0)
 647642                                 /* NOTHING YET */;
 648643                         else if (strcmp(argp, "-pedantic") == 0)
 649644                                 /* NOTHING YET */;
 650645                         else if ((t = argnxt(argp, "-print-prog-name="))) {
 651646                                 fname = t;
 652647                                 printprogname = 1;
 653648                         } else if ((t = argnxt(argp, "-print-file-name="))) {
 654649                                 fname = t;
 655650                                 printfilename = 1;
 656651                         } else if (match(argp, "-print-libgcc-file-name")) {
 657652                                 fname = "libpcc.a";
 658653                                 printfilename = 1;
 659654                         } else
 660655                                 oerror(argp);
 661656                         break;
 662657 
 663658                 case 'r':
 664659                         rflag = 1;
 665660                         break;
 666661 
 667662                 case 'T':
 668663                         strlist_append(&inputs, argp);
 669664                         if (argp[2] == 0 ||
 670665                             strcmp(argp, "-Ttext") == 0 ||
 671666                             strcmp(argp, "-Tdata") == 0 ||
 672667                             strcmp(argp, "-Tbss") == 0)
 673668                                 strlist_append(&inputs, nxtopt(0));
 674669                         break;
 675670 
 676671                 case 's':
 677672                         if (match(argp, "-shared")) {
 678673                                 shared = 1;
 679674                         } else if (match(argp, "-static")) {
 680675                                 Bstatic = 1;
 681676                         } else if (match(argp, "-symbolic")) {
 682677                                 strlist_append(&middle_linker_flags,
 683678                                     "-Bsymbolic");
 684679                         } else if (strncmp(argp, "-std", 4) == 0) {
 685680                                 if (strcmp(&argp[5], "gnu99") == 0 ||
 686681                                     strcmp(&argp[5], "gnu9x") == 0)
 687682                                         xgnu99 = 1;
 688683                                 if (strcmp(&argp[5], "gnu89") == 0)
 689684                                         xgnu89 = 1;
 690685                         } else
 691686                                 oerror(argp);
 692687                         break;
 693688 
 694689                 case 'S':
 695690                         Sflag++;
 696691                         cflag++;
 697692                         break;
 698693 
 699694                 case 't':
 700695                         tflag++;
 701696                         break;
 702697 
 703698                 case 'o':
 704699                         if (outfile)
 705700                                 errorx(8, "too many -o");
 706701                         outfile = nxtopt("-o");
 707702                         break;
 708703 
 709704                 case 'O':
 710705                         if (argp[2] == '\0')
 711706                                 Oflag++;
 712707                         else if (argp[3] == '\0' &&
 713708                             isdigit((unsigned char)argp[2]))
 714709                                 Oflag = argp[2] - '0';
 715710                         else if (argp[3] == '\0' && argp[2] == 's')
 716711                                 Oflag = 1;      /* optimize for space only */
 717712                         else
 718713                                 oerror(argp);
 719714                         break;
 720715 
 721716                 case 'P':
 722717                         strlist_append(&preprocessor_flags, argp);
 723718                         break;
 724719 
 725720                 case 'M':
 726721                         needM = 1;
 727722                         if (match(argp, "-M")) {
 728723                                 Mflag++;
 729724                                 strlist_append(&depflags, argp);
 730725                         } else if (match(argp, "-MP")) {
 731726                                 strlist_append(&depflags, "-xMP");
 732727                         } else if (match(argp, "-MF")) {
 733728                                 MFfile = nxtopt("-MF");
 734729                         } else if (match(argp, "-MT") || match(argp, "-MQ")) {
 735730                                 t = cat("-xMT,", nxtopt("-MT"));
 736731                                 t[3] = argp[2];
 737732                                 strlist_append(&depflags, t);
 738733                         } else if (match(argp, "-MD")) {
 739734                                 MDflag++;
 740735                                 needM = 0;
 741736                                 strlist_append(&depflags, "-M");
 742737                         } else
 743738                                 oerror(argp);
 744739                         break;
 745740 
 746741                 case 'v':
 747742                         printf("%s\n", VERSSTR);
 748743                         vflag++;
 749744                         break;
 750745 
 751746                 case 'W': /* Ignore (most of) W-flags */
 752747                         if ((t = argnxt(argp, "-Wl,"))) {
 753748                                 u = strtok(t, ",");
 754749                                 do {
 755750                                         strlist_append(&inputs, u);
 756751                                 } while ((u = strtok(NULL, ",")) != NULL);
 757752                         } else if ((t = argnxt(argp, "-Wa,"))) {
 758753                                 u = strtok(t, ",");
 759754                                 do {
 760755                                         strlist_append(&assembler_flags, u);
 761756                                 } while ((u = strtok(NULL, ",")) != NULL);
 762757                         } else if ((t = argnxt(argp, "-Wc,"))) {
 763758                                 u = strtok(t, ",");
 764759                                 do {
 765760                                         strlist_append(&compiler_flags, u);
 766761                                 } while ((u = strtok(NULL, ",")) != NULL);
 767762                         } else if ((t = argnxt(argp, "-Wp,"))) {
 768763                                 u = strtok(t, ",");
 769764                                 do {
 770765                                         strlist_append(&preprocessor_flags, u);
 771766                                 } while ((u = strtok(NULL, ",")) != NULL);
 772767                         } else if (strcmp(argp, "-Werror") == 0) {
 773768                                 strlist_append(&compiler_flags, "-Werror");
 774769                                 strlist_append(&preprocessor_flags, "-E");
 775770                         } else if (strcmp(argp, "-Wall") == 0) {
 776771                                 for (Wf = Wflags; Wf->name; Wf++)
 777772                                         if (Wf->flags & INWALL)
 778773                                                 strlist_append(&compiler_flags,
 779774                                                     cat("-W", Wf->name));
 780775                         } else if (strcmp(argp, "-WW") == 0) {
 781776                                 for (Wf = Wflags; Wf->name; Wf++)
 782777                                         strlist_append(&compiler_flags,
 783778                                             cat("-W", Wf->name));
 784779                         } else {
 785780                                 /* pass through, if supported */
 786781                                 t = &argp[2];
 787782                                 if (strncmp(t, "no-", 3) == 0)
 788783                                         t += 3;
 789784                                 if (strncmp(t, "error=", 6) == 0)
 790785                                         t += 6;
 791786                                 for (Wf = Wflags; Wf->name; Wf++) {
 792787                                         if (strcmp(t, Wf->name) == 0)
 793788                                                 strlist_append(&compiler_flags,
 794789                                                     argp);
 795790                                 }
 796791                         }
 797792                         break;
 798793 
 799794                 case 'x':
 800795                         t = nxtopt("-x");
 801796                         if (match(t, "none"))
 802797                                 strlist_append(&inputs, ")");
 803798                         else if (match(t, "c"))
 804799                                 strlist_append(&inputs, ")c");
 805800                         else if (match(t, "assembler"))
 806801                                 strlist_append(&inputs, ")s");
 807802                         else if (match(t, "assembler-with-cpp"))
 808803                                 strlist_append(&inputs, ")S");
 809804                         else if (match(t, "c++"))
 810805                                 strlist_append(&inputs, ")c++");
 811806                         else {
 812807                                 strlist_append(&compiler_flags, "-x");
 813808                                 strlist_append(&compiler_flags, t);
 814809                         }
 815810                         break;
 816811 
 817812                 }
 818813                 continue;
 819814 
 820815         }
 821816 
 822817         /* Sanity checking */
 823818         if (cppflag) {
 824819                 if (ninput == 0) {
 825820                         strlist_append(&inputs, "-");
 826821                         ninput++;
 827822                 } else if (ninput > 2 || (ninput == 2 && outfile)) {
 828823                         errorx(8, "too many files");
 829824                 } else if (ninput == 2) {
 830825                         outfile = STRLIST_NEXT(STRLIST_FIRST(&inputs))->value;
 831826                         STRLIST_FIRST(&inputs)->next = NULL;
 832827                         ninput--;
 833828                 }
 834829         }
 835830         if (ninput == 0 && !(printprogname || printfilename))
 836831                 errorx(8, "no input files");
 837832         if (outfile && (cflag || Sflag || Eflag) && ninput > 1)
 838833                 errorx(8, "-o given with -c || -E || -S and more than one file");
 839834 #if 0
 840835         if (outfile && clist[0] && strcmp(outfile, clist[0]) == 0)
 841836                 errorx(8, "output file will be clobbered");
 842837 #endif
 843838 
 844839         if (needM && !Mflag && !MDflag)
 845840                 errorx(8, "to make dependencies needs -M");
 846841 
 847842 
 848843         if (signal(SIGINT, SIG_IGN) != SIG_IGN/* interrupt */
 849844                 signal(SIGINT, idexit);
 850845         if (signal(SIGTERM, SIG_IGN) != SIG_IGN)        /* terminate */
 851846                 signal(SIGTERM, idexit);
 852847 
 853848         /* after arg parsing */
 854849         strlist_append(&progdirs, LIBEXECDIR);
 855850         if (pcclibdir)
 856851                 strlist_append(&crtdirs, pcclibdir);
 857852         for (j = 0; deflibdirs[j]; j++) {
 858853                 if (sysroot)
 859854                         deflibdirs[j] = cat(sysroot, deflibdirs[j]);
 860855                 strlist_append(&crtdirs, deflibdirs[j]);
 861856         }
 862857 
 863858         setup_cpp_flags();
 864859         setup_ccom_flags();
 865860         setup_as_flags();
 866861 
 867862         if (isysroot == NULL)
 868863                 isysroot = sysroot;
 869864         expand_sysroot();
 870865 
 871866         if (printprogname) {
 872867                 printf("%s\n", find_file(fname, &progdirs, X_OK));
 873868                 return 0;
 874869         } else if (printfilename) {
 875870                 printf("%s\n", find_file(fname, &crtdirs, R_OK));
 876871                 return 0;
 877872         }
 878873 
 879874         msuffix = NULL;
 880875         STRLIST_FOREACH(s, &inputs) {
 881876                 char *suffix;
 882877                 char *ifile, *ofile = NULL;
 883878 
 884879                 ifile = s->value;
 885880                 if (ifile[0] == ')') { /* -x source type given */
 886881                         msuffix = ifile[1] ? &ifile[1] : NULL;
 887882                         continue;
 888883                 }
 889884                 if (ifile[0] == '-' && ifile[1] == 0)
 890885                         suffix = msuffix ? msuffix : "c";
 891886                 else if (ifile[0] == '-')
 892887                         suffix = "o"; /* source files cannot begin with - */
 893888                 else if (msuffix)
 894889                         suffix = msuffix;
 895890                 else
 896891                         suffix = getsufp(ifile);
 897892                 /*
 898893                  * C preprocessor
 899894                  */
 900895                 ascpp = match(suffix, "S");
 901896                 if (ascpp || match(suffix, "c") || cxxsuf(suffix)) {
 902897                         /* find out next output file */
 903898                         if (Mflag || MDflag) {
 904899                                 char *Mofile = NULL;
 905900 
 906901                                 if (MFfile)
 907902                                         Mofile = MFfile;
 908903                                 else if (outfile)
 909904                                         Mofile = setsuf(outfile, 'd');
 910905                                 else if (MDflag)
 911906                                         Mofile = setsuf(ifile, 'd');
 912907                                 if (preprocess_input(ifile, Mofile, 1))
 913908                                         exandrm(Mofile);
 914909                         }
 915910                         if (Mflag)
 916911                                 continue;
 917912                         if (Eflag) {
 918913                                 /* last pass */
 919914                                 ofile = outfile;
 920915                         } else {
 921916                                 /* to temp file */
 922917                                 strlist_append(&temp_outputs, ofile = gettmp());
 923918                         }
 924919                         if (preprocess_input(ifile, ofile, 0))
 925920                                 exandrm(ofile);
 926921                         if (Eflag)
 927922                                 continue;
 928923                         ifile = ofile;
 929924                         suffix = match(suffix, "S") ? "s" : "i";
 930925                 }
 931926 
 932927                 /*
 933928                  * C compiler
 934929                  */
 935930                 if (match(suffix, "i")) {
 936931                         /* find out next output file */
 937932                         if (Sflag) {
 938933                                 ofile = outfile;
 939934                                 if (outfile == NULL)
 940935                                         ofile = setsuf(s->value, 's');
 941936                         } else
 942937                                 strlist_append(&temp_outputs, ofile = gettmp());
 943938                         if (compile_input(ifile, ofile))
 944939                                 exandrm(ofile);
 945940                         if (Sflag)
 946941                                 continue;
 947942                         ifile = ofile;
 948943                         suffix = "s";
 949944                 }
 950945 
 951946                 /*
 952947                  * Assembler
 953948                  */
 954949                 if (match(suffix, "s")) {
 955950                         if (cflag) {
 956951                                 ofile = outfile;
 957952                                 if (ofile == NULL)
 958953                                         ofile = setsuf(s->value, 'o');
 959954                         } else {
 960955                                 strlist_append(&temp_outputs, ofile = gettmp());
 961956                                 /* strlist_append linker */
 962957                         }
 963958                         if (assemble_input(ifile, ofile))
 964959                                 exandrm(ofile);
 965960                         ifile = ofile;
 966961                 }
 967962 
 968963                 if (ninput > 1 && !Eflag && ifile == ofile && ifile[0] != '-')
 969964                         printf("%s:\n", ifile);
 970965 
 971966                 strlist_append(&middle_linker_flags, ifile);
 972967         }
 973968 
 974969         if (cflag || Eflag || Mflag)
 975970                 dexit(0);
 976971 
 977972         /*
 978973          * Linker
 979974          */
 980975         setup_ld_flags();
 981976         if (run_linker())
 982977                 exandrm(0);
 983978 
 984979 #ifdef notdef
 985980         strlist_free(&crtdirs);
 986981         strlist_free(&libdirs);
 987982         strlist_free(&progdirs);
 988983         strlist_free(&incdirs);
 989984         strlist_free(&preprocessor_flags);
 990985         strlist_free(&user_sysincdirs);
 991986         strlist_free(&includes);
 992987         strlist_free(&sysincdirs);
 993988         strlist_free(&dirafterdirs);
 994989         strlist_free(&depflags);
 995990         strlist_free(&early_linker_flags);
 996991         strlist_free(&middle_linker_flags);
 997992         strlist_free(&late_linker_flags);
 998993         strlist_free(&inputs);
 999994         strlist_free(&assembler_flags);
 1000995         strlist_free(&temp_outputs);
 1001996         strlist_free(&compiler_flags);
 1002997 #endif
 1003998         dexit(0);
 1004999         return 0;
 10051000 }
 10061001 
 10071002 /*
 10081003  * exit and cleanup after interrupt.
 10091004  */
 10101005 void
 10111006 idexit(int arg)
 10121007 {
 10131008         dexit(100);
 10141009 }
 10151010 
 10161011 /*
 10171012  * exit and cleanup.
 10181013  */
 10191014 void
 10201015 dexit(int eval)
 10211016 {
 10221017         struct string *s;
 10231018 
 10241019         if (!Xflag) {
 10251020                 STRLIST_FOREACH(s, &temp_outputs)
 10261021                         cunlink(s->value);
 10271022         }
 10281023         exit(eval);
 10291024 }
 10301025 
 10311026 /*
 10321027  * Called when something failed.
 10331028  */
 10341029 void
 10351030 exandrm(char *s)
 10361031 {
 10371032         if (s && *s)
 10381033                 strlist_append(&temp_outputs, s);
 10391034         dexit(1);
 10401035 }
 10411036 
 10421037 static void
 10431038 ccerror(char *s, va_list ap)
 10441039 {
 10451040         vfprintf(Eflag ? stderr : stdout, s, ap);
 10461041         putc('\n', Eflag? stderr : stdout);
 10471042 }
 10481043 
 10491044 /*
 10501045  * complain a bit.
 10511046  */
 10521047 void
 10531048 error(char *s, ...)
 10541049 {
 10551050         va_list ap;
 10561051 
 10571052         va_start(ap, s);
 10581053         ccerror(s, ap);
 10591054         va_end(ap);
 10601055         dexit(1);
 10611056 }
 10621057 
 10631058 /*
 10641059  * complain a bit and then exit.
 10651060  */
 10661061 void
 10671062 errorx(int eval, char *s, ...)
 10681063 {
 10691064         va_list ap;
 10701065 
 10711066         va_start(ap, s);
 10721067         ccerror(s, ap);
 10731068         va_end(ap);
 10741069         dexit(eval);
 10751070 }
 10761071 
 10771072 static char *
 10781073 find_file(const char *file, struct strlist *path, int mode)
 10791074 {
 10801075         struct string *s;
 10811076         char *f;
 10821077         size_t lf, lp;
 10831078         int need_sep;
 10841079 
 10851080         lf = strlen(file);
 10861081         STRLIST_FOREACH(s, path) {
 10871082                 lp = strlen(s->value);
 10881083                 need_sep = (lp && s->value[lp - 1] != '/') ? 1 : 0;
 10891084                 f = xmalloc(lp + lf + need_sep + 1);
 10901085                 memcpy(f, s->value, lp);
 10911086                 if (need_sep)
 10921087                         f[lp] = '/';
 10931088                 memcpy(f + lp + need_sep, file, lf + 1);
 10941089                 if (access(f, mode) == 0)
 10951090                         return f;
 10961091                 free(f);
 10971092         }
 10981093         return xstrdup(file);
 10991094 }
 11001095 
 11011096 static int
 11021097 compile_input(char *input, char *output)
 11031098 {
 11041099         struct strlist args;
 11051100         int retval;
 11061101 
 11071102         strlist_init(&args);
 11081103         strlist_append_list(&args, &compiler_flags);
 11091104         strlist_append(&args, input);
 11101105         strlist_append(&args, output);
 11111106         strlist_prepend(&args,
 11121107             find_file(cxxflag ? passxx0 : pass0, &progdirs, X_OK));
 11131108         retval = strlist_exec(&args);
 11141109         strlist_free(&args);
 11151110         return retval;
 11161111 }
 11171112 
 11181113 static int
 11191114 assemble_input(char *input, char *output)
 11201115 {
 11211116         struct strlist args;
 11221117         int retval;
 11231118 
 11241119         strlist_init(&args);
 11251120 #ifdef PCC_EARLY_AS_ARGS
 11261121         PCC_EARLY_AS_ARGS
 11271122 #endif
 11281123         strlist_append_list(&args, &assembler_flags);
 11291124         strlist_append(&args, input);
 11301125         strlist_append(&args, "-o");
 11311126         strlist_append(&args, output);
 11321127         strlist_prepend(&args,
 11331128             find_file(as, &progdirs, X_OK));
 11341129 #ifdef PCC_LATE_AS_ARGS
 11351130         PCC_LATE_AS_ARGS
 11361131 #endif
 11371132         retval = strlist_exec(&args);
 11381133         strlist_free(&args);
 11391134         return retval;
 11401135 }
 11411136 
 11421137 static int
 11431138 preprocess_input(char *input, char *output, int dodep)
 11441139 {
 11451140         struct strlist args;
 11461141         struct string *s;
 11471142         int retval;
 11481143 
 11491144         strlist_init(&args);
 11501145         strlist_append_list(&args, &preprocessor_flags);
 11511146         if (ascpp) {
 11521147                 strlist_append(&args, "-A");
 11531148                 strlist_append(&args, "-D__ASSEMBLER__");
 11541149         }
 11551150         STRLIST_FOREACH(s, &includes) {
 11561151                 strlist_append(&args, "-i");
 11571152                 strlist_append(&args, s->value);
 11581153         }
 11591154         STRLIST_FOREACH(s, &incdirs) {
 11601155                 strlist_append(&args, "-I");
 11611156                 strlist_append(&args, s->value);
 11621157         }
 11631158         STRLIST_FOREACH(s, &user_sysincdirs) {
 11641159                 strlist_append(&args, "-S");
 11651160                 strlist_append(&args, s->value);
 11661161         }
 11671162         if (!nostdinc) {
 11681163                 STRLIST_FOREACH(s, &sysincdirs) {
 11691164                         strlist_append(&args, "-S");
 11701165                         strlist_append(&args, s->value);
 11711166                 }
 11721167         }
 11731168         if (dodep)
 11741169                 strlist_append_list(&args, &depflags);
 11751170         strlist_append(&args, input);
 11761171         if (output)
 11771172                 strlist_append(&args, output);
 11781173 
 11791174         strlist_prepend(&args, find_file(passp, &progdirs, X_OK));
 11801175         retval = strlist_exec(&args);
 11811176         strlist_free(&args);
 11821177         return retval;
 11831178 }
 11841179 
 11851180 static int
 11861181 run_linker(void)
 11871182 {
 11881183         struct strlist linker_flags;
 11891184         int retval;
 11901185 
 11911186         if (outfile) {
 11921187                 strlist_prepend(&early_linker_flags, outfile);
 11931188                 strlist_prepend(&early_linker_flags, "-o");
 11941189         }
 11951190         strlist_init(&linker_flags);
 11961191         strlist_append_list(&linker_flags, &early_linker_flags);
 11971192         strlist_append_list(&linker_flags, &middle_linker_flags);
 11981193         strlist_append_list(&linker_flags, &late_linker_flags);
 11991194         strlist_prepend(&linker_flags, find_file(ld, &progdirs, X_OK));
 12001195 
 12011196         retval = strlist_exec(&linker_flags);
 12021197 
 12031198         strlist_free(&linker_flags);
 12041199         return retval;
 12051200 }
 12061201 
 12071202 static char *cxxt[] = { "cc", "cp", "cxx", "cpp", "CPP", "c++", "C" };
 12081203 int
 12091204 cxxsuf(char *s)
 12101205 {
 12111206         unsigned i;
 12121207         for (i = 0; i < sizeof(cxxt)/sizeof(cxxt[0]); i++)
 12131208                 if (strcmp(s, cxxt[i]) == 0)
 12141209                         return 1;
 12151210         return 0;
 12161211 }
 12171212 
 12181213 char *
 12191214 getsufp(char *s)
 12201215 {
 12211216         register char *p;
 12221217 
 12231218         if ((p = strrchr(s, '.')) && p[1] != '\0')
 12241219                 return &p[1];
 12251220         return "";
 12261221 }
 12271222 
 12281223 int
 12291224 getsuf(char *s)
 12301225 {
 12311226         register char *p;
 12321227 
 12331228         if ((p = strrchr(s, '.')) && p[1] != '\0' && p[2] == '\0')
 12341229                 return p[1];
 12351230         return(0);
 12361231 }
 12371232 
 12381233 /*
 12391234  * Get basename of string s, copy it and change its suffix to ch.
 12401235  */
 12411236 char *
 12421237 setsuf(char *s, char ch)
 12431238 {
 12441239         char *e, *p, *rp;
 12451240 
 12461241         e = NULL;
 12471242         for (p = s; *p; p++) {
 12481243                 if (*p == '/')
 12491244                         s = p + 1;
 12501245                 if (*p == '.')
 12511246                         e = p;
 12521247         }
 12531248         if (s > e)
 12541249                 e = p;
 12551250 
 12561251         rp = p = xmalloc(e - s + 3);
 12571252         while (s < e)
 12581253                 *p++ = *s++;
 12591254 
 12601255         *p++ = '.';
 12611256         *p++ = ch;
 12621257         *p = '\0';
 12631258         return rp;
 12641259 }
 12651260 
 12661261 #ifdef os_win32
 12671262 
 12681263 static int
 12691264 strlist_exec(struct strlist *l)
 12701265 {
 12711266         char *cmd;
 12721267         STARTUPINFO si;
 12731268         PROCESS_INFORMATION pi;
 12741269         DWORD exitCode;
 12751270         BOOL ok;
 12761271 
 12771272         cmd = win32commandline(l);
 12781273         if (vflag)
 12791274                 printf("%s\n", cmd);
 12801275 
 12811276         ZeroMemory(&si, sizeof(STARTUPINFO));
 12821277         si.cb = sizeof(STARTUPINFO);
 12831278         ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
 12841279 
 12851280         ok = CreateProcess(NULL// the executable program
 12861281                 cmd,   // the command line arguments
 12871282                 NULL,       // ignored
 12881283                 NULL,       // ignored
 12891284                 TRUE,       // inherit handles
 12901285                 HIGH_PRIORITY_CLASS,
 12911286                 NULL,       // ignored
 12921287                 NULL,       // ignored
 12931288                 &si,
 12941289                 &pi);
 12951290 
 12961291         if (!ok) {
 12971292                 fprintf(stderr, "Can't find %s\n", STRLIST_FIRST(l)->value);
 12981293                 return 100;
 12991294         }
 13001295 
 13011296         WaitForSingleObject(pi.hProcess, INFINITE);
 13021297         GetExitCodeProcess(pi.hProcess, &exitCode);
 13031298         CloseHandle(pi.hProcess);
 13041299         CloseHandle(pi.hThread);
 13051300 
 13061301         return (exitCode != 0);
 13071302 }
 13081303 
 13091304 #else
 13101305 
 13111306 static int
 13121307 strlist_exec(struct strlist *l)
 13131308 {
 13141309         sig_atomic_t exit_now = 0;
 13151310         sig_atomic_t child;
 13161311         char **argv;
 13171312         size_t argc;
 13181313         int result;
 13191314 
 13201315         strlist_make_array(l, &argv, &argc);
 13211316         if (vflag) {
 13221317                 printf("Calling ");
 13231318                 strlist_print(l, stdout);
 13241319                 printf("\n");
 13251320         }
 13261321 
 13271322         switch ((child = fork())) {
 13281323         case 0:
 13291324                 execvp(argv[0], argv);
 13301325                 result = write(STDERR_FILENO, "Exec of ", 8);
 13311326                 result = write(STDERR_FILENO, argv[0], strlen(argv[0]));
 13321327                 result = write(STDERR_FILENO, "failed\n", 7);
 13331328                 (void)result;
 13341329                 _exit(127);
 13351330         case -1:
 13361331                 error("fork failed");
 13371332         default:
 13381333                 while (waitpid(child, &result, 0) == -1 && errno == EINTR)
 13391334                         /* nothing */(void)0;
 13401335                 result = WEXITSTATUS(result);
 13411336                 if (result)
 13421337                         error("%s terminated with status %d", argv[0], result);
 13431338                 while (argc-- > 0)
 13441339                         free(argv[argc]);
 13451340                 free(argv);
 13461341                 break;
 13471342         }
 13481343         return exit_now;
 13491344 }
 13501345 
 13511346 #endif
 13521347 
 13531348 /*
 13541349  * Catenate two (optional) strings together
 13551350  */
 13561351 char *
 13571352 cat(const char *a, const char *b)
 13581353 {
 13591354         size_t len;
 13601355         char *rv;
 13611356 
 13621357         len = (a ? strlen(a) : 0) + (b ? strlen(b) : 0) + 1;
 13631358         rv = xmalloc(len);
 13641359         snprintf(rv, len, "%s%s", (a ? a : ""), (b ? b : ""));
 13651360         return rv;
 13661361 }
 13671362 
 13681363 int
 13691364 cunlink(char *f)
 13701365 {
 13711366         if (f==0 || Xflag)
 13721367                 return(0);
 13731368         return (unlink(f));
 13741369 }
 13751370 
 13761371 #ifdef os_win32
 13771372 char *
 13781373 gettmp(void)
 13791374 {
 13801375         DWORD pathSize;
 13811376         char pathBuffer[MAX_PATH + 1];
 13821377         char tempFilename[MAX_PATH];
 13831378         UINT uniqueNum;
 13841379 
 13851380         pathSize = GetTempPath(sizeof(pathBuffer), pathBuffer);
 13861381         if (pathSize == 0 || pathSize > sizeof(pathBuffer))
 13871382                 pathBuffer[0] = '\0';
 13881383         uniqueNum = GetTempFileName(pathBuffer, "ctm", 0, tempFilename);
 13891384         if (uniqueNum == 0)
 13901385                 errorx(8, "GetTempFileName failed: path \"%s\"", pathBuffer);
 13911386 
 13921387         return xstrdup(tempFilename);
 13931388 }
 13941389 
 13951390 #else
 13961391 
 13971392 char *
 13981393 gettmp(void)
 13991394 {
 14001395         char *sfn = xstrdup("/tmp/ctm.XXXXXX");
 14011396         int fd = -1;
 14021397 
 14031398         if ((fd = mkstemp(sfn)) == -1) {
 14041399                 fprintf(stderr, "%s: %s\n", sfn, strerror(errno));
 14051400                 dexit(8);
 14061401         }
 14071402         close(fd);
 14081403         return sfn;
 14091404 }
 14101405 #endif
 14111406 
 14121407 static void
 14131408 expand_sysroot(void)
 14141409 {
 14151410         struct string *s;
 14161411         struct strlist *lists[] = { &crtdirs, &sysincdirs, &incdirs,
 14171412             &user_sysincdirs, &libdirs, &progdirs, &dirafterdirs, NULL };
 14181413         const char *sysroots[] = { sysroot, isysroot, isysroot, isysroot,
 14191414             sysroot, sysroot, isysroot, NULL };
 14201415         size_t i, sysroot_len, value_len;
 14211416         char *path;
 14221417 
 14231418         assert(sizeof(lists) / sizeof(lists[0]) ==
 14241419                sizeof(sysroots) / sizeof(sysroots[0]));
 14251420 
 14261421         for (i = 0; lists[i] != NULL; ++i) {
 14271422                 STRLIST_FOREACH(s, lists[i]) {
 14281423                         if (s->value[0] != '=')
 14291424                                 continue;
 14301425                         sysroot_len = strlen(sysroots[i]);
 14311426                         /* Skipped '=' compensates additional space for '\0' */
 14321427                         value_len = strlen(s->value);
 14331428                         path = xmalloc(sysroot_len + value_len);
 14341429                         memcpy(path, sysroots[i], sysroot_len);
 14351430                         memcpy(path + sysroot_len, s->value + 1, value_len);
 14361431                         free(s->value);
 14371432                         s->value = path;
 14381433                 }
 14391434         }
 14401435 }
 14411436 
 14421437 
 14431438 void
 14441439 oerror(char *s)
 14451440 {
 14461441         fprintf(stderr, "error: unknown option '%s'\n", s);
 14471442         dexit(8);
 14481443 }
 14491444 
 14501445 void
 14511446 aerror(char *s)
 14521447 {
 14531448         fprintf(stderr, "error: missing argument to '%s'\n", s);
 14541449         dexit(8);
 14551450 }
 14561451 
 14571452 /*
 14581453  * See if m matches the beginning of string str, if it does return the
 14591454  * remaining of str, otherwise NULL.
 14601455  */
 14611456 char *
 14621457 argnxt(char *str, char *m)
 14631458 {
 14641459         if (strncmp(str, m, strlen(m)))
 14651460                 return NULL; /* No match */
 14661461         return str + strlen(m);
 14671462 }
 14681463 
 14691464 /*
 14701465  * Return next argument to option, or complain.
 14711466  */
 14721467 char *
 14731468 nxtopt(char *o)
 14741469 {
 14751470         int l;
 14761471 
 14771472         if (o != NULL) {
 14781473                 l = strlen(o);
 14791474                 if (lav[0][l] != 0)
 14801475                         return &lav[0][l];
 14811476         }
 14821477         if (lac == 0)
 14831478                 aerror(o);
 14841479         lav++;
 14851480         lac--;
 14861481         return lav[0];
 14871482 }
 14881483 
 14891484 struct flgcheck {
 14901485         int *flag;
 14911486         int set;
 14921487         char *def;
 14931488 } cppflgcheck[] = {
 14941489         { &vflag, 1, "-v" },
 14951490         { &freestanding, 1, "-D__STDC_HOSTED__=0" },
 14961491         { &freestanding, 0, "-D__STDC_HOSTED__=1" },
 14971492         { &cxxflag, 1, "-D__cplusplus" },
 14981493         { &xuchar, 1, "-D__CHAR_UNSIGNED__" },
 14991494         { &sspflag, 1, "-D__SSP__" },
 15001495         { &pthreads, 1, "-D_PTHREADS" },
 15011496         { &Oflag, 1, "-D__OPTIMIZE__" },
 15021497         { &tflag, 1, "-t" },
 15031498         { &kflag, 1, "-D__PIC__" },
 15041499         { 0 },
 15051500 };
 15061501 
 15071502 static void
 15081503 cksetflags(struct flgcheck *fs, struct strlist *sl, int which)
 15091504 {
 15101505         void (*fn)(struct strlist *, const char *);
 15111506 
 15121507         fn = which == 'p' ? strlist_prepend : strlist_append;
 15131508         for (; fs->flag; fs++) {
 15141509                 if (fs->set && *fs->flag)
 15151510                         fn(sl, fs->def);
 15161511                 if (!fs->set && !*fs->flag)
 15171512                         fn(sl, fs->def);
 15181513         }
 15191514 }
 15201515 
 15211516 static char *defflags[] = {
 15221517         "-D__PCC__=" MKS(PCC_MAJOR),
 15231518         "-D__PCC_MINOR__=" MKS(PCC_MINOR),
 15241519         "-D__PCC_MINORMINOR__=" MKS(PCC_MINORMINOR),
 15251520         "-D__VERSION__=" MKS(VERSSTR),
 15261521         "-D__SCHAR_MAX__=" MKS(MAX_CHAR),
 15271522         "-D__SHRT_MAX__=" MKS(MAX_SHORT),
 15281523         "-D__INT_MAX__=" MKS(MAX_INT),
 15291524         "-D__LONG_MAX__=" MKS(MAX_LONG),
 15301525         "-D__LONG_LONG_MAX__=" MKS(MAX_LONGLONG),
 15311526 
 15321527         "-D__STDC_ISO_10646__=200009L",
 15331528         "-D__WCHAR_TYPE__=" WCT,
 15341529         "-D__SIZEOF_WCHAR_T__=" MKS(WCHAR_SIZE),
 15351530         "-D__WCHAR_MAX__=" WCM,
 15361531         "-D__WINT_TYPE__=" PCC_WINT_TYPE,
 15371532         "-D__SIZE_TYPE__=" PCC_SIZE_TYPE,
 15381533         "-D__PTRDIFF_TYPE__=" PCC_PTRDIFF_TYPE,
 15391534         "-D__SIZEOF_WINT_T__=4",
 15401535 };
 15411536 
 15421537 static char *gcppflags[] = {
 15431538 #ifndef os_win32
 15441539 #ifdef GCC_COMPAT
 15451540         "-D__GNUC__=4",
 15461541         "-D__GNUC_MINOR__=3",
 15471542         "-D__GNUC_PATCHLEVEL__=1",
 15481543         "-D__REGISTER_PREFIX__=" REGISTER_PREFIX,
 15491544         "-D__USER_LABEL_PREFIX__=" USER_LABEL_PREFIX,
 15501545 #if SZLONG == 64
 15511546         "-D__SIZEOF_LONG__=8",
 15521547 #elif SZLONG == 32
 15531548         "-D__SIZEOF_LONG__=4",
 15541549 #endif
 15551550 #if SZPOINT(CHAR) == 64
 15561551         "-D__SIZEOF_POINTER__=8",
 15571552 #elif SZPOINT(CHAR) == 32
 15581553         "-D__SIZEOF_POINTER__=4",
 15591554 #endif
 15601555 #endif
 15611556 #endif
 15621557 };
 15631558 
 15641559 /* These should _not_ be defined here */
 15651560 static char *fpflags[] = {
 15661561 #ifdef TARGET_FLT_EVAL_METHOD
 15671562         "-D__FLT_EVAL_METHOD__=" MKS(TARGET_FLT_EVAL_METHOD),
 15681563 #endif
 15691564 #if defined(os_darwin) || defined(os_netbsd)
 15701565         "-D__FLT_RADIX__=2",
 15711566 #if defined(mach_vax)
 15721567         "-D__FLT_DIG__=6",
 15731568         "-D__FLT_EPSILON__=1.19209290e-07F",
 15741569         "-D__FLT_MANT_DIG__=24",
 15751570         "-D__FLT_MAX_10_EXP__=38",
 15761571         "-D__FLT_MAX_EXP__=127",
 15771572         "-D__FLT_MAX__=1.70141173e+38F",
 15781573         "-D__FLT_MIN_10_EXP__=(-38)",
 15791574         "-D__FLT_MIN_EXP__=(-127)",
 15801575         "-D__FLT_MIN__=2.93873588e-39F",
 15811576         "-D__DBL_DIG__=16",
 15821577         "-D__DBL_EPSILON__=2.77555756156289135e-17",
 15831578         "-D__DBL_MANT_DIG__=56",
 15841579         "-D__DBL_MAX_10_EXP__=38",
 15851580         "-D__DBL_MAX_EXP__=127",
 15861581         "-D__DBL_MAX__=1.701411834604692294e+38",
 15871582         "-D__DBL_MIN_10_EXP__=(-38)",
 15881583         "-D__DBL_MIN_EXP__=(-127)",
 15891584         "-D__DBL_MIN__=2.938735877055718770e-39",
 15901585 #else
 15911586         "-D__FLT_DIG__=6",
 15921587         "-D__FLT_EPSILON__=1.19209290e-07F",
 15931588         "-D__FLT_MANT_DIG__=24",
 15941589         "-D__FLT_MAX_10_EXP__=38",
 15951590         "-D__FLT_MAX_EXP__=128",
 15961591         "-D__FLT_MAX__=3.40282347e+38F",
 15971592         "-D__FLT_MIN_10_EXP__=(-37)",
 15981593         "-D__FLT_MIN_EXP__=(-125)",
 15991594         "-D__FLT_MIN__=1.17549435e-38F",
 16001595         "-D__DBL_DIG__=15",
 16011596         "-D__DBL_EPSILON__=2.2204460492503131e-16",
 16021597         "-D__DBL_MANT_DIG__=53",
 16031598         "-D__DBL_MAX_10_EXP__=308",
 16041599         "-D__DBL_MAX_EXP__=1024",
 16051600         "-D__DBL_MAX__=1.7976931348623157e+308",
 16061601         "-D__DBL_MIN_10_EXP__=(-307)",
 16071602         "-D__DBL_MIN_EXP__=(-1021)",
 16081603         "-D__DBL_MIN__=2.2250738585072014e-308",
 16091604 #endif
 16101605 #if defined(mach_i386) || defined(mach_amd64)
 16111606         "-D__LDBL_DIG__=18",
 16121607         "-D__LDBL_EPSILON__=1.08420217248550443401e-19L",
 16131608         "-D__LDBL_MANT_DIG__=64",
 16141609         "-D__LDBL_MAX_10_EXP__=4932",
 16151610         "-D__LDBL_MAX_EXP__=16384",
 16161611         "-D__LDBL_MAX__=1.18973149535723176502e+4932L",
 16171612         "-D__LDBL_MIN_10_EXP__=(-4931)",
 16181613         "-D__LDBL_MIN_EXP__=(-16381)",
 16191614         "-D__LDBL_MIN__=3.36210314311209350626e-4932L",
 16201615 #elif defined(mach_vax)
 16211616         "-D__LDBL_DIG__=16",
 16221617         "-D__LDBL_EPSILON__=2.77555756156289135e-17",
 16231618         "-D__LDBL_MANT_DIG__=56",
 16241619         "-D__LDBL_MAX_10_EXP__=38",
 16251620         "-D__LDBL_MAX_EXP__=127",
 16261621         "-D__LDBL_MAX__=1.701411834604692294e+38",
 16271622         "-D__LDBL_MIN_10_EXP__=(-38)",
 16281623         "-D__LDBL_MIN_EXP__=(-127)",
 16291624         "-D__LDBL_MIN__=2.938735877055718770e-39",
 16301625 #else
 16311626         "-D__LDBL_DIG__=15",
 16321627         "-D__LDBL_EPSILON__=2.2204460492503131e-16",
 16331628         "-D__LDBL_MANT_DIG__=53",
 16341629         "-D__LDBL_MAX_10_EXP__=308",
 16351630         "-D__LDBL_MAX_EXP__=1024",
 16361631         "-D__LDBL_MAX__=1.7976931348623157e+308",
 16371632         "-D__LDBL_MIN_10_EXP__=(-307)",
 16381633         "-D__LDBL_MIN_EXP__=(-1021)",
 16391634         "-D__LDBL_MIN__=2.2250738585072014e-308",
 16401635 #endif
 16411636 #endif
 16421637 };
 16431638 
 16441639 /*
 16451640  * Configure the standard cpp flags.
 16461641  */
 16471642 void
 16481643 setup_cpp_flags(void)
 16491644 {
 16501645         int i;
 16511646 
 16521647         /* a bunch of misc defines */
 16531648         for (i = 0; i < (int)sizeof(defflags)/(int)sizeof(char *); i++)
 16541649                 strlist_prepend(&preprocessor_flags, defflags[i]);
 16551650 
 16561651         for (i = 0; i < (int)sizeof(gcppflags)/(int)sizeof(char *); i++)
 16571652                 strlist_prepend(&preprocessor_flags, gcppflags[i]);
 16581653         strlist_prepend(&preprocessor_flags, xgnu89 ?
 16591654             "-D__GNUC_GNU_INLINE__" : "-D__GNUC_STDC_INLINE__");
 16601655 
 16611656         cksetflags(cppflgcheck, &preprocessor_flags, 'p');
 16621657 
 16631658         for (i = 0; i < (int)sizeof(fpflags)/(int)sizeof(char *); i++)
 16641659                 strlist_prepend(&preprocessor_flags, fpflags[i]);
 16651660 
 16661661         for (i = 0; cppadd[i]; i++)
 16671662                 strlist_prepend(&preprocessor_flags, cppadd[i]);
 16681663         for (i = 0; cppmdadd[i]; i++)
 16691664                 strlist_prepend(&preprocessor_flags, cppmdadd[i]);
 16701665 
 16711666         /* Include dirs */
 16721667         strlist_append(&sysincdirs, "=" INCLUDEDIR "pcc/");
 16731668         strlist_append(&sysincdirs, "=" STDINC);
 16741669 #ifdef PCCINCDIR
 16751670         if (cxxflag)
 16761671                 strlist_append(&sysincdirs, "=" PCCINCDIR "/c++");
 16771672         strlist_append(&sysincdirs, "=" PCCINCDIR);
 16781673 #endif
 16791674 }
 16801675 
 16811676 struct flgcheck ccomflgcheck[] = {
 16821677         { &Oflag, 1, "-xtemps" },
 16831678         { &Oflag, 1, "-xdeljumps" },
 16841679         { &Oflag, 1, "-xinline" },
 16851680         { &Oflag, 1, "-xdce" },
 16861681 #ifdef notyet
 16871682         { &Oflag, 1, "-xssa" },
 16881683 #endif
 16891684         { &freestanding, 1, "-ffreestanding" },
 16901685         { &pgflag, 1, "-p" },
 16911686         { &gflag, 1, "-g" },
 16921687         { &xgnu89, 1, "-xgnu89" },
 16931688         { &xgnu99, 1, "-xgnu99" },
 16941689         { &xuchar, 1, "-xuchar" },
 16951690 #if !defined(os_sunos) && !defined(mach_i386)
 16961691         { &vflag, 1, "-v" },
 16971692 #endif
 16981693 #ifdef os_darwin
 16991694         { &Bstatic, 0, "-k" },
 17001695 #elif defined(os_sunos) && defined(mach_i386)
 17011696         { &kflag, 1, "-K" },
 17021697         { &kflag, 1, "pic" },
 17031698 #else
 17041699         { &kflag, 1, "-k" },
 17051700 #endif
 17061701         { &sspflag, 1, "-fstack-protector" },
 17071702         { 0 }
 17081703 };
 17091704 
 17101705 void
 17111706 setup_ccom_flags(void)
 17121707 {
 17131708 
 17141709         cksetflags(ccomflgcheck, &compiler_flags, 'a');
 17151710 }
 17161711 
 17171712 static int one = 1;
 17181713 
 17191714 struct flgcheck asflgcheck[] = {
 17201715 #if defined(USE_YASM)
 17211716         { &one, 1, "-p" },
 17221717         { &one, 1, "gnu" },
 17231718         { &one, 1, "-f" },
 17241719 #if defined(os_win32)
 17251720         { &one, 1, "win32" },
 17261721 #elif defined(os_darwin)
 17271722         { &one, 1, "macho" },
 17281723 #else
 17291724         { &one, 1, "elf" },
 17301725 #endif
 17311726 #endif
 17321727 #if defined(os_sunos) && defined(mach_sparc64)
 17331728         { &one, 1, "-m64" },
 17341729 #endif
 17351730 #if defined(os_darwin)
 17361731         { &Bstatic, 1, "-static" },
 17371732 #endif
 17381733 #if !defined(USE_YASM)
 17391734         { &vflag, 1, "-v" },
 17401735 #endif
 17411736         { &kflag, 1, "-k" },
 17421737 #ifdef os_darwin
 17431738         { &one, 1, "-arch" },
 17441739 #if mach_amd64
 17451740         { &amd64_i386, 1, "i386" },
 17461741         { &amd64_i386, 0, "x86_64" },
 17471742 #else
 17481743         { &one, 1, "i386" },
 17491744 #endif
 17501745 #else
 17511746 #ifdef mach_amd64
 17521747         { &amd64_i386, 1, "--32" },
 17531748 #endif
 17541749 #endif
 17551750         { 0 }
 17561751 };
 17571752 void
 17581753 setup_as_flags(void)
 17591754 {
 17601755         one = one;
 17611756 #ifdef PCC_SETUP_AS_ARGS
 17621757         PCC_SETUP_AS_ARGS
 17631758 #endif
 17641759         cksetflags(asflgcheck, &assembler_flags, 'a');
 17651760 }
 17661761 
 17671762 struct flgcheck ldflgcheck[] = {
 17681763 #ifndef MSLINKER
 17691764         { &vflag, 1, "-v" },
 17701765 #endif
 17711766 #ifdef os_darwin
 17721767         { &shared, 1, "-dylib" },
 17731768 #elif defined(os_win32)
 17741769         { &shared, 1, "-Bdynamic" },
 17751770 #else
 17761771         { &shared, 1, "-shared" },
 17771772 #endif
 17781773 #if !defined(os_sunos) && !defined(os_win32)
 17791774 #ifndef os_darwin
 17801775         { &shared, 0, "-d" },
 17811776 #endif
 17821777 #endif
 17831778 #ifdef os_darwin
 17841779         { &Bstatic, 1, "-static" },
 17851780 #else
 17861781         { &Bstatic, 1, "-Bstatic" },
 17871782 #endif
 17881783 #if !defined(os_darwin) && !defined(os_sunos)
 17891784         { &gflag, 1, "-g" },
 17901785 #endif
 17911786         { &pthreads, 1, "-lpthread" },
 17921787         { 0 },
 17931788 };
 17941789 
 17951790 static void
 17961791 strap(struct strlist *sh, struct strlist *cd, char *n, int where)
 17971792 {
 17981793         void (*fn)(struct strlist *, const char *);
 17991794         char *fil;
 18001795 
 18011796         if (n == 0)
 18021797                 return; /* no crtfile */
 18031798 
 18041799         fn = where == 'p' ? strlist_prepend : strlist_append;
 18051800         fil = find_file(n, cd, R_OK);
 18061801         (*fn)(sh, fil);
 18071802 }
 18081803 
 18091804 void
 18101805 setup_ld_flags(void)
 18111806 {
 18121807         char *b, *e;
 18131808         int i;
 18141809 
 18151810         cksetflags(ldflgcheck, &early_linker_flags, 'a');
 18161811         if (Bstatic == 0 && shared == 0 && rflag == 0) {
 18171812                 for (i = 0; dynlinker[i]; i++)
 18181813                         strlist_append(&early_linker_flags, dynlinker[i]);
 18191814                 strlist_append(&early_linker_flags, "-e");
 18201815                 strlist_append(&early_linker_flags, STARTLABEL);
 18211816         }
 18221817         if (shared == 0 && rflag)
 18231818                 strlist_append(&early_linker_flags, "-r");
 18241819         if (sysroot && *sysroot)
 18251820                 strlist_append(&early_linker_flags, cat("--sysroot=", sysroot));
 18261821         if (!nostdlib) {
 18271822                 /* library search paths */
 18281823                 if (pcclibdir)
 18291824                         strlist_append(&late_linker_flags,
 18301825                             cat("-L", pcclibdir));
 18311826                 for (i = 0; deflibdirs[i]; i++)
 18321827                         strlist_append(&late_linker_flags,
 18331828                             cat("-L", deflibdirs[i]));
 18341829                 /* standard libraries */
 18351830                 if (pgflag) {
 18361831                         for (i = 0; defproflibs[i]; i++)
 18371832                                 strlist_append(&late_linker_flags,
 18381833                                      defproflibs[i]);
 18391834                 } else if (cxxflag) {
 18401835                         for (i = 0; defcxxlibs[i]; i++)
 18411836                                 strlist_append(&late_linker_flags,
 18421837                                     defcxxlibs[i]);
 18431838                 } else {
 18441839                         for (i = 0; deflibs[i]; i++)
 18451840                                 strlist_append(&late_linker_flags, deflibs[i]);
 18461841                 }
 18471842         }
 18481843         if (!nostartfiles) {
 18491844                 if (Bstatic) {
 18501845                         b = CRTBEGIN_T;
 18511846                         e = CRTEND_T;
 18521847                 } else if (shared /* || pieflag */) {
 18531848                         b = CRTBEGIN_S;
 18541849                         e = CRTEND_S;
 18551850                 }  else {
 18561851                         b = CRTBEGIN;
 18571852                         e = CRTEND;
 18581853                 }
 18591854                 strap(&middle_linker_flags, &crtdirs, b, 'p');
 18601855                 strap(&late_linker_flags, &crtdirs, e, 'a');
 18611856                 strap(&middle_linker_flags, &crtdirs, CRTI, 'p');
 18621857                 strap(&late_linker_flags, &crtdirs, CRTN, 'a');
 18631858                 if (shared == 0) {
 18641859                         if (pgflag)
 18651860                                 b = GCRT0;
 18661861 #ifdef notyet
 18671862                         else if (pieflag)
 18681863                                 b = SCRT0;
 18691864 #endif
 18701865                         else
 18711866                                 b = CRT0;
 18721867                         strap(&middle_linker_flags, &crtdirs, b, 'p');
 18731868                 }
 18741869         }
 18751870 }
 18761871 
 18771872 #ifdef os_win32
 18781873 char *
 18791874 win32pathsubst(char *s)
 18801875 {
 18811876         char env[1024];
 18821877         DWORD len;
 18831878 
 18841879         len = ExpandEnvironmentStrings(s, env, sizeof(env));
 18851880         if (len == 0 || len > sizeof(env))
 18861881                 errorx(8, "ExpandEnvironmentStrings failed, len %lu", len);
 18871882 
 18881883         len--;  /* skip nil */
 18891884         while (len-- > 0 && (env[len] == '/' || env[len] == '\\'))
 18901885                 env[len] = '\0';
 18911886 
 18921887         return xstrdup(env);
 18931888 }
 18941889 
 18951890 char *
 18961891 win32commandline(struct strlist *l)
 18971892 {
 18981893         const struct string *s;
 18991894         char *cmd;
 19001895         char *p;
 19011896         int len;
 19021897         int j, k;
 19031898 
 19041899         len = 0;
 19051900         STRLIST_FOREACH(s, l) {
 19061901                 len++;
 19071902                 for (j = 0; s->value[j] != '\0'; j++) {
 19081903                         if (s->value[j] == '\"') {
 19091904                                 for (k = j-1; k >= 0 && s->value[k] == '\\'; k--)
 19101905                                         len++;
 19111906                                 len++;
 19121907                         }
 19131908                         len++;
 19141909                 }
 19151910                 for (k = j-1; k >= 0 && s->value[k] == '\\'; k--)
 19161911                         len++;
 19171912                 len++;
 19181913                 len++;
 19191914         }
 19201915 
 19211916         p = cmd = xmalloc(len);
 19221917 
 19231918         STRLIST_FOREACH(s, l) {
 19241919                 *p++ = '\"';
 19251920                 for (j = 0; s->value[j] != '\0'; j++) {
 19261921                         if (s->value[j] == '\"') {
 19271922                                 for (k = j-1; k >= 0 && s->value[k] == '\\'; k--)
 19281923                                         *p++ = '\\';
 19291924                                 *p++ = '\\';
 19301925                         }
 19311926                         *p++ = s->value[j];
 19321927                 }
 19331928                 for (k = j-1; k >= 0 && s->value[k] == '\\'; k--)
 19341929                         *p++ = '\\';
 19351930                 *p++ = '\"';
 19361931                 *p++ = ' ';
 19371932         }
 19381933         p[-1] = '\0';
 19391934 
 19401935         return cmd;
 19411936 }
 19421937 #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-10-31 09:28 +0100