OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [trunk/] [lcc/] [etc/] [lcc.c] - Blame information for rev 333

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 hellwig
/*
2
 * lcc [ option ]... [ file | -llib ]...
3
 * front end for the ANSI C compiler
4
 */
5
static char rcsid[] = "$Id: lcc.c,v 4.33 2001/06/28 22:19:58 drh Exp $";
6
 
7
#include <stdio.h>
8
#include <stdarg.h>
9
#include <stdlib.h>
10
#include <string.h>
11
#include <assert.h>
12
#include <ctype.h>
13
#include <signal.h>
14
 
15
#ifndef TEMPDIR
16
#define TEMPDIR "/tmp"
17
#endif
18
 
19
typedef struct list *List;
20
struct list {           /* circular list nodes: */
21
        char *str;              /* option or file name */
22
        List link;              /* next list element */
23
};
24
 
25
static void *alloc(int);
26
static List append(char *,List);
27
extern char *basepath(char *);
28
static int callsys(char *[]);
29
extern char *concat(char *, char *);
30
static int compile(char *, char *);
31
static void compose(char *[], List, List, List);
32
static void error(char *, char *);
33
static char *exists(char *);
34
static char *first(char *);
35
static int filename(char *, char *);
36
static List find(char *, List);
37
static void help(void);
38
static void initinputs(void);
39
static void interrupt(int);
40
static void opt(char *);
41
static List path2list(const char *);
42
extern int main(int, char *[]);
43
extern char *replace(const char *, int, int);
44
static void rm(List);
45
extern char *strsave(const char *);
46
extern char *stringf(const char *, ...);
47
extern int suffix(char *, char *[], int);
48
extern char *tempname(char *);
49
 
50
extern int access(char *, int);
51
extern int getpid(void);
52
 
53
extern char *cpp[], *include[], *com[], *as[],*ld[], inputs[], *suffixes[];
54
extern int option(char *);
55
 
56
static int errcnt;              /* number of errors */
57
static int Eflag;               /* -E specified */
58
static int Sflag;               /* -S specified */
59
static int cflag;               /* -c specified */
60
static int verbose;             /* incremented for each -v */
61
static List llist[2];           /* loader files, flags */
62
static List alist;              /* assembler flags */
63
static List clist;              /* compiler flags */
64
static List plist;              /* preprocessor flags */
65
static List ilist;              /* list of additional includes from LCCINPUTS */
66
static List rmlist;             /* list of files to remove */
67
static char *outfile;           /* ld output file or -[cS] object file */
68
static int ac;                  /* argument count */
69
static char **av;               /* argument vector */
70
char *tempdir = TEMPDIR;        /* directory for temporary files */
71
static char *progname;
72
static List lccinputs;          /* list of input directories */
73
 
