summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2012-01-16 03:32:49 +0000
committerPaul Smith <psmith@gnu.org>2012-01-16 03:32:49 +0000
commit49cc211819851b76c58fb37eeb579bd88a5ac65a (patch)
tree7846b379f1444f31458313bc97b2acf24c8a2a87
parent4e2e5eb199b5fbaf7cfdb203c64099b514fba5d0 (diff)
downloadmake-49cc211819851b76c58fb37eeb579bd88a5ac65a.tar.gz
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.
-rw-r--r--ChangeLog8
-rw-r--r--function.c45
-rw-r--r--guile.c27
-rw-r--r--make.h3
-rw-r--r--variable.h3
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 <psmith@gnu.org>
+ * 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 <psmith@gnu.org>
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},
@@ -2432,6 +2414,33 @@ func_call (char *o, char **argv, const char *funcname UNUSED)
}
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)
{
hash_init (&function_table, FUNCTION_TABLE_ENTRIES * 2,
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);