Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added 'readline' extension to main makefile, 'potion_load' can figure…

… out which file to load by the argument now, interactive mode uses readline.
  • Loading branch information...
commit ed9e1ffcb00bdf90b3528f9825da12294ade866b 1 parent 2efb901
@orangea orangea authored
Showing with 90 additions and 26 deletions.
  1. +10 −2 Makefile
  2. +73 −17 core/load.c
  3. +5 −5 core/potion.c
  4. +2 −2 lib/readline/Makefile
View
12 Makefile
@@ -33,9 +33,11 @@ COMMIT = `git rev-list HEAD -1 --abbrev=7 --abbrev-commit`
RELEASE ?= ${VERSION}.${REVISION}
PKG := "potion-${RELEASE}"
-all: potion
+all: pn
+${MAKE} -s usage
+pn: potion libpotion.a lib/readline/readline.so
+
rebuild: clean potion test
usage:
@@ -114,7 +116,7 @@ tools/greg: tools/greg.c tools/compile.c tools/tree.c
@${ECHO} CC $@
@${CC} -O3 -DNDEBUG -o $@ tools/greg.c tools/compile.c tools/tree.c -Itools
-potion: ${OBJ_POTION} ${OBJ} libpotion.a
+potion: ${OBJ_POTION} ${OBJ}
@${ECHO} LINK potion
@${CC} ${CFLAGS} ${OBJ_POTION} ${OBJ} ${LIBS} -o potion
@if [ "${DEBUG}" != "1" ]; then \
@@ -127,6 +129,12 @@ libpotion.a: ${OBJ_POTION} ${OBJ}
@if [ -e $@ ]; then rm -f $@; fi
@${AR} rcs $@ core/*.o > /dev/null
+lib/readline/readline.so:
+ @${ECHO} MAKE $@
+ @cd lib/readline; \
+ ${MAKE} readline.so; \
+ cd ../..
+
bench: potion test/api/gc-bench
@${ECHO}; \
${ECHO} running GC benchmark; \
View
90 core/load.c
@@ -16,16 +16,10 @@
void potion_load_code(Potion *P, const char *filename) {
PN buf, code;
- int fd = -1;
- struct stat stats;
- if (stat(filename, &stats) == -1) {
- fprintf(stderr, "** %s does not exist.", filename);
- goto done;
- }
- fd = open(filename, O_RDONLY | O_BINARY);
+ int fd = open(filename, O_RDONLY | O_BINARY);
if (fd == -1) {
fprintf(stderr, "** could not open %s. check permissions.", filename);
- goto done;
+ return;
}
buf = potion_bytes(P, stats.st_size);
if (read(fd, PN_STR_PTR(buf), stats.st_size) == stats.st_size) {
@@ -33,15 +27,12 @@ void potion_load_code(Potion *P, const char *filename) {
code = potion_source_load(P, PN_NIL, buf);
if (!PN_IS_PROTO(code)) {
potion_run(P, potion_send(
- potion_parse(P, buf), PN_compile, potion_str(P, filename), PN_NIL), POTION_JIT);
+ potion_parse(P, buf), PN_compile, potion_str(P, filename), PN_NIL), POTION_JIT);
}
} else {
fprintf(stderr, "** could not read entire file: %s.", filename);
- }
-
-done:
- if (fd != -1)
close(fd);
+ }
}
static char *potion_initializer_name(Potion *P, const char *filename, PN_SIZE len) {
@@ -82,26 +73,91 @@ void potion_load_dylib(Potion *P, const char *filename) {
func(P);
}
+static PN pn_loader_path;
+static char *pn_loader_extensions[] = {
+ ".pn", ".so", ".dylib"
+};
+
+static char *find_extension(char *str) {
+ int i;
+ PN_SIZE str_len = strlen(str);
+ struct stat st;
+ for (i = 0;
+ i < sizeof(pn_loader_extensions) / sizeof(void *);
+ i++) {
+ PN_SIZE len = strlen(pn_loader_extensions[i]);
+ char buf[str_len + len + 1];
+ strncpy(buf, str, str_len);
+ strncpy(buf + str_len, pn_loader_extensions[i], len);
+ buf[str_len + len] = '\0';
+ if (stat(buf, &st) == 0 && S_ISREG(st.st_mode))
+ return pn_loader_extensions[i];
+ }
+ return NULL;
+}
+
+char *potion_find_file(char *str, PN_SIZE str_len) {
+ char *r = NULL;
+ struct stat st;
+ PN_TUPLE_EACH(pn_loader_path, i, prefix, {
+ PN_SIZE prefix_len = PN_STR_LEN(prefix);
+ char dirname[prefix_len + 1 + str_len + 1];
+ char *str_pos = dirname + prefix_len + 1;
+ char *dot;
+ memcpy(str_pos, str, str_len);
+ for (dot = str_pos; dot < str_pos + str_len; dot++)
+ if (*dot == '.') { *dot = '\0'; break; }
+ if (dot == str_pos + str_len)
+ dirname[prefix_len + 1 + str_len] = '\0';
+ memcpy(dirname, PN_STR_PTR(prefix), prefix_len);
+ dirname[prefix_len] = '/';
+ if (stat(dirname, &st) == 0 && S_ISREG(st.st_mode)) {
+ if (asprintf(&r, "%s", str) == -1) potion_allocation_error();
+ } else {
+ if (asprintf(&r, "%s/%s", dirname, str) == -1) potion_allocation_error();
+ if (stat(r, &st) != 0 || !S_ISREG(st.st_mode)) {
+ char *ext = find_extension(r);
+ int r_len = prefix_len + 1 + str_len * 2 + 1;
+ if (ext == NULL) { free(r); r = NULL; continue; }
+ r = realloc(r, r_len + strlen(ext));
+ if (r == NULL) potion_allocation_error();
+ strcpy(r + r_len, ext);
+ }
+ break;
+ }
+ });
+ return r;
+}
+
PN potion_load(Potion *P, PN cl, PN self, PN file) {
- char *filename = PN_STR_PTR(file),
- *file_ext = filename + PN_STR_LEN(file);
+ char *filename = potion_find_file(PN_STR_PTR(file), PN_STR_LEN(file)), *file_ext;
+ if (filename == NULL) {
+ fprintf(stderr, "** can't find %s\n", PN_STR_PTR(file));
+ return PN_NIL;
+ }
+ file_ext = filename + strlen(filename);
while (*--file_ext != '.' && file_ext >= filename);
if (file_ext++ != filename) {
if (strcmp(file_ext, "pn") == 0)
potion_load_code(P, filename);
else if (strcmp(file_ext, "so") == 0 ||
strcmp(file_ext, "dylib") == 0
- )
+ )
potion_load_dylib(P, filename);
else
fprintf(stderr, "** unrecognized file extension: %s\n", file_ext);
} else {
fprintf(stderr, "** no file extension: %s\n", filename);
}
-
+ free(filename);
return PN_NIL;
}
void potion_loader_init(Potion *P) {
+ pn_loader_path = PN_TUP0();
+ PN_PUSH(pn_loader_path, potion_str(P, "."));
+ PN_PUSH(pn_loader_path, potion_str(P, "./lib"));
+
+ potion_define_global(P, potion_str(P, "LOADER_PATH"), pn_loader_path);
potion_method(P->lobby, "load", potion_load, "file=S");
}
View
10 core/potion.c
@@ -243,11 +243,11 @@ int main(int argc, char *argv[]) {
if (!exec || verbose) potion_fatal("no filename given");
Potion *P = potion_create(sp);
potion_eval(P, potion_byte_str(P,
+ "load 'readline'\n" \
"loop:\n" \
- " '>> ' print\n" \
- " code = read\n" \
- " if (not code): break.\n" \
- " if (code != \"\\n\"):\n" \
+ " code = readline('>> ')\n" \
+ " if (not code): \"\\n\" print, break.\n" \
+ " if (code != ''):\n" \
" obj = code eval\n" \
" if (obj kind == Error):\n" \
" obj string print." \
@@ -257,4 +257,4 @@ int main(int argc, char *argv[]) {
potion_destroy(P);
}
return 0;
-}
+}
View
4 lib/readline/Makefile
@@ -5,5 +5,5 @@ CFLAGS = $(INCS) $(LIBS) -Wall -fno-strict-aliasing -Wno-return-type -fpic -Wl,-
all: readline.so
-readline.so:
- @$(CC) -shared $(CFLAGS) -o $@ readline.c
+%.so: %.c
+ @$(CC) -shared $(CFLAGS) -o $@ $<

0 comments on commit ed9e1ff

Please sign in to comment.
Something went wrong with that request. Please try again.