mirror of
https://github.com/mirror/make.git
synced 2024-12-27 13:20:34 +08:00
* Add configure option to enable dmalloc library.
* Various code cleanups.
This commit is contained in:
parent
73846549f6
commit
588da9812e
40
ChangeLog
40
ChangeLog
@ -1,3 +1,36 @@
|
||||
1999-07-21 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* various: Changed !strncmp() calls to strneq() macros.
|
||||
|
||||
* misc.c (sindex): Make slightly more efficient.
|
||||
|
||||
* dir.c (file_impossible): Change savestring(X,strlen(X)) to xstrdup().
|
||||
* implicit.c (pattern_search): Ditto.
|
||||
* main.c (enter_command_line_file): Ditto.
|
||||
(main): Ditto.
|
||||
* misc.c (copy_dep_chain): Ditto.
|
||||
* read.c (read_makefile): Ditto.
|
||||
(parse_file_seq): Ditto.
|
||||
(tilde_expand): Ditto.
|
||||
(multi_glob): Ditto.
|
||||
* rule.c (install_pattern_rule): Ditto.
|
||||
* variable.c (define_variable_in_set): Ditto.
|
||||
(define_automatic_variables): Ditto.
|
||||
* vpath.c (construct_vpath_list): Ditto.
|
||||
|
||||
* misc.c (xrealloc): If PTR is NULL, call malloc to conform to
|
||||
the standard--some older versions of realloc are non-standard so
|
||||
make xrealloc DTRT.
|
||||
* main.c (main): Call xrealloc() directly instead of testing for
|
||||
NULL.
|
||||
|
||||
* function.c (func_sort): Don't try to free NULL; some older,
|
||||
non-standard versions of free() don't like it.
|
||||
|
||||
* configure.in (--enable-dmalloc): Install some support for using
|
||||
dmalloc (http://www.dmalloc.com) with make. Use --enable-dmalloc
|
||||
with configure.
|
||||
|
||||
1999-07-20 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* job.c (start_job_command): Ensure that the state of the target
|
||||
@ -29,10 +62,11 @@
|
||||
* read.c (read_makefile): Fix some potential memory stomps parsing
|
||||
`define' directives where no variable name is given.
|
||||
|
||||
* function.c (func_apply): Various code cleanup and tightening.
|
||||
(function_table): Add "apply" as a valid builtin function.
|
||||
* function.c (func_call): Rename from func_apply. Various code
|
||||
cleanup and tightening.
|
||||
(function_table): Add "call" as a valid builtin function.
|
||||
|
||||
* make.texinfo (Apply Function): Document it.
|
||||
* make.texinfo (Call Function): Document it.
|
||||
|
||||
* NEWS: Announce it.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# -*-Makefile-*-, or close enough
|
||||
# This is a -*-Makefile-*-, or close enough
|
||||
|
||||
AUTOMAKE_OPTIONS = 1.3
|
||||
|
||||
|
4
arscan.c
4
arscan.c
@ -699,9 +699,9 @@ ar_name_equal (name, mem, truncated)
|
||||
#else
|
||||
struct ar_hdr hdr;
|
||||
#if !defined (__hpux) && !defined (cray)
|
||||
return !strncmp (name, mem, sizeof(hdr.ar_name) - 1);
|
||||
return strneq (name, mem, sizeof(hdr.ar_name) - 1);
|
||||
#else
|
||||
return !strncmp (name, mem, sizeof(hdr.ar_name) - 2);
|
||||
return strneq (name, mem, sizeof(hdr.ar_name) - 2);
|
||||
#endif /* !__hpux && !cray */
|
||||
#endif /* !AIAMAG */
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ set_file_variables (file)
|
||||
for (d = enter_file (".SUFFIXES")->deps; d != 0; d = d->next)
|
||||
{
|
||||
unsigned int slen = strlen (dep_name (d));
|
||||
if (len > slen && !strncmp (dep_name (d), name + (len - slen), slen))
|
||||
if (len > slen && strneq (dep_name (d), name + (len - slen), slen))
|
||||
{
|
||||
file->stem = savestring (name, len - slen);
|
||||
break;
|
||||
|
12
configure.in
12
configure.in
@ -136,6 +136,18 @@ case "$ac_cv_func_pipe $make_cv_job_server" in
|
||||
"yes yes") AC_DEFINE(MAKE_JOBSERVER) ;;
|
||||
esac
|
||||
|
||||
dnl Allow building with dmalloc
|
||||
|
||||
AC_ARG_ENABLE(dmalloc,
|
||||
[ --enable-dmalloc Enable support for the dmalloc debugging library],
|
||||
[make_cv_dmalloc="$enableval"],
|
||||
[make_cv_dmalloc="no"])
|
||||
|
||||
case "$make_cv_dmalloc" in
|
||||
yes) AC_CHECK_HEADERS(dmalloc.h)
|
||||
AC_CHECK_LIB(dmalloc, dmalloc_shutdown)
|
||||
CPPFLAGS="$CPPFLAGS -DDMALLOC_FUNC_CHECK" ;;
|
||||
esac
|
||||
|
||||
AC_CACHE_CHECK(for location of SCCS get command, make_cv_path_sccs_get, [
|
||||
if test -f /usr/sccs/get; then
|
||||
|
2
dir.c
2
dir.c
@ -772,7 +772,7 @@ file_impossible (filename)
|
||||
new = (struct dirfile *) xmalloc (sizeof (struct dirfile));
|
||||
new->next = dir->contents->files[hash];
|
||||
dir->contents->files[hash] = new;
|
||||
new->name = savestring (filename, strlen (filename));
|
||||
new->name = xstrdup (filename);
|
||||
new->impossible = 1;
|
||||
}
|
||||
|
||||
|
54
function.c
54
function.c
@ -171,14 +171,14 @@ patsubst_expand (o, text, pattern, replace, pattern_percent, replace_percent)
|
||||
if (!fail && pattern_prepercent_len > 0
|
||||
&& (*t != *pattern
|
||||
|| t[pattern_prepercent_len - 1] != pattern_percent[-1]
|
||||
|| strncmp (t + 1, pattern + 1, pattern_prepercent_len - 1)))
|
||||
|| !strneq (t + 1, pattern + 1, pattern_prepercent_len - 1)))
|
||||
fail = 1;
|
||||
|
||||
/* Does the suffix match? */
|
||||
if (!fail && pattern_postpercent_len > 0
|
||||
&& (t[len - 1] != pattern_percent[pattern_postpercent_len]
|
||||
|| t[len - pattern_postpercent_len] != pattern_percent[1]
|
||||
|| strncmp (&t[len - pattern_postpercent_len],
|
||||
|| !strneq (&t[len - pattern_postpercent_len],
|
||||
&pattern_percent[1], pattern_postpercent_len - 1)))
|
||||
fail = 1;
|
||||
|
||||
@ -266,7 +266,7 @@ pattern_matches (pattern, percent, str)
|
||||
strlength = strlen (str);
|
||||
|
||||
if (strlength < (percent - pattern) + sfxlen
|
||||
|| strncmp (pattern, str, percent - pattern))
|
||||
|| !strneq (pattern, str, percent - pattern))
|
||||
return 0;
|
||||
|
||||
return !strcmp (percent + 1, str + (strlength - sfxlen));
|
||||
@ -1154,6 +1154,8 @@ func_sort (o, argv, funcname)
|
||||
char *t = argv[0];
|
||||
char *p=0;
|
||||
int len;
|
||||
int i;
|
||||
|
||||
while ((p = find_next_token (&t, &len)) != 0)
|
||||
{
|
||||
if (wordi >= nwords - 1)
|
||||
@ -1165,29 +1167,29 @@ func_sort (o, argv, funcname)
|
||||
words[wordi++] = savestring (p, len);
|
||||
}
|
||||
|
||||
if (wordi > 0)
|
||||
if (!wordi)
|
||||
return o;
|
||||
|
||||
/* Now sort the list of words. */
|
||||
qsort ((char *) words, wordi, sizeof (char *), alpha_compare);
|
||||
|
||||
/* Now write the sorted list. */
|
||||
for (i = 0; i < wordi; ++i)
|
||||
{
|
||||
int i;
|
||||
/* Now sort the list of words. */
|
||||
qsort ((char *) words, wordi, sizeof (char *), alpha_compare);
|
||||
|
||||
/* Now write the sorted list. */
|
||||
for (i = 0; i < wordi; ++i)
|
||||
{
|
||||
len = strlen (words[i]);
|
||||
if (i == wordi - 1 || strlen (words[i + 1]) != len
|
||||
|| strcmp (words[i], words[i + 1]))
|
||||
{
|
||||
o = variable_buffer_output (o, words[i], len);
|
||||
o = variable_buffer_output (o, " ", 1);
|
||||
}
|
||||
free (words[i]);
|
||||
}
|
||||
/* Kill the last space. */
|
||||
--o;
|
||||
len = strlen (words[i]);
|
||||
if (i == wordi - 1 || strlen (words[i + 1]) != len
|
||||
|| strcmp (words[i], words[i + 1]))
|
||||
{
|
||||
o = variable_buffer_output (o, words[i], len);
|
||||
o = variable_buffer_output (o, " ", 1);
|
||||
}
|
||||
free (words[i]);
|
||||
}
|
||||
/* Kill the last space. */
|
||||
--o;
|
||||
|
||||
free (words);
|
||||
|
||||
free ((char *) words);
|
||||
return o;
|
||||
}
|
||||
|
||||
@ -1724,7 +1726,7 @@ func_if (char* o, char **argv, char *funcname)
|
||||
assigned to $1, $2, ... $N. $0 is the name of the function. */
|
||||
|
||||
char *
|
||||
func_apply (o, argv, funcname)
|
||||
func_call (o, argv, funcname)
|
||||
char *o;
|
||||
char **argv;
|
||||
const char *funcname;
|
||||
@ -1735,7 +1737,7 @@ func_apply (o, argv, funcname)
|
||||
int i;
|
||||
const struct function_table_entry *entry_p;
|
||||
|
||||
/* Applying nothing is a no-op. */
|
||||
/* Calling nothing is a no-op. */
|
||||
if (*argv[0] == '\0')
|
||||
return o;
|
||||
|
||||
@ -1835,7 +1837,7 @@ static struct function_table_entry function_table[] =
|
||||
{ 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("apply"), 1, 1, func_apply},
|
||||
{ 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
|
||||
|
10
implicit.c
10
implicit.c
@ -247,11 +247,11 @@ pattern_search (file, archive, depth, recursions)
|
||||
if (check_lastslash)
|
||||
{
|
||||
if (stem > (lastslash + 1)
|
||||
&& strncmp (target, lastslash + 1, stem - lastslash - 1))
|
||||
&& !strneq (target, lastslash + 1, stem - lastslash - 1))
|
||||
continue;
|
||||
}
|
||||
else if (stem > filename
|
||||
&& strncmp (target, filename, stem - filename))
|
||||
&& !strneq (target, filename, stem - filename))
|
||||
continue;
|
||||
|
||||
/* Check that the rule pattern matches the text after the stem.
|
||||
@ -400,7 +400,7 @@ pattern_search (file, archive, depth, recursions)
|
||||
&& (((fp = lookup_file (p)) != 0 && !fp->intermediate)
|
||||
|| file_exists_p (p)))
|
||||
{
|
||||
found_files[deps_found++] = savestring (p, strlen (p));
|
||||
found_files[deps_found++] = xstrdup (p);
|
||||
continue;
|
||||
}
|
||||
/* This code, given FILENAME = "lib/foo.o", dependency name
|
||||
@ -432,7 +432,7 @@ pattern_search (file, archive, depth, recursions)
|
||||
if (pattern_search (intermediate_file, 0, depth + 1,
|
||||
recursions + 1))
|
||||
{
|
||||
p = savestring (p, strlen (p));
|
||||
p = xstrdup (p);
|
||||
intermediate_patterns[deps_found]
|
||||
= intermediate_file->name;
|
||||
intermediate_file->name = p;
|
||||
@ -441,7 +441,7 @@ pattern_search (file, archive, depth, recursions)
|
||||
/* Allocate an extra copy to go in FOUND_FILES,
|
||||
because every elt of FOUND_FILES is consumed
|
||||
or freed later. */
|
||||
found_files[deps_found] = savestring (p, strlen (p));
|
||||
found_files[deps_found] = xstrdup (p);
|
||||
++deps_found;
|
||||
continue;
|
||||
}
|
||||
|
4
job.c
4
job.c
@ -2136,7 +2136,7 @@ construct_command_argv_internal (line, restp, shell, ifs, batch_filename_ptr)
|
||||
#ifdef __MSDOS__
|
||||
/* A dot is only special as part of the "..."
|
||||
wildcard. */
|
||||
if (strncmp (p + 1, ".\\.\\.", 5) == 0)
|
||||
if (strneq (p + 1, ".\\.\\.", 5))
|
||||
{
|
||||
*ap++ = '.';
|
||||
*ap++ = '.';
|
||||
@ -2354,7 +2354,7 @@ construct_command_argv_internal (line, restp, shell, ifs, batch_filename_ptr)
|
||||
|| index (sh_chars, *p) != 0))
|
||||
*ap++ = '\\';
|
||||
#ifdef __MSDOS__
|
||||
else if (unixy_shell && strncmp (p, "...", 3) == 0)
|
||||
else if (unixy_shell && strneq (p, "...", 3))
|
||||
{
|
||||
/* The case of `...' wildcard again. */
|
||||
strcpy (ap, "\\.\\.\\");
|
||||
|
25
main.c
25
main.c
@ -468,7 +468,7 @@ enter_command_line_file (name)
|
||||
name[2] = '\0';
|
||||
}
|
||||
|
||||
return enter_file (savestring (name, strlen (name)));
|
||||
return enter_file (xstrdup (name));
|
||||
}
|
||||
|
||||
/* Toggle -d on receipt of SIGUSR1. */
|
||||
@ -826,8 +826,7 @@ int main (int argc, char ** argv)
|
||||
directory_before_chdir = 0;
|
||||
}
|
||||
else
|
||||
directory_before_chdir = savestring (current_directory,
|
||||
strlen (current_directory));
|
||||
directory_before_chdir = xstrdup (current_directory);
|
||||
#ifdef __MSDOS__
|
||||
/* Make sure we will return to the initial directory, come what may. */
|
||||
atexit (msdos_return_to_initial_directory);
|
||||
@ -849,7 +848,7 @@ int main (int argc, char ** argv)
|
||||
while (*ep != '=')
|
||||
++ep;
|
||||
#ifdef WINDOWS32
|
||||
if (!unix_path && !strncmp(envp[i], "PATH=", 5))
|
||||
if (!unix_path && strneq(envp[i], "PATH=", 5))
|
||||
unix_path = ep+1;
|
||||
else if (!windows32_path && !strnicmp(envp[i], "Path=", 5)) {
|
||||
do_not_define = 1; /* it gets defined after loop exits */
|
||||
@ -960,7 +959,7 @@ int main (int argc, char ** argv)
|
||||
*/
|
||||
if (strpbrk(argv[0], "/:\\") ||
|
||||
strstr(argv[0], "..") ||
|
||||
!strncmp(argv[0], "//", 2))
|
||||
strneq(argv[0], "//", 2))
|
||||
argv[0] = xstrdup(w32ify(argv[0],1));
|
||||
#else /* WINDOWS32 */
|
||||
if (current_directory[0] != '\0'
|
||||
@ -1429,13 +1428,9 @@ int main (int argc, char ** argv)
|
||||
}
|
||||
if (f == NULL || !f->double_colon)
|
||||
{
|
||||
if (makefile_mtimes == 0)
|
||||
makefile_mtimes = (FILE_TIMESTAMP *)
|
||||
xmalloc (sizeof (FILE_TIMESTAMP));
|
||||
else
|
||||
makefile_mtimes = (FILE_TIMESTAMP *)
|
||||
xrealloc ((char *) makefile_mtimes,
|
||||
(mm_idx + 1) * sizeof (FILE_TIMESTAMP));
|
||||
makefile_mtimes = (FILE_TIMESTAMP *)
|
||||
xrealloc ((char *) makefile_mtimes,
|
||||
(mm_idx + 1) * sizeof (FILE_TIMESTAMP));
|
||||
makefile_mtimes[mm_idx++] = file_mtime_no_search (d->file);
|
||||
last = d;
|
||||
d = d->next;
|
||||
@ -1535,7 +1530,7 @@ int main (int argc, char ** argv)
|
||||
/* These names might have changed. */
|
||||
register unsigned int i, j = 0;
|
||||
for (i = 1; i < argc; ++i)
|
||||
if (!strncmp (argv[i], "-f", 2)) /* XXX */
|
||||
if (strneq (argv[i], "-f", 2)) /* XXX */
|
||||
{
|
||||
char *p = &argv[i][2];
|
||||
if (*p == '\0')
|
||||
@ -1550,7 +1545,7 @@ int main (int argc, char ** argv)
|
||||
if (stdin_nm)
|
||||
{
|
||||
nargv = (char **)xmalloc((nargc + 2) * sizeof(char *));
|
||||
bcopy(argv, nargv, argc * sizeof(char *));
|
||||
bcopy((char *)argv, (char *)nargv, argc * sizeof(char *));
|
||||
nargv[nargc++] = concat("-o", stdin_nm, "");
|
||||
nargv[nargc] = 0;
|
||||
}
|
||||
@ -1576,7 +1571,7 @@ int main (int argc, char ** argv)
|
||||
|
||||
#ifndef _AMIGA
|
||||
for (p = environ; *p != 0; ++p)
|
||||
if (!strncmp (*p, "MAKELEVEL=", 10))
|
||||
if (strneq (*p, "MAKELEVEL=", 10))
|
||||
{
|
||||
/* The SGI compiler apparently can't understand
|
||||
the concept of storing the result of a function
|
||||
|
23
make.h
23
make.h
@ -46,6 +46,11 @@ Boston, MA 02111-1307, USA. */
|
||||
# define signal bsdsignal
|
||||
#endif
|
||||
|
||||
/* If we're compiling for the dmalloc debugger, turn off string inlining. */
|
||||
#if defined(HAVE_DMALLOC_H) && defined(__GNUC__)
|
||||
# define __NO_STRING_INLINES
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE 1
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@ -284,13 +289,12 @@ extern char *alloca ();
|
||||
((a) == (b) || \
|
||||
(*(a) == *(b) && (*(a) == '\0' || !strcmp ((a) + 1, (b) + 1))))
|
||||
# ifdef HAVE_CASE_INSENSITIVE_FS
|
||||
/* This is only used on Windows/DOS platforms, so we assume strcmpi(). */
|
||||
# define strieq(a, b) \
|
||||
((a) == (b) || \
|
||||
(tolower(*(a)) == tolower(*(b)) && (*(a) == '\0' || !strcmpi ((a) + 1, (b) + 1))))
|
||||
# else
|
||||
# define strieq(a, b) \
|
||||
((a) == (b) || \
|
||||
(*(a) == *(b) && (*(a) == '\0' || !strcmp ((a) + 1, (b) + 1))))
|
||||
# define strieq(a, b) streq(a, b)
|
||||
# endif
|
||||
#else
|
||||
/* Buggy compiler can't handle this. */
|
||||
@ -371,7 +375,7 @@ extern void die PARAMS ((int)) __attribute__ ((noreturn));
|
||||
extern void log_working_directory PARAMS ((int));
|
||||
extern void pfatal_with_name PARAMS ((char *)) __attribute__ ((noreturn));
|
||||
extern void perror_with_name PARAMS ((char *, char *));
|
||||
extern char *savestring PARAMS ((char *, unsigned int));
|
||||
extern char *savestring PARAMS ((const char *, unsigned int));
|
||||
extern char *concat PARAMS ((char *, char *, char *));
|
||||
extern char *xmalloc PARAMS ((unsigned int));
|
||||
extern char *xrealloc PARAMS ((char *, unsigned int));
|
||||
@ -381,8 +385,9 @@ extern char *next_token PARAMS ((char *));
|
||||
extern char *end_of_token PARAMS ((char *));
|
||||
extern void collapse_continuations PARAMS ((char *));
|
||||
extern void remove_comments PARAMS((char *));
|
||||
extern char *sindex PARAMS ((char *, unsigned int, char *, unsigned int));
|
||||
extern char *lindex PARAMS ((char *, char *, int));
|
||||
extern char *sindex PARAMS ((const char *, unsigned int, \
|
||||
const char *, unsigned int));
|
||||
extern char *lindex PARAMS ((const char *, const char *, int));
|
||||
extern int alpha_compare PARAMS ((const void *, const void *));
|
||||
extern void print_spaces PARAMS ((unsigned int));
|
||||
extern char *find_char_unquote PARAMS ((char *, char *, int));
|
||||
@ -507,3 +512,9 @@ extern int handling_fatal_signal;
|
||||
# define EXIT_TROUBLE 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Set up heap debugging library dmalloc. */
|
||||
|
||||
#ifdef HAVE_DMALLOC_H
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
|
44
make.texinfo
44
make.texinfo
@ -269,7 +269,7 @@ Functions for Transforming Text
|
||||
* Text Functions:: General-purpose text manipulation functions.
|
||||
* File Name Functions:: Functions for manipulating file names.
|
||||
* Foreach Function:: Repeat some text with controlled variation.
|
||||
* Apply Function:: Expand a user-defined function.
|
||||
* Call Function:: Expand a user-defined function.
|
||||
* Origin Function:: Find where a variable got its value.
|
||||
* Shell Function:: Substitute the output of a shell command.
|
||||
|
||||
@ -5200,7 +5200,7 @@ call, just as a variable might be substituted.
|
||||
* Text Functions:: General-purpose text manipulation functions.
|
||||
* File Name Functions:: Functions for manipulating file names.
|
||||
* Foreach Function:: Repeat some text with controlled variation.
|
||||
* Apply Function:: Expand a user-defined function.
|
||||
* Call Function:: Expand a user-defined function.
|
||||
* Origin Function:: Find where a variable got its value.
|
||||
* Shell Function:: Substitute the output of a shell command.
|
||||
* Make Control Functions:: Functions that control how make runs.
|
||||
@ -5228,7 +5228,7 @@ $@{@var{function} @var{arguments}@}
|
||||
|
||||
Here @var{function} is a function name; one of a short list of names
|
||||
that are part of @code{make}. You can also essentially create your own
|
||||
functions by using the @code{apply} builtin function.
|
||||
functions by using the @code{call} builtin function.
|
||||
|
||||
The @var{arguments} are the arguments of the function. They are
|
||||
separated from the function name by one or more spaces or tabs, and if
|
||||
@ -5749,7 +5749,7 @@ that match the pattern.
|
||||
@xref{Wildcards, ,Using Wildcard Characters in File Names}.
|
||||
@end table
|
||||
|
||||
@node Foreach Function, Apply Function, File Name Functions, Functions
|
||||
@node Foreach Function, Call Function, File Name Functions, Functions
|
||||
@section The @code{foreach} Function
|
||||
@findex foreach
|
||||
@cindex words, iterating over
|
||||
@ -5837,33 +5837,33 @@ might be useful if the value of @code{find_files} references the variable
|
||||
whose name is @samp{Esta escrito en espanol!} (es un nombre bastante largo,
|
||||
no?), but it is more likely to be a mistake.
|
||||
|
||||
@node Apply Function, Origin Function, Foreach Function, Functions
|
||||
@section The @code{apply} Function
|
||||
@findex apply
|
||||
@node Call Function, Origin Function, Foreach Function, Functions
|
||||
@section The @code{call} Function
|
||||
@findex call
|
||||
@cindex functions, user defined
|
||||
@cindex user defined functions
|
||||
|
||||
The @code{apply} function is unique in that it can be used to create new
|
||||
The @code{call} function is unique in that it can be used to create new
|
||||
parameterized functions. You can write a complex expression as the
|
||||
value of a variable, then use @code{apply} to expand it with different
|
||||
value of a variable, then use @code{call} to expand it with different
|
||||
values.
|
||||
|
||||
The syntax of the @code{apply} function is:
|
||||
The syntax of the @code{call} function is:
|
||||
|
||||
@example
|
||||
$(apply @var{variable}, @var{param}, @var{param}, @dots{})
|
||||
$(call @var{variable}, @var{param}, @var{param}, @dots{})
|
||||
@end example
|
||||
|
||||
When @code{make} expands this function, it assigns each @var{param} to
|
||||
temporary variables @var{$(1)}, @var{$(2)}, etc. The variable
|
||||
@var{$(0)} will contain @var{variable}. There is no maximum number of
|
||||
parameter arguments. There is no minimum, either, but it doesn't make
|
||||
sense to use @code{apply} with no parameters.
|
||||
sense to use @code{call} with no parameters.
|
||||
|
||||
Then @var{variable} is expanded as a @code{make} variable in the context
|
||||
of these temporary assignments. Thus, any reference to @var{$(1)} in
|
||||
the value of @var{variable} will resolve to the first @var{param} in the
|
||||
invocation of @code{apply}.
|
||||
invocation of @code{call}.
|
||||
|
||||
Note that @var{variable} is the @emph{name} of a variable, not a
|
||||
@emph{reference} to that variable. Therefore you would not normally use
|
||||
@ -5883,7 +5883,7 @@ This macro simply reverses its arguments:
|
||||
reverse = $2 $1
|
||||
|
||||
foo = a b
|
||||
bar = $(apply reverse,$(foo))
|
||||
bar = $(call reverse,$(foo))
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
@ -5895,38 +5895,38 @@ the first instance of a program in @code{PATH}:
|
||||
@smallexample
|
||||
pathsearch = $(firstword $(wildcard $(addsufix /$1,$(subst :, ,$(PATH)))))
|
||||
|
||||
LS := $(apply pathsearch,ls)
|
||||
LS := $(call pathsearch,ls)
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
Now the variable LS contains @code{/bin/ls} or similar.
|
||||
|
||||
The @code{apply} function can be nested. Each recursive invocation gets
|
||||
The @code{call} function can be nested. Each recursive invocation gets
|
||||
its own local values for @var{$(1)}, etc. that mask the values of
|
||||
higher-level @code{apply}. For example, here is an implementation of a
|
||||
higher-level @code{call}. For example, here is an implementation of a
|
||||
@dfn{map} function:
|
||||
|
||||
@smallexample
|
||||
map = $(foreach a,$2,$(apply $1,$a))
|
||||
map = $(foreach a,$2,$(call $1,$a))
|
||||
@end smallexample
|
||||
|
||||
Now you can @var{map} a function that normally takes only one argument,
|
||||
such as @code{origin}, to multiple values in one step:
|
||||
|
||||
@smallexample
|
||||
o = $(apply map,origin,o map MAKE)
|
||||
o = $(call map,origin,o map MAKE)
|
||||
@end smallexample
|
||||
|
||||
and end up with @var{o} containing something like @samp{file file default}.
|
||||
|
||||
A final caution: be careful when adding whitespace to the arguments to
|
||||
@code{apply}. As with other functions, any whitespace contained in the
|
||||
@code{call}. As with other functions, any whitespace contained in the
|
||||
second and subsequent arguments is kept; this can cause strange
|
||||
effects. It's generally safest to remove all extraneous whitespace when
|
||||
defining variables for use with @code{apply}.
|
||||
providing parameters to @code{call}.
|
||||
|
||||
|
||||
@node Origin Function, Shell Function, Apply Function, Functions
|
||||
@node Origin Function, Shell Function, Call Function, Functions
|
||||
@section The @code{origin} Function
|
||||
@findex origin
|
||||
@cindex variables, origin of
|
||||
|
44
misc.c
44
misc.c
@ -352,9 +352,13 @@ pfatal_with_name (name)
|
||||
}
|
||||
|
||||
/* Like malloc but get fatal error if memory is exhausted. */
|
||||
/* Don't bother if we're using dmalloc; it provides these for us. */
|
||||
|
||||
#ifndef HAVE_DMALLOC_H
|
||||
|
||||
#undef xmalloc
|
||||
#undef xrealloc
|
||||
#undef xstrdup
|
||||
|
||||
char *
|
||||
xmalloc (size)
|
||||
@ -372,7 +376,10 @@ xrealloc (ptr, size)
|
||||
char *ptr;
|
||||
unsigned int size;
|
||||
{
|
||||
char *result = (char *) realloc (ptr, size);
|
||||
char *result;
|
||||
|
||||
/* Some older implementations of realloc() don't conform to ANSI. */
|
||||
result = ptr ? realloc (ptr, size) : malloc (size);
|
||||
if (result == 0)
|
||||
fatal (NILF, "virtual memory exhausted");
|
||||
return result;
|
||||
@ -401,9 +408,11 @@ xstrdup (ptr)
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* HAVE_DMALLOC_H */
|
||||
|
||||
char *
|
||||
savestring (str, length)
|
||||
char *str;
|
||||
const char *str;
|
||||
unsigned int length;
|
||||
{
|
||||
register char *out = (char *) xmalloc (length + 1);
|
||||
@ -419,21 +428,28 @@ savestring (str, length)
|
||||
|
||||
char *
|
||||
sindex (big, blen, small, slen)
|
||||
char *big;
|
||||
const char *big;
|
||||
unsigned int blen;
|
||||
char *small;
|
||||
const char *small;
|
||||
unsigned int slen;
|
||||
{
|
||||
register unsigned int b;
|
||||
|
||||
if (blen < 1)
|
||||
if (!blen)
|
||||
blen = strlen (big);
|
||||
if (slen < 1)
|
||||
if (!slen)
|
||||
slen = strlen (small);
|
||||
|
||||
for (b = 0; b < blen; ++b)
|
||||
if (big[b] == *small && !strncmp (&big[b + 1], small + 1, slen - 1))
|
||||
return (&big[b]);
|
||||
if (slen && blen >= slen)
|
||||
{
|
||||
register unsigned int b;
|
||||
|
||||
/* Quit when there's not enough room left for the small string. */
|
||||
--slen;
|
||||
blen -= slen;
|
||||
|
||||
for (b = 0; b < blen; ++b, ++big)
|
||||
if (*big == *small && strneq (big + 1, small + 1, slen))
|
||||
return (char *)big;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -446,12 +462,12 @@ sindex (big, blen, small, slen)
|
||||
|
||||
char *
|
||||
lindex (s, limit, c)
|
||||
register char *s, *limit;
|
||||
register const char *s, *limit;
|
||||
int c;
|
||||
{
|
||||
while (s < limit)
|
||||
if (*s++ == c)
|
||||
return s - 1;
|
||||
return (char *)(s - 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -547,7 +563,7 @@ copy_dep_chain (d)
|
||||
c = (struct dep *) xmalloc (sizeof (struct dep));
|
||||
bcopy ((char *) d, (char *) c, sizeof (struct dep));
|
||||
if (c->name != 0)
|
||||
c->name = savestring (c->name, strlen (c->name));
|
||||
c->name = xstrdup (c->name);
|
||||
c->next = 0;
|
||||
if (firstnew == 0)
|
||||
firstnew = lastnew = c;
|
||||
|
21
read.c
21
read.c
@ -378,7 +378,7 @@ read_makefile (filename, flags)
|
||||
deps->file = lookup_file (filename);
|
||||
if (deps->file == 0)
|
||||
{
|
||||
deps->file = enter_file (savestring (filename, strlen (filename)));
|
||||
deps->file = enter_file (xstrdup (filename));
|
||||
if (flags & RM_DONTCARE)
|
||||
deps->file->dontcare = 1;
|
||||
}
|
||||
@ -468,7 +468,7 @@ read_makefile (filename, flags)
|
||||
remove_comments (collapsed);
|
||||
|
||||
/* Compare a word, both length and contents. */
|
||||
#define word1eq(s, l) (len == l && !strncmp (s, p, l))
|
||||
#define word1eq(s, l) (len == l && strneq (s, p, l))
|
||||
p = collapsed;
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
@ -551,7 +551,7 @@ read_makefile (filename, flags)
|
||||
p2 = next_token (p + 8);
|
||||
if (*p2 == '\0')
|
||||
error (&fileinfo, "empty `override' directive");
|
||||
if (!strncmp (p2, "define", 6) && (isblank (p2[6]) || p2[6] == '\0'))
|
||||
if (strneq (p2, "define", 6) && (isblank (p2[6]) || p2[6] == '\0'))
|
||||
{
|
||||
if (ignoring)
|
||||
in_ignored_define = 1;
|
||||
@ -857,7 +857,7 @@ read_makefile (filename, flags)
|
||||
/* There's no need to be ivory-tower about this: check for
|
||||
one of the most common bugs found in makefiles... */
|
||||
fatal (&fileinfo, "missing separator%s",
|
||||
strncmp(lb.buffer, " ", 8) ? ""
|
||||
!strneq(lb.buffer, " ", 8) ? ""
|
||||
: " (did you mean TAB instead of 8 spaces?)");
|
||||
continue;
|
||||
}
|
||||
@ -902,7 +902,7 @@ read_makefile (filename, flags)
|
||||
wtype = get_next_mword(p2, NULL, &p, &len);
|
||||
v_origin = o_file;
|
||||
if (wtype == w_static && (len == (sizeof("override")-1)
|
||||
&& !strncmp(p, "override", len)))
|
||||
&& strneq(p, "override", len)))
|
||||
{
|
||||
v_origin = o_override;
|
||||
(void)get_next_mword(p+len, NULL, &p, &len);
|
||||
@ -1089,7 +1089,7 @@ do_define (name, namelen, origin, infile, flocp)
|
||||
p = next_token (lb.buffer);
|
||||
len = strlen (p);
|
||||
if ((len == 5 || (len > 5 && isblank (p[5])))
|
||||
&& !strncmp (p, "endef", 5))
|
||||
&& strneq (p, "endef", 5))
|
||||
{
|
||||
p += 5;
|
||||
remove_comments (p);
|
||||
@ -1750,7 +1750,7 @@ record_files (filenames, pattern, pattern_percent, deps, cmds_started,
|
||||
for (d2 = suffix_file->deps; d2 != 0; d2 = d2->next)
|
||||
{
|
||||
register unsigned int len = strlen (dep_name (d2));
|
||||
if (strncmp (name, dep_name (d2), len))
|
||||
if (!strneq (name, dep_name (d2), len))
|
||||
continue;
|
||||
if (streq (name + len, dep_name (d)))
|
||||
{
|
||||
@ -1946,7 +1946,7 @@ parse_file_seq (stringp, stopchar, size, strip)
|
||||
* Savestring called because q may be read-only string constant.
|
||||
*/
|
||||
{
|
||||
char *qbase = savestring(q, strlen(q));
|
||||
char *qbase = xstrdup (q);
|
||||
char *pbase = qbase + (p-q);
|
||||
char *q1 = qbase;
|
||||
char *q2 = q1;
|
||||
@ -2544,7 +2544,7 @@ tilde_expand (name)
|
||||
if (pwent != 0)
|
||||
{
|
||||
if (userend == 0)
|
||||
return savestring (pwent->pw_dir, strlen (pwent->pw_dir));
|
||||
return xstrdup (pwent->pw_dir);
|
||||
else
|
||||
return concat (pwent->pw_dir, "/", userend + 1);
|
||||
}
|
||||
@ -2662,8 +2662,7 @@ multi_glob (chain, size)
|
||||
#endif /* !NO_ARCHIVES */
|
||||
{
|
||||
struct nameseq *elt = (struct nameseq *) xmalloc (size);
|
||||
elt->name = savestring (gl.gl_pathv[i],
|
||||
strlen (gl.gl_pathv[i]));
|
||||
elt->name = xstrdup (gl.gl_pathv[i]);
|
||||
elt->next = new;
|
||||
new = elt;
|
||||
}
|
||||
|
4
rule.c
4
rule.c
@ -423,7 +423,7 @@ install_pattern_rule (p, terminal)
|
||||
r->cmds->fileinfo.lineno = 0;
|
||||
/* These will all be string literals, but we malloc space for them
|
||||
anyway because somebody might want to free them later. */
|
||||
r->cmds->commands = savestring (p->commands, strlen (p->commands));
|
||||
r->cmds->commands = xstrdup (p->commands);
|
||||
r->cmds->command_lines = 0;
|
||||
}
|
||||
}
|
||||
@ -599,7 +599,7 @@ lookup_pattern_var (target)
|
||||
stemlen = targlen - p->len + 1;
|
||||
|
||||
/* Compare the text in the pattern before the stem, if any. */
|
||||
if (stem > target && strncmp (p->target, target, stem - target))
|
||||
if (stem > target && !strneq (p->target, target, stem - target))
|
||||
continue;
|
||||
|
||||
/* Compare the text in the pattern after the stem, if any.
|
||||
|
12
variable.c
12
variable.c
@ -77,7 +77,7 @@ define_variable_in_set (name, length, value, origin, recursive, set)
|
||||
|
||||
for (v = set->table[hashval]; v != 0; v = v->next)
|
||||
if (*v->name == *name
|
||||
&& !strncmp (v->name + 1, name + 1, length - 1)
|
||||
&& strneq (v->name + 1, name + 1, length - 1)
|
||||
&& v->name[length] == '\0')
|
||||
break;
|
||||
|
||||
@ -98,7 +98,7 @@ define_variable_in_set (name, length, value, origin, recursive, set)
|
||||
{
|
||||
if (v->value != 0)
|
||||
free (v->value);
|
||||
v->value = savestring (value, strlen (value));
|
||||
v->value = xstrdup (value);
|
||||
v->origin = origin;
|
||||
v->recursive = recursive;
|
||||
}
|
||||
@ -109,7 +109,7 @@ define_variable_in_set (name, length, value, origin, recursive, set)
|
||||
|
||||
v = (struct variable *) xmalloc (sizeof (struct variable));
|
||||
v->name = savestring (name, length);
|
||||
v->value = savestring (value, strlen (value));
|
||||
v->value = xstrdup (value);
|
||||
v->origin = origin;
|
||||
v->recursive = recursive;
|
||||
v->expanding = 0;
|
||||
@ -176,7 +176,7 @@ lookup_variable (name, length)
|
||||
|
||||
for (v = set->table[hashval]; v != 0; v = v->next)
|
||||
if (*v->name == *name
|
||||
&& !strncmp (v->name + 1, name + 1, length - 1)
|
||||
&& strneq (v->name + 1, name + 1, length - 1)
|
||||
&& v->name[length] == 0)
|
||||
return v;
|
||||
}
|
||||
@ -205,7 +205,7 @@ lookup_variable_in_set (name, length, set)
|
||||
|
||||
for (v = set->table[hash]; v != 0; v = v->next)
|
||||
if (*v->name == *name
|
||||
&& !strncmp (v->name + 1, name + 1, length - 1)
|
||||
&& strneq (v->name + 1, name + 1, length - 1)
|
||||
&& v->name[length] == 0)
|
||||
return v;
|
||||
|
||||
@ -446,7 +446,7 @@ define_automatic_variables ()
|
||||
{
|
||||
free (v->value);
|
||||
v->origin = o_file;
|
||||
v->value = savestring (default_shell, strlen (default_shell));
|
||||
v->value = xstrdup (default_shell);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
6
vmsify.c
6
vmsify.c
@ -403,7 +403,7 @@ vmsify (name, type)
|
||||
{
|
||||
if (*(s2-1) == '.') /* ends in '.]' */
|
||||
{
|
||||
if (strncmp (fptr, "000000", 6) != 0)
|
||||
if (!strneq (fptr, "000000", 6))
|
||||
rooted = 0;
|
||||
}
|
||||
else
|
||||
@ -661,7 +661,7 @@ vmsify (name, type)
|
||||
nstate = N_OPEN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -840,7 +840,7 @@ vmsify (name, type)
|
||||
|
||||
}
|
||||
while (state > 0);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
4
vpath.c
4
vpath.c
@ -169,7 +169,7 @@ construct_vpath_list (pattern, dirpath)
|
||||
|
||||
if (pattern != 0)
|
||||
{
|
||||
pattern = savestring (pattern, strlen (pattern));
|
||||
pattern = xstrdup (pattern);
|
||||
percent = find_percent (pattern);
|
||||
}
|
||||
|
||||
@ -324,7 +324,7 @@ gpath_search (file, len)
|
||||
|
||||
if (gpaths && (len <= gpaths->maxlen))
|
||||
for (gp = gpaths->searchpath; *gp != NULL; ++gp)
|
||||
if (!strncmp(*gp, file, len) && (*gp)[len] == '\0')
|
||||
if (strneq (*gp, file, len) && (*gp)[len] == '\0')
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user