summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Palevich <jackpal@google.com>2009-05-05 10:34:09 -0700
committerJack Palevich <jackpal@google.com>2009-05-05 10:34:09 -0700
commitc197a79045d298929737ea53dd56d567f21ed8d2 (patch)
treed3a9498f6dd2603f285b5379f554534c87648c36
parent59c0e7ea797dc846ea676d7c0db3cf7333bff3bb (diff)
downloadlcc-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.mk150
-rwxr-xr-xetc/darwin.c89
-rw-r--r--etc/get_my_path.h19
-rw-r--r--etc/get_my_path_darwin.c31
-rw-r--r--etc/get_my_path_linux.c35
-rw-r--r--etc/get_my_path_windows.c34
-rwxr-xr-xetc/lcc.c1283
-rwxr-xr-xetc/linux.c117
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;
+}
+
diff --git a/etc/lcc.c b/etc/lcc.c
index 06a9d3e..5f37082 100755
--- a/etc/lcc.c
+++ b/etc/lcc.c
@@ -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);
+ }
}