74 328 hellwig
int main(int argc, char *argv[]) {
75 4 hellwig
        int i, j, nf;
76
 
77
        progname = argv[0];
78
        ac = argc + 50;
79
        av = alloc(ac*sizeof(char *));
80
        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
81
                signal(SIGINT, interrupt);
82
        if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
83
                signal(SIGTERM, interrupt);
84
#ifdef SIGHUP
85
        if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
86
                signal(SIGHUP, interrupt);
87
#endif
88
        if (getenv("TMP"))
89
                tempdir = getenv("TMP");
90
        else if (getenv("TEMP"))
91
                tempdir = getenv("TEMP");
92
        else if (getenv("TMPDIR"))
93
                tempdir = getenv("TMPDIR");
94
        assert(tempdir);
95
        i = strlen(tempdir);
96
        for (; i > 0 && tempdir[i-1] == '/' || tempdir[i-1] == '\\'; i--)
97
                tempdir[i-1] = '\0';
98
        if (argc <= 1) {
99
                help();
100
                exit(0);
101
        }
102
        plist = append("-D__LCC__", 0);
103
        initinputs();
104
        if (getenv("LCCDIR"))
105
                option(stringf("-lccdir=%s", getenv("LCCDIR")));
106
        for (nf = 0, i = j = 1; i < argc; i++) {
107
                if (strcmp(argv[i], "-o") == 0) {
108
                        if (++i < argc) {
109
                                if (suffix(argv[i], suffixes, 2) >= 0) {
110
                                        error("-o would overwrite %s", argv[i]);
111
                                        exit(8);
112
                                }
113
                                outfile = argv[i];
114
                                continue;
115
                        } else {
116
                                error("unrecognized option `%s'", argv[i-1]);
117
                                exit(8);
118
                        }
119
                } else if (strcmp(argv[i], "-target") == 0) {
120
                        if (argv[i+1] && *argv[i+1] != '-')
121
                                i++;
122
                        continue;
123
                } else if (*argv[i] == '-' && argv[i][1] != 'l') {
124
                        opt(argv[i]);
125
                        continue;
126
                } else if (*argv[i] != '-' && suffix(argv[i], suffixes, 3) >= 0)
127
                        nf++;
128
                argv[j++] = argv[i];
129
        }
130
        if ((cflag || Sflag) && outfile && nf != 1) {
131
                fprintf(stderr, "%s: -o %s ignored\n", progname, outfile);
132
                outfile = 0;
133
        }
134
        argv[j] = 0;
135
        for (i = 0; include[i]; i++)
136
                plist = append(include[i], plist);
137
        if (ilist) {
138
                List b = ilist;
139
                do {
140
                        b = b->link;
141
                        plist = append(b->str, plist);
142
                } while (b != ilist);
143
        }
144
        ilist = 0;
145
        for (i = 1; argv[i]; i++)
146
                if (strcmp(argv[i], "-l") == 0 && argv[i+1] && *argv[i+1] != '-') {      /* -l file */
147
                        llist[1] = append(argv[i++], llist[1]);
148
                        llist[1] = append(argv[i],   llist[1]);
149
                } else if (*argv[i] == '-')
150
                        opt(argv[i]);
151
                else {
152
                        char *name = exists(argv[i]);
153
                        if (name) {
154
                                if (strcmp(name, argv[i]) != 0
155
                                || nf > 1 && suffix(name, suffixes, 3) >= 0)
156
                                        fprintf(stderr, "%s:\n", name);
157
                                filename(name, 0);
158
                        } else
159
                                error("can't find `%s'", argv[i]);
160
                }
161
        if (errcnt == 0 && !Eflag && !Sflag && !cflag && llist[1]) {
162
                compose(ld, llist[0], llist[1],
163
                        append(outfile ? outfile : concat("a", first(suffixes[4])), 0));
164
                if (callsys(av))
165
                        errcnt++;
166
        }
167
        rm(rmlist);
168
        return errcnt ? EXIT_FAILURE : EXIT_SUCCESS;
169
}
170
 
171
/* alloc - allocate n bytes or die */
172
static void *alloc(int n) {
173
        static char *avail, *limit;
174
 
175
        n = (n + sizeof(char *) - 1)&~(sizeof(char *) - 1);
176
        if (n >= limit - avail) {
177
                avail = malloc(n + 4*1024);
178
                assert(avail);
179
                limit = avail + n + 4*1024;
180
        }
181
        avail += n;
182
        return avail - n;
183
}
184
 
185
/* append - append a node with string str onto list, return new list */
186
static List append(char *str, List list) {
187
        List p = alloc(sizeof *p);
188
 
189
        p->str = str;
190
        if (list) {
191
                p->link = list->link;
192
                list->link = p;
193
        } else
194
                p->link = p;
195
        return p;
196
}
197
 
198
/* basepath - return base name for name, e.g. /usr/drh/foo.c => foo */
199
char *basepath(char *name) {
200
        char *s, *b, *t = 0;
201
 
202
        for (b = s = name; *s; s++)
203
                if (*s == '/' || *s == '\\') {
204
                        b = s + 1;
205
                        t = 0;
206
                } else if (*s == '.')
207
                        t = s;
208
        s = strsave(b);
209
        if (t)
210
                s[t-b] = 0;
211
        return s;
212
}
213
 
214
#ifdef WIN32
215
#include <process.h>
216
#else
217
#define _P_WAIT 0
218
extern int fork(void);
219
extern int wait(int *);
220
extern int execv(const char *, char *[]);
221
 
