diff options
author | Jack Palevich <jackpal@google.com> | 2009-05-05 10:34:09 -0700 |
---|---|---|
committer | Jack Palevich <jackpal@google.com> | 2009-05-05 10:34:09 -0700 |
commit | c197a79045d298929737ea53dd56d567f21ed8d2 (patch) | |
tree | d3a9498f6dd2603f285b5379f554534c87648c36 | |
parent | 59c0e7ea797dc846ea676d7c0db3cf7333bff3bb (diff) | |
download | lcc-c197a79045d298929737ea53dd56d567f21ed8d2.tar.gz |
Configure lcc to run for both Linux and OSX
Currently builds x86/linux executables. This means that the full compile
doesn't work on OSX, it errors when the Linux-style assembly is assembled with the
Darwin "as" tool. But the first two steps, "lcc-cpp" and "lcc-rcc" work fine on OSX.
-rw-r--r-- | Android.mk | 150 | ||||
-rwxr-xr-x | etc/darwin.c | 89 | ||||
-rw-r--r-- | etc/get_my_path.h | 19 | ||||
-rw-r--r-- | etc/get_my_path_darwin.c | 31 | ||||
-rw-r--r-- | etc/get_my_path_linux.c | 35 | ||||
-rw-r--r-- | etc/get_my_path_windows.c | 34 | ||||
-rwxr-xr-x | etc/lcc.c | 1283 | ||||
-rwxr-xr-x | etc/linux.c | 117 |
8 files changed, 1074 insertions, 684 deletions
diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..d09df40 --- /dev/null +++ b/Android.mk @@ -0,0 +1,150 @@ +# +# Copyright 2009 The Android Open Source Project +# +# Android.mk for building the lcc compiler for arm. +# + + +BUILD_LCC := false +ifneq ($(TARGET_SIMULATOR),true) # not 64 bit clean + +ifeq ($(HOST_OS),darwin) + BUILD_LCC := true +endif + +ifeq ($(HOST_OS),linux) + BUILD_LCC := true +endif + +endif # TARGET_SIMULATOR + +ifeq ($(BUILD_LCC),true) + +TOP_LOCAL_PATH:= $(call my-dir) + +# Build lburg + +LOCAL_PATH:= $(TOP_LOCAL_PATH)/lburg +include $(CLEAR_VARS) + +LOCAL_MODULE := lcc-lburg + +LOCAL_SRC_FILES := \ + gram.c \ + lburg.c + +include $(BUILD_HOST_EXECUTABLE) + +LLC_LBURG:=$(LOCAL_BUILT_MODULE) + +# Build cpp + +LOCAL_PATH:= $(TOP_LOCAL_PATH)/cpp +include $(CLEAR_VARS) + +LOCAL_MODULE := lcc-cpp + +LOCAL_SRC_FILES := \ + cpp.c \ + eval.c \ + getopt.c \ + hideset.c \ + include.c \ + lex.c \ + macro.c \ + nlist.c \ + tokens.c \ + unix.c + +include $(BUILD_HOST_EXECUTABLE) + +# Build rcc + +LOCAL_PATH := $(TOP_LOCAL_PATH)/src +include $(CLEAR_VARS) + +LOCAL_MODULE := lcc-rcc + +# These two symbols are normally defined by BUILD_XXX, but we need to define them +# here so that local-intermediates-dir works. + +LOCAL_IS_HOST_MODULE := true +LOCAL_MODULE_CLASS := EXECUTABLES + +intermediates:= $(local-intermediates-dir)/ir +GEN := $(addprefix $(intermediates)/, \ + dagcheck.c \ + alpha.c \ + mips.c \ + sparc.c \ + x86.c \ + x86linux.c \ + ) +$(GEN): PRIVATE_CUSTOM_TOOL = $(LLC_LBURG) $< > $@ +$(GEN): $(LLC_LBURG) +$(GEN): $(intermediates)/%.c : $(LOCAL_PATH)/%.md + $(transform-generated-source) +LOCAL_GENERATED_SOURCES += $(GEN) + +LOCAL_SRC_FILES := \ + alloc.c \ + bind.c \ + dag.c \ + decl.c \ + enode.c \ + error.c \ + expr.c \ + event.c \ + init.c \ + inits.c \ + input.c \ + lex.c \ + list.c \ + main.c \ + output.c \ + prof.c \ + profio.c \ + simp.c \ + stmt.c \ + string.c \ + sym.c \ + trace.c \ + tree.c \ + types.c \ + null.c \ + symbolic.c \ + bytecode.c \ + gen.c \ + stab.c \ + +include $(BUILD_HOST_EXECUTABLE) + +# Build lcc + +LOCAL_PATH:= $(TOP_LOCAL_PATH)/etc +include $(CLEAR_VARS) + +LOCAL_MODULE := lcc + +LOCAL_SRC_FILES := \ + lcc.c + +ifeq ($(HOST_OS),darwin) + LOCAL_LDLIBS += -framework Carbon + + LOCAL_SRC_FILES += \ + darwin.c \ + get_my_path_darwin.c +endif + +ifeq ($(HOST_OS),linux) + + LOCAL_SRC_FILES += \ + linux.c \ + get_my_path_linux.c +endif + + +include $(BUILD_HOST_EXECUTABLE) + +endif # BUILD_LCC diff --git a/etc/darwin.c b/etc/darwin.c new file mode 100755 index 0000000..53eae83 --- /dev/null +++ b/etc/darwin.c @@ -0,0 +1,89 @@ +/* x86s running Linux */ + +#include <string.h> +#include "get_my_path.h" + +static char cppPath[PATH_MAX]; +static char rccPath[PATH_MAX]; + +static const char cppBase[] = "lcc-cpp"; +static const char rccBase[] = "lcc-rcc"; + +#define LCCDIR "/usr/bin" + +char *suffixes[] = { ".c", ".i", ".s", ".o", ".out", 0 }; +char inputs[256] = ""; +char *cpp[] = { cppPath, + "-U__GNUC__", "-D_POSIX_SOURCE", "-D__STDC__=1", "-D__STRICT_ANSI__", + "-Dunix", "-Di386", "-Dlinux", + "-D__unix__", "-D__i386__", "-D__linux__", "-D__signed__=signed", + "$1", "$2", "$3", 0 }; +char *include[] = {"-I" LCCDIR "include", "-I" LCCDIR "gcc/include", "-I/usr/include", 0 }; +char *com[] = {rccPath, "-target=x86/linux", "$1", "$2", "$3", 0 }; +char *as[] = { "/usr/bin/as", "-o", "$3", "$1", "$2", 0 }; +char *ld[] = { + /* 0 */ "/usr/bin/ld", "-m", "elf_i386", "-dynamic-linker", + /* 4 */ "/lib/ld-linux.so.2", "-o", "$3", + /* 7 */ "/usr/lib/crt1.o", "/usr/lib/crti.o", + /* 9 */ LCCDIR "/gcc/crtbegin.o", + "$1", "$2", + /* 12 */ "-L" LCCDIR, + /* 13 */ "-llcc", + /* 14 */ "-L" LCCDIR "/gcc", "-lgcc", "-lc", "-lm", + /* 18 */ "", + /* 19 */ LCCDIR "/gcc/crtend.o", "/usr/lib/crtn.o", + 0 }; + +extern char *concat(char *, char *); + +int option(char *arg) { + if (strncmp(arg, "-lccdir=", 8) == 0) { + cpp[0] = concat(&arg[8], "/gcc/cpp"); + include[0] = concat("-I", concat(&arg[8], "/include")); + include[1] = concat("-I", concat(&arg[8], "/gcc/include")); + ld[9] = concat(&arg[8], "/gcc/crtbegin.o"); + ld[12] = concat("-L", &arg[8]); + ld[14] = concat("-L", concat(&arg[8], "/gcc")); + ld[19] = concat(&arg[8], "/gcc/crtend.o"); + com[0] = concat(&arg[8], "/rcc"); + } else if (strcmp(arg, "-p") == 0 || strcmp(arg, "-pg") == 0) { + ld[7] = "/usr/lib/gcrt1.o"; + ld[18] = "-lgmon"; + } else if (strcmp(arg, "-b") == 0) + ; + else if (strcmp(arg, "-g") == 0) + ; + else if (strncmp(arg, "-ld=", 4) == 0) + ld[0] = &arg[4]; + else if (strcmp(arg, "-static") == 0) { + ld[3] = "-static"; + ld[4] = ""; + } else + return 0; + return 1; +} + +static void combine(char* dest, size_t destSize, const char* a, const char* b) { + if (destSize < 1) { + return; + } + size_t aLen = strlen(a); + size_t bLen = strlen(b); + if (aLen + bLen > destSize-1) { + dest[0] = 0; + return; + } + memcpy(dest, a, aLen); + memcpy(dest + aLen, b, bLen + 1); +} + +void platform_init() { + char myDir[PATH_MAX]; + get_my_path(myDir); + char* lastSlash = strrchr(myDir, '/'); + if (lastSlash != NULL) { + lastSlash[1] = '\0'; + combine(cppPath, PATH_MAX, myDir, cppBase); + combine(rccPath, PATH_MAX, myDir, rccBase); + } +} diff --git a/etc/get_my_path.h b/etc/get_my_path.h new file mode 100644 index 0000000..d9c9870 --- /dev/null +++ b/etc/get_my_path.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <limits.h> + +void get_my_path(char exe[PATH_MAX]); diff --git a/etc/get_my_path_darwin.c b/etc/get_my_path_darwin.c new file mode 100644 index 0000000..0ea0364 --- /dev/null +++ b/etc/get_my_path_darwin.c @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "get_my_path.h" +#import <Carbon/Carbon.h> +#include <unistd.h> + +void get_my_path(char s[PATH_MAX]) +{ + ProcessSerialNumber psn; + GetCurrentProcess(&psn); + CFDictionaryRef dict; + dict = ProcessInformationCopyDictionary(&psn, 0xffffffff); + CFStringRef value = (CFStringRef)CFDictionaryGetValue(dict, + CFSTR("CFBundleExecutable")); + CFStringGetCString(value, s, PATH_MAX - 1, kCFStringEncodingUTF8); +} + diff --git a/etc/get_my_path_linux.c b/etc/get_my_path_linux.c new file mode 100644 index 0000000..c455a24 --- /dev/null +++ b/etc/get_my_path_linux.c @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "get_my_path.h" +#include <sys/types.h> +#include <unistd.h> +#include <limits.h> +#include <stdio.h> + +void get_my_path(char exe[PATH_MAX]) +{ + char proc[64]; + snprintf(proc, sizeof proc, "/proc/%d/exe", getpid()); + int err = readlink(proc, exe, PATH_MAX - 1); + if(err > 0) { + exe[err] = 0; + } else { + exe[0] = 0; + } +} + diff --git a/etc/get_my_path_windows.c b/etc/get_my_path_windows.c new file mode 100644 index 0000000..22c6323 --- /dev/null +++ b/etc/get_my_path_windows.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "get_my_path.h" + +#include <limits.h> +#include <assert.h> +#include <windows.h> + +void get_my_path(char exe[PATH_MAX]) +{ + char* r; + + GetModuleFileName( NULL, exe, PATH_MAX-1 ); + exe[PATH_MAX-1] = 0; + r = strrchr( exe, '\\' ); + if (r) + *r = 0; +} + @@ -17,9 +17,9 @@ static char rcsid[] = "$Id: lcc.c 355 2007-02-18 22:08:49Z drh $"; #endif typedef struct list *List; -struct list { /* circular list nodes: */ - char *str; /* option or file name */ - List link; /* next list element */ +struct list { /* circular list nodes: */ + char *str; /* option or file name */ + List link; /* next list element */ }; static void *alloc(int); @@ -52,163 +52,166 @@ extern int getpid(void); extern char *cpp[], *include[], *com[], *as[],*ld[], inputs[], *suffixes[]; extern int option(char *); - -static int errcnt; /* number of errors */ -static int Eflag; /* -E specified */ -static int Sflag; /* -S specified */ -static int cflag; /* -c specified */ -static int verbose; /* incremented for each -v */ -static List llist[2]; /* loader files, flags */ -static List alist; /* assembler flags */ -static List clist; /* compiler flags */ -static List plist; /* preprocessor flags */ -static List ilist; /* list of additional includes from LCCINPUTS */ -static List rmlist; /* list of files to remove */ -static char *outfile; /* ld output file or -[cS] object file */ -static int ac; /* argument count */ -static char **av; /* argument vector */ -char *tempdir = TEMPDIR; /* directory for temporary files */ +extern void platform_init(); + +static int errcnt; /* number of errors */ +static int Eflag; /* -E specified */ +static int Sflag; /* -S specified */ +static int cflag; /* -c specified */ +static int verbose; /* incremented for each -v */ +static List llist[2]; /* loader files, flags */ +static List alist; /* assembler flags */ +static List clist; /* compiler flags */ +static List plist; /* preprocessor flags */ +static List ilist; /* list of additional includes from LCCINPUTS */ +static List rmlist; /* list of files to remove */ +static char *outfile; /* ld output file or -[cS] object file */ +static int ac; /* argument count */ +static char **av; /* argument vector */ +char *tempdir = TEMPDIR; /* directory for temporary files */ static char *progname; -static List lccinputs; /* list of input directories */ +static List lccinputs; /* list of input directories */ main(int argc, char *argv[]) { - int i, j, nf; - - progname = argv[0]; - ac = argc + 50; - av = alloc(ac*sizeof(char *)); - if (signal(SIGINT, SIG_IGN) != SIG_IGN) - signal(SIGINT, interrupt); - if (signal(SIGTERM, SIG_IGN) != SIG_IGN) - signal(SIGTERM, interrupt); + int i, j, nf; + + platform_init(); + + progname = argv[0]; + ac = argc + 50; + av = alloc(ac*sizeof(char *)); + if (signal(SIGINT, SIG_IGN) != SIG_IGN) + signal(SIGINT, interrupt); + if (signal(SIGTERM, SIG_IGN) != SIG_IGN) + signal(SIGTERM, interrupt); #ifdef SIGHUP - if (signal(SIGHUP, SIG_IGN) != SIG_IGN) - signal(SIGHUP, interrupt); + if (signal(SIGHUP, SIG_IGN) != SIG_IGN) + signal(SIGHUP, interrupt); #endif - if (getenv("TMP")) - tempdir = getenv("TMP"); - else if (getenv("TEMP")) - tempdir = getenv("TEMP"); - else if (getenv("TMPDIR")) - tempdir = getenv("TMPDIR"); - assert(tempdir); - i = strlen(tempdir); - for (; i > 0 && tempdir[i-1] == '/' || tempdir[i-1] == '\\'; i--) - tempdir[i-1] = '\0'; - if (argc <= 1) { - help(); - exit(0); - } - plist = append("-D__LCC__", 0); - initinputs(); - if (getenv("LCCDIR")) - option(stringf("-lccdir=%s", getenv("LCCDIR"))); - for (nf = 0, i = j = 1; i < argc; i++) { - if (strcmp(argv[i], "-o") == 0) { - if (++i < argc) { - if (suffix(argv[i], suffixes, 2) >= 0) { - error("-o would overwrite %s", argv[i]); - exit(8); - } - outfile = argv[i]; - continue; - } else { - error("unrecognized option `%s'", argv[i-1]); - exit(8); - } - } else if (strcmp(argv[i], "-target") == 0) { - if (argv[i+1] && *argv[i+1] != '-') - i++; - continue; - } else if (*argv[i] == '-' && argv[i][1] != 'l') { - opt(argv[i]); - continue; - } else if (*argv[i] != '-' && suffix(argv[i], suffixes, 3) >= 0) - nf++; - argv[j++] = argv[i]; - } - if ((cflag || Sflag) && outfile && nf != 1) { - fprintf(stderr, "%s: -o %s ignored\n", progname, outfile); - outfile = 0; - } - argv[j] = 0; - for (i = 0; include[i]; i++) - plist = append(include[i], plist); - if (ilist) { - List b = ilist; - do { - b = b->link; - plist = append(b->str, plist); - } while (b != ilist); - } - ilist = 0; - for (i = 1; argv[i]; i++) - if (strcmp(argv[i], "-l") == 0 && argv[i+1] && *argv[i+1] != '-') { /* -l file */ - llist[1] = append(argv[i++], llist[1]); - llist[1] = append(argv[i], llist[1]); - } else if (*argv[i] == '-') - opt(argv[i]); - else { - char *name = exists(argv[i]); - if (name) { - if (strcmp(name, argv[i]) != 0 - || nf > 1 && suffix(name, suffixes, 3) >= 0) - fprintf(stderr, "%s:\n", name); - filename(name, 0); - } else - error("can't find `%s'", argv[i]); - } - if (errcnt == 0 && !Eflag && !Sflag && !cflag && llist[1]) { - compose(ld, llist[0], llist[1], - append(outfile ? outfile : concat("a", first(suffixes[4])), 0)); - if (callsys(av)) - errcnt++; - } - rm(rmlist); - return errcnt ? EXIT_FAILURE : EXIT_SUCCESS; + if (getenv("TMP")) + tempdir = getenv("TMP"); + else if (getenv("TEMP")) + tempdir = getenv("TEMP"); + else if (getenv("TMPDIR")) + tempdir = getenv("TMPDIR"); + assert(tempdir); + i = strlen(tempdir); + for (; i > 0 && tempdir[i-1] == '/' || tempdir[i-1] == '\\'; i--) + tempdir[i-1] = '\0'; + if (argc <= 1) { + help(); + exit(0); + } + plist = append("-D__LCC__", 0); + initinputs(); + if (getenv("LCCDIR")) + option(stringf("-lccdir=%s", getenv("LCCDIR"))); + for (nf = 0, i = j = 1; i < argc; i++) { + if (strcmp(argv[i], "-o") == 0) { + if (++i < argc) { + if (suffix(argv[i], suffixes, 2) >= 0) { + error("-o would overwrite %s", argv[i]); + exit(8); + } + outfile = argv[i]; + continue; + } else { + error("unrecognized option `%s'", argv[i-1]); + exit(8); + } + } else if (strcmp(argv[i], "-target") == 0) { + if (argv[i+1] && *argv[i+1] != '-') + i++; + continue; + } else if (*argv[i] == '-' && argv[i][1] != 'l') { + opt(argv[i]); + continue; + } else if (*argv[i] != '-' && suffix(argv[i], suffixes, 3) >= 0) + nf++; + argv[j++] = argv[i]; + } + if ((cflag || Sflag) && outfile && nf != 1) { + fprintf(stderr, "%s: -o %s ignored\n", progname, outfile); + outfile = 0; + } + argv[j] = 0; + for (i = 0; include[i]; i++) + plist = append(include[i], plist); + if (ilist) { + List b = ilist; + do { + b = b->link; + plist = append(b->str, plist); + } while (b != ilist); + } + ilist = 0; + for (i = 1; argv[i]; i++) + if (strcmp(argv[i], "-l") == 0 && argv[i+1] && *argv[i+1] != '-') { /* -l file */ + llist[1] = append(argv[i++], llist[1]); + llist[1] = append(argv[i], llist[1]); + } else if (*argv[i] == '-') + opt(argv[i]); + else { + char *name = exists(argv[i]); + if (name) { + if (strcmp(name, argv[i]) != 0 + || nf > 1 && suffix(name, suffixes, 3) >= 0) + fprintf(stderr, "%s:\n", name); + filename(name, 0); + } else + error("can't find `%s'", argv[i]); + } + if (errcnt == 0 && !Eflag && !Sflag && !cflag && llist[1]) { + compose(ld, llist[0], llist[1], + append(outfile ? outfile : concat("a", first(suffixes[4])), 0)); + if (callsys(av)) + errcnt++; + } + rm(rmlist); + return errcnt ? EXIT_FAILURE : EXIT_SUCCESS; } /* alloc - allocate n bytes or die */ static void *alloc(int n) { - static char *avail, *limit; - - n = (n + sizeof(char *) - 1)&~(sizeof(char *) - 1); - if (n >= limit - avail) { - avail = malloc(n + 4*1024); - assert(avail); - limit = avail + n + 4*1024; - } - avail += n; - return avail - n; + static char *avail, *limit; + + n = (n + sizeof(char *) - 1)&~(sizeof(char *) - 1); + if (n >= limit - avail) { + avail = malloc(n + 4*1024); + assert(avail); + limit = avail + n + 4*1024; + } + avail += n; + return avail - n; } -/* append - append a node with string str onto list, return new list */ +/* append - append a node with string str onto list, return new list */ static List append(char *str, List list) { - List p = alloc(sizeof *p); - - p->str = str; - if (list) { - p->link = list->link; - list->link = p; - } else - p->link = p; - return p; + List p = alloc(sizeof *p); + + p->str = str; + if (list) { + p->link = list->link; + list->link = p; + } else + p->link = p; + return p; } /* basepath - return base name for name, e.g. /usr/drh/foo.c => foo */ char *basepath(char *name) { - char *s, *b, *t = 0; - - for (b = s = name; *s; s++) - if (*s == '/' || *s == '\\') { - b = s + 1; - t = 0; - } else if (*s == '.') - t = s; - s = strsave(b); - if (t) - s[t-b] = 0; - return s; + char *s, *b, *t = 0; + + for (b = s = name; *s; s++) + if (*s == '/' || *s == '\\') { + b = s + 1; + t = 0; + } else if (*s == '.') + t = s; + s = strsave(b); + if (t) + s[t-b] = 0; + return s; } #ifdef WIN32 @@ -220,599 +223,599 @@ extern int wait(int *); extern void execv(const char *, char *[]); static int _spawnvp(int mode, const char *cmdname, const char *const argv[]) { - int pid, n, status; - - switch (pid = fork()) { - case -1: - fprintf(stderr, "%s: no more processes\n", progname); - return 100; - case 0: - execv(cmdname, (char **)argv); - fprintf(stderr, "%s: ", progname); - perror(cmdname); - fflush(stdout); - exit(100); - } - while ((n = wait(&status)) != pid && n != -1) - ; - if (n == -1) - status = -1; - if (status&0377) { - fprintf(stderr, "%s: fatal error in %s\n", progname, cmdname); - status |= 0400; - } - return (status>>8)&0377; + int pid, n, status; + + switch (pid = fork()) { + case -1: + fprintf(stderr, "%s: no more processes\n", progname); + return 100; + case 0: + execv(cmdname, (char **)argv); + fprintf(stderr, "%s: ", progname); + perror(cmdname); + fflush(stdout); + exit(100); + } + while ((n = wait(&status)) != pid && n != -1) + ; + if (n == -1) + status = -1; + if (status&0377) { + fprintf(stderr, "%s: fatal error in %s\n", progname, cmdname); + status |= 0400; + } + return (status>>8)&0377; } #endif /* callsys - execute the command described by av[0...], return status */ static int callsys(char **av) { - int i, status = 0; - static char **argv; - static int argc; - - for (i = 0; av[i] != NULL; i++) - ; - if (i + 1 > argc) { - argc = i + 1; - if (argv == NULL) - argv = malloc(argc*sizeof *argv); - else - argv = realloc(argv, argc*sizeof *argv); - assert(argv); - } - for (i = 0; status == 0 && av[i] != NULL; ) { - int j = 0; - char *s; - for ( ; av[i] != NULL && (s = strchr(av[i], '\n')) == NULL; i++) - argv[j++] = av[i]; - if (s != NULL) { - if (s > av[i]) - argv[j++] = stringf("%.*s", s - av[i], av[i]); - if (s[1] != '\0') - av[i] = s + 1; - else - i++; - } - argv[j] = NULL; - if (verbose > 0) { - int k; - fprintf(stderr, "%s", argv[0]); - for (k = 1; argv[k] != NULL; k++) - fprintf(stderr, " %s", argv[k]); - fprintf(stderr, "\n"); - } - if (verbose < 2) - status = _spawnvp(_P_WAIT, argv[0], (const char * const *)argv); - if (status == -1) { - fprintf(stderr, "%s: ", progname); - perror(argv[0]); - } - } - return status; + int i, status = 0; + static char **argv; + static int argc; + + for (i = 0; av[i] != NULL; i++) + ; + if (i + 1 > argc) { + argc = i + 1; + if (argv == NULL) + argv = malloc(argc*sizeof *argv); + else + argv = realloc(argv, argc*sizeof *argv); + assert(argv); + } + for (i = 0; status == 0 && av[i] != NULL; ) { + int j = 0; + char *s; + for ( ; av[i] != NULL && (s = strchr(av[i], '\n')) == NULL; i++) + argv[j++] = av[i]; + if (s != NULL) { + if (s > av[i]) + argv[j++] = stringf("%.*s", s - av[i], av[i]); + if (s[1] != '\0') + av[i] = s + 1; + else + i++; + } + argv[j] = NULL; + if (verbose > 0) { + int k; + fprintf(stderr, "%s", argv[0]); + for (k = 1; argv[k] != NULL; k++) + fprintf(stderr, " %s", argv[k]); + fprintf(stderr, "\n"); + } + if (verbose < 2) + status = _spawnvp(_P_WAIT, argv[0], (const char * const *)argv); + if (status == -1) { + fprintf(stderr, "%s: ", progname); + perror(argv[0]); + } + } + return status; } /* concat - return concatenation of strings s1 and s2 */ char *concat(char *s1, char *s2) { - int n = strlen(s1); - char *s = alloc(n + strlen(s2) + 1); + int n = strlen(s1); + char *s = alloc(n + strlen(s2) + 1); - strcpy(s, s1); - strcpy(s + n, s2); - return s; + strcpy(s, s1); + strcpy(s + n, s2); + return s; } /* compile - compile src into dst, return status */ static int compile(char *src, char *dst) { - compose(com, clist, append(src, 0), append(dst, 0)); - return callsys(av); + compose(com, clist, append(src, 0), append(dst, 0)); + return callsys(av); } /* compose - compose cmd into av substituting a, b, c for $1, $2, $3, resp. */ static void compose(char *cmd[], List a, List b, List c) { - int i, j; - List lists[3]; - - lists[0] = a; - lists[1] = b; - lists[2] = c; - for (i = j = 0; cmd[i]; i++) { - char *s = strchr(cmd[i], '$'); - if (s && isdigit(s[1])) { - int k = s[1] - '0'; - assert(k >=1 && k <= 3); - if (b = lists[k-1]) { - b = b->link; - av[j] = alloc(strlen(cmd[i]) + strlen(b->str) - 1); - strncpy(av[j], cmd[i], s - cmd[i]); - av[j][s-cmd[i]] = '\0'; - strcat(av[j], b->str); - strcat(av[j++], s + 2); - while (b != lists[k-1]) { - b = b->link; - assert(j < ac); - av[j++] = b->str; - }; - } - } else if (*cmd[i]) { - assert(j < ac); - av[j++] = cmd[i]; - } - } - av[j] = NULL; + int i, j; + List lists[3]; + + lists[0] = a; + lists[1] = b; + lists[2] = c; + for (i = j = 0; cmd[i]; i++) { + char *s = strchr(cmd[i], '$'); + if (s && isdigit(s[1])) { + int k = s[1] - '0'; + assert(k >=1 && k <= 3); + if (b = lists[k-1]) { + b = b->link; + av[j] = alloc(strlen(cmd[i]) + strlen(b->str) - 1); + strncpy(av[j], cmd[i], s - cmd[i]); + av[j][s-cmd[i]] = '\0'; + strcat(av[j], b->str); + strcat(av[j++], s + 2); + while (b != lists[k-1]) { + b = b->link; + assert(j < ac); + av[j++] = b->str; + }; + } + } else if (*cmd[i]) { + assert(j < ac); + av[j++] = cmd[i]; + } + } + av[j] = NULL; } /* error - issue error msg according to fmt, bump error count */ static void error(char *fmt, char *msg) { - fprintf(stderr, "%s: ", progname); - fprintf(stderr, fmt, msg); - fprintf(stderr, "\n"); - errcnt++; + fprintf(stderr, "%s: ", progname); + fprintf(stderr, fmt, msg); + fprintf(stderr, "\n"); + errcnt++; } /* exists - if `name' readable return its path name or return null */ static char *exists(char *name) { - List b; - - if ( (name[0] == '/' || name[0] == '\\' || name[2] == ':') - && access(name, 4) == 0) - return name; - if (!(name[0] == '/' || name[0] == '\\' || name[2] == ':') - && (b = lccinputs)) - do { - b = b->link; - if (b->str[0]) { - char buf[1024]; - sprintf(buf, "%s/%s", b->str, name); - if (access(buf, 4) == 0) - return strsave(buf); - } else if (access(name, 4) == 0) - return name; - } while (b != lccinputs); - if (verbose > 1) - return name; - return 0; + List b; + + if ( (name[0] == '/' || name[0] == '\\' || name[2] == ':') + && access(name, 4) == 0) + return name; + if (!(name[0] == '/' || name[0] == '\\' || name[2] == ':') + && (b = lccinputs)) + do { + b = b->link; + if (b->str[0]) { + char buf[1024]; + sprintf(buf, "%s/%s", b->str, name); + if (access(buf, 4) == 0) + return strsave(buf); + } else if (access(name, 4) == 0) + return name; + } while (b != lccinputs); + if (verbose > 1) + return name; + return 0; } /* first - return first component in semicolon separated list */ static char *first(char *list) { - char *s = strchr(list, ';'); - - if (s) { - char buf[1024]; - strncpy(buf, list, s-list); - buf[s-list] = '\0'; - return strsave(buf); - } else - return list; + char *s = strchr(list, ';'); + + if (s) { + char buf[1024]; + strncpy(buf, list, s-list); + buf[s-list] = '\0'; + return strsave(buf); + } else + return list; } /* filename - process file name argument `name', return status */ static int filename(char *name, char *base) { - int status = 0; - static char *stemp, *itemp; - - if (base == 0) - base = basepath(name); - switch (suffix(name, suffixes, 4)) { - case 0: /* C source files */ - compose(cpp, plist, append(name, 0), 0); - if (Eflag) { - status = callsys(av); - break; - } - if (itemp == NULL) - itemp = tempname(first(suffixes[1])); - compose(cpp, plist, append(name, 0), append(itemp, 0)); - status = callsys(av); - if (status == 0) - return filename(itemp, base); - break; - case 1: /* preprocessed source files */ - if (Eflag) - break; - if (Sflag) - status = compile(name, outfile ? outfile : concat(base, first(suffixes[2]))); - else if ((status = compile(name, stemp?stemp:(stemp=tempname(first(suffixes[2]))))) == 0) - return filename(stemp, base); - break; - case 2: /* assembly language files */ - if (Eflag) - break; - if (!Sflag) { - char *ofile; - if (cflag && outfile) - ofile = outfile; - else if (cflag) - ofile = concat(base, first(suffixes[3])); - else - ofile = tempname(first(suffixes[3])); - compose(as, alist, append(name, 0), append(ofile, 0)); - status = callsys(av); - if (!find(ofile, llist[1])) - llist[1] = append(ofile, llist[1]); - } - break; - case 3: /* object files */ - if (!find(name, llist[1])) - llist[1] = append(name, llist[1]); - break; - default: - if (Eflag) { - compose(cpp, plist, append(name, 0), 0); - status = callsys(av); - } - llist[1] = append(name, llist[1]); - break; - } - if (status) - errcnt++; - return status; + int status = 0; + static char *stemp, *itemp; + + if (base == 0) + base = basepath(name); + switch (suffix(name, suffixes, 4)) { + case 0: /* C source files */ + compose(cpp, plist, append(name, 0), 0); + if (Eflag) { + status = callsys(av); + break; + } + if (itemp == NULL) + itemp = tempname(first(suffixes[1])); + compose(cpp, plist, append(name, 0), append(itemp, 0)); + status = callsys(av); + if (status == 0) + return filename(itemp, base); + break; + case 1: /* preprocessed source files */ + if (Eflag) + break; + if (Sflag) + status = compile(name, outfile ? outfile : concat(base, first(suffixes[2]))); + else if ((status = compile(name, stemp?stemp:(stemp=tempname(first(suffixes[2]))))) == 0) + return filename(stemp, base); + break; + case 2: /* assembly language files */ + if (Eflag) + break; + if (!Sflag) { + char *ofile; + if (cflag && outfile) + ofile = outfile; + else if (cflag) + ofile = concat(base, first(suffixes[3])); + else + ofile = tempname(first(suffixes[3])); + compose(as, alist, append(name, 0), append(ofile, 0)); + status = callsys(av); + if (!find(ofile, llist[1])) + llist[1] = append(ofile, llist[1]); + } + break; + case 3: /* object files */ + if (!find(name, llist[1])) + llist[1] = append(name, llist[1]); + break; + default: + if (Eflag) { + compose(cpp, plist, append(name, 0), 0); + status = callsys(av); + } + llist[1] = append(name, llist[1]); + break; + } + if (status) + errcnt++; + return status; } /* find - find 1st occurrence of str in list, return list node or 0 */ static List find(char *str, List list) { - List b; - - if (b = list) - do { - if (strcmp(str, b->str) == 0) - return b; - } while ((b = b->link) != list); - return 0; + List b; + + if (b = list) + do { + if (strcmp(str, b->str) == 0) + return b; + } while ((b = b->link) != list); + return 0; } /* help - print help message */ static void help(void) { - static char *msgs[] = { + static char *msgs[] = { "", " [ option | file ]...\n", -" except for -l, options are processed left-to-right before files\n", -" unrecognized options are taken to be linker options\n", -"-A warn about nonANSI usage; 2nd -A warns more\n", -"-b emit expression-level profiling code; see bprint(1)\n", +" except for -l, options are processed left-to-right before files\n", +" unrecognized options are taken to be linker options\n", +"-A warn about nonANSI usage; 2nd -A warns more\n", +"-b emit expression-level profiling code; see bprint(1)\n", #ifdef sparc -"-Bstatic -Bdynamic specify static or dynamic libraries\n", +"-Bstatic -Bdynamic specify static or dynamic libraries\n", #endif -"-Bdir/ use the compiler named `dir/rcc'\n", -"-c compile only\n", -"-dn set switch statement density to `n'\n", -"-Dname -Dname=def define the preprocessor symbol `name'\n", -"-E run only the preprocessor on the named C programs and unsuffixed files\n", -"-g produce symbol table information for debuggers\n", -"-help or -? print this message on standard error\n", -"-Idir add `dir' to the beginning of the list of #include directories\n", -"-lx search library `x'\n", -"-M emit makefile dependencies; implies -E\n", -"-N do not search the standard directories for #include files\n", -"-n emit code to check for dereferencing zero pointers\n", -"-O is ignored\n", -"-o file leave the output in `file'\n", -"-P print ANSI-style declarations for globals on standard error\n", -"-p -pg emit profiling code; see prof(1) and gprof(1)\n", -"-S compile to assembly language\n", -"-static specify static libraries (default is dynamic)\n", -"-dynamic specify dynamically linked libraries\n", -"-t -tname emit function tracing calls to printf or to `name'\n", -"-target name is ignored\n", -"-tempdir=dir place temporary files in `dir/'", "\n" -"-Uname undefine the preprocessor symbol `name'\n", -"-v show commands as they are executed; 2nd -v suppresses execution\n", -"-w suppress warnings\n", -"-Woarg specify system-specific `arg'\n", -"-W[pfal]arg pass `arg' to the preprocessor, compiler, assembler, or linker\n", - 0 }; - int i; - char *s; - - msgs[0] = progname; - for (i = 0; msgs[i]; i++) { - fprintf(stderr, "%s", msgs[i]); - if (strncmp("-tempdir", msgs[i], 8) == 0 && tempdir) - fprintf(stderr, "; default=%s", tempdir); - } +"-Bdir/ use the compiler named `dir/rcc'\n", +"-c compile only\n", +"-dn set switch statement density to `n'\n", +"-Dname -Dname=def define the preprocessor symbol `name'\n", +"-E run only the preprocessor on the named C programs and unsuffixed files\n", +"-g produce symbol table information for debuggers\n", +"-help or -? print this message on standard error\n", +"-Idir add `dir' to the beginning of the list of #include directories\n", +"-lx search library `x'\n", +"-M emit makefile dependencies; implies -E\n", +"-N do not search the standard directories for #include files\n", +"-n emit code to check for dereferencing zero pointers\n", +"-O is ignored\n", +"-o file leave the output in `file'\n", +"-P print ANSI-style declarations for globals on standard error\n", +"-p -pg emit profiling code; see prof(1) and gprof(1)\n", +"-S compile to assembly language\n", +"-static specify static libraries (default is dynamic)\n", +"-dynamic specify dynamically linked libraries\n", +"-t -tname emit function tracing calls to printf or to `name'\n", +"-target name is ignored\n", +"-tempdir=dir place temporary files in `dir/'", "\n" +"-Uname undefine the preprocessor symbol `name'\n", +"-v show commands as they are executed; 2nd -v suppresses execution\n", +"-w suppress warnings\n", +"-Woarg specify system-specific `arg'\n", +"-W[pfal]arg pass `arg' to the preprocessor, compiler, assembler, or linker\n", + 0 }; + int i; + char *s; + + msgs[0] = progname; + for (i = 0; msgs[i]; i++) { + fprintf(stderr, "%s", msgs[i]); + if (strncmp("-tempdir", msgs[i], 8) == 0 && tempdir) + fprintf(stderr, "; default=%s", tempdir); + } #define xx(v) if (s = getenv(#v)) fprintf(stderr, #v "=%s\n", s) - xx(LCCINPUTS); - xx(LCCDIR); + xx(LCCINPUTS); + xx(LCCDIR); #ifdef WIN32 - xx(include); - xx(lib); + xx(include); + xx(lib); #endif #undef xx } /* initinputs - if LCCINPUTS or include is defined, use them to initialize various lists */ static void initinputs(void) { - char *s = getenv("LCCINPUTS"); - List list, b; - - if (s == 0 && (s = inputs)[0] == 0) - s = "."; - if (s) { - lccinputs = path2list(s); - if (b = lccinputs) - do { - b = b->link; - if (strcmp(b->str, ".") != 0) { - ilist = append(concat("-I", b->str), ilist); - if (strstr(com[1], "win32") == NULL) - llist[0] = append(concat("-L", b->str), llist[0]); - } else - b->str = ""; - } while (b != lccinputs); - } + char *s = getenv("LCCINPUTS"); + List list, b; + + if (s == 0 && (s = inputs)[0] == 0) + s = "."; + if (s) { + lccinputs = path2list(s); + if (b = lccinputs) + do { + b = b->link; + if (strcmp(b->str, ".") != 0) { + ilist = append(concat("-I", b->str), ilist); + if (strstr(com[1], "win32") == NULL) + llist[0] = append(concat("-L", b->str), llist[0]); + } else + b->str = ""; + } while (b != lccinputs); + } #ifdef WIN32 - if (list = b = path2list(getenv("include"))) - do { - int n; - b = b->link; - n = strlen(b->str); - if (b->str[n-1] == '\\') - b->str[n-1] = '/'; - ilist = append(stringf("-I\"%s\"", b->str), ilist); - } while (b != list); + if (list = b = path2list(getenv("include"))) + do { + int n; + b = b->link; + n = strlen(b->str); + if (b->str[n-1] == '\\') + b->str[n-1] = '/'; + ilist = append(stringf("-I\"%s\"", b->str), ilist); + } while (b != list); #endif } /* interrupt - catch interrupt signals */ static void interrupt(int n) { - rm(rmlist); - exit(n = 100); + rm(rmlist); + exit(n = 100); } /* opt - process option in arg */ static void opt(char *arg) { - switch (arg[1]) { /* multi-character options */ - case 'W': /* -Wxarg */ - if (arg[2] && arg[3]) - switch (arg[2]) { - case 'o': - if (option(&arg[3])) - return; - break; - case 'p': - plist = append(&arg[3], plist); - return; - case 'f': - if (strcmp(&arg[3], "-C") == 0 && !option("-b")) - break; /* -C requires that -b is supported */ - clist = append(&arg[3], clist); - if (strcmp(&arg[3], "-unsigned_char=1") == 0) { - plist = append("-D__CHAR_UNSIGNED__", plist); - plist = append("-U_CHAR_IS_SIGNED", plist); - } + switch (arg[1]) { /* multi-character options */ + case 'W': /* -Wxarg */ + if (arg[2] && arg[3]) + switch (arg[2]) { + case 'o': + if (option(&arg[3])) + return; + break; + case 'p': + plist = append(&arg[3], plist); + return; + case 'f': + if (strcmp(&arg[3], "-C") == 0 && !option("-b")) + break; /* -C requires that -b is supported */ + clist = append(&arg[3], clist); + if (strcmp(&arg[3], "-unsigned_char=1") == 0) { + plist = append("-D__CHAR_UNSIGNED__", plist); + plist = append("-U_CHAR_IS_SIGNED", plist); + } #define xx(name,k) \ - if (strcmp(&arg[3], "-wchar_t=" #name) == 0) \ - plist = append("-D_WCHAR_T_SIZE=" #k, plist); + if (strcmp(&arg[3], "-wchar_t=" #name) == 0) \ + plist = append("-D_WCHAR_T_SIZE=" #k, plist); xx(unsigned_char,1) xx(unsigned_short,2) xx(unsigned_int,4) #undef xx - return; - case 'a': - alist = append(&arg[3], alist); - return; - case 'l': - llist[0] = append(&arg[3], llist[0]); - return; - } - fprintf(stderr, "%s: %s ignored\n", progname, arg); - return; - case 'd': /* -dn -dynamic */ - if (strcmp(arg, "-dynamic") == 0) { - if (!option(arg)) - fprintf(stderr, "%s: %s ignored\n", progname, arg); - } else { - arg[1] = 's'; - clist = append(arg, clist); - } - return; - case 't': /* -t -tname -tempdir=dir */ - if (strncmp(arg, "-tempdir=", 9) == 0) - tempdir = arg + 9; - else - clist = append(arg, clist); - return; - case 'p': /* -p -pg */ - if (option(arg)) - clist = append(arg, clist); - else - fprintf(stderr, "%s: %s ignored\n", progname, arg); - return; - case 'D': /* -Dname -Dname=def */ - case 'U': /* -Uname */ - case 'I': /* -Idir */ - plist = append(arg, plist); - return; - case 'B': /* -Bdir -Bstatic -Bdynamic */ + return; + case 'a': + alist = append(&arg[3], alist); + return; + case 'l': + llist[0] = append(&arg[3], llist[0]); + return; + } + fprintf(stderr, "%s: %s ignored\n", progname, arg); + return; + case 'd': /* -dn -dynamic */ + if (strcmp(arg, "-dynamic") == 0) { + if (!option(arg)) + fprintf(stderr, "%s: %s ignored\n", progname, arg); + } else { + arg[1] = 's'; + clist = append(arg, clist); + } + return; + case 't': /* -t -tname -tempdir=dir */ + if (strncmp(arg, "-tempdir=", 9) == 0) + tempdir = arg + 9; + else + clist = append(arg, clist); + return; + case 'p': /* -p -pg */ + if (option(arg)) + clist = append(arg, clist); + else + fprintf(stderr, "%s: %s ignored\n", progname, arg); + return; + case 'D': /* -Dname -Dname=def */ + case 'U': /* -Uname */ + case 'I': /* -Idir */ + plist = append(arg, plist); + return; + case 'B': /* -Bdir -Bstatic -Bdynamic */ #ifdef sparc - if (strcmp(arg, "-Bstatic") == 0 || strcmp(arg, "-Bdynamic") == 0) - llist[1] = append(arg, llist[1]); - else -#endif - { - static char *path; - if (path) - error("-B overwrites earlier option", 0); - path = arg + 2; - if (strstr(com[1], "win32") != NULL) - com[0] = concat(replace(path, '/', '\\'), concat("rcc", first(suffixes[4]))); - else - com[0] = concat(path, "rcc"); - if (path[0] == 0) - error("missing directory in -B option", 0); - } - return; - case 'h': - if (strcmp(arg, "-help") == 0) { - static int printed = 0; - case '?': - if (!printed) - help(); - printed = 1; - return; - } - break; - case 's': - if (strcmp(arg, "-static") == 0) { - if (!option(arg)) - fprintf(stderr, "%s: %s ignored\n", progname, arg); - return; - } - break; - } - if (arg[2] == 0) - switch (arg[1]) { /* single-character options */ - case 'S': - Sflag++; - return; - case 'O': - fprintf(stderr, "%s: %s ignored\n", progname, arg); - return; - case 'A': case 'n': case 'w': case 'P': - clist = append(arg, clist); - return; - case 'g': case 'b': - if (option(arg)) - clist = append(arg[1] == 'g' ? "-g2" : arg, clist); - else - fprintf(stderr, "%s: %s ignored\n", progname, arg); - return; - case 'G': - if (option(arg)) { - clist = append("-g3", clist); - llist[0] = append("-N", llist[0]); - } else - fprintf(stderr, "%s: %s ignored\n", progname, arg); - return; - case 'E': - Eflag++; - return; - case 'c': - cflag++; - return; - case 'M': - Eflag++; /* -M implies -E */ - plist = append(arg, plist); - return; - case 'N': - if (strcmp(basepath(cpp[0]), "gcc-cpp") == 0) - plist = append("-nostdinc", plist); - include[0] = 0; - ilist = 0; - return; - case 'v': - if (verbose++ == 0) { - if (strcmp(basepath(cpp[0]), "gcc-cpp") == 0) - plist = append(arg, plist); - clist = append(arg, clist); - fprintf(stderr, "%s %s\n", progname, rcsid); - } - return; - } - if (cflag || Sflag || Eflag) - fprintf(stderr, "%s: %s ignored\n", progname, arg); - else - llist[1] = append(arg, llist[1]); + if (strcmp(arg, "-Bstatic") == 0 || strcmp(arg, "-Bdynamic") == 0) + llist[1] = append(arg, llist[1]); + else +#endif + { + static char *path; + if (path) + error("-B overwrites earlier option", 0); + path = arg + 2; + if (strstr(com[1], "win32") != NULL) + com[0] = concat(replace(path, '/', '\\'), concat("rcc", first(suffixes[4]))); + else + com[0] = concat(path, "rcc"); + if (path[0] == 0) + error("missing directory in -B option", 0); + } + return; + case 'h': + if (strcmp(arg, "-help") == 0) { + static int printed = 0; + case '?': + if (!printed) + help(); + printed = 1; + return; + } + break; + case 's': + if (strcmp(arg, "-static") == 0) { + if (!option(arg)) + fprintf(stderr, "%s: %s ignored\n", progname, arg); + return; + } + break; + } + if (arg[2] == 0) + switch (arg[1]) { /* single-character options */ + case 'S': + Sflag++; + return; + case 'O': + fprintf(stderr, "%s: %s ignored\n", progname, arg); + return; + case 'A': case 'n': case 'w': case 'P': + clist = append(arg, clist); + return; + case 'g': case 'b': + if (option(arg)) + clist = append(arg[1] == 'g' ? "-g2" : arg, clist); + else + fprintf(stderr, "%s: %s ignored\n", progname, arg); + return; + case 'G': + if (option(arg)) { + clist = append("-g3", clist); + llist[0] = append("-N", llist[0]); + } else + fprintf(stderr, "%s: %s ignored\n", progname, arg); + return; + case 'E': + Eflag++; + return; + case 'c': + cflag++; + return; + case 'M': + Eflag++; /* -M implies -E */ + plist = append(arg, plist); + return; + case 'N': + if (strcmp(basepath(cpp[0]), "gcc-cpp") == 0) + plist = append("-nostdinc", plist); + include[0] = 0; + ilist = 0; + return; + case 'v': + if (verbose++ == 0) { + if (strcmp(basepath(cpp[0]), "gcc-cpp") == 0) + plist = append(arg, plist); + clist = append(arg, clist); + fprintf(stderr, "%s %s\n", progname, rcsid); + } + return; + } + if (cflag || Sflag || Eflag) + fprintf(stderr, "%s: %s ignored\n", progname, arg); + else + llist[1] = append(arg, llist[1]); } /* path2list - convert a colon- or semicolon-separated list to a list */ static List path2list(const char *path) { - List list = NULL; - char sep = ':'; - - if (path == NULL) - return NULL; - if (strchr(path, ';')) - sep = ';'; - while (*path) { - char *p, buf[512]; - if (p = strchr(path, sep)) { - assert(p - path < sizeof buf); - strncpy(buf, path, p - path); - buf[p-path] = '\0'; - } else { - assert(strlen(path) < sizeof buf); - strcpy(buf, path); - } - if (!find(buf, list)) - list = append(strsave(buf), list); - if (p == 0) - break; - path = p + 1; - } - return list; + List list = NULL; + char sep = ':'; + + if (path == NULL) + return NULL; + if (strchr(path, ';')) + sep = ';'; + while (*path) { + char *p, buf[512]; + if (p = strchr(path, sep)) { + assert(p - path < sizeof buf); + strncpy(buf, path, p - path); + buf[p-path] = '\0'; + } else { + assert(strlen(path) < sizeof buf); + strcpy(buf, path); + } + if (!find(buf, list)) + list = append(strsave(buf), list); + if (p == 0) + break; + path = p + 1; + } + return list; } /* replace - copy str, then replace occurrences of from with to, return the copy */ char *replace(const char *str, int from, int to) { - char *s = strsave(str), *p = s; + char *s = strsave(str), *p = s; - for ( ; (p = strchr(p, from)) != NULL; p++) - *p = to; - return s; + for ( ; (p = strchr(p, from)) != NULL; p++) + *p = to; + return s; } /* rm - remove files in list */ static void rm(List list) { - if (list) { - List b = list; - if (verbose) - fprintf(stderr, "rm"); - do { - if (verbose) - fprintf(stderr, " %s", b->str); - if (verbose < 2) - remove(b->str); - } while ((b = b->link) != list); - if (verbose) - fprintf(stderr, "\n"); - } + if (list) { + List b = list; + if (verbose) + fprintf(stderr, "rm"); + do { + if (verbose) + fprintf(stderr, " %s", b->str); + if (verbose < 2) + remove(b->str); + } while ((b = b->link) != list); + if (verbose) + fprintf(stderr, "\n"); + } } /* strsave - return a saved copy of string str */ char *strsave(const char *str) { - return strcpy(alloc(strlen(str)+1), str); + return strcpy(alloc(strlen(str)+1), str); } /* stringf - format and return a string */ char *stringf(const char *fmt, ...) { - char buf[1024]; - va_list ap; - int n; - - va_start(ap, fmt); - n = vsprintf(buf, fmt, ap); - va_end(ap); - return strsave(buf); + char buf[1024]; + va_list ap; + int n; + + va_start(ap, fmt); + n = vsprintf(buf, fmt, ap); + va_end(ap); + return strsave(buf); } /* suffix - if one of tails[0..n-1] holds a proper suffix of name, return its index */ int suffix(char *name, char *tails[], int n) { - int i, len = strlen(name); - - for (i = 0; i < n; i++) { - char *s = tails[i], *t; - for ( ; t = strchr(s, ';'); s = t + 1) { - int m = t - s; - if (len > m && strncmp(&name[len-m], s, m) == 0) - return i; - } - if (*s) { - int m = strlen(s); - if (len > m && strncmp(&name[len-m], s, m) == 0) - return i; - } - } - return -1; + int i, len = strlen(name); + + for (i = 0; i < n; i++) { + char *s = tails[i], *t; + for ( ; t = strchr(s, ';'); s = t + 1) { + int m = t - s; + if (len > m && strncmp(&name[len-m], s, m) == 0) + return i; + } + if (*s) { + int m = strlen(s); + if (len > m && strncmp(&name[len-m], s, m) == 0) + return i; + } + } + return -1; } /* tempname - generate a temporary file name in tempdir with given suffix */ char *tempname(char *suffix) { - static int n; - char *name = stringf("%s/lcc%d%d%s", tempdir, getpid(), n++, suffix); + static int n; + char *name = stringf("%s/lcc%d%d%s", tempdir, getpid(), n++, suffix); - if (strstr(com[1], "win32") != NULL) - name = replace(name, '/', '\\'); - rmlist = append(name, rmlist); - return name; + if (strstr(com[1], "win32") != NULL) + name = replace(name, '/', '\\'); + rmlist = append(name, rmlist); + return name; } diff --git a/etc/linux.c b/etc/linux.c index cbf7db0..e33cb87 100755 --- a/etc/linux.c +++ b/etc/linux.c @@ -1,62 +1,91 @@ /* x86s running Linux */ #include <string.h> +#include "get_my_path.h" static char rcsid[] = "$Id: linux.c 355 2007-02-18 22:08:49Z drh $"; -#ifndef LCCDIR -#define LCCDIR "/usr/local/lib/lcc/" -#endif +static char cppPath[PATH_MAX]; +static char rccPath[PATH_MAX]; + +static const char cppBase[] = "lcc-cpp"; +static const char rccBase[] = "lcc-rcc"; + +#define LCCDIR "/usr/bin" char *suffixes[] = { ".c", ".i", ".s", ".o", ".out", 0 }; char inputs[256] = ""; -char *cpp[] = { LCCDIR "gcc/cpp", - "-U__GNUC__", "-D_POSIX_SOURCE", "-D__STDC__=1", "-D__STRICT_ANSI__", - "-Dunix", "-Di386", "-Dlinux", - "-D__unix__", "-D__i386__", "-D__linux__", "-D__signed__=signed", - "$1", "$2", "$3", 0 }; +char *cpp[] = { cppPath, + "-U__GNUC__", "-D_POSIX_SOURCE", "-D__STDC__=1", "-D__STRICT_ANSI__", + "-Dunix", "-Di386", "-Dlinux", + "-D__unix__", "-D__i386__", "-D__linux__", "-D__signed__=signed", + "$1", "$2", "$3", 0 }; char *include[] = {"-I" LCCDIR "include", "-I" LCCDIR "gcc/include", "-I/usr/include", 0 }; -char *com[] = {LCCDIR "rcc", "-target=x86/linux", "$1", "$2", "$3", 0 }; +char *com[] = {rccPath, "-target=x86/linux", "$1", "$2", "$3", 0 }; char *as[] = { "/usr/bin/as", "-o", "$3", "$1", "$2", 0 }; char *ld[] = { - /* 0 */ "/usr/bin/ld", "-m", "elf_i386", "-dynamic-linker", - /* 4 */ "/lib/ld-linux.so.2", "-o", "$3", - /* 7 */ "/usr/lib/crt1.o", "/usr/lib/crti.o", - /* 9 */ LCCDIR "/gcc/crtbegin.o", + /* 0 */ "/usr/bin/ld", "-m", "elf_i386", "-dynamic-linker", + /* 4 */ "/lib/ld-linux.so.2", "-o", "$3", + /* 7 */ "/usr/lib/crt1.o", "/usr/lib/crti.o", + /* 9 */ LCCDIR "/gcc/crtbegin.o", "$1", "$2", - /* 12 */ "-L" LCCDIR, - /* 13 */ "-llcc", - /* 14 */ "-L" LCCDIR "/gcc", "-lgcc", "-lc", "-lm", - /* 18 */ "", - /* 19 */ LCCDIR "/gcc/crtend.o", "/usr/lib/crtn.o", - 0 }; + /* 12 */ "-L" LCCDIR, + /* 13 */ "-llcc", + /* 14 */ "-L" LCCDIR "/gcc", "-lgcc", "-lc", "-lm", + /* 18 */ "", + /* 19 */ LCCDIR "/gcc/crtend.o", "/usr/lib/crtn.o", + 0 }; extern char *concat(char *, char *); int option(char *arg) { - if (strncmp(arg, "-lccdir=", 8) == 0) { - if (strcmp(cpp[0], LCCDIR "gcc/cpp") == 0) - cpp[0] = concat(&arg[8], "/gcc/cpp"); - include[0] = concat("-I", concat(&arg[8], "/include")); - include[1] = concat("-I", concat(&arg[8], "/gcc/include")); - ld[9] = concat(&arg[8], "/gcc/crtbegin.o"); - ld[12] = concat("-L", &arg[8]); - ld[14] = concat("-L", concat(&arg[8], "/gcc")); - ld[19] = concat(&arg[8], "/gcc/crtend.o"); - com[0] = concat(&arg[8], "/rcc"); - } else if (strcmp(arg, "-p") == 0 || strcmp(arg, "-pg") == 0) { - ld[7] = "/usr/lib/gcrt1.o"; - ld[18] = "-lgmon"; - } else if (strcmp(arg, "-b") == 0) - ; - else if (strcmp(arg, "-g") == 0) - ; - else if (strncmp(arg, "-ld=", 4) == 0) - ld[0] = &arg[4]; - else if (strcmp(arg, "-static") == 0) { - ld[3] = "-static"; - ld[4] = ""; - } else - return 0; - return 1; + if (strncmp(arg, "-lccdir=", 8) == 0) { + cpp[0] = concat(&arg[8], "/gcc/cpp"); + include[0] = concat("-I", concat(&arg[8], "/include")); + include[1] = concat("-I", concat(&arg[8], "/gcc/include")); + ld[9] = concat(&arg[8], "/gcc/crtbegin.o"); + ld[12] = concat("-L", &arg[8]); + ld[14] = concat("-L", concat(&arg[8], "/gcc")); + ld[19] = concat(&arg[8], "/gcc/crtend.o"); + com[0] = concat(&arg[8], "/rcc"); + } else if (strcmp(arg, "-p") == 0 || strcmp(arg, "-pg") == 0) { + ld[7] = "/usr/lib/gcrt1.o"; + ld[18] = "-lgmon"; + } else if (strcmp(arg, "-b") == 0) + ; + else if (strcmp(arg, "-g") == 0) + ; + else if (strncmp(arg, "-ld=", 4) == 0) + ld[0] = &arg[4]; + else if (strcmp(arg, "-static") == 0) { + ld[3] = "-static"; + ld[4] = ""; + } else + return 0; + return 1; +} + +static void combine(char* dest, size_t destSize, const char* a, const char* b) { + if (destSize < 1) { + return; + } + size_t aLen = strlen(a); + size_t bLen = strlen(b); + if (aLen + bLen > destSize-1) { + dest[0] = 0; + return; + } + memcpy(dest, a, aLen); + memcpy(dest + aLen, b, bLen + 1); +} + +void platform_init() { + char myDir[PATH_MAX]; + get_my_path(myDir); + char* lastSlash = strrchr(myDir, '/'); + if (lastSlash != NULL) { + lastSlash[1] = '\0'; + combine(cppPath, PATH_MAX, myDir, cppBase); + combine(rccPath, PATH_MAX, myDir, rccBase); + } } |