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.
This commit is contained in:
Paul Smith 2012-01-16 03:32:49 +00:00
parent 4e2e5eb199
commit 49cc211819
5 changed files with 59 additions and 27 deletions

View file

@ -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>

View file

@ -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)
{

27
guile.c
View file

@ -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;
}

3
make.h
View file

@ -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

View file

@ -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);