21 if (stat(filename, &stats) == -1) {
22 fprintf(stderr,
"** %s does not exist.", filename);
25 fd = open(filename, O_RDONLY |
O_BINARY);
27 fprintf(stderr,
"** could not open %s. check permissions.", filename);
31 if (read(fd,
PN_STR_PTR(buf), stats.st_size) == stats.st_size) {
41 fprintf(stderr,
"** could not read entire file: %s.", filename);
49 char *allocated_str, *ext_name, *func_name;
50 while (*(filename + ++ext_name_len) !=
'.' && ext_name_len <= len);
51 allocated_str = ext_name = malloc(ext_name_len + 1);
53 strncpy(ext_name, filename, ext_name_len);
54 ext_name[ext_name_len] =
'\0';
55 ext_name += ext_name_len;
56 while (*--ext_name !=
'/' && ext_name >= allocated_str);
58 if (asprintf(&func_name,
"Potion_Init_%s", ext_name) == -1)
65 void *handle = dlopen(filename, RTLD_LAZY);
67 char *err, *init_func_name;
70 fprintf(stderr,
"** error loading %s: %s\n", filename, dlerror());
74 func = (void (*)(
Potion *))dlsym(handle, init_func_name);
75 err = (
char *)dlerror();
78 fprintf(stderr,
"** error loading %s in %s: %s\n", init_func_name, filename, err);
101 char buf[str_len + len + 1];
102 strncpy(buf, str, str_len);
104 buf[str_len + len] =
'\0';
105 if (stat(buf, &st) == 0 && S_ISREG(st.st_mode))
114 if (!str_len) str_len = strlen(str);
117 char dirname[prefix_len + 1 + str_len + 1];
118 char *str_pos = dirname + prefix_len + 1;
121 memcpy(str_pos, str, str_len);
122 dot = memchr(str,
'.', str_len);
124 dirname[
sizeof(dirname) - 1] =
'\0';
127 memcpy(dirname,
PN_STR_PTR(prefix), prefix_len);
128 dirname[prefix_len] =
'/';
129 if (stat(dirname, &st) == 0 && S_ISREG(st.st_mode)) {
137 if ((file = strrchr(str,
'/')) == NULL)
142 if (stat(r, &st) != 0 || !S_ISREG(st.st_mode)) {
143 int r_len = prefix_len + 1 + str_len * 2 + 1;
144 if ((ext =
find_extension(r)) == NULL) { free(r); r = NULL;
continue; }
145 r = realloc(r, r_len + strlen(ext));
147 strcpy(r + r_len, ext);
161 if (filename == NULL) {
162 fprintf(stderr,
"** can't find %s\n",
PN_STR_PTR(file));
165 file_ext = filename + strlen(filename);
166 while (*--file_ext !=
'.' && file_ext >= filename);
167 if (file_ext++ != filename) {
168 if (strcmp(file_ext,
"pn") == 0)
170 else if (strcmp(file_ext,
"pnb") == 0)
175 fprintf(stderr,
"** unrecognized file extension: %s\n", file_ext);
177 fprintf(stderr,
"** no file extension: %s\n", filename);
PN potion_bytes(Potion *, size_t)
PN potion_str(Potion *, const char *)
static char * potion_initializer_name(Potion *P, const char *filename, PN_SIZE len)
#define potion_method(RCV, MSG, FN, SIG)
PN potion_source_load(Potion *P, PN cl, PN buf)
PN potion_load(Potion *P, PN cl, PN self, PN file)
PN potion_run(Potion *P, PN code, int jit)
void potion_define_global(Potion *P, PN name, PN val)
PN potion_parse(Potion *, PN, char *)
static PN potion_load_dylib(Potion *P, const char *filename)
static PN potion_load_code(Potion *P, const char *filename)
static const char * find_extension(char *str)
static const char * pn_loader_extensions[]
the global interpreter state P. currently singleton (not threads yet)
void potion_loader_init(Potion *P)
the central table type, based on core/khash.h
#define potion_send(RCV, MSG, ARGS...)
method caches (more great stuff from ian piumarta)
void potion_allocation_error(void)
void potion_loader_add(Potion *P, PN path)
#define PN_TUPLE_EACH(T, I, V, B)
char * potion_find_file(Potion *P, char *str, PN_SIZE str_len)