summaryrefslogtreecommitdiff
path: root/xen.c
diff options
context:
space:
mode:
authorAlessio Treglia <alessio@debian.org>2011-03-24 09:13:51 +0100
committerAlessio Treglia <alessio@debian.org>2011-03-24 09:13:51 +0100
commite5328e59987b90c4e98959510b810510e384650d (patch)
tree0f140b79d942c4654701d8fb4cfe2f1dd904f9f0 /xen.c
parent36cf8384e5699cda3f1ca607753fe4d4a8515b01 (diff)
Imported Upstream version 12.0
Diffstat (limited to 'xen.c')
-rw-r--r--xen.c447
1 files changed, 135 insertions, 312 deletions
diff --git a/xen.c b/xen.c
index 48e8910..0f7be8b 100644
--- a/xen.c
+++ b/xen.c
@@ -162,9 +162,7 @@ int xen_to_c_int_or_else(XEN obj, int fallback)
void xen_gc_mark(XEN val)
{
-#if HAVE_REASONABLE_RB_GC_MARK
rb_gc_mark(val);
-#endif
}
@@ -567,14 +565,6 @@ static XEN xen_rb_rescue(XEN val)
}
-#if (!HAVE_RB_ERRINFO)
-XEN rb_errinfo(void)
-{
- return ruby_errinfo;
-}
-#endif
-
-
void xen_repl(int argc, char **argv)
{
while (true)
@@ -585,7 +575,7 @@ void xen_repl(int argc, char **argv)
&status);
if (status != 0)
{
- fprintf(stderr, "%s\n", XEN_AS_STRING(rb_errinfo()));
+ fprintf(stderr, "%s\n", XEN_AS_STRING(rb_gv_get("$!")));
status = 0;
}
}
@@ -598,7 +588,7 @@ XEN xen_rb_eval_string_with_error(const char *str)
XEN res;
res = rb_eval_string_protect(str, &status);
if (status != 0)
- return(XEN_TO_STRING(rb_errinfo()));
+ return(XEN_TO_STRING(rb_gv_get("$!")));
return(res);
}
@@ -608,27 +598,20 @@ XEN xen_rb_load_file_with_error(XEN file)
int status = 0;
rb_load_protect(file, 0, &status);
if (status != 0)
- return(XEN_TO_STRING(rb_errinfo()));
+ return(XEN_TO_STRING(rb_gv_get("$!")));
return(XEN_TRUE);
}
-XEN xen_rb_add_to_load_path(char *path)
-{
-#if (!HAVE_RB_GET_LOAD_PATH)
- extern VALUE rb_load_path;
- XEN rpath;
- rpath = rb_str_new2(path);
- if (XEN_FALSE_P(rb_ary_includes(rb_load_path, rpath)))
- rb_ary_unshift(rb_load_path, rpath);
-#else
- XEN rpath;
- rpath = rb_str_new2(path);
- if (XEN_FALSE_P(rb_ary_includes(rb_get_load_path(), rpath)))
- rb_ary_unshift(rb_get_load_path(), rpath);
-#endif
- return(XEN_FALSE);
-}
+XEN xen_rb_add_to_load_path(char *path)
+{
+ XEN rpath, load_path;
+ rpath = rb_str_new2(path);
+ load_path = rb_gv_get("$:");
+ if (XEN_FALSE_P(rb_ary_includes(load_path, rpath)))
+ rb_ary_unshift(load_path, rpath);
+ return(XEN_FALSE);
+}
static char *lstbuf = NULL;
@@ -680,11 +663,24 @@ XEN xen_rb_obj_as_string(XEN obj)
}
+#if HAVE_RB_PROC_NEW
+
+static XEN xen_rb_apply_1(XEN args)
+{
+ return(rb_apply(XEN_CAR(args), rb_intern("call"), XEN_CADR(args)));
+}
+
+#else
+
static XEN xen_rb_apply_1(XEN args)
{
- return(rb_apply(XEN_CAR(args), rb_intern("call"), XEN_CADR(args)));
+ if (XEN_PROCEDURE_P(XEN_CAR(args)))
+ return(rb_apply(XEN_CAR(args), rb_intern("call"), XEN_CADR(args)));
+ return(rb_apply(rb_mKernel, XEN_CAR(args), XEN_CADR(args)));
}
+#endif
+
XEN xen_rb_apply(XEN func, XEN args)
{
@@ -694,7 +690,7 @@ XEN xen_rb_apply(XEN func, XEN args)
XEN_LIST_2(func, args),
&status);
if (status != 0)
- return(XEN_TO_STRING(rb_errinfo()));
+ return(XEN_TO_STRING(rb_gv_get("$!")));
return(val);
}
@@ -713,7 +709,7 @@ XEN xen_rb_funcall_0(XEN func)
func,
&status);
if (status != 0)
- return(XEN_TO_STRING(rb_errinfo()));
+ return(XEN_TO_STRING(rb_gv_get("$!")));
return(val);
}
@@ -722,22 +718,7 @@ XEN xen_rb_copy_list(XEN val)
{
if ((val == XEN_EMPTY_LIST) || (!XEN_CONS_P(val)))
return XEN_EMPTY_LIST;
-
-#if (!HAVE_RB_ARY_DUP)
- {
- /* if this is considered bad form, we could fall back on flatten (rb_ary_dup?) */
- long len, i;
- VALUE collect;
- len = RB_ARRAY_LEN(val);
- collect = rb_ary_new2(len);
- for (i = 0; i < len; i++)
- RB_ARRAY_PTR(collect)[i] = RB_ARRAY_PTR(val)[i];
- RB_ARRAY_LEN(collect) = len;
- return(collect);
- }
-#else
return rb_ary_dup(val);
-#endif
}
@@ -885,6 +866,59 @@ static XEN xen_rb_hook_add_hook(int argc, XEN *argv, XEN hook)
}
+#if HAVE_RB_PROC_NEW
+
+static XEN xen_proc_call(XEN args, XEN id)
+{
+ return(rb_apply(rb_mKernel, (ID)id, XEN_CONS_P(args) ? args : XEN_LIST_1(args)));
+}
+
+#if 0
+ VALUE rb_proc_new((VALUE (*)(ANYARGS/* VALUE yieldarg[, VALUE procarg] */), VALUE));
+#endif
+
+static XEN xen_rb_proc_new(const char *name, XEN (*func)(), int arity, const char* doc)
+{
+ rb_define_module_function(rb_mKernel, name, XEN_PROCEDURE_CAST func, arity);
+ if (doc) C_SET_OBJECT_HELP(name, doc);
+ return(rb_proc_new(XEN_PROCEDURE_CAST xen_proc_call, rb_intern(name)));
+}
+
+
+static XEN xen_rb_hook_arity(XEN hook);
+
+XEN xen_rb_add_hook(XEN hook, VALUE (*func)(), const char *name, const char* doc)
+{
+ /* called from C, not Ruby, to add a function to a Ruby-side hook */
+ char *temp;
+ temp = xen_scheme_procedure_to_ruby(name);
+ rb_ary_push(rb_iv_get(hook, "@procs"), rb_ary_new3(2, C_TO_XEN_STRING(temp), xen_rb_proc_new(temp, func, XEN_TO_C_INT(xen_rb_hook_arity(hook)), doc)));
+ if (temp) free(temp);
+ return(hook);
+}
+
+#else
+
+XEN xen_rb_add_hook(XEN hook, VALUE (*func)(), const char *name, const char* doc)
+{
+ /* called from C, not Ruby, to add a function to a Ruby-side hook
+ * this doesn't work in g++ because it thinks the funcs are invalid:
+ * "error: invalid conversion from 'VALUE (*)(VALUE, VALUE)' to 'VALUE (*)(...)'" (snd-file.c etc)
+ */
+ XEN var;
+ char *temp;
+ temp = xen_scheme_procedure_to_ruby(name);
+ rb_define_module_function(rb_mKernel, temp, XEN_PROCEDURE_CAST func, XEN_TO_C_INT_OR_ELSE(rb_iv_get(hook, "@arity"), 0));
+ if (doc) C_SET_OBJECT_HELP(temp, doc);
+ var = rb_intern(temp);
+ rb_ary_push(rb_iv_get(hook, "@procs"), rb_ary_new3(2, C_TO_XEN_STRING(temp), var));
+ if (temp) free(temp);
+ return(hook);
+}
+
+#endif
+
+
static XEN xen_rb_hook_remove_hook(XEN hook, XEN name)
{
XEN ary;
@@ -1030,6 +1064,20 @@ XEN xen_rb_create_hook(char *name, int arity, char *help)
return(var);
}
+static int simple_hook_number = 0;
+
+
+XEN xen_rb_create_simple_hook(int arity)
+{
+ char *name;
+ XEN hook;
+ name = (char *)calloc(20, sizeof(char));
+ snprintf(name, 20, "simple_%02d_hook", simple_hook_number++);
+ hook = xen_rb_create_hook(name, arity, NULL);
+ free(name);
+ return(hook);
+}
+
/*
* make_hook(name, arity = 0, help = "", hook_name = nil, &func)
@@ -1179,24 +1227,16 @@ XEN rb_properties(void)
static XEN g_gc_off(void)
{
-#if HAVE_RB_GC_DISABLE
#define H_gc_off "(" S_gc_off ") turns off garbage collection"
rb_gc_disable();
-#else
- #define H_gc_off "(" S_gc_off ") is a no-op"
-#endif
return(XEN_FALSE);
}
static XEN g_gc_on(void)
{
-#if HAVE_RB_GC_DISABLE
#define H_gc_on "(" S_gc_on ") turns on garbage collection"
rb_gc_enable();
-#else
- #define H_gc_on "(" S_gc_on ") is a no-op"
-#endif
return(XEN_FALSE);
}
@@ -1498,11 +1538,20 @@ void xen_s7_ignore(s7_function func) /* squelch compiler warnings */
XEN xen_define_variable(const char *name, XEN value)
{
XEN_DEFINE(name, value);
- s7_gc_protect(s7, value);
+ /* s7_gc_protect(s7, value); */
+ /* XEN_DEFINE places value in the global env, so it is already gc protected */
return(C_STRING_TO_XEN_SYMBOL(name));
}
+XEN xen_s7_define_hook(const char *name, XEN value)
+{
+ s7_define_constant(s7, name, value);
+ /* s7_gc_protect(s7, value); -- see above */
+ return(value);
+}
+
+
void xen_gc_mark(XEN val)
{
s7_mark_object(val);
@@ -1595,241 +1644,6 @@ XEN xen_assoc(s7_scheme *sc, XEN key, XEN alist)
}
-/* hooks */
-
-typedef struct {
- int arity;
- XEN functions;
- const char *documentation;
-} ghook;
-
-static XEN_OBJECT_TYPE ghook_tag;
-
-#define XEN_TO_GHOOK(Obj) (ghook *)XEN_OBJECT_REF(Obj)
-
-static int ghook_arity(ghook *hook) {return(hook->arity);}
-
-static XEN ghook_functions(ghook *hook) {return(hook->functions);}
-
-static void reset_ghook(ghook *hook) {hook->functions = XEN_EMPTY_LIST;}
-
-
-static ghook *make_ghook(int arity)
-{
- ghook *hook;
- hook = (ghook *)calloc(1, sizeof(ghook));
- hook->arity = arity;
- hook->functions = XEN_EMPTY_LIST;
- hook->documentation = NULL;
- return(hook);
-}
-
-
-static void free_ghook(ghook *hook)
-{
- if (hook)
- {
- hook->functions = XEN_FALSE;
- free(hook);
- }
-}
-
-
-static char *hook_to_string(ghook *hook)
-{
- if (hook)
- {
- int len;
- char *functions = NULL, *str;
- functions = XEN_AS_STRING(hook->functions);
- len = 64 + strlen(functions);
- str = (char *)calloc(len, sizeof(char));
- snprintf(str, len, "<hook arity: %d, hooks: %s>", hook->arity, functions);
- if (functions) free(functions);
- return(str);
- }
- return(NULL);
-}
-
-
-static void add_ghook(ghook *hook, XEN function, bool at_end)
-{
- if (at_end)
- hook->functions = XEN_APPEND(hook->functions, XEN_LIST_1(function));
- else hook->functions = XEN_CONS(function, hook->functions);
-}
-
-
-bool xen_hook_p(XEN obj)
-{
- return(XEN_OBJECT_TYPE_P(obj, ghook_tag));
-}
-
-
-static XEN g_hook_p(XEN val)
-{
- return(C_TO_XEN_BOOLEAN(xen_hook_p(val)));
-}
-
-
-static XEN g_hook_empty_p(XEN hook)
-{
- XEN_ASSERT_TYPE(xen_hook_p(hook), hook, XEN_ONLY_ARG, "hook-empty?", "a hook");
- return(C_TO_XEN_BOOLEAN(XEN_NULL_P(ghook_functions(XEN_TO_GHOOK(hook)))));
-}
-
-
-bool xen_hook_empty_p(XEN hook)
-{
- return(XEN_NULL_P(ghook_functions(XEN_TO_GHOOK(hook))));
-}
-
-
-XEN xen_hook_to_list(XEN hook)
-{
- XEN_ASSERT_TYPE(xen_hook_p(hook), hook, XEN_ONLY_ARG, "hook->list", "a hook");
- return(ghook_functions(XEN_TO_GHOOK(hook)));
-}
-
-
-const char *xen_s7_hook_documentation(XEN hook)
-{
- ghook *obj;
- obj = XEN_TO_GHOOK(hook);
- return(obj->documentation);
-}
-
-
-static XEN g_make_hook(XEN arity, XEN help)
-{
- ghook *hook;
- XEN_ASSERT_TYPE(XEN_INTEGER_P(arity), arity, XEN_ARG_1, "make-hook", "an integer");
- XEN_ASSERT_TYPE(XEN_STRING_P(help) || XEN_NOT_BOUND_P(help), help, XEN_ARG_2, "make-hook", "a string if bound");
- hook = make_ghook(XEN_TO_C_INT(arity));
- if (XEN_STRING_P(help)) hook->documentation = xen_strdup(XEN_TO_C_STRING(help));
- XEN_MAKE_AND_RETURN_OBJECT(ghook_tag, hook, 0, 0);
-}
-
-
-static XEN g_add_hook(XEN hook, XEN function, XEN position)
-{
- ghook *obj;
- XEN arity;
- bool at_end = false, arity_ok;
- int gc_loc;
-
- obj = XEN_TO_GHOOK(hook);
- XEN_ASSERT_TYPE(xen_hook_p(hook), hook, XEN_ARG_1, "add-hook!", "a hook");
- XEN_ASSERT_TYPE(XEN_PROCEDURE_P(function), function, XEN_ARG_2, "add-hook!", "a function");
- XEN_ASSERT_TYPE(XEN_BOOLEAN_IF_BOUND_P(position), position, XEN_ARG_3, "add-hook!", "boolean");
-
- arity = XEN_ARITY(function);
- gc_loc = s7_gc_protect(s7, arity);
- arity_ok = ((XEN_TO_C_INT(XEN_CAR(arity)) == ghook_arity(obj)) ||
- (XEN_TO_C_INT(XEN_CAR(arity)) + XEN_TO_C_INT(XEN_CADR(arity)) >= ghook_arity(obj)) ||
- (XEN_TRUE_P(XEN_CADDR(arity))));
- s7_gc_unprotect_at(s7, gc_loc);
- XEN_ASSERT_TYPE(arity_ok, function, XEN_ARG_2, "add-hook!", "a function whose arity matches the hook's");
-
- if (XEN_BOOLEAN_P(position)) at_end = XEN_TO_C_BOOLEAN(position);
- add_ghook(obj, function, at_end);
- return(hook);
-}
-
-
-XEN xen_s7_reset_hook(XEN hook)
-{
- XEN_ASSERT_TYPE(xen_hook_p(hook), hook, XEN_ONLY_ARG, "reset-hook!", "a hook");
- reset_ghook(XEN_TO_GHOOK(hook));
- return(hook);
-}
-
-
-static XEN g_run_hook(XEN all_args)
-{
- XEN hook, args;
- ghook *obj;
- int arglen;
- XEN functions, val = XEN_FALSE;
-
- hook = XEN_CAR(all_args);
- XEN_ASSERT_TYPE(xen_hook_p(hook), hook, XEN_ARG_1, "run-hook", "a hook");
-
- obj = XEN_TO_GHOOK(hook);
- args = XEN_CDR(all_args);
- arglen = XEN_LIST_LENGTH(args);
-
- if (ghook_arity(obj) != arglen)
- XEN_ERROR(XEN_ERROR_TYPE("wrong-number-of-args"),
- XEN_LIST_5(C_TO_XEN_STRING("run hook (~A) got ~A args, but wants ~A (args: ~A)"),
- hook,
- C_TO_XEN_INT(arglen),
- C_TO_XEN_INT(ghook_arity(obj)),
- args));
-
-
- functions = ghook_functions(obj);
- while (XEN_NOT_NULL_P(functions))
- {
- val = XEN_APPLY(XEN_CAR(functions), args, "run-hook");
- functions = XEN_CDR(functions);
- }
-
- return(val);
-}
-
-
-static XEN g_remove_hook(XEN hook, XEN function)
-{
- ghook *obj;
- XEN_ASSERT_TYPE(xen_hook_p(hook), hook, XEN_ARG_1, "remove-hook!", "a hook");
- obj = XEN_TO_GHOOK(hook);
- XEN_ASSERT_TYPE(XEN_PROCEDURE_P(function), function, XEN_ARG_2, "remove-hook!", "a function");
- obj->functions = s7_remv(s7, obj->functions, function);
- return(hook);
-}
-
-
-XEN xen_s7_define_hook(const char *name, int arity, const char *help)
-{
- XEN hook;
- ghook *obj;
- hook = g_make_hook(C_TO_XEN_INT(arity), XEN_UNDEFINED);
- obj = XEN_TO_GHOOK(hook);
- obj->documentation = help;
- if (name)
- {
- XEN_DEFINE(name, hook);
- }
- s7_gc_protect(s7, hook);
- return(hook);
-}
-
-
-static bool equalp_hook(void *uv1, void *uv2)
-{
- return(uv1 == uv2);
-}
-
-
-static void mark_hook(void *v)
-{
- s7_mark_object(((ghook *)v)->functions);
-}
-
-
-static void free_hook(void *v)
-{
- free_ghook((ghook *)v);
-}
-
-
-static char *print_hook(s7_scheme *sc, void *v)
-{
- return(hook_to_string((ghook *)v));
-}
-
-
/* add various file functions that everyone else implements */
#if (defined(HAVE_LIBC_H) && (!defined(HAVE_UNISTD_H)))
@@ -2058,15 +1872,6 @@ static XEN g_gc_on(void)
-XEN_NARGIFY_1(g_hook_p_w, g_hook_p);
-XEN_NARGIFY_1(g_hook_empty_p_w, g_hook_empty_p)
-XEN_NARGIFY_2(g_remove_hook_w, g_remove_hook)
-XEN_NARGIFY_1(g_hook_to_list_w, xen_hook_to_list)
-XEN_VARGIFY(g_run_hook_w, g_run_hook)
-XEN_NARGIFY_1(g_reset_hook_w, xen_s7_reset_hook)
-XEN_ARGIFY_2(g_make_hook_w, g_make_hook)
-XEN_ARGIFY_3(g_add_hook_w, g_add_hook)
-
XEN_NARGIFY_0(g_getpid_w, g_getpid)
XEN_NARGIFY_1(g_file_exists_p_w, g_file_exists_p)
XEN_NARGIFY_1(g_file_is_directory_w, g_file_is_directory)
@@ -2104,20 +1909,10 @@ s7_scheme *s7_xen_initialize(s7_scheme *sc)
xen_undefined = s7_undefined(s7);
xen_zero = s7_make_integer(s7, 0);
- ghook_tag = XEN_MAKE_OBJECT_TYPE("<hook>", print_hook, free_hook, equalp_hook, mark_hook, NULL, NULL, NULL, NULL, NULL);
-
- XEN_DEFINE_PROCEDURE("hook?", g_hook_p_w, 1, 0, 0, "(hook? obj) -> #t if obj is a hook");
- XEN_DEFINE_PROCEDURE("hook-empty?", g_hook_empty_p_w, 1, 0, 0, "(hook-empty? hook) -> #t if obj is an empty hook");
- XEN_DEFINE_PROCEDURE("remove-hook!", g_remove_hook_w, 2, 0, 0, "(remove-hook! hook func) removes func from hook obj");
- XEN_DEFINE_PROCEDURE("reset-hook!", g_reset_hook_w, 1, 0, 0, "(reset-hook! hook) removes all funcs from hook obj");
- XEN_DEFINE_PROCEDURE("hook->list", g_hook_to_list_w, 1, 0, 0, "(hook->list hook) -> list of functions on hook obj");
- XEN_DEFINE_PROCEDURE("run-hook", g_run_hook_w, 0, 0, 1, "(run-hook hook . args) applies each hook function to args");
- XEN_DEFINE_PROCEDURE("make-hook", g_make_hook_w, 1, 1, 0, "(make-hook arity :optional help) makes a new hook object");
- XEN_DEFINE_PROCEDURE("add-hook!", g_add_hook_w, 2, 1, 0, "(add-hook! hook func :optional append) adds func to the hooks function list");
-
XEN_DEFINE_PROCEDURE("getpid", g_getpid_w, 0, 0, 0, H_getpid);
XEN_DEFINE_PROCEDURE("file-exists?", g_file_exists_p_w, 1, 0, 0, H_file_exists_p);
- XEN_DEFINE_PROCEDURE("file-is-directory?", g_file_is_directory_w, 1, 0, 0, H_file_is_directory); /* "directory?" would be a better name, but we follow Guile */
+ XEN_DEFINE_PROCEDURE("directory?", g_file_is_directory_w, 1, 0, 0, H_file_is_directory);
+ XEN_EVAL_C_STRING("(define file-is-directory? directory?)"); /* backwards compatibility: */
XEN_DEFINE_PROCEDURE("system", g_system_w, 1, 0, 0, H_system);
XEN_DEFINE_PROCEDURE("getenv", g_s7_getenv_w, 1, 0, 0, H_getenv);
XEN_DEFINE_PROCEDURE("delete-file", g_delete_file_w, 1, 0, 0, H_delete_file);
@@ -2130,6 +1925,34 @@ s7_scheme *s7_xen_initialize(s7_scheme *sc)
XEN_DEFINE_PROCEDURE(S_gc_off, g_gc_off_w, 0, 0, 0, H_gc_off);
XEN_DEFINE_PROCEDURE(S_gc_on, g_gc_on_w, 0, 0, 0, H_gc_on);
+ /* backwards compatibility (guile hook functions) */
+ XEN_EVAL_C_STRING("(define (hook-empty? hook) (null? (hook-functions hook)))");
+ XEN_EVAL_C_STRING("(define (reset-hook! hook) (set! (hook-functions hook) '()))");
+ XEN_EVAL_C_STRING("(define (run-hook . args) (hook-apply (car args) (cdr args)))");
+ XEN_EVAL_C_STRING("(define hook->list hook-functions)");
+ XEN_EVAL_C_STRING("(define* (add-hook! hook func (at-end #f)) \n\
+ (set! (hook-functions hook) \n\
+ (if (not at-end) \n\
+ (cons func (hook-functions hook)) \n\
+ (append (hook-functions hook) (list func)))))");
+ XEN_EVAL_C_STRING("(define (remove-hook! hook func) \n\
+ (set! (hook-functions hook)\n\
+ (let loop ((l (hook-functions hook))\n\
+ (result '()))\n\
+ (cond ((null? l) (reverse! result))\n\
+ ((eq? func (car l)) (loop (cdr l) result))\n\
+ (else (loop (cdr l) (cons (car l) result)))))))");
+
+ /* these three to replace add-hook! and remove-hook! */
+ XEN_EVAL_C_STRING("(define (hook-push hook func) \n\
+ \"(hook-push hook func) adds func to hook's function list\" \n\
+ (set! (hook-functions hook) (cons func (hook-functions hook))))");
+ XEN_EVAL_C_STRING("(define (hook-append hook func) \n\
+ \"(hook-append hook func) adds func to the end of hook's function list\" \n\
+ (set! (hook-functions hook) (append (hook-functions hook) (list func))))");
+ XEN_EVAL_C_STRING("(define hook-remove remove-hook!)");
+
+
XEN_EVAL_C_STRING("(define load-from-path load)");
XEN_EVAL_C_STRING("(define (1+ x) \"add 1 to arg\" (+ x 1))");
XEN_EVAL_C_STRING("(define (1- x) \"subtract 1 from arg\" (- x 1))");