00001
00002
00003
00004
00005 static char rcsid[] = "Id: dummy rcsid";
00006
00007 #include <stdio.h>
00008 #include <stdarg.h>
00009 #include <stdlib.h>
00010 #include <string.h>
00011 #include <assert.h>
00012 #include <ctype.h>
00013 #include <signal.h>
00014
00015 #ifndef TEMPDIR
00016 #define TEMPDIR "/tmp"
00017 #endif
00018
00019 typedef struct list *List;
00020 struct list {
00021 char *str;
00022 List link;
00023 };
00024
00025 static void *alloc(int);
00026 static List append(char *,List);
00027 extern char *basepath(char *);
00028 static int callsys(char *[]);
00029 extern char *concat(char *, char *);
00030 static int compile(char *, char *);
00031 static void compose(char *[], List, List, List);
00032 static void error(char *, char *);
00033 static char *exists(char *);
00034 static char *first(char *);
00035 static int filename(char *, char *);
00036 static List find(char *, List);
00037 static void help(void);
00038 static void initinputs(void);
00039 static void interrupt(int);
00040 static void opt(char *);
00041 static List path2list(const char *);
00042 extern int main(int, char *[]);
00043 extern char *replace(const char *, int, int);
00044 static void rm(List);
00045 extern char *strsave(const char *);
00046 extern char *stringf(const char *, ...);
00047 extern int suffix(char *, char *[], int);
00048 extern char *tempname(char *);
00049
00050 extern int access(char *, int);
00051 extern int getpid(void);
00052
00053 extern char *cpp[], *include[], *com[], *as[],*ld[], inputs[], *suffixes[];
00054 extern int option(char *);
00055
00056 static int errcnt;
00057 static int Eflag;
00058 static int Sflag;
00059 static int cflag;
00060 static int verbose;
00061 static List llist[2];
00062 static List alist;
00063 static List clist;
00064 static List plist;
00065 static List ilist;
00066 static List rmlist;
00067 static char *outfile;
00068 static int ac;
00069 static char **av;
00070 char *tempdir = TEMPDIR;
00071 static char *progname;
00072 static List lccinputs;
00073
00074 main(int argc, char *argv[]) {
00075 int i, j, nf;
00076
00077 progname = argv[0];
00078 ac = argc + 50;
00079 av = alloc(ac*sizeof(char *));
00080 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
00081 signal(SIGINT, interrupt);
00082 if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
00083 signal(SIGTERM, interrupt);
00084 #ifdef SIGHUP
00085 if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
00086 signal(SIGHUP, interrupt);
00087 #endif
00088 if (getenv("TMP"))
00089 tempdir = getenv("TMP");
00090 else if (getenv("TEMP"))
00091 tempdir = getenv("TEMP");
00092 else if (getenv("TMPDIR"))
00093 tempdir = getenv("TMPDIR");
00094 assert(tempdir);
00095 i = strlen(tempdir);
00096 for (; i > 0 && tempdir[i-1] == '/' || tempdir[i-1] == '\\'; i--)
00097 tempdir[i-1] = '\0';
00098 if (argc <= 1) {
00099 help();
00100 exit(0);
00101 }
00102 plist = append("-D__LCC__", 0);
00103 initinputs();
00104 if (getenv("LCCDIR"))
00105 option(stringf("-lccdir=%s", getenv("LCCDIR")));
00106 for (nf = 0, i = j = 1; i < argc; i++) {
00107 if (strcmp(argv[i], "-o") == 0) {
00108 if (++i < argc) {
00109 if (suffix(argv[i], suffixes, 2) >= 0) {
00110 error("-o would overwrite %s", argv[i]);
00111 exit(8);
00112 }
00113 outfile = argv[i];
00114 continue;
00115 } else {
00116 error("unrecognized option `%s'", argv[i-1]);
00117 exit(8);
00118 }
00119 } else if (strcmp(argv[i], "-target") == 0) {
00120 if (argv[i+1] && *argv[i+1] != '-')
00121 i++;
00122 continue;
00123 } else if (*argv[i] == '-' && argv[i][1] != 'l') {
00124 opt(argv[i]);
00125 continue;
00126 } else if (*argv[i] != '-' && suffix(argv[i], suffixes, 3) >= 0)
00127 nf++;
00128 argv[j++] = argv[i];
00129 }
00130 if ((cflag || Sflag) && outfile && nf != 1) {
00131 fprintf(stderr, "%s: -o %s ignored\n", progname, outfile);
00132 outfile = 0;
00133 }
00134 argv[j] = 0;
00135 for (i = 0; include[i]; i++)
00136 plist = append(include[i], plist);
00137 if (ilist) {
00138 List b = ilist;
00139 do {
00140 b = b->link;
00141 plist = append(b->str, plist);
00142 } while (b != ilist);
00143 }
00144 ilist = 0;
00145 for (i = 1; argv[i]; i++)
00146 if (*argv[i] == '-')
00147 opt(argv[i]);
00148 else {
00149 char *name = exists(argv[i]);
00150 if (name) {
00151 if (strcmp(name, argv[i]) != 0
00152 || nf > 1 && suffix(name, suffixes, 3) >= 0)
00153 fprintf(stderr, "%s:\n", name);
00154 filename(name, 0);
00155 } else
00156 error("can't find `%s'", argv[i]);
00157 }
00158 if (errcnt == 0 && !Eflag && !Sflag && !cflag && llist[1]) {
00159 compose(ld, llist[0], llist[1],
00160 append(outfile ? outfile : concat("a", first(suffixes[4])), 0));
00161 if (callsys(av))
00162 errcnt++;
00163 }
00164 rm(rmlist);
00165 return errcnt ? EXIT_FAILURE : EXIT_SUCCESS;
00166 }
00167
00168
00169 static void *alloc(int n) {
00170 static char *avail, *limit;
00171
00172 n = (n + sizeof(char *) - 1)&~(sizeof(char *) - 1);
00173 if (n >= limit - avail) {
00174 avail = malloc(n + 4*1024);
00175 assert(avail);
00176 limit = avail + n + 4*1024;
00177 }
00178 avail += n;
00179 return avail - n;
00180 }
00181
00182
00183 static List append(char *str, List list) {
00184 List p = alloc(sizeof *p);
00185
00186 p->str = str;
00187 if (list) {
00188 p->link = list->link;
00189 list->link = p;
00190 } else
00191 p->link = p;
00192 return p;
00193 }
00194
00195
00196 char *basepath(char *name) {
00197 char *s, *b, *t = 0;
00198
00199 for (b = s = name; *s; s++)
00200 if (*s == '/' || *s == '\\') {
00201 b = s + 1;
00202 t = 0;
00203 } else if (*s == '.')
00204 t = s;
00205 s = strsave(b);
00206 if (t)
00207 s[t-b] = 0;
00208 return s;
00209 }
00210
00211 #ifdef WIN32
00212 #include <process.h>
00213 #else
00214 #define _P_WAIT 0
00215 extern int fork(void);
00216 extern int wait(int *);
00217 extern void execv(const char *, char *[]);
00218
00219 static int _spawnvp(int mode, const char *cmdname, char *argv[]) {
00220 int pid, n, status;
00221
00222 switch (pid = fork()) {
00223 case -1:
00224 fprintf(stderr, "%s: no more processes\n", progname);
00225 return 100;
00226 case 0:
00227
00228 execvp(cmdname, argv);
00229 fprintf(stderr, "%s: ", progname);
00230 perror(cmdname);
00231 fflush(stdout);
00232 exit(100);
00233 }
00234 while ((n = wait(&status)) != pid && n != -1)
00235 ;
00236 if (n == -1)
00237 status = -1;
00238 if (status&0377) {
00239 fprintf(stderr, "%s: fatal error in %s\n", progname, cmdname);
00240 status |= 0400;
00241 }
00242 return (status>>8)&0377;
00243 }
00244 #endif
00245
00246
00247 static int callsys(char **av) {
00248 int i, status = 0;
00249 static char **argv;
00250 static int argc;
00251
00252 for (i = 0; av[i] != NULL; i++)
00253 ;
00254 if (i + 1 > argc) {
00255 argc = i + 1;
00256 if (argv == NULL)
00257 argv = malloc(argc*sizeof *argv);
00258 else
00259 argv = realloc(argv, argc*sizeof *argv);
00260 assert(argv);
00261 }
00262 for (i = 0; status == 0 && av[i] != NULL; ) {
00263 int j = 0;
00264 char *s;
00265 for ( ; av[i] != NULL && (s = strchr(av[i], '\n')) == NULL; i++)
00266 argv[j++] = av[i];
00267 if (s != NULL) {
00268 if (s > av[i])
00269 argv[j++] = stringf("%.*s", s - av[i], av[i]);
00270 if (s[1] != '\0')
00271 av[i] = s + 1;
00272 else
00273 i++;
00274 }
00275 argv[j] = NULL;
00276 if (verbose > 0) {
00277 int k;
00278 fprintf(stderr, "%s", argv[0]);
00279 for (k = 1; argv[k] != NULL; k++)
00280 fprintf(stderr, " %s", argv[k]);
00281 fprintf(stderr, "\n");
00282 }
00283 if (verbose < 2)
00284 status = _spawnvp(_P_WAIT, argv[0], argv);
00285 if (status == -1) {
00286 fprintf(stderr, "%s: ", progname);
00287 perror(argv[0]);
00288 }
00289 }
00290 return status;
00291 }
00292
00293
00294 char *concat(char *s1, char *s2) {
00295 int n = strlen(s1);
00296 char *s = alloc(n + strlen(s2) + 1);
00297
00298 strcpy(s, s1);
00299 strcpy(s + n, s2);
00300 return s;
00301 }
00302
00303
00304 static int compile(char *src, char *dst) {
00305 compose(com, clist, append(src, 0), append(dst, 0));
00306 return callsys(av);
00307 }
00308
00309
00310 static void compose(char *cmd[], List a, List b, List c) {
00311 int i, j;
00312 List lists[3];
00313
00314 lists[0] = a;
00315 lists[1] = b;
00316 lists[2] = c;
00317 for (i = j = 0; cmd[i]; i++) {
00318 char *s = strchr(cmd[i], '$');
00319 if (s && isdigit(s[1])) {
00320 int k = s[1] - '0';
00321 assert(k >=1 && k <= 3);
00322 if (b = lists[k-1]) {
00323 b = b->link;
00324 av[j] = alloc(strlen(cmd[i]) + strlen(b->str) - 1);
00325 strncpy(av[j], cmd[i], s - cmd[i]);
00326 av[j][s-cmd[i]] = '\0';
00327 strcat(av[j], b->str);
00328 strcat(av[j++], s + 2);
00329 while (b != lists[k-1]) {
00330 b = b->link;
00331 assert(j < ac);
00332 av[j++] = b->str;
00333 };
00334 }
00335 } else if (*cmd[i]) {
00336 assert(j < ac);
00337 av[j++] = cmd[i];
00338 }
00339 }
00340 av[j] = NULL;
00341 }
00342
00343
00344 static void error(char *fmt, char *msg) {
00345 fprintf(stderr, "%s: ", progname);
00346 fprintf(stderr, fmt, msg);
00347 fprintf(stderr, "\n");
00348 errcnt++;
00349 }
00350
00351
00352 static char *exists(char *name) {
00353 List b;
00354
00355 if ( (name[0] == '/' || name[0] == '\\' || name[2] == ':')
00356 && access(name, 4) == 0)
00357 return name;
00358 if (!(name[0] == '/' || name[0] == '\\' || name[2] == ':')
00359 && (b = lccinputs))
00360 do {
00361 b = b->link;
00362 if (b->str[0]) {
00363 char buf[1024];
00364 sprintf(buf, "%s/%s", b->str, name);
00365 if (access(buf, 4) == 0)
00366 return strsave(buf);
00367 } else if (access(name, 4) == 0)
00368 return name;
00369 } while (b != lccinputs);
00370 if (verbose > 1)
00371 return name;
00372 return 0;
00373 }
00374
00375
00376 static char *first(char *list) {
00377 char *s = strchr(list, ';');
00378
00379 if (s) {
00380 char buf[1024];
00381 strncpy(buf, list, s-list);
00382 buf[s-list] = '\0';
00383 return strsave(buf);
00384 } else
00385 return list;
00386 }
00387
00388
00389 static int filename(char *name, char *base) {
00390 int status = 0;
00391 static char *stemp, *itemp;
00392
00393 if (base == 0)
00394 base = basepath(name);
00395 switch (suffix(name, suffixes, 4)) {
00396 case 0:
00397 compose(cpp, plist, append(name, 0), 0);
00398 if (Eflag) {
00399 status = callsys(av);
00400 break;
00401 }
00402 if (itemp == NULL)
00403 itemp = tempname(first(suffixes[1]));
00404 compose(cpp, plist, append(name, 0), append(itemp, 0));
00405 status = callsys(av);
00406 if (status == 0)
00407 return filename(itemp, base);
00408 break;
00409 case 1:
00410 if (Eflag)
00411 break;
00412 if (Sflag)
00413 status = compile(name, outfile ? outfile : concat(base, first(suffixes[2])));
00414 else if ((status = compile(name, stemp?stemp:(stemp=tempname(first(suffixes[2]))))) == 0)
00415 return filename(stemp, base);
00416 break;
00417 case 2:
00418 if (Eflag)
00419 break;
00420 if (!Sflag) {
00421 char *ofile;
00422 if (cflag && outfile)
00423 ofile = outfile;
00424 else if (cflag)
00425 ofile = concat(base, first(suffixes[3]));
00426 else
00427 ofile = tempname(first(suffixes[3]));
00428 compose(as, alist, append(name, 0), append(ofile, 0));
00429 status = callsys(av);
00430 if (!find(ofile, llist[1]))
00431 llist[1] = append(ofile, llist[1]);
00432 }
00433 break;
00434 case 3:
00435 if (!find(name, llist[1]))
00436 llist[1] = append(name, llist[1]);
00437 break;
00438 default:
00439 if (Eflag) {
00440 compose(cpp, plist, append(name, 0), 0);
00441 status = callsys(av);
00442 }
00443 llist[1] = append(name, llist[1]);
00444 break;
00445 }
00446 if (status)
00447 errcnt++;
00448 return status;
00449 }
00450
00451
00452 static List find(char *str, List list) {
00453 List b;
00454
00455 if (b = list)
00456 do {
00457 if (strcmp(str, b->str) == 0)
00458 return b;
00459 } while ((b = b->link) != list);
00460 return 0;
00461 }
00462
00463
00464 static void help(void) {
00465 static char *msgs[] = {
00466 "", " [ option | file ]...\n",
00467 " except for -l, options are processed left-to-right before files\n",
00468 " unrecognized options are taken to be linker options\n",
00469 "-A warn about nonANSI usage; 2nd -A warns more\n",
00470 "-b emit expression-level profiling code; see bprint(1)\n",
00471 #ifdef sparc
00472 "-Bstatic -Bdynamic specify static or dynamic libraries\n",
00473 #endif
00474 "-Bdir/ use the compiler named `dir/rcc'\n",
00475 "-c compile only\n",
00476 "-dn set switch statement density to `n'\n",
00477 "-Dname -Dname=def define the preprocessor symbol `name'\n",
00478 "-E run only the preprocessor on the named C programs and unsuffixed files\n",
00479 "-g produce symbol table information for debuggers\n",
00480 "-help or -? print this message\n",
00481 "-Idir add `dir' to the beginning of the list of #include directories\n",
00482 "-lx search library `x'\n",
00483 "-N do not search the standard directories for #include files\n",
00484 "-n emit code to check for dereferencing zero pointers\n",
00485 "-O is ignored\n",
00486 "-o file leave the output in `file'\n",
00487 "-P print ANSI-style declarations for globals\n",
00488 "-p -pg emit profiling code; see prof(1) and gprof(1)\n",
00489 "-S compile to assembly language\n",
00490 #ifdef linux
00491 "-static specify static libraries (default is dynamic)\n",
00492 #endif
00493 "-t -tname emit function tracing calls to printf or to `name'\n",
00494 "-target name is ignored\n",
00495 "-tempdir=dir place temporary files in `dir/'", "\n"
00496 "-Uname undefine the preprocessor symbol `name'\n",
00497 "-v show commands as they are executed; 2nd -v suppresses execution\n",
00498 "-w suppress warnings\n",
00499 "-Woarg specify system-specific `arg'\n",
00500 "-W[pfal]arg pass `arg' to the preprocessor, compiler, assembler, or linker\n",
00501 0 };
00502 int i;
00503 char *s;
00504
00505 msgs[0] = progname;
00506 for (i = 0; msgs[i]; i++) {
00507 fprintf(stderr, "%s", msgs[i]);
00508 if (strncmp("-tempdir", msgs[i], 8) == 0 && tempdir)
00509 fprintf(stderr, "; default=%s", tempdir);
00510 }
00511 #define xx(v) if (s = getenv(#v)) fprintf(stderr, #v "=%s\n", s)
00512 xx(LCCINPUTS);
00513 xx(LCCDIR);
00514 #ifdef WIN32
00515 xx(include);
00516 xx(lib);
00517 #endif
00518 #undef xx
00519 }
00520
00521
00522 static void initinputs(void) {
00523 char *s = getenv("LCCINPUTS");
00524 List list, b;
00525
00526 if (s == 0 || (s = inputs)[0] == 0)
00527 s = ".";
00528 if (s) {
00529 lccinputs = path2list(s);
00530 if (b = lccinputs)
00531 do {
00532 b = b->link;
00533 if (strcmp(b->str, ".") != 0) {
00534 ilist = append(concat("-I", b->str), ilist);
00535 if (strstr(com[1], "win32") == NULL)
00536 llist[0] = append(concat("-L", b->str), llist[0]);
00537 } else
00538 b->str = "";
00539 } while (b != lccinputs);
00540 }
00541 #ifdef WIN32
00542 if (list = b = path2list(getenv("include")))
00543 do {
00544 b = b->link;
00545 ilist = append(stringf("-I\"%s\"", b->str), ilist);
00546 } while (b != list);
00547 #endif
00548 }
00549
00550
00551 static void interrupt(int n) {
00552 rm(rmlist);
00553 exit(n = 100);
00554 }
00555
00556
00557 static void opt(char *arg) {
00558 switch (arg[1]) {
00559 case 'W':
00560 if (arg[2] && arg[3])
00561 switch (arg[2]) {
00562 case 'o':
00563 if (option(&arg[3]))
00564 return;
00565 break;
00566 case 'p':
00567 plist = append(&arg[3], plist);
00568 return;
00569 case 'f':
00570 if (strcmp(&arg[3], "-C") || option("-b")) {
00571 clist = append(&arg[3], clist);
00572 return;
00573 }
00574 break;
00575 case 'a':
00576 alist = append(&arg[3], alist);
00577 return;
00578 case 'l':
00579 llist[0] = append(&arg[3], llist[0]);
00580 return;
00581 }
00582 fprintf(stderr, "%s: %s ignored\n", progname, arg);
00583 return;
00584 case 'd':
00585 arg[1] = 's';
00586 clist = append(arg, clist);
00587 return;
00588 case 't':
00589 if (strncmp(arg, "-tempdir=", 9) == 0)
00590 tempdir = arg + 9;
00591 else
00592 clist = append(arg, clist);
00593 return;
00594 case 'p':
00595 if (option(arg))
00596 clist = append(arg, clist);
00597 else
00598 fprintf(stderr, "%s: %s ignored\n", progname, arg);
00599 return;
00600 case 'D':
00601 case 'U':
00602 case 'I':
00603 plist = append(arg, plist);
00604 return;
00605 case 'B':
00606 #ifdef sparc
00607 if (strcmp(arg, "-Bstatic") == 0 || strcmp(arg, "-Bdynamic") == 0)
00608 llist[1] = append(arg, llist[1]);
00609 else
00610 #endif
00611 {
00612 static char *path;
00613 if (path)
00614 error("-B overwrites earlier option", 0);
00615 path = arg + 2;
00616 if (strstr(com[1], "win32") != NULL)
00617 com[0] = concat(replace(path, '/', '\\'), concat("rcc", first(suffixes[4])));
00618 else
00619 com[0] = concat(path, "rcc");
00620 if (path[0] == 0)
00621 error("missing directory in -B option", 0);
00622 }
00623 return;
00624 case 'h':
00625 if (strcmp(arg, "-help") == 0) {
00626 static int printed = 0;
00627 case '?':
00628 if (!printed)
00629 help();
00630 printed = 1;
00631 return;
00632 }
00633 #ifdef linux
00634 case 's':
00635 if (strcmp(arg,"-static") == 0) {
00636 if (!option(arg))
00637 fprintf(stderr, "%s: %s ignored\n", progname, arg);
00638 return;
00639 }
00640 #endif
00641 }
00642 if (arg[2] == 0)
00643 switch (arg[1]) {
00644 case 'S':
00645 Sflag++;
00646 return;
00647 case 'O':
00648 fprintf(stderr, "%s: %s ignored\n", progname, arg);
00649 return;
00650 case 'A': case 'n': case 'w': case 'P':
00651 clist = append(arg, clist);
00652 return;
00653 case 'g': case 'b':
00654 if (option(arg))
00655 clist = append(arg[1] == 'g' ? "-g2" : arg, clist);
00656 else
00657 fprintf(stderr, "%s: %s ignored\n", progname, arg);
00658 return;
00659 case 'G':
00660 if (option(arg)) {
00661 clist = append("-g3", clist);
00662 llist[0] = append("-N", llist[0]);
00663 } else
00664 fprintf(stderr, "%s: %s ignored\n", progname, arg);
00665 return;
00666 case 'E':
00667 Eflag++;
00668 return;
00669 case 'c':
00670 cflag++;
00671 return;
00672 case 'N':
00673 if (strcmp(basepath(cpp[0]), "gcc-cpp") == 0)
00674 plist = append("-nostdinc", plist);
00675 include[0] = 0;
00676 ilist = 0;
00677 return;
00678 case 'v':
00679 if (verbose++ == 0) {
00680 if (strcmp(basepath(cpp[0]), "gcc-cpp") == 0)
00681 plist = append(arg, plist);
00682 clist = append(arg, clist);
00683 fprintf(stderr, "%s %s\n", progname, rcsid);
00684 }
00685 return;
00686 }
00687 if (cflag || Sflag || Eflag)
00688 fprintf(stderr, "%s: %s ignored\n", progname, arg);
00689 else
00690 llist[1] = append(arg, llist[1]);
00691 }
00692
00693
00694 static List path2list(const char *path) {
00695 List list = NULL;
00696 char sep = ':';
00697
00698 if (path == NULL)
00699 return NULL;
00700 if (strchr(path, ';'))
00701 sep = ';';
00702 while (*path) {
00703 char *p, buf[512];
00704 if (p = strchr(path, sep)) {
00705 assert(p - path < sizeof buf);
00706 strncpy(buf, path, p - path);
00707 buf[p-path] = '\0';
00708 } else {
00709 assert(strlen(path) < sizeof buf);
00710 strcpy(buf, path);
00711 }
00712 if (!find(buf, list))
00713 list = append(strsave(buf), list);
00714 if (p == 0)
00715 break;
00716 path = p + 1;
00717 }
00718 return list;
00719 }
00720
00721
00722 char *replace(const char *str, int from, int to) {
00723 char *s = strsave(str), *p = s;
00724
00725 for ( ; (p = strchr(p, from)) != NULL; p++)
00726 *p = to;
00727 return s;
00728 }
00729
00730
00731 static void rm(List list) {
00732 if (list) {
00733 List b = list;
00734 if (verbose)
00735 fprintf(stderr, "rm");
00736 do {
00737 if (verbose)
00738 fprintf(stderr, " %s", b->str);
00739 if (verbose < 2)
00740 remove(b->str);
00741 } while ((b = b->link) != list);
00742 if (verbose)
00743 fprintf(stderr, "\n");
00744 }
00745 }
00746
00747
00748 char *strsave(const char *str) {
00749 return strcpy(alloc(strlen(str)+1), str);
00750 }
00751
00752
00753 char *stringf(const char *fmt, ...) {
00754 char buf[1024];
00755 va_list ap;
00756 int n;
00757
00758 va_start(ap, fmt);
00759 n = vsprintf(buf, fmt, ap);
00760 va_end(ap);
00761 return strsave(buf);
00762 }
00763
00764
00765 int suffix(char *name, char *tails[], int n) {
00766 int i, len = strlen(name);
00767
00768 for (i = 0; i < n; i++) {
00769 char *s = tails[i], *t;
00770 for ( ; t = strchr(s, ';'); s = t + 1) {
00771 int m = t - s;
00772 if (len > m && strncmp(&name[len-m], s, m) == 0)
00773 return i;
00774 }
00775 if (*s) {
00776 int m = strlen(s);
00777 if (len > m && strncmp(&name[len-m], s, m) == 0)
00778 return i;
00779 }
00780 }
00781 return -1;
00782 }
00783
00784
00785 char *tempname(char *suffix) {
00786 static int n;
00787 char *name = stringf("%s/lcc%d%d%s", tempdir, getpid(), n++, suffix);
00788
00789 if (strstr(com[1], "win32") != NULL)
00790 name = replace(name, '/', '\\');
00791 rmlist = append(name, rmlist);
00792 return name;
00793 }