Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

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