222
static int _spawnvp(int mode, const char *cmdname, const char *const argv[]) {
223
        int pid, n, status;
224
 
225
        switch (pid = fork()) {
226
        case -1:
227
                fprintf(stderr, "%s: no more processes\n", progname);
228
                return 100;
229
        case 0:
230
                execv(cmdname, (char **)argv);
231
                fprintf(stderr, "%s: ", progname);
232
                perror(cmdname);
233
                fflush(stdout);
234
                exit(100);
235
        }
236
        while ((n = wait(&status)) != pid && n != -1)
237
                ;
238
        if (n == -1)
239
                status = -1;
240
        if (status&0377) {
241
                fprintf(stderr, "%s: fatal error in %s\n", progname, cmdname);
242
                status |= 0400;
243
        }
244
        return (status>>8)&0377;
245
}
246
#endif
247
 
248
/* callsys - execute the command described by av[0...], return status */
249
static int callsys(char **av) {
250
        int i, status = 0;
251
        static char **argv;
252
        static int argc;
253
 
254
        for (i = 0; av[i] != NULL; i++)
255
                ;
256
        if (i + 1 > argc) {
257
                argc = i + 1;
258
                if (argv == NULL)
259
                        argv = malloc(argc*sizeof *argv);
260
                else
261
                        argv = realloc(argv, argc*sizeof *argv);
262
                assert(argv);
263
        }
264
        for (i = 0; status == 0 && av[i] != NULL; ) {
265
                int j = 0;
266
                char *s;
267
                for ( ; av[i] != NULL && (s = strchr(av[i], '\n')) == NULL; i++)
268
                        argv[j++] = av[i];
269
                if (s != NULL) {
270
                        if (s > av[i])
271
                                argv[j++] = stringf("%.*s", s - av[i], av[i]);
272
                        if (s[1] != '\0')
273
                                av[i] = s + 1;
274
                        else
275
                                i++;
276
                }
277
                argv[j] = NULL;
278
                if (verbose > 0) {
279
                        int k;
280
                        fprintf(stderr, "%s", argv[0]);
281
                        for (k = 1; argv[k] != NULL; k++)
282
                                fprintf(stderr, " %s", argv[k]);
283
                        fprintf(stderr, "\n");
284
                }
285
                if (verbose < 2)
286
                        status = _spawnvp(_P_WAIT, argv[0], (const char * const *)argv);
287
                if (status == -1) {
288
                        fprintf(stderr, "%s: ", progname);
289
                        perror(argv[0]);
290
                }
291
        }
292
        return status;
293
}
294
 
295
/* concat - return concatenation of strings s1 and s2 */
296
char *concat(char *s1, char *s2) {
297
        int n = strlen(s1);
298
        char *s = alloc(n + strlen(s2) + 1);
299
 
300
        strcpy(s, s1);
301
        strcpy(s + n, s2);
302
        return s;
303
}
304
 
305
/* compile - compile src into dst, return status */
306
static int compile(char *src, char *dst) {
307
        compose(com, clist, append(src, 0), append(dst, 0));
308
        return callsys(av);
309
}
310
 
311
/* compose - compose cmd into av substituting a, b, c for $1, $2, $3, resp. */
312
static void compose(char *cmd[], List a, List b, List c) {
313
        int i, j;
314
        List lists[3];
315
 
316
        lists[0] = a;
317
        lists[1] = b;
318
        lists[2] = c;
319
        for (i = j = 0; cmd[i]; i++) {
320
                char *s = strchr(cmd[i], '$');
321
                if (s && isdigit(s[1])) {
322
                        int k = s[1] - '0';
323
                        assert(k >=1 && k <= 3);
324
                        if (b = lists[k-1]) {
325
                                b = b->link;
326
                                av[j] = alloc(strlen(cmd[i]) + strlen(b->str) - 1);
327
                                strncpy(av[j], cmd[i], s - cmd[i]);
328
                                av[j][s-cmd[i]] = '\0';
329
                                strcat(av[j], b->str);
330
                                strcat(av[j++], s + 2);
331
                                while (b != lists[k-1]) {
332
                                        b = b->link;
333
                                        assert(j < ac);
334
                                        av[j++] = b->str;
335
                                };
336
                        }
337
                } else if (*cmd[i]) {
338
                        assert(j < ac);
339
                        av[j++] = cmd[i];
340
                }
341
        }
342
        av[j] = NULL;
343
}
344
 
345
/* error - issue error msg according to fmt, bump error count */
346
static void error(char *fmt, char *msg) {
347
        fprintf(stderr, "%s: ", progname);
348
        fprintf(stderr, fmt, msg);
349
        fprintf(stderr, "\n");
350
        errcnt++;
351
}
352
 
