diff --git a/Makefile b/Makefile index 175688ce..4214d381 100644 --- a/Makefile +++ b/Makefile @@ -6,10 +6,10 @@ all: chibi-scheme CC ?= cc PREFIX ?= /usr/local -BINDIR=$(PREFIX)/bin -LIBDIR=$(PREFIX)/lib -INCDIR=$(PREFIX)/include/chibi -MODDIR=$(PREFIX)/share/chibi +BINDIR ?= $(PREFIX)/bin +LIBDIR ?= $(PREFIX)/lib +INCDIR ?= $(PREFIX)/include/chibi +MODDIR ?= $(PREFIX)/share/chibi ifndef PLATFORM ifeq ($(shell uname),Darwin) @@ -23,6 +23,7 @@ ifeq ($(PLATFORM),macosx) SO = .dylib EXE = CLIBFLAGS = -dynamiclib +STATICFLAGS = -static-libgcc else ifeq ($(PLATFORM),mingw) SO = .dll EXE = .exe @@ -31,6 +32,7 @@ else SO = .so EXE = CLIBFLAGS = -fPIC -shared +STATICFLAGS = -static endif ifdef USE_BOEHM @@ -43,13 +45,18 @@ LDFLAGS := $(LDFLAGS) -lm CPPFLAGS := $(CPPFLAGS) -Iinclude CFLAGS := $(CFLAGS) -Wall -O2 -g -sexp.o: sexp.c gc.c include/chibi/sexp.h include/chibi/config.h Makefile +INCLUDES = include/chibi/sexp.h include/chibi/config.h include/chibi/install.h + +include/chibi/install.h: Makefile + echo '#define sexp_module_dir "'$(MODDIR)'"' > $@ + +sexp.o: sexp.c gc.c $(INCLUDES) Makefile $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $< -eval.o: eval.c debug.c opcodes.c include/chibi/eval.h include/chibi/sexp.h include/chibi/config.h Makefile +eval.o: eval.c debug.c opcodes.c include/chibi/eval.h $(INCLUDES) Makefile $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $< -main.o: main.c eval.c debug.c opcodes.c include/chibi/eval.h include/chibi/sexp.h include/chibi/config.h Makefile +main.o: main.c $(INCLUDES) Makefile $(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $< libchibi-scheme$(SO): eval.o sexp.o @@ -59,13 +66,13 @@ chibi-scheme$(EXE): main.o libchibi-scheme$(SO) $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< $(LDFLAGS) $(GCLDFLAGS) -L. -lchibi-scheme chibi-scheme-static$(EXE): main.o eval.o sexp.o - $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(GCLDFLAGS) + $(CC) $(CFLAGS) $(STATICFLAGS) -o $@ $^ $(LDFLAGS) $(GCLDFLAGS) clean: rm -f *.o *.i *.s cleaner: clean - rm -f chibi-scheme + rm -f chibi-scheme chibi-scheme-static *$(SO) rm -rf *.dSYM test-basic: chibi-scheme @@ -81,20 +88,20 @@ test-basic: chibi-scheme test: chibi-scheme ./chibi-scheme -l syntax-rules.scm tests/r5rs-tests.scm -# install: chibi-scheme -# cp chibi-scheme $(BINDIR)/ -# mkdir -p $(MODDIR) -# cp init.scm $(MODDIR)/ -# mkdir -p $(INCDIR) -# cp *.h $(INCDIR)/ -# cp *.$(SO) $(LIBDIR)/ +install: chibi-scheme + cp chibi-scheme $(BINDIR)/ + mkdir -p $(MODDIR) + cp init.scm syntax-rules.scm $(MODDIR)/ + mkdir -p $(INCDIR) + cp $(INCLUDES) include/chibi/eval.h $(INCDIR)/ + mkdir -p $(LIBDIR) + cp libchibi-scheme$(SO) $(LIBDIR)/ -# uninstall: -# rm -f $(BINDIR)/chibi-scheme -# rm -f $(LIBDIR)/libchibischeme.$(SO) -# rm -f $(LIBDIR)/libchibisexp.$(SO) -# rm -f $(INCDIR)/*.h -# rm -f $(MODDIR)/*.scm +uninstall: + rm -f $(BINDIR)/chibi-scheme* + rm -f $(LIBDIR)/libchibischeme$(SO) + cd $(INCDIR) && rm -f $(INCLUDES) include/chibi/eval.h + rm -f $(MODDIR)/*.scm dist: cleaner rm -f chibi-scheme-`cat VERSION`.tgz diff --git a/include/chibi/eval.h b/include/chibi/eval.h index 65fc66a1..dcee8420 100644 --- a/include/chibi/eval.h +++ b/include/chibi/eval.h @@ -128,13 +128,13 @@ enum opcode_names { /**************************** prototypes ******************************/ -SEXP_API void sexp_scheme_init(); -SEXP_API sexp sexp_apply(sexp context, sexp proc, sexp args); -SEXP_API sexp sexp_eval(sexp context, sexp obj); -SEXP_API sexp sexp_eval_string(sexp context, char *str); -SEXP_API sexp sexp_load(sexp context, sexp expr, sexp env); -SEXP_API sexp sexp_make_context(sexp context, sexp stack, sexp env); -SEXP_API void sexp_warn_undefs (sexp from, sexp to, sexp out); +void sexp_scheme_init(); +sexp sexp_apply(sexp context, sexp proc, sexp args); +sexp sexp_eval(sexp context, sexp obj); +sexp sexp_eval_string(sexp context, char *str); +sexp sexp_load(sexp context, sexp expr, sexp env); +sexp sexp_make_context(sexp context, sexp stack, sexp env); +void sexp_warn_undefs (sexp from, sexp to, sexp out); #endif /* ! SEXP_EVAL_H */ diff --git a/include/chibi/sexp.h b/include/chibi/sexp.h index c4979f02..348052d4 100644 --- a/include/chibi/sexp.h +++ b/include/chibi/sexp.h @@ -6,6 +6,7 @@ #define SEXP_H #include "config.h" +#include "install.h" #include #include @@ -16,10 +17,6 @@ #include #include -#ifndef SEXP_API -#define SEXP_API extern -#endif - /* tagging system * bits end in 00: pointer * 01: fixnum @@ -515,43 +512,43 @@ sexp sexp_make_flonum(sexp ctx, double f); #define sexp_scanf(p, ...) (fscanf(sexp_port_stream(p), __VA_ARGS__)) #define sexp_flush(p) (fflush(sexp_port_stream(p))) -SEXP_API sexp sexp_alloc_tagged(sexp ctx, size_t size, sexp_uint_t tag); -SEXP_API sexp sexp_cons(sexp ctx, sexp head, sexp tail); -SEXP_API sexp sexp_list2(sexp ctx, sexp a, sexp b); -SEXP_API sexp sexp_equalp (sexp ctx, sexp a, sexp b); -SEXP_API sexp sexp_listp(sexp ctx, sexp obj); -SEXP_API sexp sexp_reverse(sexp ctx, sexp ls); -SEXP_API sexp sexp_nreverse(sexp ctx, sexp ls); -SEXP_API sexp sexp_append2(sexp ctx, sexp a, sexp b); -SEXP_API sexp sexp_memq(sexp ctx, sexp x, sexp ls); -SEXP_API sexp sexp_assq(sexp ctx, sexp x, sexp ls); -SEXP_API sexp sexp_length(sexp ctx, sexp ls); -SEXP_API sexp sexp_c_string(sexp ctx, char *str, sexp_sint_t slen); -SEXP_API sexp sexp_make_string(sexp ctx, sexp len, sexp ch); -SEXP_API sexp sexp_substring (sexp ctx, sexp str, sexp start, sexp end); -SEXP_API sexp sexp_intern(sexp ctx, char *str); -SEXP_API sexp sexp_string_to_symbol(sexp ctx, sexp str); -SEXP_API sexp sexp_make_vector(sexp ctx, sexp len, sexp dflt); -SEXP_API sexp sexp_list_to_vector(sexp ctx, sexp ls); -SEXP_API sexp sexp_vector(sexp ctx, int count, ...); -SEXP_API void sexp_write(sexp obj, sexp out); -SEXP_API sexp sexp_read_string(sexp ctx, sexp in); -SEXP_API sexp sexp_read_symbol(sexp ctx, sexp in, int init, int internp); -SEXP_API sexp sexp_read_number(sexp ctx, sexp in, int base); -SEXP_API sexp sexp_read_raw(sexp ctx, sexp in); -SEXP_API sexp sexp_read(sexp ctx, sexp in); -SEXP_API sexp sexp_read_from_string(sexp ctx, char *str); -SEXP_API sexp sexp_make_input_port(sexp ctx, FILE* in, sexp name); -SEXP_API sexp sexp_make_output_port(sexp ctx, FILE* out, sexp name); -SEXP_API sexp sexp_make_input_string_port(sexp ctx, sexp str); -SEXP_API sexp sexp_make_output_string_port(sexp ctx); -SEXP_API sexp sexp_get_output_string(sexp ctx, sexp port); -SEXP_API sexp sexp_make_exception(sexp ctx, sexp kind, sexp message, sexp irritants, sexp procedure, sexp file, sexp line); -SEXP_API sexp sexp_user_exception (sexp ctx, sexp self, char *message, sexp obj); -SEXP_API sexp sexp_type_exception (sexp ctx, char *message, sexp obj); -SEXP_API sexp sexp_range_exception (sexp ctx, sexp obj, sexp start, sexp end); -SEXP_API sexp sexp_print_exception(sexp ctx, sexp exn, sexp out); -SEXP_API void sexp_init(); +sexp sexp_alloc_tagged(sexp ctx, size_t size, sexp_uint_t tag); +sexp sexp_cons(sexp ctx, sexp head, sexp tail); +sexp sexp_list2(sexp ctx, sexp a, sexp b); +sexp sexp_equalp (sexp ctx, sexp a, sexp b); +sexp sexp_listp(sexp ctx, sexp obj); +sexp sexp_reverse(sexp ctx, sexp ls); +sexp sexp_nreverse(sexp ctx, sexp ls); +sexp sexp_append2(sexp ctx, sexp a, sexp b); +sexp sexp_memq(sexp ctx, sexp x, sexp ls); +sexp sexp_assq(sexp ctx, sexp x, sexp ls); +sexp sexp_length(sexp ctx, sexp ls); +sexp sexp_c_string(sexp ctx, char *str, sexp_sint_t slen); +sexp sexp_make_string(sexp ctx, sexp len, sexp ch); +sexp sexp_substring (sexp ctx, sexp str, sexp start, sexp end); +sexp sexp_intern(sexp ctx, char *str); +sexp sexp_string_to_symbol(sexp ctx, sexp str); +sexp sexp_make_vector(sexp ctx, sexp len, sexp dflt); +sexp sexp_list_to_vector(sexp ctx, sexp ls); +sexp sexp_vector(sexp ctx, int count, ...); +void sexp_write(sexp obj, sexp out); +sexp sexp_read_string(sexp ctx, sexp in); +sexp sexp_read_symbol(sexp ctx, sexp in, int init, int internp); +sexp sexp_read_number(sexp ctx, sexp in, int base); +sexp sexp_read_raw(sexp ctx, sexp in); +sexp sexp_read(sexp ctx, sexp in); +sexp sexp_read_from_string(sexp ctx, char *str); +sexp sexp_make_input_port(sexp ctx, FILE* in, sexp name); +sexp sexp_make_output_port(sexp ctx, FILE* out, sexp name); +sexp sexp_make_input_string_port(sexp ctx, sexp str); +sexp sexp_make_output_string_port(sexp ctx); +sexp sexp_get_output_string(sexp ctx, sexp port); +sexp sexp_make_exception(sexp ctx, sexp kind, sexp message, sexp irritants, sexp procedure, sexp file, sexp line); +sexp sexp_user_exception (sexp ctx, sexp self, char *message, sexp obj); +sexp sexp_type_exception (sexp ctx, char *message, sexp obj); +sexp sexp_range_exception (sexp ctx, sexp obj, sexp start, sexp end); +sexp sexp_print_exception(sexp ctx, sexp exn, sexp out); +void sexp_init(); #endif /* ! SEXP_H */ diff --git a/main.c b/main.c index 1beb9889..b09a2f87 100644 --- a/main.c +++ b/main.c @@ -2,8 +2,39 @@ /* Copyright (c) 2009 Alex Shinn. All rights reserved. */ /* BSD-style license: http://synthcode.com/license.txt */ +#include #include "chibi/eval.h" +char *chibi_module_dir = NULL; + +sexp find_module_file (sexp ctx, char *file) { + sexp res; + int mlen, flen; + char *path; + struct stat buf; + + if (! stat(file, &buf)) + return sexp_c_string(ctx, file, -1); + if (! chibi_module_dir) { + chibi_module_dir = getenv("CHIBI_MODULE_DIR"); + if (! chibi_module_dir) + chibi_module_dir = sexp_module_dir; + } + mlen = strlen(chibi_module_dir); + flen = strlen(file); + path = (char*) malloc(mlen+flen+2); + memcpy(path, chibi_module_dir, mlen); + path[mlen+1] = '/'; + memcpy(path+mlen+1, file, flen); + path[mlen+flen] = '\0'; + if (! stat(path, &buf)) + res = sexp_c_string(ctx, path, mlen+flen+1); + else + res = SEXP_FALSE; + free(path); + return res; +} + void repl (sexp ctx) { sexp tmp, res, env, in, out, err; sexp_gc_var(ctx, obj, s_obj); @@ -54,7 +85,7 @@ void run_main (int argc, char **argv) { case 'e': case 'p': if (! init_loaded++) - sexp_load(ctx, str=sexp_c_string(ctx, sexp_init_file, -1), env); + sexp_load(ctx, str=find_module_file(ctx, sexp_init_file), env); res = sexp_read_from_string(ctx, argv[i+1]); if (! sexp_exceptionp(res)) res = sexp_eval(ctx, res); @@ -70,12 +101,15 @@ void run_main (int argc, char **argv) { #endif case 'l': if (! init_loaded++) - sexp_load(ctx, str=sexp_c_string(ctx, sexp_init_file, -1), env); - sexp_load(ctx, str=sexp_c_string(ctx, argv[++i], -1), env); + sexp_load(ctx, str=find_module_file(ctx, sexp_init_file), env); + sexp_load(ctx, str=find_module_file(ctx, argv[++i]), env); break; case 'q': init_loaded = 1; break; + case 'm': + chibi_module_dir = argv[++i]; + break; default: errx(1, "unknown option: %s", argv[i]); } @@ -83,7 +117,7 @@ void run_main (int argc, char **argv) { if (! quit) { if (! init_loaded) - sexp_load(ctx, str=sexp_c_string(ctx, sexp_init_file, -1), env); + sexp_load(ctx, str=find_module_file(ctx, sexp_init_file), env); if (i < argc) for ( ; i < argc; i++) sexp_load(ctx, str=sexp_c_string(ctx, argv[i], -1), env);