Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.259
 
1.260
 
MAIN:plunky:20121026110439
 
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 
<>432 -#ifdef EARLY_SETUP
 433 -        EARLY_SETUP;
  432+#ifdef PCC_EARLY_SETUP
  433+        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 
<>474 -#ifdef EARLY_ARG_CHECK
 475 -                EARLY_ARG_CHECK;
  474+#ifdef PCC_EARLY_ARG_CHECK
  475+                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;
 553553                         }
 554554                         /* silently ignore the rest */
 555555                         break;
 556556 
 557557                 case 'g': /* create debug output */
 558558                         if (argp[2] == '0')
 559559                                 gflag = 0;
 560560                         else
 561561                                 gflag++;
 562562                         break;
 563563 
 564564 
 565565                 case 'X':
 566566                         Xflag++;
 567567                         break;
 568568 
 569569                 case 'D':
 570570                 case 'U':
 571571                         strlist_append(&preprocessor_flags, argp);
 572572                         if (argp[2] != 0)
 573573                                 break;
 574574                         strlist_append(&preprocessor_flags, nxtopt(argp));
 575575                         break;
 576576 
 577577                 case 'I': /* Add include dirs */
 578578                         strlist_append(&incdirs, nxtopt("-I"));
 579579                         break;
 580580 
 581581                 case 'i':
 582582                         if (match(argp, "-isystem")) {
 583583                                 strlist_append(&user_sysincdirs, nxtopt(0));
 584584                         } else if (match(argp, "-include")) {
 585585                                 strlist_append(&includes, nxtopt(0));
 586586                         } else if (match(argp, "-isysroot")) {
 587587                                 isysroot = nxtopt(0);
 588588                         } else if (strcmp(argp, "-idirafter") == 0) {
 589589                                 strlist_append(&dirafterdirs, nxtopt(0));
 590590                         } else
 591591                                 oerror(argp);
 592592                         break;
 593593 
 594594                 case 'k': /* generate PIC code */
 595595                         kflag = argp[2] ? argp[2] - '0' : F_pic;
 596596                         break;
 597597 
 598598                 case 'l':
 599599                 case 'L':
 600600                         if (argp[2] == 0)
 601601                                 argp = cat(argp, nxtopt(0));
 602602                         strlist_append(&inputs, argp);
 603603                         break;
 604604 
 605605                 case 'm': /* target-dependent options */
 606606 #ifdef mach_amd64
 607607                         /* need to call i386 ccom for this */
 608608                         if (strcmp(argp, "-m32") == 0) {
 609609                                 pass0 = LIBEXECDIR "/ccom_i386";
 610610                                 amd64_i386 = 1;
 611611                                 break;
 612612                         }
 613613 #endif
 614614                         strlist_append(&middle_linker_flags, argp);
 615615                         if (argp[2] == 0) {
 616616                                 t = nxtopt(0);
 617617                                 strlist_append(&middle_linker_flags, t);
 618618                         }
 619619                         break;
 620620 
 621621                 case 'n': /* handle -n flags */
 622622                         if (strcmp(argp, "-nostdinc") == 0)
 623623                                 nostdinc++;
 624624                         else if (strcmp(argp, "-nostdlib") == 0) {
 625625                                 nostdlib++;
 626626                                 nostartfiles++;
 627627                         } else if (strcmp(argp, "-nostartfiles") == 0)
 628628                                 nostartfiles = 1;
 629629                         else if (strcmp(argp, "-nodefaultlibs") == 0)
 630630                                 nostdlib++;
 631631                         else
 632632                                 oerror(argp);
 633633                         break;
 634634 
 635635                 case 'p':
 636636                         if (strcmp(argp, "-pg") == 0 ||
 637637                             strcmp(argp, "-p") == 0)
 638638                                 pgflag++;
 639639                         else if (strcmp(argp, "-pthread") == 0)
 640640                                 pthreads++;
 641641                         else if (strcmp(argp, "-pipe") == 0)
 642642                                 /* NOTHING YET */;
 643643                         else if (strcmp(argp, "-pedantic") == 0)
 644644                                 /* NOTHING YET */;
 645645                         else if ((t = argnxt(argp, "-print-prog-name="))) {
 646646                                 fname = t;
 647647                                 printprogname = 1;
 648648                         } else if ((t = argnxt(argp, "-print-file-name="))) {
 649649                                 fname = t;
 650650                                 printfilename = 1;
 651651                         } else if (match(argp, "-print-libgcc-file-name")) {
 652652                                 fname = "libpcc.a";
 653653                                 printfilename = 1;
 654654                         } else
 655655                                 oerror(argp);
 656656                         break;
 657657 
 658658                 case 'r':
 659659                         rflag = 1;
 660660                         break;
 661661 
 662662                 case 'T':
 663663                         strlist_append(&inputs, argp);
 664664                         if (argp[2] == 0 ||
 665665                             strcmp(argp, "-Ttext") == 0 ||
 666666                             strcmp(argp, "-Tdata") == 0 ||
 667667                             strcmp(argp, "-Tbss") == 0)
 668668                                 strlist_append(&inputs, nxtopt(0));
 669669                         break;
 670670 
 671671                 case 's':
 672672                         if (match(argp, "-shared")) {
 673673                                 shared = 1;
 674674                         } else if (match(argp, "-static")) {
 675675                                 Bstatic = 1;
 676676                         } else if (match(argp, "-symbolic")) {
 677677                                 strlist_append(&middle_linker_flags,
 678678                                     "-Bsymbolic");
 679679                         } else if (strncmp(argp, "-std", 4) == 0) {
 680680                                 if (strcmp(&argp[5], "gnu99") == 0 ||
 681681                                     strcmp(&argp[5], "gnu9x") == 0)
 682682                                         xgnu99 = 1;
 683683                                 if (strcmp(&argp[5], "gnu89") == 0)
 684684                                         xgnu89 = 1;
 685685                         } else
 686686                                 oerror(argp);
 687687                         break;
 688688 
 689689                 case 'S':
 690690                         Sflag++;
 691691                         cflag++;
 692692                         break;
 693693 
 694694                 case 't':
 695695                         tflag++;
 696696                         break;
 697697 
 698698                 case 'o':
 699699                         if (outfile)
 700700                                 errorx(8, "too many -o");
 701701                         outfile = nxtopt("-o");
 702702                         break;
 703703 
 704704                 case 'O':
 705705                         if (argp[2] == '\0')
 706706                                 Oflag++;
 707707                         else if (argp[3] == '\0' &&
 708708                             isdigit((unsigned char)argp[2]))
 709709                                 Oflag = argp[2] - '0';
 710710                         else if (argp[3] == '\0' && argp[2] == 's')
 711711                                 Oflag = 1;      /* optimize for space only */
 712712                         else
 713713                                 oerror(argp);
 714714                         break;
 715715 
 716716                 case 'P':
 717717                         strlist_append(&preprocessor_flags, argp);
 718718                         break;
 719719 
 720720                 case 'M':
 721721                         needM = 1;
 722722                         if (match(argp, "-M")) {
 723723                                 Mflag++;
 724724                                 strlist_append(&depflags, argp);
 725725                         } else if (match(argp, "-MP")) {
 726726                                 strlist_append(&depflags, "-xMP");
 727727                         } else if (match(argp, "-MF")) {
 728728                                 MFfile = nxtopt("-MF");
 729729                         } else if (match(argp, "-MT") || match(argp, "-MQ")) {
 730730                                 t = cat("-xMT,", nxtopt("-MT"));
 731731                                 t[3] = argp[2];
 732732                                 strlist_append(&depflags, t);
 733733                         } else if (match(argp, "-MD")) {
 734734                                 MDflag++;
 735735                                 needM = 0;
 736736                                 strlist_append(&depflags, "-M");
 737737                         } else
 738738                                 oerror(argp);
 739739                         break;
 740740 
 741741                 case 'v':
 742742                         printf("%s\n", VERSSTR);
 743743                         vflag++;
 744744                         break;
 745745 
 746746                 case 'W': /* Ignore (most of) W-flags */
 747747                         if ((t = argnxt(argp, "-Wl,"))) {
 748748                                 u = strtok(t, ",");
 749749                                 do {
 750750                                         strlist_append(&inputs, u);
 751751                                 } while ((u = strtok(NULL, ",")) != NULL);
 752752                         } else if ((t = argnxt(argp, "-Wa,"))) {
 753753                                 u = strtok(t, ",");
 754754                                 do {
 755755                                         strlist_append(&assembler_flags, u);
 756756                                 } while ((u = strtok(NULL, ",")) != NULL);
 757757                         } else if ((t = argnxt(argp, "-Wc,"))) {
 758758                                 u = strtok(t, ",");
 759759                                 do {
 760760                                         strlist_append(&compiler_flags, u);
 761761                                 } while ((u = strtok(NULL, ",")) != NULL);
 762762                         } else if ((t = argnxt(argp, "-Wp,"))) {
 763763                                 u = strtok(t, ",");
 764764                                 do {
 765765                                         strlist_append(&preprocessor_flags, u);
 766766                                 } while ((u = strtok(NULL, ",")) != NULL);
 767767                         } else if (strcmp(argp, "-Werror") == 0) {
 768768                                 strlist_append(&compiler_flags, "-Werror");
 769769                         } else if (strcmp(argp, "-Wall") == 0) {
 770770                                 for (Wf = Wflags; Wf->name; Wf++)
 771771                                         if (Wf->flags & INWALL)
 772772                                                 strlist_append(&compiler_flags,
 773773                                                     cat("-W", Wf->name));
 774774                         } else if (strcmp(argp, "-WW") == 0) {
 775775                                 for (Wf = Wflags; Wf->name; Wf++)
 776776                                         strlist_append(&compiler_flags,
 777777                                             cat("-W", Wf->name));
 778778                         } else {
 779779                                 /* pass through, if supported */
 780780                                 t = &argp[2];
 781781                                 if (strncmp(t, "no-", 3) == 0)
 782782                                         t += 3;
 783783                                 if (strncmp(t, "error=", 6) == 0)
 784784                                         t += 6;
 785785                                 for (Wf = Wflags; Wf->name; Wf++) {
 786786                                         if (strcmp(t, Wf->name) == 0)
 787787                                                 strlist_append(&compiler_flags,
 788788                                                     argp);
 789789                                 }
 790790                         }
 791791                         break;
 792792 
 793793                 case 'x':
 794794                         t = nxtopt("-x");
 795795                         if (match(t, "c"))
 796796                                 strlist_append(&inputs, ")c");
 797797                         else if (match(t, "assembler"))
 798798                                 strlist_append(&inputs, ")s");
 799799                         else if (match(t, "assembler-with-cpp"))
 800800                                 strlist_append(&inputs, ")S");
 801801                         else if (match(t, "c++"))
 802802                                 strlist_append(&inputs, ")c++");
 803803                         else {
 804804                                 strlist_append(&compiler_flags, "-x");
 805805                                 strlist_append(&compiler_flags, t);
 806806                         }
 807807                         break;
 808808 
 809809                 }
 810810                 continue;
 811811 
 812812         }
 813813 
 814814         /* Sanity checking */
 815815         if (cppflag) {
 816816                 if (ninput == 0) {
 817817                         strlist_append(&inputs, "-");
 818818                         ninput++;
 819819                 } else if (ninput > 2 || (ninput == 2 && outfile)) {
 820820                         errorx(8, "too many files");
 821821                 } else if (ninput == 2) {
 822822                         outfile = STRLIST_NEXT(STRLIST_FIRST(&inputs))->value;
 823823                         STRLIST_FIRST(&inputs)->next = NULL;
 824824                         ninput--;
 825825                 }
 826826         }
 827827         if (ninput == 0 && !(printprogname || printfilename))
 828828                 errorx(8, "no input files");
 829829         if (outfile && (cflag || Sflag || Eflag) && ninput > 1)
 830830                 errorx(8, "-o given with -c || -E || -S and more than one file");
 831831 #if 0
 832832         if (outfile && clist[0] && strcmp(outfile, clist[0]) == 0)
 833833                 errorx(8, "output file will be clobbered");
 834834 #endif
 835835 
 836836         if (needM && !Mflag && !MDflag)
 837837                 errorx(8, "to make dependencies needs -M");
 838838 
 839839 
 840840         if (signal(SIGINT, SIG_IGN) != SIG_IGN/* interrupt */
 841841                 signal(SIGINT, idexit);
 842842         if (signal(SIGTERM, SIG_IGN) != SIG_IGN)        /* terminate */
 843843                 signal(SIGTERM, idexit);
 844844 
 845845         /* after arg parsing */
 846846         strlist_append(&progdirs, LIBEXECDIR);
 847847         if (pcclibdir)
 848848                 strlist_append(&crtdirs, pcclibdir);
 849849         for (j = 0; deflibdirs[j]; j++)
 850850                 strlist_append(&crtdirs, deflibdirs[j]);
 851851 
 852852         setup_cpp_flags();
 853853         setup_ccom_flags();
 854854         setup_as_flags();
 855855 
 856856         if (isysroot == NULL)
 857857                 isysroot = sysroot;
 858858         expand_sysroot();
 859859 
 860860         if (printprogname) {
 861861                 printf("%s\n", find_file(fname, &progdirs, X_OK));
 862862                 return 0;
 863863         } else if (printfilename) {
 864864                 printf("%s\n", find_file(fname, &crtdirs, R_OK));
 865865                 return 0;
 866866         }
 867867 
 868868         msuffix = NULL;
 869869         STRLIST_FOREACH(s, &inputs) {
 870870                 char *suffix;
 871871                 char *ifile, *ofile;
 872872 
 873873                 ifile = s->value;
 874874                 if (ninput > 1 && !Eflag)
 875875                         printf("%s:\n", ifile);
 876876 
 877877                 if (ifile[0] == ')') {
 878878                         msuffix = &ifile[1]; /* -x source type given */
 879879                         ascpp = match(msuffix, "S");
 880880                         continue;
 881881                 }
 882882                 if (ifile[0] == '-' && ifile[1] == 0)
 883883                         suffix = msuffix ? msuffix : "c";
 884884                 else if (ifile[0] == '-')
 885885                         suffix = "o"; /* source files cannot begin with - */
 886886                 else if (msuffix)
 887887                         suffix = msuffix;
 888888                 else
 889889                         suffix = getsufp(ifile);
 890890                 /*
 891891                  * C preprocessor
 892892                  */
 893893                 if (match(suffix, "c") || match(suffix, "S") ||
 894894                     cxxsuf(s->value)) {
 895895                         /* find out next output file */
 896896                         if (Mflag || MDflag) {
 897897                                 char *Mofile;
 898898 
 899899                                 if (MFfile)
 900900                                         Mofile = MFfile;
 901901                                 else if (outfile)
 902902                                         Mofile = setsuf(outfile, 'd');
 903903                                 else
 904904                                         Mofile = setsuf(ifile, 'd');
 905905                                 if (preprocess_input(ifile, Mofile, 1))
 906906                                         exandrm(Mofile);
 907907                         }
 908908                         if (Mflag)
 909909                                 continue;
 910910                         if (Eflag) {
 911911                                 /* last pass */
 912912                                 ofile = outfile;
 913913                         } else {
 914914                                 /* to temp file */
 915915                                 strlist_append(&temp_outputs, ofile = gettmp());
 916916                         }
 917917                         if (preprocess_input(ifile, ofile, 0))
 918918                                 exandrm(ofile);
 919919                         if (Eflag)
 920920                                 continue;
 921921                         ifile = ofile;
 922922                         suffix = match(suffix, "S") ? "s" : "i";
 923923                 }
 924924 
 925925                 /*
 926926                  * C compiler
 927927                  */
 928928                 if (match(suffix, "i")) {
 929929                         /* find out next output file */
 930930                         if (Sflag) {
 931931                                 ofile = outfile;
 932932                                 if (outfile == NULL)
 933933                                         ofile = setsuf(s->value, 's');
 934934                         } else
 935935                                 strlist_append(&temp_outputs, ofile = gettmp());
 936936                         if (compile_input(ifile, ofile))
 937937                                 exandrm(ofile);
 938938                         if (Sflag)
 939939                                 continue;
 940940                         ifile = ofile;
 941941                         suffix = "s";
 942942                 }
 943943 
 944944                 /*
 945945                  * Assembler
 946946                  */
 947947                 if (match(suffix, "s")) {
 948948                         if (cflag) {
 949949                                 ofile = outfile;
 950950                                 if (ofile == NULL)
 951951                                         ofile = setsuf(s->value, 'o');
 952952                         } else {
 953953                                 strlist_append(&temp_outputs, ofile = gettmp());
 954954                                 /* strlist_append linker */
 955955                         }
 956956                         if (assemble_input(ifile, ofile))
 957957                                 exandrm(ofile);
 958958                         ifile = ofile;
 959959                 }
 960960                 strlist_append(&middle_linker_flags, ifile);
 961961         }
 962962 
 963963         if (cflag || Eflag || Mflag)
 964964                 dexit(0);
 965965 
 966966         /*
 967967          * Linker
 968968          */
 969969         setup_ld_flags();
 970970         if (run_linker())
 971971                 exandrm(0);
 972972 
 973973 #ifdef notdef
 974974         strlist_free(&crtdirs);
 975975         strlist_free(&libdirs);
 976976         strlist_free(&progdirs);
 977977         strlist_free(&incdirs);
 978978         strlist_free(&preprocessor_flags);
 979979         strlist_free(&user_sysincdirs);
 980980         strlist_free(&includes);
 981981         strlist_free(&sysincdirs);
 982982         strlist_free(&dirafterdirs);
 983983         strlist_free(&depflags);
 984984         strlist_free(&early_linker_flags);
 985985         strlist_free(&middle_linker_flags);
 986986         strlist_free(&late_linker_flags);
 987987         strlist_free(&inputs);
 988988         strlist_free(&assembler_flags);
 989989         strlist_free(&temp_outputs);
 990990         strlist_free(&compiler_flags);
 991991 #endif
 992992         dexit(0);
 993993         return 0;
 994994 }
 995995 
 996996 /*
 997997  * exit and cleanup after interrupt.
 998998  */
 999999 void
 10001000 idexit(int arg)
 10011001 {
 10021002         dexit(100);
 10031003 }
 10041004 
 10051005 /*
 10061006  * exit and cleanup.
 10071007  */
 10081008 void
 10091009 dexit(int eval)
 10101010 {
 10111011         struct string *s;
 10121012 
 10131013         if (!Xflag) {
 10141014                 STRLIST_FOREACH(s, &temp_outputs)
 10151015                         cunlink(s->value);
 10161016         }
 10171017         exit(eval);
 10181018 }
 10191019 
 10201020 /*
 10211021  * Called when something failed.
 10221022  */
 10231023 void
 10241024 exandrm(char *s)
 10251025 {
 10261026         if (s && *s)
 10271027                 strlist_append(&temp_outputs, s);
 10281028         dexit(1);
 10291029 }
 10301030 
 10311031 static void
 10321032 ccerror(char *s, va_list ap)
 10331033 {
 10341034         vfprintf(Eflag ? stderr : stdout, s, ap);
 10351035         putc('\n', Eflag? stderr : stdout);
 10361036 }
 10371037 
 10381038 /*
 10391039  * complain a bit.
 10401040  */
 10411041 void
 10421042 error(char *s, ...)
 10431043 {
 10441044         va_list ap;
 10451045 
 10461046         va_start(ap, s);
 10471047         ccerror(s, ap);
 10481048         va_end(ap);
 10491049         dexit(1);
 10501050 }
 10511051 
 10521052 /*
 10531053  * complain a bit and then exit.
 10541054  */
 10551055 void
 10561056 errorx(int eval, char *s, ...)
 10571057 {
 10581058         va_list ap;
 10591059 
 10601060         va_start(ap, s);
 10611061         ccerror(s, ap);
 10621062         va_end(ap);
 10631063         dexit(eval);
 10641064 }
 10651065 
 10661066 static char *
 10671067 find_file(const char *file, struct strlist *path, int mode)
 10681068 {
 10691069         struct string *s;
 10701070         char *f;
 10711071         size_t lf, lp;
 10721072         int need_sep;
 10731073 
 10741074         lf = strlen(file);
 10751075         STRLIST_FOREACH(s, path) {
 10761076                 lp = strlen(s->value);
 10771077                 need_sep = (lp && s->value[lp - 1] != '/') ? 1 : 0;
 10781078                 f = xmalloc(lp + lf + need_sep + 1);
 10791079                 memcpy(f, s->value, lp);
 10801080                 if (need_sep)
 10811081                         f[lp] = '/';
 10821082                 memcpy(f + lp + need_sep, file, lf + 1);
 10831083                 if (access(f, mode) == 0)
 10841084                         return f;
 10851085                 free(f);
 10861086         }
 10871087         return xstrdup(file);
 10881088 }
 10891089 
 10901090 static int
 10911091 compile_input(char *input, char *output)
 10921092 {
 10931093         struct strlist args;
 10941094         int retval;
 10951095 
 10961096         strlist_init(&args);
 10971097         strlist_append_list(&args, &compiler_flags);
 10981098         strlist_append(&args, input);
 10991099         strlist_append(&args, output);
 11001100         strlist_prepend(&args,
 11011101             find_file(cxxflag ? passxx0 : pass0, &progdirs, X_OK));
 11021102         retval = strlist_exec(&args);
 11031103         strlist_free(&args);
 11041104         return retval;
 11051105 }
 11061106 
 11071107 static int
 11081108 assemble_input(char *input, char *output)
 11091109 {
 11101110         struct strlist args;
 11111111         int retval;
 11121112 
 11131113         strlist_init(&args);
 11141114 #ifdef PCC_EARLY_AS_ARGS
 11151115         PCC_EARLY_AS_ARGS
 11161116 #endif
 11171117         strlist_append_list(&args, &assembler_flags);
 11181118         strlist_append(&args, input);
 11191119         strlist_append(&args, "-o");
 11201120         strlist_append(&args, output);
 11211121         strlist_prepend(&args,
 11221122             find_file(as, &progdirs, X_OK));
 11231123 #ifdef PCC_LATE_AS_ARGS
 11241124         PCC_LATE_AS_ARGS
 11251125 #endif
 11261126         retval = strlist_exec(&args);
 11271127         strlist_free(&args);
 11281128         return retval;
 11291129 }
 11301130 
 11311131 static int
 11321132 preprocess_input(char *input, char *output, int dodep)
 11331133 {
 11341134         struct strlist args;
 11351135         struct string *s;
 11361136         int retval;
 11371137 
 11381138         strlist_init(&args);
 11391139         strlist_append_list(&args, &preprocessor_flags);
 11401140         if (ascpp)
 11411141                 strlist_append(&args, "-D__ASSEMBLER__");
 11421142         STRLIST_FOREACH(s, &includes) {
 11431143                 strlist_append(&args, "-i");
 11441144                 strlist_append(&args, s->value);
 11451145         }
 11461146         STRLIST_FOREACH(s, &incdirs) {
 11471147                 strlist_append(&args, "-I");
 11481148                 strlist_append(&args, s->value);
 11491149         }
 11501150         STRLIST_FOREACH(s, &user_sysincdirs) {
 11511151                 strlist_append(&args, "-S");
 11521152                 strlist_append(&args, s->value);
 11531153         }
 11541154         if (!nostdinc) {
 11551155                 STRLIST_FOREACH(s, &sysincdirs) {
 11561156                         strlist_append(&args, "-S");
 11571157                         strlist_append(&args, s->value);
 11581158                 }
 11591159         }
 11601160         if (dodep)
 11611161                 strlist_append_list(&args, &depflags);
 11621162         strlist_append(&args, input);
 11631163         if (output)
 11641164                 strlist_append(&args, output);
 11651165 
 11661166         strlist_prepend(&args, find_file(passp, &progdirs, X_OK));
 11671167         retval = strlist_exec(&args);
 11681168         strlist_free(&args);
 11691169         return retval;
 11701170 }
 11711171 
 11721172 static int
 11731173 run_linker(void)
 11741174 {
 11751175         struct strlist linker_flags;
 11761176         int retval;
 11771177 
 11781178         if (outfile) {
 11791179                 strlist_prepend(&early_linker_flags, outfile);
 11801180                 strlist_prepend(&early_linker_flags, "-o");
 11811181         }
 11821182         strlist_init(&linker_flags);
 11831183         strlist_append_list(&linker_flags, &early_linker_flags);
 11841184         strlist_append_list(&linker_flags, &middle_linker_flags);
 11851185         strlist_append_list(&linker_flags, &late_linker_flags);
 11861186         strlist_prepend(&linker_flags, find_file(ld, &progdirs, X_OK));
 11871187 
 11881188         retval = strlist_exec(&linker_flags);
 11891189 
 11901190         strlist_free(&linker_flags);
 11911191         return retval;
 11921192 }
 11931193 
 11941194 static char *cxxt[] = { "cc", "cp", "cxx", "cpp", "CPP", "c++", "C" };
 11951195 int
 11961196 cxxsuf(char *s)
 11971197 {
 11981198         unsigned i;
 11991199         for (i = 0; i < sizeof(cxxt)/sizeof(cxxt[0]); i++)
 12001200                 if (strcmp(s, cxxt[i]) == 0)
 12011201                         return 1;
 12021202         return 0;
 12031203 }
 12041204 
 12051205 char *
 12061206 getsufp(char *s)
 12071207 {
 12081208         register char *p;
 12091209 
 12101210         if ((p = strrchr(s, '.')) && p[1] != '\0')
 12111211                 return &p[1];
 12121212         return "";
 12131213 }
 12141214 
 12151215 int
 12161216 getsuf(char *s)
 12171217 {
 12181218         register char *p;
 12191219 
 12201220         if ((p = strrchr(s, '.')) && p[1] != '\0' && p[2] == '\0')
 12211221                 return p[1];
 12221222         return(0);
 12231223 }
 12241224 
 12251225 /*
 12261226  * Get basename of string s, copy it and change its suffix to ch.
 12271227  */
 12281228 char *
 12291229 setsuf(char *s, char ch)
 12301230 {
 12311231         char *e, *p, *rp;
 12321232 
 12331233         e = NULL;
 12341234         for (p = s; *p; p++) {
 12351235                 if (*p == '/')
 12361236                         s = p + 1;
 12371237                 if (*p == '.')
 12381238                         e = p;
 12391239         }
 12401240         if (s > e)
 12411241                 e = p;
 12421242 
 12431243         rp = p = xmalloc(e - s + 3);
 12441244         while (s < e)
 12451245                 *p++ = *s++;
 12461246 
 12471247         *p++ = '.';
 12481248         *p++ = ch;
 12491249         *p = '\0';
 12501250         return rp;
 12511251 }
 12521252 
 12531253 #ifdef os_win32
 12541254 
 12551255 static int
 12561256 strlist_exec(struct strlist *l)
 12571257 {
 12581258         char *cmd;
 12591259         STARTUPINFO si;
 12601260         PROCESS_INFORMATION pi;
 12611261         DWORD exitCode;
 12621262         BOOL ok;
 12631263 
 12641264         cmd = win32commandline(l);
 12651265         if (vflag)
 12661266                 printf("%s\n", cmd);
 12671267 
 12681268         ZeroMemory(&si, sizeof(STARTUPINFO));
 12691269         si.cb = sizeof(STARTUPINFO);
 12701270         ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
 12711271 
 12721272         ok = CreateProcess(NULL// the executable program
 12731273                 cmd,   // the command line arguments
 12741274                 NULL,       // ignored
 12751275                 NULL,       // ignored
 12761276                 TRUE,       // inherit handles
 12771277                 HIGH_PRIORITY_CLASS,
 12781278                 NULL,       // ignored
 12791279                 NULL,       // ignored
 12801280                 &si,
 12811281                 &pi);
 12821282 
 12831283         if (!ok) {
 12841284                 fprintf(stderr, "Can't find %s\n", STRLIST_FIRST(l)->value);
 12851285                 return 100;
 12861286         }
 12871287 
 12881288         WaitForSingleObject(pi.hProcess, INFINITE);
 12891289         GetExitCodeProcess(pi.hProcess, &exitCode);
 12901290         CloseHandle(pi.hProcess);
 12911291         CloseHandle(pi.hThread);
 12921292 
 12931293         return (exitCode != 0);
 12941294 }
 12951295 
 12961296 #else
 12971297 
 12981298 static int
 12991299 strlist_exec(struct strlist *l)
 13001300 {
 13011301         sig_atomic_t exit_now = 0;
 13021302         sig_atomic_t child;
 13031303         char **argv;
 13041304         size_t argc;
 13051305         int result;
 13061306 
 13071307         strlist_make_array(l, &argv, &argc);
 13081308         if (vflag) {
 13091309                 printf("Calling ");
 13101310                 strlist_print(l, stdout);
 13111311                 printf("\n");
 13121312         }
 13131313 
 13141314         switch ((child = fork())) {
 13151315         case 0:
 13161316                 execvp(argv[0], argv);
 13171317                 result = write(STDERR_FILENO, "Exec of ", 8);
 13181318                 result = write(STDERR_FILENO, argv[0], strlen(argv[0]));
 13191319                 result = write(STDERR_FILENO, "failed\n", 7);
 13201320                 (void)result;
 13211321                 _exit(127);
 13221322         case -1:
 13231323                 error("fork failed");
 13241324         default:
 13251325                 while (waitpid(child, &result, 0) == -1 && errno == EINTR)
 13261326                         /* nothing */(void)0;
 13271327                 result = WEXITSTATUS(result);
 13281328                 if (result)
 13291329                         error("%s terminated with status %d", argv[0], result);
 13301330                 while (argc-- > 0)
 13311331                         free(argv[argc]);
 13321332                 free(argv);
 13331333                 break;
 13341334         }
 13351335         return exit_now;
 13361336 }
 13371337 
 13381338 #endif
 13391339 
 13401340 /*
 13411341  * Catenate two (optional) strings together
 13421342  */
 13431343 char *
 13441344 cat(const char *a, const char *b)
 13451345 {
 13461346         size_t len;
 13471347         char *rv;
 13481348 
 13491349         len = (a ? strlen(a) : 0) + (b ? strlen(b) : 0) + 1;
 13501350         rv = xmalloc(len);
 13511351         snprintf(rv, len, "%s%s", (a ? a : ""), (b ? b : ""));
 13521352         return rv;
 13531353 }
 13541354 
 13551355 int
 13561356 cunlink(char *f)
 13571357 {
 13581358         if (f==0 || Xflag)
 13591359                 return(0);
 13601360         return (unlink(f));
 13611361 }
 13621362 
 13631363 #ifdef os_win32
 13641364 char *
 13651365 gettmp(void)
 13661366 {
 13671367         DWORD pathSize;
 13681368         char pathBuffer[MAX_PATH + 1];
 13691369         char tempFilename[MAX_PATH];
 13701370         UINT uniqueNum;
 13711371 
 13721372         pathSize = GetTempPath(sizeof(pathBuffer), pathBuffer);
 13731373         if (pathSize == 0 || pathSize > sizeof(pathBuffer))
 13741374                 pathBuffer[0] = '\0';
 13751375         uniqueNum = GetTempFileName(pathBuffer, "ctm", 0, tempFilename);
 13761376         if (uniqueNum == 0)
 13771377                 errorx(8, "GetTempFileName failed: path \"%s\"", pathBuffer);
 13781378 
 13791379         return xstrdup(tempFilename);
 13801380 }
 13811381 
 13821382 #else
 13831383 
 13841384 char *
 13851385 gettmp(void)
 13861386 {
 13871387         char *sfn = xstrdup("/tmp/ctm.XXXXXX");
 13881388         int fd = -1;
 13891389 
 13901390         if ((fd = mkstemp(sfn)) == -1) {
 13911391                 fprintf(stderr, "%s: %s\n", sfn, strerror(errno));
 13921392                 dexit(8);
 13931393         }
 13941394         close(fd);
 13951395         return sfn;
 13961396 }
 13971397 #endif
 13981398 
 13991399 static void
 14001400 expand_sysroot(void)
 14011401 {
 14021402         struct string *s;
 14031403         struct strlist *lists[] = { &crtdirs, &sysincdirs, &incdirs,
 14041404             &user_sysincdirs, &libdirs, &progdirs, &dirafterdirs, NULL };
 14051405         const char *sysroots[] = { sysroot, isysroot, isysroot, isysroot,
 14061406             sysroot, sysroot, isysroot, NULL };
 14071407         size_t i, sysroot_len, value_len;
 14081408         char *path;
 14091409 
 14101410         assert(sizeof(lists) / sizeof(lists[0]) ==
 14111411                sizeof(sysroots) / sizeof(sysroots[0]));
 14121412 
 14131413         for (i = 0; lists[i] != NULL; ++i) {
 14141414                 STRLIST_FOREACH(s, lists[i]) {
 14151415                         if (s->value[0] != '=')
 14161416                                 continue;
 14171417                         sysroot_len = strlen(sysroots[i]);
 14181418                         /* Skipped '=' compensates additional space for '\0' */
 14191419                         value_len = strlen(s->value);
 14201420                         path = xmalloc(sysroot_len + value_len);
 14211421                         memcpy(path, sysroots[i], sysroot_len);
 14221422                         memcpy(path + sysroot_len, s->value + 1, value_len);
 14231423                         free(s->value);
 14241424                         s->value = path;
 14251425                 }
 14261426         }
 14271427 }
 14281428 
 14291429 
 14301430 void
 14311431 oerror(char *s)
 14321432 {
 14331433         fprintf(stderr, "error: unknown option '%s'\n", s);
 14341434         dexit(8);
 14351435 }
 14361436 
 14371437 void
 14381438 aerror(char *s)
 14391439 {
 14401440         fprintf(stderr, "error: missing argument to '%s'\n", s);
 14411441         dexit(8);
 14421442 }
 14431443 
 14441444 /*
 14451445  * See if m matches the beginning of string str, if it does return the
 14461446  * remaining of str, otherwise NULL.
 14471447  */
 14481448 char *
 14491449 argnxt(char *str, char *m)
 14501450 {
 14511451         if (strncmp(str, m, strlen(m)))
 14521452                 return NULL; /* No match */
 14531453         return str + strlen(m);
 14541454 }
 14551455 
 14561456 /*
 14571457  * Return next argument to option, or complain.
 14581458  */
 14591459 char *
 14601460 nxtopt(char *o)
 14611461 {
 14621462         int l;
 14631463 
 14641464         if (o != NULL) {
 14651465                 l = strlen(o);
 14661466                 if (lav[0][l] != 0)
 14671467                         return &lav[0][l];
 14681468         }
 14691469         if (lac == 0)
 14701470                 aerror(o);
 14711471         lav++;
 14721472         lac--;
 14731473         return lav[0];
 14741474 }
 14751475 
 14761476 struct flgcheck {
 14771477         int *flag;
 14781478         int set;
 14791479         char *def;
 14801480 } cppflgcheck[] = {
 14811481         { &vflag, 1, "-v" },
 14821482         { &freestanding, 1, "-D__STDC_HOSTED__=0" },
 14831483         { &freestanding, 0, "-D__STDC_HOSTED__=1" },
 14841484         { &cxxflag, 1, "-D__cplusplus" },
 14851485         { &xuchar, 1, "-D__CHAR_UNSIGNED__" },
 14861486         { &sspflag, 1, "-D__SSP__" },
 14871487         { &pthreads, 1, "-D_PTHREADS" },
 14881488         { &Oflag, 1, "-D__OPTIMIZE__" },
 14891489         { &tflag, 1, "-t" },
 14901490         { &kflag, 1, "-D__PIC__" },
 14911491         { 0 },
 14921492 };
 14931493 
 14941494 static void
 14951495 cksetflags(struct flgcheck *fs, struct strlist *sl, int which)
 14961496 {
 14971497         void (*fn)(struct strlist *, const char *);
 14981498 
 14991499         fn = which == 'p' ? strlist_prepend : strlist_append;
 15001500         for (; fs->flag; fs++) {
 15011501                 if (fs->set && *fs->flag)
 15021502                         fn(sl, fs->def);
 15031503                 if (!fs->set && !*fs->flag)
 15041504                         fn(sl, fs->def);
 15051505         }
 15061506 }
 15071507 
 15081508 static char *defflags[] = {
 15091509         "-D__PCC__=" MKS(PCC_MAJOR),
 15101510         "-D__PCC_MINOR__=" MKS(PCC_MINOR),
 15111511         "-D__PCC_MINORMINOR__=" MKS(PCC_MINORMINOR),
 15121512         "-D__VERSION__=" MKS(VERSSTR),
 15131513         "-D__SCHAR_MAX__=" MKS(MAX_CHAR),
 15141514         "-D__SHRT_MAX__=" MKS(MAX_SHORT),
 15151515         "-D__INT_MAX__=" MKS(MAX_INT),
 15161516         "-D__LONG_MAX__=" MKS(MAX_LONG),
 15171517         "-D__LONG_LONG_MAX__=" MKS(MAX_LONGLONG),
 15181518 
 15191519         "-D__STDC_ISO_10646__=200009L",
 15201520         "-D__WCHAR_TYPE__=" WCT,
 15211521         "-D__SIZEOF_WCHAR_T__=" MKS(WCHAR_SIZE),
 15221522         "-D__WCHAR_MAX__=" WCM,
 15231523         "-D__WINT_TYPE__=" PCC_WINT_TYPE,
 15241524         "-D__SIZE_TYPE__=" PCC_SIZE_TYPE,
 15251525         "-D__PTRDIFF_TYPE__=" PCC_PTRDIFF_TYPE,
 15261526         "-D__SIZEOF_WINT_T__=4",
 15271527 };
 15281528 
 15291529 static char *gcppflags[] = {
 15301530 #ifndef os_win32
 15311531 #ifdef GCC_COMPAT
 15321532         "-D__GNUC__=4",
 15331533         "-D__GNUC_MINOR__=3",
 15341534         "-D__GNUC_PATCHLEVEL__=1",
 15351535         "-D__REGISTER_PREFIX__=" REGISTER_PREFIX,
 15361536         "-D__USER_LABEL_PREFIX__=" USER_LABEL_PREFIX,
 15371537 #endif
 15381538 #endif
 15391539 };
 15401540 
 15411541 /* These should _not_ be defined here */
 15421542 static char *fpflags[] = {
 15431543 #if defined(os_darwin) || defined(os_netbsd)
 15441544         "-D__FLT_RADIX__=2",
 15451545         "-D__FLT_DIG__=6",
 15461546         "-D__FLT_EPSILON__=1.19209290e-07F",
 15471547         "-D__FLT_MANT_DIG__=24",
 15481548         "-D__FLT_MAX_10_EXP__=38",
 15491549         "-D__FLT_MAX_EXP__=128",
 15501550         "-D__FLT_MAX__=3.40282347e+38F",
 15511551         "-D__FLT_MIN_10_EXP__=(-37)",
 15521552         "-D__FLT_MIN_EXP__=(-125)",
 15531553         "-D__FLT_MIN__=1.17549435e-38F",
 15541554         "-D__DBL_DIG__=15",
 15551555         "-D__DBL_EPSILON__=2.2204460492503131e-16",
 15561556         "-D__DBL_MANT_DIG__=53",
 15571557         "-D__DBL_MAX_10_EXP__=308",
 15581558         "-D__DBL_MAX_EXP__=1024",
 15591559         "-D__DBL_MAX__=1.7976931348623157e+308",
 15601560         "-D__DBL_MIN_10_EXP__=(-307)",
 15611561         "-D__DBL_MIN_EXP__=(-1021)",
 15621562         "-D__DBL_MIN__=2.2250738585072014e-308",
 15631563 #if defined(mach_i386) || defined(mach_amd64)
 15641564         "-D__LDBL_DIG__=18",
 15651565         "-D__LDBL_EPSILON__=1.08420217248550443401e-19L",
 15661566         "-D__LDBL_MANT_DIG__=64",
 15671567         "-D__LDBL_MAX_10_EXP__=4932",
 15681568         "-D__LDBL_MAX_EXP__=16384",
 15691569         "-D__LDBL_MAX__=1.18973149535723176502e+4932L",
 15701570         "-D__LDBL_MIN_10_EXP__=(-4931)",
 15711571         "-D__LDBL_MIN_EXP__=(-16381)",
 15721572         "-D__LDBL_MIN__=3.36210314311209350626e-4932L",
 15731573 #else
 15741574         "-D__LDBL_DIG__=15",
 15751575         "-D__LDBL_EPSILON__=2.2204460492503131e-16",
 15761576         "-D__LDBL_MANT_DIG__=53",
 15771577         "-D__LDBL_MAX_10_EXP__=308",
 15781578         "-D__LDBL_MAX_EXP__=1024",
 15791579         "-D__LDBL_MAX__=1.7976931348623157e+308",
 15801580         "-D__LDBL_MIN_10_EXP__=(-307)",
 15811581         "-D__LDBL_MIN_EXP__=(-1021)",
 15821582         "-D__LDBL_MIN__=2.2250738585072014e-308",
 15831583 #endif
 15841584 #endif
 15851585 };
 15861586 
 15871587 
 15881588 /*
 15891589  * Configure the standard cpp flags.
 15901590  */
 15911591 void
 15921592 setup_cpp_flags(void)
 15931593 {
 15941594         int i;
 15951595 
 15961596         /* a bunch of misc defines */
 15971597         for (i = 0; i < (int)sizeof(defflags)/(int)sizeof(char *); i++)
 15981598                 strlist_prepend(&preprocessor_flags, defflags[i]);
 15991599 
 16001600         for (i = 0; i < (int)sizeof(gcppflags)/(int)sizeof(char *); i++)
 16011601                 strlist_prepend(&preprocessor_flags, gcppflags[i]);
 16021602         strlist_prepend(&preprocessor_flags, xgnu89 ?
 16031603             "-D__GNUC_GNU_INLINE__" : "-D__GNUC_STDC_INLINE__");
 16041604 
 16051605         cksetflags(cppflgcheck, &preprocessor_flags, 'p');
 16061606 
 16071607         for (i = 0; i < (int)sizeof(fpflags)/(int)sizeof(char *); i++)
 16081608                 strlist_prepend(&preprocessor_flags, fpflags[i]);
 16091609 
 16101610         for (i = 0; cppadd[i]; i++)
 16111611                 strlist_prepend(&preprocessor_flags, cppadd[i]);
 16121612         for (i = 0; cppmdadd[i]; i++)
 16131613                 strlist_prepend(&preprocessor_flags, cppmdadd[i]);
 16141614 
 16151615         /* Include dirs */
 16161616         strlist_append(&sysincdirs, "=" INCLUDEDIR "pcc/");
 16171617         strlist_append(&sysincdirs, "=" STDINC);
 16181618 #ifdef PCCINCDIR
 16191619         if (cxxflag)
 16201620                 strlist_append(&sysincdirs, "=" PCCINCDIR "/c++");
 16211621         strlist_append(&sysincdirs, "=" PCCINCDIR);
 16221622 #endif
 16231623 }
 16241624 
 16251625 struct flgcheck ccomflgcheck[] = {
 16261626         { &Oflag, 1, "-xtemps" },
 16271627         { &Oflag, 1, "-xdeljumps" },
 16281628         { &Oflag, 1, "-xinline" },
 16291629         { &Oflag, 1, "-xdce" },
 16301630 #ifdef notyet
 16311631         { &Oflag, 1, "-xssa" },
 16321632 #endif
 16331633         { &freestanding, 1, "-ffreestanding" },
 16341634         { &pgflag, 1, "-p" },
 16351635         { &gflag, 1, "-g" },
 16361636         { &xgnu89, 1, "-xgnu89" },
 16371637         { &xgnu99, 1, "-xgnu99" },
 16381638         { &xuchar, 1, "-xuchar" },
 16391639 #if !defined(os_sunos) && !defined(mach_i386)
 16401640         { &vflag, 1, "-v" },
 16411641 #endif
 16421642 #ifdef os_darwin
 16431643         { &Bstatic, 1, "-k" },
 16441644 #elif defined(os_sunos) && defined(mach_i386)
 16451645         { &kflag, 1, "-K" },
 16461646         { &kflag, 1, "pic" },
 16471647 #else
 16481648         { &kflag, 1, "-k" },
 16491649 #endif
 16501650         { &sspflag, 1, "-fstack-protector" },
 16511651         { 0 }
 16521652 };
 16531653 
 16541654 void
 16551655 setup_ccom_flags(void)
 16561656 {
 16571657 
 16581658         cksetflags(ccomflgcheck, &compiler_flags, 'a');
 16591659 }
 16601660 
 16611661 static int one = 1;
 16621662 
 16631663 struct flgcheck asflgcheck[] = {
 16641664 #if defined(USE_YASM)
 16651665         { &one, 1, "-p" },
 16661666         { &one, 1, "gnu" },
 16671667         { &one, 1, "-f" },
 16681668 #if defined(os_win32)
 16691669         { &one, 1, "win32" },
 16701670 #elif defined(os_darwin)
 16711671         { &one, 1, "macho" },
 16721672 #else
 16731673         { &one, 1, "elf" },
 16741674 #endif
 16751675 #endif
 16761676 #if defined(os_sunos) && defined(mach_sparc64)
 16771677         { &one, 1, "-m64" },
 16781678 #endif
 16791679 #if defined(os_darwin)
 16801680         { &Bstatic, 1, "-static" },
 16811681 #endif
 16821682 #if !defined(USE_YASM)
 16831683         { &vflag, 1, "-v" },
 16841684 #endif
 16851685         { &kflag, 1, "-k" },
 16861686 #ifdef os_darwin
 16871687         { &one, 1, "-arch" },
 16881688 #if mach_amd64
 16891689         { &amd64_i386, 1, "i386" },
 16901690         { &amd64_i386, 0, "x86_64" },
 16911691 #else
 16921692         { &one, 1, "i386" },
 16931693 #endif
 16941694 #else
 16951695 #ifdef mach_amd64
 16961696         { &amd64_i386, 1, "--32" },
 16971697 #endif
 16981698 #endif
 16991699         { 0 }
 17001700 };
 17011701 void
 17021702 setup_as_flags(void)
 17031703 {
 17041704         one = one;
 17051705 #ifdef PCC_SETUP_AS_ARGS
<>1706 -        PCC_SETUP_AS_ARGS;
  1706+        PCC_SETUP_AS_ARGS
<_17071707 #endif
 17081708         cksetflags(asflgcheck, &assembler_flags, 'a');
 17091709 }
 17101710 
 17111711 struct flgcheck ldflgcheck[] = {
 17121712 #ifndef MSLINKER
 17131713         { &vflag, 1, "-v" },
 17141714 #endif
 17151715 #ifdef os_darwin
 17161716         { &shared, 1, "-dylib" },
 17171717 #elif defined(os_win32)
 17181718         { &shared, 1, "-Bdynamic" },
 17191719 #else
 17201720         { &shared, 1, "-shared" },
 17211721 #endif
 17221722 #if !defined(os_sunos) && !defined(os_win32)
 17231723 #ifndef os_darwin
 17241724         { &shared, 0, "-d" },
 17251725 #endif
 17261726 #endif
 17271727 #ifdef os_darwin
 17281728         { &Bstatic, 1, "-static" },
 17291729 #else
 17301730         { &Bstatic, 1, "-Bstatic" },
 17311731 #endif
 17321732 #if !defined(os_darwin) && !defined(os_sunos)
 17331733         { &gflag, 1, "-g" },
 17341734 #endif
 17351735         { &pthreads, 1, "-lpthread" },
 17361736         { 0 },
 17371737 };
 17381738 
 17391739 static void
 17401740 strap(struct strlist *sh, struct strlist *cd, char *n, int where)
 17411741 {
 17421742         void (*fn)(struct strlist *, const char *);
 17431743         char *fil;
 17441744 
 17451745         if (n == 0)
 17461746                 return; /* no crtfile */
 17471747 
 17481748         fn = where == 'p' ? strlist_prepend : strlist_append;
 17491749         fil = find_file(n, cd, R_OK);
 17501750         (*fn)(sh, fil);
 17511751 }
 17521752 
 17531753 void
 17541754 setup_ld_flags(void)
 17551755 {
 17561756         char *b, *e;
 17571757         int i;
 17581758 
 17591759         cksetflags(ldflgcheck, &early_linker_flags, 'a');
 17601760         if (Bstatic == 0 && shared == 0 && rflag == 0) {
 17611761                 for (i = 0; dynlinker[i]; i++)
 17621762                         strlist_append(&early_linker_flags, dynlinker[i]);
 17631763                 strlist_append(&early_linker_flags, "-e");
 17641764                 strlist_append(&early_linker_flags, STARTLABEL);
 17651765         }
 17661766         if (shared == 0 && rflag)
 17671767                 strlist_append(&early_linker_flags, "-r");
 17681768         if (sysroot && *sysroot)
 17691769                 strlist_append(&early_linker_flags, cat("--sysroot=", sysroot));
 17701770         if (!nostdlib) {
 17711771                 /* library search paths */
 17721772                 if (pcclibdir)
 17731773                         strlist_append(&late_linker_flags,
 17741774                             cat("-L", pcclibdir));
 17751775                 for (i = 0; deflibdirs[i]; i++)
 17761776                         strlist_append(&late_linker_flags,
 17771777                             cat("-L", deflibdirs[i]));
 17781778                 /* standard libraries */
 17791779                 if (pgflag) {
 17801780                         for (i = 0; defproflibs[i]; i++)
 17811781                                 strlist_append(&late_linker_flags,
 17821782                                      defproflibs[i]);
 17831783                 } else if (cxxflag) {
 17841784                         for (i = 0; defcxxlibs[i]; i++)
 17851785                                 strlist_append(&late_linker_flags,
 17861786                                     defcxxlibs[i]);
 17871787                 } else {
 17881788                         for (i = 0; deflibs[i]; i++)
 17891789                                 strlist_append(&late_linker_flags, deflibs[i]);
 17901790                 }
 17911791         }
 17921792         if (!nostartfiles) {
 17931793                 if (Bstatic) {
 17941794                         b = CRTBEGIN_T;
 17951795                         e = CRTEND_T;
 17961796                 } else if (shared /* || pieflag */) {
 17971797                         b = CRTBEGIN_S;
 17981798                         e = CRTEND_S;
 17991799                 }  else {
 18001800                         b = CRTBEGIN;
 18011801                         e = CRTEND;
 18021802                 }
 18031803                 strap(&middle_linker_flags, &crtdirs, b, 'p');
 18041804                 strap(&late_linker_flags, &crtdirs, e, 'a');
 18051805                 strap(&middle_linker_flags, &crtdirs, CRTI, 'p');
 18061806                 strap(&late_linker_flags, &crtdirs, CRTN, 'a');
 18071807                 if (shared == 0) {
 18081808                         if (pgflag)
 18091809                                 b = GCRT0;
 18101810 #ifdef notyet
 18111811                         else if (pieflag)
 18121812                                 b = SCRT0;
 18131813 #endif
 18141814                         else
 18151815                                 b = CRT0;
 18161816                         strap(&middle_linker_flags, &crtdirs, b, 'p');
 18171817                 }
 18181818         }
 18191819 }
 18201820 
 18211821 #ifdef os_win32
 18221822 char *
 18231823 win32pathsubst(char *s)
 18241824 {
 18251825         char env[1024];
 18261826         DWORD len;
 18271827 
 18281828         len = ExpandEnvironmentStrings(s, env, sizeof(env));
 18291829         if (len == 0 || len > sizeof(env))
 18301830                 errorx(8, "ExpandEnvironmentStrings failed, len %lu", len);
 18311831 
 18321832         len--;  /* skip nil */
 18331833         while (len-- > 0 && (env[len] == '/' || env[len] == '\\'))
 18341834                 env[len] = '\0';
 18351835 
 18361836         return xstrdup(env);
 18371837 }
 18381838 
 18391839 char *
 18401840 win32commandline(struct strlist *l)
 18411841 {
 18421842         const struct string *s;
 18431843         char *cmd;
 18441844         char *p;
 18451845         int len;
 18461846         int j, k;
 18471847 
 18481848         len = 0;
 18491849         STRLIST_FOREACH(s, l) {
 18501850                 len++;
 18511851                 for (j = 0; s->value[j] != '\0'; j++) {
 18521852                         if (s->value[j] == '\"') {
 18531853                                 for (k = j-1; k >= 0 && s->value[k] == '\\'; k--)
 18541854                                         len++;
 18551855                                 len++;
 18561856                         }
 18571857                         len++;
 18581858                 }
 18591859                 for (k = j-1; k >= 0 && s->value[k] == '\\'; k--)
 18601860                         len++;
 18611861                 len++;
 18621862                 len++;
 18631863         }
 18641864 
 18651865         p = cmd = xmalloc(len);
 18661866 
 18671867         STRLIST_FOREACH(s, l) {
 18681868                 *p++ = '\"';
 18691869                 for (j = 0; s->value[j] != '\0'; j++) {
 18701870                         if (s->value[j] == '\"') {
 18711871                                 for (k = j-1; k >= 0 && s->value[k] == '\\'; k--)
 18721872                                         *p++ = '\\';
 18731873                                 *p++ = '\\';
 18741874                         }
 18751875                         *p++ = s->value[j];
 18761876                 }
 18771877                 for (k = j-1; k >= 0 && s->value[k] == '\\'; k--)
 18781878                         *p++ = '\\';
 18791879                 *p++ = '\"';
 18801880                 *p++ = ' ';
 18811881         }
 18821882         p[-1] = '\0';
 18831883 
 18841884         return cmd;
 18851885 }
 18861886 #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-09-01 09:45 +0200