353
/* exists - if `name' readable return its path name or return null */
354
static char *exists(char *name) {
355
        List b;
356
 
357
        if ( (name[0] == '/' || name[0] == '\\' || name[2] == ':')
358
        && access(name, 4) == 0)
359
                return name;
360
        if (!(name[0] == '/' || name[0] == '\\' || name[2] == ':')
361
        && (b = lccinputs))
362
                do {
363
                        b = b->link;
364
                        if (b->str[0]) {
365
                                char buf[1024];
366
                                sprintf(buf, "%s/%s", b->str, name);
367
                                if (access(buf, 4) == 0)
368
                                        return strsave(buf);
369
                        } else if (access(name, 4) == 0)
370
                                return name;
371
                } while (b != lccinputs);
372
        if (verbose > 1)
373
                return name;
374
        return 0;
375
}
376
 
377
/* first - return first component in semicolon separated list */
378
static char *first(char *list) {
379
        char *s = strchr(list, ';');
380
 
381
        if (s) {
382
                char buf[1024];
383
                strncpy(buf, list, s-list);
384
                buf[s-list] = '\0';
385
                return strsave(buf);
386
        } else
387
                return list;
388
}
389
 
390
/* filename - process file name argument `name', return status */
391
static int filename(char *name, char *base) {
392
        int status = 0;
393
        static char *stemp, *itemp;
394
 
395
        if (base == 0)
396
                base = basepath(name);
397
        switch (suffix(name, suffixes, 4)) {
398
        case 0:  /* C source files */
399
                compose(cpp, plist, append(name, 0), 0);
400
                if (Eflag) {
401
                        status = callsys(av);
402
                        break;
403
                }
404
                if (itemp == NULL)
405
                        itemp = tempname(first(suffixes[1]));
406
                compose(cpp, plist, append(name, 0), append(itemp, 0));
407
                status = callsys(av);
408
                if (status == 0)
409
                        return filename(itemp, base);
410
                break;
411
        case 1: /* preprocessed source files */
412
                if (Eflag)
413
                        break;
414
                if (Sflag)
415
                        status = compile(name, outfile ? outfile : concat(base, first(suffixes[2])));
416
                else if ((status = compile(name, stemp?stemp:(stemp=tempname(first(suffixes[2]))))) == 0)
417
                        return filename(stemp, base);
418
                break;
419
        case 2: /* assembly language files */
420
                if (Eflag)
421
                        break;
422
                if (!Sflag) {
423
                        char *ofile;
424
                        if (cflag && outfile)
425
                                ofile = outfile;
426
                        else if (cflag)
427
                                ofile = concat(base, first(suffixes[3]));
428
                        else
429
                                ofile = tempname(first(suffixes[3]));
430
                        compose(as, alist, append(name, 0), append(ofile, 0));
431
                        status = callsys(av);
432
                        if (!find(ofile, llist[1]))
433
                                llist[1] = append(ofile, llist[1]);
434
                }
435
                break;
436
        case 3: /* object files */
437
                if (!find(name, llist[1]))
438
                        llist[1] = append(name, llist[1]);
439
                break;
440
        default:
441
                if (Eflag) {
442
                        compose(cpp, plist, append(name, 0), 0);
443
                        status = callsys(av);
444
                }
445
                llist[1] = append(name, llist[1]);
446
                break;
447
        }
448
        if (status)
449
                errcnt++;
450
        return status;
451
}
452
 
453
/* find - find 1st occurrence of str in list, return list node or 0 */
454
static List find(char *str, List list) {
455
        List b;
456
 
457
        if (b = list)
458
                do {
459
                        if (strcmp(str, b->str) == 0)
460
                                return b;
461
                } while ((b = b->link) != list);
462
        return 0;
463
}
464
 
