mirror of
https://github.com/mirror/make.git
synced 2025-01-27 21:00:22 +08:00
* Make some portability fixes.
This commit is contained in:
parent
c8a60e7431
commit
b05cb1d99e
11
ChangeLog
11
ChangeLog
@ -4,6 +4,17 @@
|
|||||||
|
|
||||||
* Makefile.am (AUTOMAKE_OPTIONS): Require automake 1.4.
|
* Makefile.am (AUTOMAKE_OPTIONS): Require automake 1.4.
|
||||||
|
|
||||||
|
* function.c: Rearrange so we don't need to predeclare the
|
||||||
|
function_table array; K&R C compilers don't like that.
|
||||||
|
|
||||||
|
* acinclude.m4 (AC_FUNC_SELECT): Ouch; this requires an ANSI C
|
||||||
|
compiler! Change to work with K&R compilers as well.
|
||||||
|
|
||||||
|
* configure.in (AC_OUTPUT): Put build.sh back. I don't know how I
|
||||||
|
thought it would work this way :-/. We'll have to think of
|
||||||
|
something else.
|
||||||
|
* Makefile.am: Remove rule to create build.sh.
|
||||||
|
|
||||||
* default.c (default_suffix_rules): Rearrange the default command
|
* default.c (default_suffix_rules): Rearrange the default command
|
||||||
lines to conform to POSIX rules (put the filename argument $<
|
lines to conform to POSIX rules (put the filename argument $<
|
||||||
_after_ the OUTPUT_OPTION, not before it).
|
_after_ the OUTPUT_OPTION, not before it).
|
||||||
|
@ -31,13 +31,6 @@ MOSTLYCLEANFILES = loadavg.c
|
|||||||
CLEANFILES = loadavg
|
CLEANFILES = loadavg
|
||||||
|
|
||||||
|
|
||||||
# --------------- Local BUILD Section
|
|
||||||
|
|
||||||
build.sh: $(top_builddir)/config.status $(srcdir)/build.sh.in
|
|
||||||
cd $(top_builddir) \
|
|
||||||
&& CONFIG_FILES=build.sh.in CONFIG_HEADERS= $(SHELL) ./config.status
|
|
||||||
|
|
||||||
|
|
||||||
# --------------- Local INSTALL Section
|
# --------------- Local INSTALL Section
|
||||||
|
|
||||||
# If necessary, change the gid of the app and turn on the setgid flag.
|
# If necessary, change the gid of the app and turn on the setgid flag.
|
||||||
|
11
acinclude.m4
11
acinclude.m4
@ -243,9 +243,16 @@ if test "$ac_cv_func_select" = yes; then
|
|||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif],
|
#endif],
|
||||||
[extern select ($ac_cv_type_fd_set_size_t,
|
[#ifdef __STDC__
|
||||||
|
extern select ($ac_cv_type_fd_set_size_t,
|
||||||
$ac_cv_type_fd_set *, $ac_cv_type_fd_set *, $ac_cv_type_fd_set *,
|
$ac_cv_type_fd_set *, $ac_cv_type_fd_set *, $ac_cv_type_fd_set *,
|
||||||
$ac_type_timeval *);],
|
$ac_type_timeval *);
|
||||||
|
#else
|
||||||
|
extern select ();
|
||||||
|
$ac_cv_type_fd_set_size_t s;
|
||||||
|
$ac_cv_type_fd_set *p;
|
||||||
|
$ac_type_timeval *t;
|
||||||
|
#endif],
|
||||||
[ac_found=yes ; break 3],ac_found=no)
|
[ac_found=yes ; break 3],ac_found=no)
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
|
@ -210,7 +210,7 @@ dnl build.sh is also an AC_OUTPUT, but we can't specify it here because
|
|||||||
dnl it's built from build.template and autoconf will crap out. So, we
|
dnl it's built from build.template and autoconf will crap out. So, we
|
||||||
dnl build it in the makefiles themselves.
|
dnl build it in the makefiles themselves.
|
||||||
|
|
||||||
AC_OUTPUT(Makefile glob/Makefile)
|
AC_OUTPUT(build.sh Makefile glob/Makefile)
|
||||||
|
|
||||||
case "$make_badcust" in
|
case "$make_badcust" in
|
||||||
yes) echo
|
yes) echo
|
||||||
|
364
function.c
364
function.c
@ -37,10 +37,8 @@ struct function_table_entry
|
|||||||
int expand_args;
|
int expand_args;
|
||||||
char *(*func_ptr) PARAMS((char *output, char **argv, const char*funcname));
|
char *(*func_ptr) PARAMS((char *output, char **argv, const char*funcname));
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct function_table_entry function_table[];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing
|
/* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing
|
||||||
each occurrence of SUBST with REPLACE. TEXT is null-terminated. SLEN is
|
each occurrence of SUBST with REPLACE. TEXT is null-terminated. SLEN is
|
||||||
the length of SUBST and RLEN is the length of REPLACE. If BY_WORD is
|
the length of SUBST and RLEN is the length of REPLACE. If BY_WORD is
|
||||||
@ -308,128 +306,6 @@ find_next_argument (startparen, endparen, ptr, end)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *
|
|
||||||
expand_builtin_function (o, argc, argv, entry_p)
|
|
||||||
char *o;
|
|
||||||
int argc;
|
|
||||||
char **argv;
|
|
||||||
struct function_table_entry *entry_p;
|
|
||||||
{
|
|
||||||
int min = (entry_p->required_args > 0
|
|
||||||
? entry_p->required_args
|
|
||||||
: -entry_p->required_args);
|
|
||||||
|
|
||||||
if (argc < min)
|
|
||||||
fatal (reading_file,
|
|
||||||
"Insufficient number of arguments (%d) to function `%s'",
|
|
||||||
argc, entry_p->name);
|
|
||||||
|
|
||||||
if (!entry_p->func_ptr)
|
|
||||||
fatal (reading_file, "Unimplemented on this platform: function `%s'",
|
|
||||||
entry_p->name);
|
|
||||||
|
|
||||||
return entry_p->func_ptr (o, argv, entry_p->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for a function invocation in *STRINGP. *STRINGP points at the
|
|
||||||
opening ( or { and is not null-terminated. If a function invocation
|
|
||||||
is found, expand it into the buffer at *OP, updating *OP, incrementing
|
|
||||||
*STRINGP past the reference and returning nonzero. If not, return zero. */
|
|
||||||
|
|
||||||
int
|
|
||||||
handle_function (op, stringp)
|
|
||||||
char **op;
|
|
||||||
char **stringp;
|
|
||||||
{
|
|
||||||
const struct function_table_entry *entry_p;
|
|
||||||
char openparen = (*stringp)[0];
|
|
||||||
char closeparen = openparen == '(' ? ')' : '}';
|
|
||||||
char *beg = *stringp + 1;
|
|
||||||
char *endref;
|
|
||||||
int count = 0;
|
|
||||||
char *argbeg;
|
|
||||||
register char *p;
|
|
||||||
char **argv, **argvp;
|
|
||||||
int nargs;
|
|
||||||
|
|
||||||
entry_p = lookup_function (function_table, beg);
|
|
||||||
|
|
||||||
if (!entry_p)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* We have found a call to a builtin function. Find the end of the
|
|
||||||
arguments, and do the function. */
|
|
||||||
|
|
||||||
endref = beg + entry_p->len;
|
|
||||||
|
|
||||||
/* Space after function name isn't part of the args. */
|
|
||||||
p = next_token (endref);
|
|
||||||
argbeg = p;
|
|
||||||
|
|
||||||
/* Find the end of the function invocation, counting nested use of
|
|
||||||
whichever kind of parens we use. Since we're looking, count commas
|
|
||||||
to get a rough estimate of how many arguments we might have. The
|
|
||||||
count might be high, but it'll never be low. */
|
|
||||||
|
|
||||||
for (nargs=1; *p != '\0'; ++p)
|
|
||||||
if (*p == ',')
|
|
||||||
++nargs;
|
|
||||||
else if (*p == openparen)
|
|
||||||
++count;
|
|
||||||
else if (*p == closeparen && --count < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (count >= 0)
|
|
||||||
fatal (reading_file,
|
|
||||||
"unterminated call to function `%s': missing `%c'",
|
|
||||||
entry_p->name, closeparen);
|
|
||||||
|
|
||||||
/* Get some memory to store the arg pointers. */
|
|
||||||
argvp = argv = (char **) alloca (sizeof(char *) * (nargs + 2));
|
|
||||||
|
|
||||||
/* Chop the string into arguments, then store the end pointer and a nul.
|
|
||||||
If REQUIRED_ARGS is positive, as soon as we hit that many assume the
|
|
||||||
rest of the string is part of the last argument. */
|
|
||||||
*argvp = argbeg;
|
|
||||||
nargs = 1;
|
|
||||||
while (entry_p->required_args > 0 && nargs < entry_p->required_args)
|
|
||||||
{
|
|
||||||
char *next = find_next_argument (openparen, closeparen, *argvp, p);
|
|
||||||
|
|
||||||
if (!next)
|
|
||||||
break;
|
|
||||||
|
|
||||||
*(++argvp) = next+1;
|
|
||||||
++nargs;
|
|
||||||
}
|
|
||||||
|
|
||||||
*(++argvp) = p+1;
|
|
||||||
*(++argvp) = 0;
|
|
||||||
|
|
||||||
/* If we should expand, do it. */
|
|
||||||
if (entry_p->expand_args)
|
|
||||||
{
|
|
||||||
for (argvp=argv; argvp[1] != 0; ++argvp)
|
|
||||||
*argvp = expand_argument (*argvp, argvp[1]-1);
|
|
||||||
|
|
||||||
/* end pointer doesn't make sense for expanded stuff. */
|
|
||||||
*argvp = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Finally! Run the function... */
|
|
||||||
*op = expand_builtin_function (*op, nargs, argv, entry_p);
|
|
||||||
|
|
||||||
/* If we allocated memory for the expanded args, free it again. */
|
|
||||||
if (entry_p->expand_args)
|
|
||||||
for (argvp=argv; *argvp != 0; ++argvp)
|
|
||||||
free (*argvp);
|
|
||||||
|
|
||||||
*stringp = p;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Glob-expand LINE. The returned pointer is
|
/* Glob-expand LINE. The returned pointer is
|
||||||
only good until the next call to string_glob. */
|
only good until the next call to string_glob. */
|
||||||
|
|
||||||
@ -1726,12 +1602,194 @@ func_if (char* o, char **argv, char *funcname)
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define STRING_SIZE_TUPLE(_s) (_s), (sizeof(_s)-1)
|
||||||
|
|
||||||
|
/* Lookup table for builtin functions.
|
||||||
|
|
||||||
|
This doesn't have to be sorted; we use a straight lookup. We might gain
|
||||||
|
some efficiency by moving most often used functions to the start of the
|
||||||
|
table.
|
||||||
|
|
||||||
|
If REQUIRED_ARGS is positive, the function takes exactly that many
|
||||||
|
arguments. All subsequent text is included with the last argument. So,
|
||||||
|
since $(sort a,b,c) takes only one argument, it will be the full string
|
||||||
|
"a,b,c". If the value is negative, it's the minimum number of arguments.
|
||||||
|
A function can have more, but if it has less an error is generated.
|
||||||
|
|
||||||
|
EXPAND_ARGS means that all arguments should be expanded before invocation.
|
||||||
|
Functions that do namespace tricks (foreach) don't automatically expand. */
|
||||||
|
|
||||||
|
static char *func_call PARAMS((char *o, char **argv, const char *funcname));
|
||||||
|
|
||||||
|
|
||||||
|
static struct function_table_entry function_table[] =
|
||||||
|
{
|
||||||
|
/* Name/size */ /* ARG EXP? Function */
|
||||||
|
{ STRING_SIZE_TUPLE("addprefix"), 2, 1, func_addsuffix_addprefix},
|
||||||
|
{ STRING_SIZE_TUPLE("addsuffix"), 2, 1, func_addsuffix_addprefix},
|
||||||
|
{ STRING_SIZE_TUPLE("basename"), 1, 1, func_basename_dir},
|
||||||
|
{ STRING_SIZE_TUPLE("dir"), 1, 1, func_basename_dir},
|
||||||
|
{ STRING_SIZE_TUPLE("notdir"), 1, 1, func_notdir_suffix},
|
||||||
|
{ STRING_SIZE_TUPLE("subst"), 3, 1, func_subst},
|
||||||
|
{ STRING_SIZE_TUPLE("suffix"), 1, 1, func_notdir_suffix},
|
||||||
|
{ STRING_SIZE_TUPLE("filter"), 2, 1, func_filter_filterout},
|
||||||
|
{ STRING_SIZE_TUPLE("filter-out"), 2, 1, func_filter_filterout},
|
||||||
|
{ STRING_SIZE_TUPLE("findstring"), 2, 1, func_findstring},
|
||||||
|
{ STRING_SIZE_TUPLE("firstword"), 1, 1, func_firstword},
|
||||||
|
{ STRING_SIZE_TUPLE("join"), 2, 1, func_join},
|
||||||
|
{ STRING_SIZE_TUPLE("patsubst"), 3, 1, func_patsubst},
|
||||||
|
{ STRING_SIZE_TUPLE("shell"), 1, 1, func_shell},
|
||||||
|
{ STRING_SIZE_TUPLE("sort"), 1, 1, func_sort},
|
||||||
|
{ STRING_SIZE_TUPLE("strip"), 1, 1, func_strip},
|
||||||
|
{ STRING_SIZE_TUPLE("wildcard"), 1, 1, func_wildcard},
|
||||||
|
{ STRING_SIZE_TUPLE("word"), 2, 1, func_word},
|
||||||
|
{ STRING_SIZE_TUPLE("wordlist"), 3, 1, func_wordlist},
|
||||||
|
{ STRING_SIZE_TUPLE("words"), 1, 1, func_words},
|
||||||
|
{ STRING_SIZE_TUPLE("origin"), 1, 1, func_origin},
|
||||||
|
{ STRING_SIZE_TUPLE("foreach"), 3, 0, func_foreach},
|
||||||
|
{ STRING_SIZE_TUPLE("call"), -1, 1, func_call},
|
||||||
|
{ STRING_SIZE_TUPLE("error"), 1, 1, func_error},
|
||||||
|
{ STRING_SIZE_TUPLE("warning"), 1, 1, func_error},
|
||||||
|
#ifdef EXPERIMENTAL
|
||||||
|
{ STRING_SIZE_TUPLE("eq"), 2, 1, func_eq},
|
||||||
|
{ STRING_SIZE_TUPLE("if"), 3, 0, func_if},
|
||||||
|
{ STRING_SIZE_TUPLE("not"), 1, 1, func_not},
|
||||||
|
#endif
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* These must come after the definition of function_table[]. */
|
||||||
|
|
||||||
|
static char *
|
||||||
|
expand_builtin_function (o, argc, argv, entry_p)
|
||||||
|
char *o;
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
struct function_table_entry *entry_p;
|
||||||
|
{
|
||||||
|
int min = (entry_p->required_args > 0
|
||||||
|
? entry_p->required_args
|
||||||
|
: -entry_p->required_args);
|
||||||
|
|
||||||
|
if (argc < min)
|
||||||
|
fatal (reading_file,
|
||||||
|
"Insufficient number of arguments (%d) to function `%s'",
|
||||||
|
argc, entry_p->name);
|
||||||
|
|
||||||
|
if (!entry_p->func_ptr)
|
||||||
|
fatal (reading_file, "Unimplemented on this platform: function `%s'",
|
||||||
|
entry_p->name);
|
||||||
|
|
||||||
|
return entry_p->func_ptr (o, argv, entry_p->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for a function invocation in *STRINGP. *STRINGP points at the
|
||||||
|
opening ( or { and is not null-terminated. If a function invocation
|
||||||
|
is found, expand it into the buffer at *OP, updating *OP, incrementing
|
||||||
|
*STRINGP past the reference and returning nonzero. If not, return zero. */
|
||||||
|
|
||||||
|
int
|
||||||
|
handle_function (op, stringp)
|
||||||
|
char **op;
|
||||||
|
char **stringp;
|
||||||
|
{
|
||||||
|
const struct function_table_entry *entry_p;
|
||||||
|
char openparen = (*stringp)[0];
|
||||||
|
char closeparen = openparen == '(' ? ')' : '}';
|
||||||
|
char *beg = *stringp + 1;
|
||||||
|
char *endref;
|
||||||
|
int count = 0;
|
||||||
|
char *argbeg;
|
||||||
|
register char *p;
|
||||||
|
char **argv, **argvp;
|
||||||
|
int nargs;
|
||||||
|
|
||||||
|
entry_p = lookup_function (function_table, beg);
|
||||||
|
|
||||||
|
if (!entry_p)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* We have found a call to a builtin function. Find the end of the
|
||||||
|
arguments, and do the function. */
|
||||||
|
|
||||||
|
endref = beg + entry_p->len;
|
||||||
|
|
||||||
|
/* Space after function name isn't part of the args. */
|
||||||
|
p = next_token (endref);
|
||||||
|
argbeg = p;
|
||||||
|
|
||||||
|
/* Find the end of the function invocation, counting nested use of
|
||||||
|
whichever kind of parens we use. Since we're looking, count commas
|
||||||
|
to get a rough estimate of how many arguments we might have. The
|
||||||
|
count might be high, but it'll never be low. */
|
||||||
|
|
||||||
|
for (nargs=1; *p != '\0'; ++p)
|
||||||
|
if (*p == ',')
|
||||||
|
++nargs;
|
||||||
|
else if (*p == openparen)
|
||||||
|
++count;
|
||||||
|
else if (*p == closeparen && --count < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (count >= 0)
|
||||||
|
fatal (reading_file,
|
||||||
|
"unterminated call to function `%s': missing `%c'",
|
||||||
|
entry_p->name, closeparen);
|
||||||
|
|
||||||
|
/* Get some memory to store the arg pointers. */
|
||||||
|
argvp = argv = (char **) alloca (sizeof(char *) * (nargs + 2));
|
||||||
|
|
||||||
|
/* Chop the string into arguments, then store the end pointer and a nul.
|
||||||
|
If REQUIRED_ARGS is positive, as soon as we hit that many assume the
|
||||||
|
rest of the string is part of the last argument. */
|
||||||
|
*argvp = argbeg;
|
||||||
|
nargs = 1;
|
||||||
|
while (entry_p->required_args < 0 || nargs < entry_p->required_args)
|
||||||
|
{
|
||||||
|
char *next = find_next_argument (openparen, closeparen, *argvp, p);
|
||||||
|
|
||||||
|
if (!next)
|
||||||
|
break;
|
||||||
|
|
||||||
|
*(++argvp) = next+1;
|
||||||
|
++nargs;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(++argvp) = p+1;
|
||||||
|
*(++argvp) = 0;
|
||||||
|
|
||||||
|
/* If we should expand, do it. */
|
||||||
|
if (entry_p->expand_args)
|
||||||
|
{
|
||||||
|
for (argvp=argv; argvp[1] != 0; ++argvp)
|
||||||
|
*argvp = expand_argument (*argvp, argvp[1]-1);
|
||||||
|
|
||||||
|
/* end pointer doesn't make sense for expanded stuff. */
|
||||||
|
*argvp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finally! Run the function... */
|
||||||
|
*op = expand_builtin_function (*op, nargs, argv, entry_p);
|
||||||
|
|
||||||
|
/* If we allocated memory for the expanded args, free it again. */
|
||||||
|
if (entry_p->expand_args)
|
||||||
|
for (argvp=argv; *argvp != 0; ++argvp)
|
||||||
|
free (*argvp);
|
||||||
|
|
||||||
|
*stringp = p;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* User-defined functions. Expand the first argument as either a builtin
|
/* User-defined functions. Expand the first argument as either a builtin
|
||||||
function or a make variable, in the context of the rest of the arguments
|
function or a make variable, in the context of the rest of the arguments
|
||||||
assigned to $1, $2, ... $N. $0 is the name of the function. */
|
assigned to $1, $2, ... $N. $0 is the name of the function. */
|
||||||
|
|
||||||
char *
|
static char *
|
||||||
func_call (o, argv, funcname)
|
func_call (o, argv, funcname)
|
||||||
char *o;
|
char *o;
|
||||||
char **argv;
|
char **argv;
|
||||||
@ -1801,57 +1859,3 @@ func_call (o, argv, funcname)
|
|||||||
|
|
||||||
return o + strlen(o);
|
return o + strlen(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define STRING_SIZE_TUPLE(_s) (_s), (sizeof(_s)-1)
|
|
||||||
|
|
||||||
/* Lookup table for builtin functions.
|
|
||||||
|
|
||||||
This doesn't have to be sorted; we use a straight lookup. We might gain
|
|
||||||
some efficiency by moving most often used functions to the start of the
|
|
||||||
table.
|
|
||||||
|
|
||||||
If REQUIRED_ARGS is positive, the function takes exactly that many
|
|
||||||
arguments. All subsequent text is included with the last argument. So,
|
|
||||||
since $(sort a,b,c) takes only one argument, it will be the full string
|
|
||||||
"a,b,c". If the value is negative, it's the minimum number of arguments.
|
|
||||||
A function can have more, but if it has less an error is generated.
|
|
||||||
|
|
||||||
EXPAND_ARGS means that all arguments should be expanded before invocation.
|
|
||||||
Functions that do namespace tricks (foreach) don't automatically expand. */
|
|
||||||
|
|
||||||
static struct function_table_entry function_table[] =
|
|
||||||
{
|
|
||||||
/* Name/size */ /* ARG EXP? Function */
|
|
||||||
{ STRING_SIZE_TUPLE("addprefix"), 2, 1, func_addsuffix_addprefix},
|
|
||||||
{ STRING_SIZE_TUPLE("addsuffix"), 2, 1, func_addsuffix_addprefix},
|
|
||||||
{ STRING_SIZE_TUPLE("basename"), 1, 1, func_basename_dir},
|
|
||||||
{ STRING_SIZE_TUPLE("dir"), 1, 1, func_basename_dir},
|
|
||||||
{ STRING_SIZE_TUPLE("notdir"), 1, 1, func_notdir_suffix},
|
|
||||||
{ STRING_SIZE_TUPLE("subst"), 3, 1, func_subst},
|
|
||||||
{ STRING_SIZE_TUPLE("suffix"), 1, 1, func_notdir_suffix},
|
|
||||||
{ STRING_SIZE_TUPLE("filter"), 2, 1, func_filter_filterout},
|
|
||||||
{ STRING_SIZE_TUPLE("filter-out"), 2, 1, func_filter_filterout},
|
|
||||||
{ STRING_SIZE_TUPLE("findstring"), 2, 1, func_findstring},
|
|
||||||
{ STRING_SIZE_TUPLE("firstword"), 1, 1, func_firstword},
|
|
||||||
{ STRING_SIZE_TUPLE("join"), 2, 1, func_join},
|
|
||||||
{ STRING_SIZE_TUPLE("patsubst"), 3, 1, func_patsubst},
|
|
||||||
{ STRING_SIZE_TUPLE("shell"), 1, 1, func_shell},
|
|
||||||
{ STRING_SIZE_TUPLE("sort"), 1, 1, func_sort},
|
|
||||||
{ STRING_SIZE_TUPLE("strip"), 1, 1, func_strip},
|
|
||||||
{ STRING_SIZE_TUPLE("wildcard"), 1, 1, func_wildcard},
|
|
||||||
{ STRING_SIZE_TUPLE("word"), 2, 1, func_word},
|
|
||||||
{ STRING_SIZE_TUPLE("wordlist"), 3, 1, func_wordlist},
|
|
||||||
{ STRING_SIZE_TUPLE("words"), 1, 1, func_words},
|
|
||||||
{ STRING_SIZE_TUPLE("origin"), 1, 1, func_origin},
|
|
||||||
{ STRING_SIZE_TUPLE("foreach"), 3, 0, func_foreach},
|
|
||||||
{ STRING_SIZE_TUPLE("call"), -1, 1, func_call},
|
|
||||||
{ STRING_SIZE_TUPLE("error"), 1, 1, func_error},
|
|
||||||
{ STRING_SIZE_TUPLE("warning"), 1, 1, func_error},
|
|
||||||
#ifdef EXPERIMENTAL
|
|
||||||
{ STRING_SIZE_TUPLE("eq"), 2, 1, func_eq},
|
|
||||||
{ STRING_SIZE_TUPLE("if"), 3, 0, func_if},
|
|
||||||
{ STRING_SIZE_TUPLE("not"), 1, 1, func_not},
|
|
||||||
#endif
|
|
||||||
{ 0 }
|
|
||||||
};
|
|
||||||
|
Loading…
Reference in New Issue
Block a user