aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile26
-rwxr-xr-xconfigure.sh44
-rw-r--r--lib/commands/commands.tm6
-rw-r--r--lib/patterns/patterns.c1
-rw-r--r--src/compile.c2
-rw-r--r--src/stdlib/stacktrace.c6
-rw-r--r--src/tomo.c36
-rw-r--r--src/typecheck.c2
9 files changed, 93 insertions, 31 deletions
diff --git a/.gitignore b/.gitignore
index 34f62c11..9a8cb004 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+/config.mk
/examples/*/*
!/examples/*.*
!/examples/*/*.*
diff --git a/Makefile b/Makefile
index b76f4053..8b4f291a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,13 @@
-PREFIX=$(HOME)/.local
+# Run ./configure.sh to choose installation locations:
+ifeq ($(wildcard config.mk),)
+all: config.mk
+ $(MAKE) all
+config.mk: configure.sh
+ ./configure.sh
+else
+
+include config.mk
+
VERSION=0.0.1
CC=cc
CCONFIG=-std=c2x -fPIC \
@@ -41,7 +50,8 @@ OSFLAGS != case $(OS) in *BSD|Darwin) echo '-D_BSD_SOURCE';; Linux) echo '-D_GNU
EXTRA=
G=-ggdb
O=-Og
-CFLAGS=$(CCONFIG) $(INCLUDE_DIRS) $(EXTRA) $(CWARN) $(G) $(O) $(OSFLAGS) $(LTO)
+CFLAGS=$(CCONFIG) $(INCLUDE_DIRS) $(EXTRA) $(CWARN) $(G) $(O) $(OSFLAGS) $(LTO) \
+ -DTOMO_HOME='"$(TOMO_HOME)"' -DTOMO_PREFIX='"$(PREFIX)"' -DDEFAULT_C_COMPILER='"$(DEFAULT_C_COMPILER)"'
CFLAGS_PLACEHOLDER="$$(printf '\033[2m<flags...>\033[m\n')"
LDLIBS=-lgc -lcord -lm -lunistring -lgmp
LIBTOMO_FLAGS=-shared
@@ -65,7 +75,7 @@ COMPILER_OBJS=$(patsubst %.c,%.o,$(wildcard src/*.c))
STDLIB_OBJS=$(patsubst %.c,%.o,$(wildcard src/stdlib/*.c))
TESTS=$(patsubst test/%.tm,test/results/%.tm.testresult,$(wildcard test/*.tm))
-all: build/$(LIB_FILE) build/$(AR_FILE) build/tomo
+all: config.mk build/$(LIB_FILE) build/$(AR_FILE) build/tomo
build/tomo: $(STDLIB_OBJS) $(COMPILER_OBJS)
@mkdir -p build
@@ -85,7 +95,10 @@ build/$(AR_FILE): $(STDLIB_OBJS)
tags:
ctags src/*.[ch] src/stdlib/*.[ch]
-%.o: %.c src/ast.h src/environment.h src/types.h
+config.mk: configure.sh
+ ./configure.sh
+
+%.o: %.c src/ast.h src/environment.h src/types.h config.mk
@echo $(CC) $(CFLAGS_PLACEHOLDER) -c $< -o $@
@$(CC) $(CFLAGS) -c $< -o $@
@@ -131,7 +144,8 @@ check-gcc:
install-files: build/tomo build/$(LIB_FILE) build/$(AR_FILE)
@if ! echo "$$PATH" | tr ':' '\n' | grep -qx "$(PREFIX)/bin"; then \
- printf "\033[31;1mError: '$(PREFIX)' is not in your \$$PATH variable!\033[m\n" >&2; \
+ echo $$PATH; \
+ printf "\033[31;1mError: '$(PREFIX)/bin' is not in your \$$PATH variable!\033[m\n" >&2; \
printf "\033[31;1mSpecify a different prefix with 'make PREFIX=... install'\033[m\n" >&2; \
printf "\033[31;1mor add the following line to your .profile:\033[m\n" >&2; \
printf "\n\033[1mexport PATH=\"$(PREFIX):\$$PATH\"\033[m\n\n" >&2; \
@@ -152,5 +166,7 @@ install: install-files install-libs
uninstall:
rm -rvf "$(PREFIX)/bin/tomo" "$(PREFIX)/include/tomo" "$(PREFIX)/lib/$(LIB_FILE)" "$(PREFIX)/lib/$(AR_FILE)" "$(PREFIX)/share/tomo";
+endif
+
.SUFFIXES:
.PHONY: all clean install install-files install-libs uninstall test tags examples deps check-gcc
diff --git a/configure.sh b/configure.sh
new file mode 100755
index 00000000..9ad06fb0
--- /dev/null
+++ b/configure.sh
@@ -0,0 +1,44 @@
+#!/bin/env bash
+
+# if [ "$1" = '--lazy' -a ! -f 'config.mk' ]; then
+# echo "Already configured!"
+# exit 0
+# fi
+
+error() {
+ printf "\033[31;1m%s\033[m\n" "$@"
+ exit 1
+}
+
+default_prefix='/usr/local'
+if echo "$PATH" | tr ':' '\n' | grep -qx "$HOME/.local/bin"; then
+ default_prefix="~/.local"
+fi
+
+printf '\033[1mChoose where to install Tomo (default: %s):\033[m ' "$default_prefix"
+read PREFIX
+if [ -z "$PREFIX" ]; then PREFIX="$default_prefix"; fi
+PREFIX="${PREFIX/#\~/$HOME}"
+
+if ! echo "$PATH" | tr ':' '\n' | grep -qx "$PREFIX/bin"; then
+ error "Your \$PATH does not include this prefix, so you won't be able to run tomo!" \
+ "Please put this in your .profile or .bashrc: export PATH=\"$PREFIX:\$PATH\""
+fi
+
+default_home="~/.local/share/tomo"
+printf '\033[1mChoose where to install Tomo libraries (default: %s):\033[m ' "$default_home"
+read TOMO_HOME
+if [ -z "$TOMO_HOME" ]; then TOMO_HOME="$default_home"; fi
+TOMO_HOME="${TOMO_HOME/#\~/$HOME}"
+
+default_cc="cc"
+printf '\033[1mChoose which C compiler to use by default (default: %s):\033[m ' "$default_cc"
+read DEFAULT_C_COMPILER
+if [ -z "$DEFAULT_C_COMPILER" ]; then DEFAULT_C_COMPILER="$default_home"; fi
+DEFAULT_C_COMPILER="${DEFAULT_C_COMPILER/#\~/$HOME}"
+
+cat <<END >config.mk
+PREFIX=$PREFIX
+TOMO_HOME=$TOMO_HOME
+DEFAULT_C_COMPILER=$DEFAULT_C_COMPILER
+END
diff --git a/lib/commands/commands.tm b/lib/commands/commands.tm
index aeadda4f..a5ce607a 100644
--- a/lib/commands/commands.tm
+++ b/lib/commands/commands.tm
@@ -18,10 +18,10 @@ enum ExitType(Exited(status:Int32), Signaled(signal:Int32), Failed)
struct ProgramResult(output:[Byte], errors:[Byte], exit_type:ExitType)
func or_fail(r:ProgramResult, message:Text?=none -> ProgramResult)
when r.exit_type is Exited(status)
- if status == 0
- return r
+ if status != 0
+ fail(message or "Program failed: $r")
else fail(message or "Program failed: $r")
- fail(message or "Program failed: $r")
+ return r
func output_text(r:ProgramResult, trim_newline=yes -> Text?)
when r.exit_type is Exited(status)
diff --git a/lib/patterns/patterns.c b/lib/patterns/patterns.c
index 5cb02ffa..04cc9c0e 100644
--- a/lib/patterns/patterns.c
+++ b/lib/patterns/patterns.c
@@ -504,6 +504,7 @@ static int64_t match_pat(TextIter_t *state, int64_t index, pat_t pat)
default: errx(1, "Invalid pattern");
}
errx(1, "Unreachable");
+ return 0;
}
static pat_t parse_next_pat(TextIter_t *state, int64_t *index)
diff --git a/src/compile.c b/src/compile.c
index 052fe309..766da09d 100644
--- a/src/compile.c
+++ b/src/compile.c
@@ -1888,7 +1888,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
return with_source_info(env, ast, CORD_all("_$", name, "$$initialize();\n"));
} else if (use->what == USE_MODULE) {
glob_t tm_files;
- if (glob(String("~/.local/share/tomo/installed/", use->path, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0)
+ if (glob(String(TOMO_HOME"/installed/", use->path, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0)
code_err(ast, "Could not find library");
CORD initialization = CORD_EMPTY;
diff --git a/src/stdlib/stacktrace.c b/src/stdlib/stacktrace.c
index 0ae4915e..798da218 100644
--- a/src/stdlib/stacktrace.c
+++ b/src/stdlib/stacktrace.c
@@ -72,8 +72,8 @@ static void _print_stack_frame(FILE *out, const char *cwd, const char *install_d
fprintf(out, USE_COLOR ? "\033[1mIn \033[33m%s()\033[37m" : "In %s()", function_display);
if (filename) {
if (install_dir[0] && strncmp(filename, install_dir, strlen(install_dir)) == 0)
- fprintf(out, USE_COLOR ? " in library \033[35m~/.local/share/tomo/installed/%s:%d" : " in library ~/.local/share/tomo/installed/%s:%d",
- filename + strlen(install_dir), lineno);
+ fprintf(out, USE_COLOR ? " in library \033[35m%s:%d" : " in library %s:%d",
+ filename, lineno);
else
fprintf(out, USE_COLOR ? " in \033[35m%s:%d" : " in %s:%d", filename, lineno);
}
@@ -97,7 +97,7 @@ public void print_stacktrace(FILE *out, int offset)
cwd[cwd_len++] = '/';
cwd[cwd_len] = '\0';
- const char *install_dir = String(getenv("HOME"), "/.local/share/tomo/installed/");
+ const char *install_dir = TOMO_HOME"/installed/";
static void *stack[1024];
int64_t size = (int64_t)backtrace(stack, sizeof(stack)/sizeof(stack[0]));
diff --git a/src/tomo.c b/src/tomo.c
index 0a75497f..f47f1934 100644
--- a/src/tomo.c
+++ b/src/tomo.c
@@ -67,12 +67,12 @@ static OptionalText_t
" -D_BSD_SOURCE"
#endif
" -DGC_THREADS"
- " -I$HOME/.local/include -I$HOME/.local/share/tomo/installed -I/usr/local/include"),
- ldlibs = Text("-lgc -lm -lgmp -lunistring -ltomo"),
- ldflags = Text("-Wl,-rpath,'$ORIGIN',-rpath,$HOME/.local/share/tomo/lib,-rpath,$HOME/.local/lib,-rpath,/usr/local/lib "
- "-L$HOME/.local/lib -L$HOME/.local/share/tomo/lib -L/usr/local/lib"),
+ " -I'" TOMO_PREFIX "/include' -I'" TOMO_HOME "/installed' -I/usr/local/include"),
+ ldlibs = Text("-lgc -lm -lgmp -lunistring '"TOMO_PREFIX"'/lib/libtomo.so"),
+ ldflags = Text("-Wl,-rpath,'$ORIGIN',-rpath,'" TOMO_HOME "/lib',-rpath,/usr/local/lib "
+ "-L'" TOMO_HOME "/lib' -L/usr/local/lib"),
optimization = Text("2"),
- cc = Text("cc");
+ cc = Text(DEFAULT_C_COMPILER);
static const char *SHARED_SUFFIX =
#ifdef __APPLE__
@@ -128,7 +128,7 @@ int main(int argc, char *argv[])
// Run a tool:
if ((streq(argv[1], "-r") || streq(argv[1], "--run")) && argc >= 3) {
if (strcspn(argv[2], "/;$") == strlen(argv[2])) {
- const char *program = String(getenv("HOME"), "/.local/share/tomo/installed/", argv[2], "/", argv[2]);
+ const char *program = String("'"TOMO_HOME"'/installed/", argv[2], "/", argv[2]);
execv(program, &argv[2]);
}
print_err("This is not an installed tomo program: \033[31;1m", argv[2], "\033[m");
@@ -145,9 +145,9 @@ int main(int argc, char *argv[])
" --verbose|-v: verbose output\n"
" --quiet|-q: quiet output\n"
" --install|-I: install the executable or library\n"
- " --c-compiler <compiler>: the C compiler to use (default: cc)\n"
+ " --c-compiler <compiler>: the C compiler to use (default: "DEFAULT_C_COMPILER")\n"
" --optimization|-O <level>: set optimization level\n"
- " --run|-r: run a program from ~/.local/share/tomo/installed\n"
+ " --run|-r: run a program from " TOMO_HOME "/installed\n"
);
Text_t help = Texts(Text("\x1b[1mtomo\x1b[m: a compiler for the Tomo programming language"), Text("\n\n"), usage);
tomo_parse_args(
@@ -199,7 +199,7 @@ int main(int argc, char *argv[])
for (int64_t i = 0; i < uninstall.length; i++) {
Text_t *u = (Text_t*)(uninstall.data + i*uninstall.stride);
- system(String("rm -rvf ~/.local/share/tomo/installed/", *u, " ~/.local/share/tomo/lib/lib", *u, SHARED_SUFFIX));
+ system(String("rm -rvf '"TOMO_HOME"'/installed/", *u, " '"TOMO_HOME"'/lib/lib", *u, SHARED_SUFFIX));
print("Uninstalled ", *u);
}
@@ -282,7 +282,7 @@ int main(int argc, char *argv[])
for (int64_t i = 0; i < files.length; i++) {
Path_t path = *(Path_t*)(files.data + i*files.stride);
Path_t exe = Path$with_extension(path, Text(""), true);
- system(String("cp -v '", exe, "' ~/.local/bin/"));
+ system(String("cp -v '", exe, "' '"TOMO_PREFIX"'/bin/"));
}
}
return 0;
@@ -494,22 +494,22 @@ void build_library(Text_t lib_dir_name)
if (should_install) {
char library_directory[PATH_MAX];
getcwd(library_directory, sizeof(library_directory));
- const char *dest = String(getenv("HOME"), "/.local/share/tomo/installed/", lib_dir_name);
+ const char *dest = String(TOMO_HOME"/installed/", lib_dir_name);
if (!streq(library_directory, dest)) {
system(String("rm -rf '", dest, "'"));
system(String("mkdir -p '", dest, "'"));
system(String("cp -r * '", dest, "/'"));
}
- system("mkdir -p ~/.local/share/tomo/lib/");
+ system("mkdir -p '"TOMO_HOME"'/lib/");
system(String("ln -f -s ../installed/'", lib_dir_name, "'/lib'", lib_dir_name, SHARED_SUFFIX,
- "' ~/.local/share/tomo/lib/lib'", lib_dir_name, SHARED_SUFFIX, "'"));
+ "' '"TOMO_HOME"'/lib/lib'", lib_dir_name, SHARED_SUFFIX, "'"));
// If we have `debugedit` on this system, use it to remap the debugging source information
// to point to the installed version of the source file. Otherwise, fail silently.
system(String("debugedit -b ", library_directory,
- " -d ~/.local/share/tomo/installed/", lib_dir_name,
- " ~/.local/share/tomo/installed/", lib_dir_name, "/lib", lib_dir_name, ".so"
+ " -d '"TOMO_HOME"'/installed/", lib_dir_name,
+ " '"TOMO_HOME"'/installed/", lib_dir_name, "/lib", lib_dir_name, ".so"
" 2>/dev/null >/dev/null"));
- print("Installed \033[1m", lib_dir_name, "\033[m to ~/.local/share/tomo/installed");
+ print("Installed \033[1m", lib_dir_name, "\033[m to "TOMO_HOME"/installed");
}
}
@@ -624,10 +624,10 @@ void build_file_dependency_graph(Path_t path, Table_t *to_compile, Table_t *to_l
break;
}
case USE_MODULE: {
- Text_t lib = Text$format("'%s/.local/share/tomo/installed/%s/lib%s%s'", getenv("HOME"), use->path, use->path, SHARED_SUFFIX);
+ Text_t lib = Text$format("'%s/installed/%s/lib%s%s'", TOMO_HOME, use->path, use->path, SHARED_SUFFIX);
Table$set(to_link, &lib, ((Bool_t[1]){1}), Table$info(&Text$info, &Bool$info));
- List_t children = Path$glob(Path$from_str(String(getenv("HOME"), "/.local/share/tomo/installed/", use->path, "/*.tm")));
+ List_t children = Path$glob(Path$from_str(String(TOMO_HOME"/installed/", use->path, "/*.tm")));
for (int64_t i = 0; i < children.length; i++) {
Path_t *child = (Path_t*)(children.data + i*children.stride);
Table_t discarded = {.fallback=to_compile};
diff --git a/src/typecheck.c b/src/typecheck.c
index 58b74739..83b715cf 100644
--- a/src/typecheck.c
+++ b/src/typecheck.c
@@ -181,7 +181,7 @@ static env_t *load_module(env_t *env, ast_t *module_ast)
}
case USE_MODULE: {
glob_t tm_files;
- if (glob(String("~/.local/share/tomo/installed/", use->path, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0)
+ if (glob(String(TOMO_HOME"/installed/", use->path, "/[!._0-9]*.tm"), GLOB_TILDE, NULL, &tm_files) != 0)
code_err(module_ast, "Could not find library");
env_t *module_env = fresh_scope(env);