From 49cc211819851b76c58fb37eeb579bd88a5ac65a Mon Sep 17 00:00:00 2001 From: Paul Smith Date: Mon, 16 Jan 2012 03:32:49 +0000 Subject: Create a new internal interface for defining new make functions. This allows us to create new functions without changing function.c. You still have to modify the GNU make code (for now) though: this is simply a preliminary step to possibly allowing make to load modules. Modify the Guile integration to use this method rather than ifdefs in function.c. --- ChangeLog | 8 ++++++++ function.c | 45 +++++++++++++++++++++++++++------------------ guile.c | 27 ++++++++++++++++++++------- make.h | 3 +-- variable.h | 3 +++ 5 files changed, 59 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7dd5d1e..f58922e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2012-01-15 Paul Smith + * variable.h: Prototype an interface for defining new make functions. + * function.c (define_new_function): Define it. + (func_guile): Remove the "guile" function. + (function_table_init): Ditto. + * guile.c (func_guile): Add the "guile" function here. + (setup_guile): Call define_new_function() to define it. + (guile_eval_string): Obsolete. + * all: Update copyright notices. 2012-01-12 Paul Smith diff --git a/function.c b/function.c index 77592db..c387b35 100644 --- a/function.c +++ b/function.c @@ -2103,21 +2103,6 @@ func_abspath (char *o, char **argv, const char *funcname UNUSED) return o; } -#ifdef HAVE_GUILE -static char * -func_guile (char *o, char **argv, const char *funcname UNUSED) -{ - if (argv[0] && argv[0][0] != '\0') - { - char *str = guile_eval_string (argv[0]); - o = variable_buffer_output (o, str, strlen (str)); - free (str); - } - - return o; -} -#endif - /* Lookup table for builtin functions. This doesn't have to be sorted; we use a straight lookup. We might gain @@ -2171,9 +2156,6 @@ static struct function_table_entry function_table_init[] = { STRING_SIZE_TUPLE("and"), 1, 0, 0, func_and}, { STRING_SIZE_TUPLE("value"), 0, 1, 1, func_value}, { STRING_SIZE_TUPLE("eval"), 0, 1, 1, func_eval}, -#ifdef HAVE_GUILE - { STRING_SIZE_TUPLE("guile"), 0, 1, 1, func_guile}, -#endif #ifdef EXPERIMENTAL { STRING_SIZE_TUPLE("eq"), 2, 2, 1, func_eq}, { STRING_SIZE_TUPLE("not"), 0, 1, 1, func_not}, @@ -2431,6 +2413,33 @@ func_call (char *o, char **argv, const char *funcname UNUSED) return o + strlen (o); } +void +define_new_function(const struct floc *flocp, + const char *name, int min, int max, int expand, + char *(*func)(char *, char **, const char *)) +{ + size_t len = strlen (name); + struct function_table_entry *ent = xmalloc (sizeof (struct function_table_entry)); + + if (len > 255) + fatal (flocp, _("Function name too long: %s\n"), name); + if (min < 0 || min > 255) + fatal (flocp, _("Invalid minimum argument count (%d) for function %s%s\n"), + min, name); + if (max < 0 || max > 255 || max < min) + fatal (flocp, _("Invalid maximum argument count (%d) for function %s%s\n"), + max, name); + + ent->name = name; + ent->len = len; + ent->minimum_args = min; + ent->maximum_args = max; + ent->expand_args = expand ? 1 : 0; + ent->func_ptr = func; + + hash_insert (&function_table, ent); +} + void hash_init_function_table (void) { diff --git a/guile.c b/guile.c index 060c6d6..c32821a 100644 --- a/guile.c +++ b/guile.c @@ -85,20 +85,33 @@ internal_guile_eval (void *arg) return cvt_scm_to_str (scm_c_eval_string (arg)); } -/* ----- Public interface ----- */ - -/* This is the make interface for passing programs to Guile. */ -char * -guile_eval_string (char *str) +/* This is the function registered with make */ +static char * +func_guile (char *o, char **argv, const char *funcname UNUSED) { - return scm_with_guile (internal_guile_eval, str); + if (argv[0] && argv[0][0] != '\0') + { + char *str = scm_with_guile (internal_guile_eval, argv[0]); + o = variable_buffer_output (o, str, strlen (str)); + free (str); + } + + return o; } -void +/* ----- Public interface ----- */ + +int setup_guile () { + /* Initialize the Guile interpreter. */ scm_with_guile (guile_init, NULL); + /* Create a make function "guile". */ + define_new_function (NILF, "guile", 0, 1, 1, func_guile); + /* Add 'guile' to the list of features. */ do_variable_definition (NILF, ".FEATURES", "guile", o_default, f_append, 0); + + return 1; } diff --git a/make.h b/make.h index 1a89b9c..8caf14a 100644 --- a/make.h +++ b/make.h @@ -466,8 +466,7 @@ const char *strcache_add_len (const char *str, unsigned int len); int strcache_setbufsize (unsigned int size); /* Guile support */ -char *guile_eval_string (char *str); -void setup_guile (void); +int setup_guile (void); #ifdef HAVE_VFORK_H diff --git a/variable.h b/variable.h index d695287..1fd1b66 100644 --- a/variable.h +++ b/variable.h @@ -167,6 +167,9 @@ struct variable *try_variable_definition (const struct floc *flocp, char *line, int target_var); void init_hash_global_variable_set (void); void hash_init_function_table (void); +void define_new_function(const struct floc *flocp, + const char *name, int min, int max, int expand, + char *(*func)(char *, char **, const char *)); struct variable *lookup_variable (const char *name, unsigned int length); struct variable *lookup_variable_in_set (const char *name, unsigned int length, const struct variable_set *set); -- cgit v1.2.3