465
/* help - print help message */
466
static void help(void) {
467
        static char *msgs[] = {
468
"", " [ option | file ]...\n",
469
"       except for -l, options are processed left-to-right before files\n",
470
"       unrecognized options are taken to be linker options\n",
471
"-A     warn about nonANSI usage; 2nd -A warns more\n",
472
"-b     emit expression-level profiling code; see bprint(1)\n",
473
#ifdef sparc
474
"-Bstatic -Bdynamic     specify static or dynamic libraries\n",
475
#endif
476
"-Bdir/ use the compiler named `dir/rcc'\n",
477
"-c     compile only\n",
478
"-dn    set switch statement density to `n'\n",
479
"-Dname -Dname=def      define the preprocessor symbol `name'\n",
480
"-E     run only the preprocessor on the named C programs and unsuffixed files\n",
481
"-g     produce symbol table information for debuggers\n",
482
"-help or -?    print this message on standard error\n",
483
"-Idir  add `dir' to the beginning of the list of #include directories\n",
484
"-lx    search library `x'\n",
485
"-M     emit makefile dependencies; implies -E\n",
486
"-N     do not search the standard directories for #include files\n",
487
"-n     emit code to check for dereferencing zero pointers\n",
488
"-O     is ignored\n",
489
"-o file        leave the output in `file'\n",
490
"-P     print ANSI-style declarations for globals on standard error\n",
491
"-p -pg emit profiling code; see prof(1) and gprof(1)\n",
492
"-S     compile to assembly language\n",
493
"-static        specify static libraries (default is dynamic)\n",
494
"-dynamic       specify dynamically linked libraries\n",
495
"-t -tname      emit function tracing calls to printf or to `name'\n",
496
"-target name   is ignored\n",
497
"-tempdir=dir   place temporary files in `dir/'", "\n"
498
"-Uname undefine the preprocessor symbol `name'\n",
499
"-v     show commands as they are executed; 2nd -v suppresses execution\n",
500
"-w     suppress warnings\n",
501
"-Woarg specify system-specific `arg'\n",
502
"-W[pfal]arg    pass `arg' to the preprocessor, compiler, assembler, or linker\n",
503
 
504
        int i;
505
        char *s;
506
 
507
        msgs[0] = progname;
508
        for (i = 0; msgs[i]; i++) {
509
                fprintf(stderr, "%s", msgs[i]);
510
                if (strncmp("-tempdir", msgs[i], 8) == 0 && tempdir)
511
                        fprintf(stderr, "; default=%s", tempdir);
512
        }
513
#define xx(v) if (s = getenv(#v)) fprintf(stderr, #v "=%s\n", s)
514
        xx(LCCINPUTS);
515
        xx(LCCDIR);
516
#ifdef WIN32
517
        xx(include);
518
        xx(lib);
519
#endif
520
#undef xx
521
}
522
 
523
/* initinputs - if LCCINPUTS or include is defined, use them to initialize various lists */
524
static void initinputs(void) {
525
        char *s = getenv("LCCINPUTS");
526
        List list, b;
527
 
528
        if (s == 0 && (s = inputs)[0] == 0)
529
                s = ".";
530
        if (s) {
531
                lccinputs = path2list(s);
532
                if (b = lccinputs)
533
                        do {
534
                                b = b->link;
535
                                if (strcmp(b->str, ".") != 0) {
536
                                        ilist = append(concat("-I", b->str), ilist);
537
                                        if (strstr(com[1], "win32") == NULL)
538
                                                llist[0] = append(concat("-L", b->str), llist[0]);
539
                                } else
540
                                        b->str = "";
541
                        } while (b != lccinputs);
542
        }
543
#ifdef WIN32
544
        if (list = b = path2list(getenv("include")))
545
                do {
546
                        int n;
547
                        b = b->link;
548
                        n = strlen(b->str);
549
                        if (b->str[n-1] == '\\')
550
                                b->str[n-1] = '/';
551
                        ilist = append(stringf("-I\"%s\"", b->str), ilist);
552
                } while (b != list);
553
#endif
554
}
555
 
556
/* interrupt - catch interrupt signals */
557
static void interrupt(int n) {
558
        rm(rmlist);
559
        exit(n = 100);
560
}
561
 
562
/* opt - process option in arg */
563
static void opt(char *arg) {
564
        switch (arg[1]) {       /* multi-character options */
565
        case 'W':       /* -Wxarg */
566
                if (arg[2] && arg[3])
567
                        switch (arg[2]) {
568
                        case 'o':
569
                                if (option(&arg[3]))
570
                                        return;
571
                                break;
572
                        case 'p':
573
                                plist = append(&arg[3], plist);
574
                                return;
575
                        case 'f':
576
                                if (strcmp(&arg[3], "-C") == 0 && !option("-b"))
577
                                        break;  /* -C requires that -b is supported */
578
                                clist = append(&arg[3], clist);
579
                                if (strcmp(&arg[3], "-unsigned_char=1") == 0) {
580
                                        plist = append("-D__CHAR_UNSIGNED__", plist);
581
                                        plist = append("-U_CHAR_IS_SIGNED", plist);
582
                                }
583
#define xx(name,k) \
584
                                if (strcmp(&arg[3], "-wchar_t=" #name) == 0) \
585
                                        plist = append("-D_WCHAR_T_SIZE=" #k, plist);
586
xx(unsigned_char,1)
587
xx(unsigned_short,2)
588
xx(unsigned_int,4)
589
#undef xx
590
                                return;
591
                        case 'a':
592
                                alist = append(&arg[3], alist);
593
                                return;
594
                        case 'l':
595
                                llist[0] = append(&arg[3], llist[0]);
596
                                return;
597
                        }
598
                fprintf(stderr, "%s: %s ignored\n", progname, arg);
599
                return;
600
        case 'd':       /* -dn -dynamic */
601
                if (strcmp(arg, "-dynamic") == 0) {
602
                        if (!option(arg))
603
                                fprintf(stderr, "%s: %s ignored\n", progname, arg);
604
                } else {
605
                        arg[1] = 's';
606
                        clist = append(arg, clist);
607
                }
608
                return;
609
        case 't':       /* -t -tname -tempdir=dir */
610
                if (strncmp(arg, "-tempdir=", 9) == 0)
611
                        tempdir = arg + 9;
612
                else
613
                        clist = append(arg, clist);
614
                return;
615
        case 'p':       /* -p -pg */
616
                if (option(arg))
617
                        clist = append(arg, clist);
618
                else
619
                        fprintf(stderr, "%s: %s ignored\n", progname, arg);
620
                return;
621
        case 'D':       /* -Dname -Dname=def */
622
        case 'U':       /* -Uname */
623
        case 'I':       /* -Idir */
624
                plist = append(arg, plist);
625
                return;
626
        case 'B':       /* -Bdir -Bstatic -Bdynamic */
627
#ifdef sparc
628
                if (strcmp(arg, "-Bstatic") == 0 || strcmp(arg, "-Bdynamic") == 0)
629
                        llist[1] = append(arg, llist[1]);
630
                else
631
#endif  
632
                {
633
                static char *path;
634
                if (path)
635
                        error("-B overwrites earlier option", 0);
636
                path = arg + 2;
637
                if (strstr(com[1], "win32") != NULL)
638
                        com[0] = concat(replace(path, '/', '\\'), concat("rcc", first(suffixes[4])));
639
                else
640
                        com[0] = concat(path, "rcc");
641
                if (path[0] == 0)
642
                        error("missing directory in -B option", 0);
643
                }
644
                return;
645
        case 'h':
646
                if (strcmp(arg, "-help") == 0) {
647
                        static int printed = 0;
648
        case '?':
649
                        if (!printed)
650
                                help();
651
                        printed = 1;
652
                        return;
653
                }
654
                break;
655
        case 's':
656
                if (strcmp(arg, "-static") == 0) {
657
                        if (!option(arg))
658
                                fprintf(stderr, "%s: %s ignored\n", progname, arg);
659
                        return;
660
                }
661
                break;
662
        }
663
        if (arg[2] == 0)
664
                switch (arg[1]) {       /* single-character options */
665
                case 'S':
666
                        Sflag++;
667
                        return;
668
                case 'O':
669
                        fprintf(stderr, "%s: %s ignored\n", progname, arg);
670
                        return;
671
                case 'A': case 'n': case 'w': case 'P':
672
                        clist = append(arg, clist);
673
                        return;
674
                case 'g': case 'b':
675
                        if (option(arg))
676
                                clist = append(arg[1] == 'g' ? "-g2" : arg, clist);
677
                        else
678
                                fprintf(stderr, "%s: %s ignored\n", progname, arg);
679
                        return;
680
                case 'G':
681
                        if (option(arg)) {
682
                                clist = append("-g3", clist);
683
                                llist[0] = append("-N", llist[0]);
684
                        } else
685
                                fprintf(stderr, "%s: %s ignored\n", progname, arg);
686
                        return;
687
                case 'E':
688
                        Eflag++;
689
                        return;
690
                case 'c':
691
                        cflag++;
692
                        return;
693
                case 'M':
694
                        Eflag++;        /* -M implies -E */
695
                        plist = append(arg, plist);
696
                        return;
697
                case 'N':
698
                        if (strcmp(basepath(cpp[0]), "gcc-cpp") == 0)
699
                                plist = append("-nostdinc", plist);
700
                        include[0] = 0;
701
                        ilist = 0;
702
                        return;
703
                case 'v':
704
                        if (verbose++ == 0) {
705
                                if (strcmp(basepath(cpp[0]), "gcc-cpp") == 0)
706
                                        plist = append(arg, plist);
707
                                clist = append(arg, clist);
708
                                fprintf(stderr, "%s %s\n", progname, rcsid);
709
                        }
710
                        return;
711
                }
712
        if (cflag || Sflag || Eflag)
713
                fprintf(stderr, "%s: %s ignored\n", progname, arg);
714
        else
715
                llist[1] = append(arg, llist[1]);
716
}
717
 
718
/* path2list - convert a colon- or semicolon-separated list to a list */
719
static List path2list(const char *path) {
720
        List list = NULL;
721
        char sep = ':';
722
 
723
        if (path == NULL)
724
                return NULL;
725
        if (strchr(path, ';'))
726
                sep = ';';
727
        while (*path) {
728
                char *p, buf[512];
729
                if (p = strchr(path, sep)) {
730
                        assert(p - path < sizeof buf);
731
                        strncpy(buf, path, p - path);
732
                        buf[p-path] = '\0';
733
                } else {
734
                        assert(strlen(path) < sizeof buf);
735
                        strcpy(buf, path);
736
                }
737
                if (!find(buf, list))
738
                        list = append(strsave(buf), list);
739
                if (p == 0)
740
                        break;
741
                path = p + 1;
742
        }
743
        return list;
744
}
745
 
746
/* replace - copy str, then replace occurrences of from with to, return the copy */
747
char *replace(const char *str, int from, int to) {
748
        char *s = strsave(str), *p = s;
749
 
750
        for ( ; (p = strchr(p, from)) != NULL; p++)
751
                *p = to;
752
        return s;
753
}
754
 
755
/* rm - remove files in list */
756
static void rm(List list) {
757
        if (list) {
758
                List b = list;
759
                if (verbose)
760
                        fprintf(stderr, "rm");
761
                do {
762
                        if (verbose)
763
                                fprintf(stderr, " %s", b->str);
764
                        if (verbose < 2)
765
                                remove(b->str);
766
                } while ((b = b->link) != list);
767
                if (verbose)
768
                        fprintf(stderr, "\n");
769
        }
770
}
771
 
772
/* strsave - return a saved copy of string str */
773
char *strsave(const char *str) {
774
        return strcpy(alloc(strlen(str)+1), str);
775
}
776
 
777
/* stringf - format and return a string */
778
char *stringf(const char *fmt, ...) {
779
        char buf[1024];
780
        va_list ap;
781
        int n;
782
 
783
        va_start(ap, fmt);
784
        n = vsprintf(buf, fmt, ap);
785
        va_end(ap);
786
        return strsave(buf);
787
}
788
 
789
/* suffix - if one of tails[0..n-1] holds a proper suffix of name, return its index */
790
int suffix(char *name, char *tails[], int n) {
791
        int i, len = strlen(name);
792
 
793
        for (i = 0; i < n; i++) {
794
                char *s = tails[i], *t;
795
                for ( ; t = strchr(s, ';'); s = t + 1) {
796
                        int m = t - s;
797
                        if (len > m && strncmp(&name[len-m], s, m) == 0)
798
                                return i;
799
                }
800
                if (*s) {
801
                        int m = strlen(s);
802
                        if (len > m && strncmp(&name[len-m], s, m) == 0)
803
                                return i;
804
                }
805
        }
806
        return -1;
807
}
808
 
809
/* tempname - generate a temporary file name in tempdir with given suffix */
810
char *tempname(char *suffix) {
811
        static int n;
812
        char *name = stringf("%s/lcc%d%d%s", tempdir, getpid(), n++, suffix);
813
 
814
        if (strstr(com[1], "win32") != NULL)
815
                name = replace(name, '/', '\\');
816
        rmlist = append(name, rmlist);
817
        return name;
818
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.