mirror of
https://git.savannah.gnu.org/git/make.git
synced 2024-12-25 05:29:46 +00:00
* New feature: .LIBPATTERNS controls the way -lfoo dependencies are expanded.
* A few tweaks to the system glob test, after trying it on a system where it's true. * Installed patches to archive handling for AIX 4.3 big archives. * Fix a memory stomp in target-specific variables. * Fix a memory leak in foreach functions.
This commit is contained in:
parent
84f38c9c6f
commit
a66668aabc
10 changed files with 324 additions and 143 deletions
31
ChangeLog
31
ChangeLog
|
@ -1,3 +1,34 @@
|
|||
1999-02-22 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* NEWS: Mention new .LIBPATTERNS feature.
|
||||
|
||||
* make.texinfo (Libraries/Search): Describe the use and
|
||||
ramifications of the new .LIBPATTERNS variable.
|
||||
|
||||
* remake.c (library_search): Instead of searching only for the
|
||||
hardcoded expansion "libX.a" for a library reference "-lX", we
|
||||
obtain a list of patterns from the .LIBPATTERNS variable and
|
||||
search those in order.
|
||||
|
||||
* default.c: Added a new default variable .LIBPATTERNS. The
|
||||
default for UNIX is "lib%.so lib%.a". Amiga and DOS values are
|
||||
also provided.
|
||||
|
||||
* read.c: Remove bogus HAVE_GLOB_H references; always include
|
||||
vanilla glob.h.
|
||||
|
||||
1999-02-21 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* function.c (expand_function): Set value to 0 to avoid freeing it.
|
||||
* variable.c (pop_variable_scope): Free the value of the variable.
|
||||
(try_variable_definition): For simple variables, use
|
||||
allocated_variable_expand() to avoid stomping on the variable
|
||||
buffer when we still need it for other things.
|
||||
|
||||
* arscan.c: Modified to support AIX 4.3 big archives. The changes
|
||||
are based on information provided by Phil Adams
|
||||
<padams@austin.ibm.com>; thanks!
|
||||
|
||||
1999-02-19 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* configure.in: Check to see if the GNU glob library is already
|
||||
|
|
26
NEWS
26
NEWS
|
@ -1,12 +1,21 @@
|
|||
GNU make NEWS -*-indented-text-*-
|
||||
History of user-visible changes.
|
||||
19 May 1998
|
||||
22 Feb 1999
|
||||
|
||||
Copyright (C) 1992,1993,1994,1995,1996,1997,1998 Free Software Foundation, Inc.
|
||||
Copyright (C) 1992,93,94,95,96,97,98,1999 Free Software Foundation, Inc.
|
||||
See the end for copying conditions.
|
||||
|
||||
All changes mentioned here are more fully described in the GNU make
|
||||
manual, which is contained in this distribution as the file make.texinfo.
|
||||
|
||||
Please send GNU make bug reports to bug-make@gnu.org.
|
||||
|
||||
Version 3.78
|
||||
|
||||
* Make defines a new variable, .LIBPATTERNS. This variable controls how
|
||||
the link library dependency expansion (dependencies like ``-lfoo'') is
|
||||
performed.
|
||||
|
||||
Version 3.77
|
||||
|
||||
* Implement BSD make's "?=" variable assignment operator. The variable
|
||||
|
@ -659,17 +668,14 @@ Version 3.05
|
|||
----------------------------------------------------------------------
|
||||
Copyright information:
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to anyone to make or distribute verbatim copies
|
||||
of this document as received, in any medium, provided that the
|
||||
copyright notice and this permission notice are preserved,
|
||||
thus giving the recipient permission to redistribute in turn.
|
||||
copyright notice and this permission notice are preserved, thus
|
||||
giving the recipient permission to redistribute in turn.
|
||||
|
||||
Permission is granted to distribute modified versions
|
||||
of this document, or of portions of it,
|
||||
under the above conditions, provided also that they
|
||||
carry prominent notices stating who last changed them.
|
||||
Permission is granted to distribute modified versions of this
|
||||
document, or of portions of it, under the above conditions, provided
|
||||
also that they carry prominent notices stating who last changed them.
|
||||
|
||||
Local variables:
|
||||
version-control: never
|
||||
|
|
198
arscan.c
198
arscan.c
|
@ -213,11 +213,28 @@ ar_scan (archive, function, arg)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
/* On AIX, define these symbols to be sure to get both archive formats.
|
||||
AIX 4.3 introduced the "big" archive format to support 64-bit object
|
||||
files, so on AIX 4.3 systems we need to support both the "normal" and
|
||||
"big" archive formats. An archive's format is indicated in the
|
||||
"fl_magic" field of the "FL_HDR" structure. For a normal archive,
|
||||
this field will be the string defined by the AIAMAG symbol. For a
|
||||
"big" archive, it will be the string defined by the AIAMAGBIG symbol
|
||||
(at least on AIX it works this way).
|
||||
|
||||
Note: we'll define these symbols regardless of which AIX version
|
||||
we're compiling on, but this is okay since we'll use the new symbols
|
||||
only if they're present. */
|
||||
#ifdef _AIX
|
||||
# define __AR_SMALL__
|
||||
# define __AR_BIG__
|
||||
#endif
|
||||
|
||||
#include <ar.h>
|
||||
|
||||
/* Cray's <ar.h> apparently defines this. */
|
||||
#ifndef AR_HDR_SIZE
|
||||
#define AR_HDR_SIZE (sizeof (struct ar_hdr))
|
||||
# define AR_HDR_SIZE (sizeof (struct ar_hdr))
|
||||
#endif
|
||||
|
||||
/* Takes three arguments ARCHIVE, FUNCTION and ARG.
|
||||
|
@ -255,6 +272,10 @@ ar_scan (archive, function, arg)
|
|||
{
|
||||
#ifdef AIAMAG
|
||||
FL_HDR fl_header;
|
||||
#ifdef AIAMAGBIG
|
||||
int big_archive = 0;
|
||||
FL_HDR_BIG fl_header_big;
|
||||
#endif
|
||||
#else
|
||||
int long_name = 0;
|
||||
#endif
|
||||
|
@ -276,11 +297,42 @@ ar_scan (archive, function, arg)
|
|||
#ifdef AIAMAG
|
||||
{
|
||||
register int nread = read (desc, (char *) &fl_header, FL_HSZ);
|
||||
if (nread != FL_HSZ || bcmp (fl_header.fl_magic, AIAMAG, SAIAMAG))
|
||||
|
||||
if (nread != FL_HSZ)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
#ifdef AIAMAGBIG
|
||||
/* If this is a "big" archive, then set the flag and
|
||||
re-read the header into the "big" structure. */
|
||||
if (!bcmp (fl_header.fl_magic, AIAMAGBIG, SAIAMAG))
|
||||
{
|
||||
big_archive = 1;
|
||||
|
||||
/* seek back to beginning of archive */
|
||||
if (lseek (desc, 0, 0) < 0)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* re-read the header into the "big" structure */
|
||||
nread = read (desc, (char *) &fl_header_big, FL_HSZ_BIG);
|
||||
if (nread != FL_HSZ_BIG)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
/* Check to make sure this is a "normal" archive. */
|
||||
if (bcmp (fl_header.fl_magic, AIAMAG, SAIAMAG))
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
|
@ -308,8 +360,18 @@ ar_scan (archive, function, arg)
|
|||
long int member_offset;
|
||||
long int last_member_offset;
|
||||
|
||||
sscanf (fl_header.fl_fstmoff, "%12ld", &member_offset);
|
||||
sscanf (fl_header.fl_lstmoff, "%12ld", &last_member_offset);
|
||||
#ifdef AIAMAGBIG
|
||||
if ( big_archive )
|
||||
{
|
||||
sscanf (fl_header_big.fl_fstmoff, "%20ld", &member_offset);
|
||||
sscanf (fl_header_big.fl_lstmoff, "%20ld", &last_member_offset);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
sscanf (fl_header.fl_fstmoff, "%12ld", &member_offset);
|
||||
sscanf (fl_header.fl_lstmoff, "%12ld", &last_member_offset);
|
||||
}
|
||||
|
||||
if (member_offset == 0)
|
||||
{
|
||||
|
@ -330,6 +392,9 @@ ar_scan (archive, function, arg)
|
|||
{
|
||||
register int nread;
|
||||
struct ar_hdr member_header;
|
||||
#ifdef AIAMAGBIG
|
||||
struct ar_hdr_big member_header_big;
|
||||
#endif
|
||||
#ifdef AIAMAG
|
||||
char name[256];
|
||||
int name_len;
|
||||
|
@ -352,34 +417,73 @@ ar_scan (archive, function, arg)
|
|||
}
|
||||
|
||||
#ifdef AIAMAG
|
||||
#define AR_MEMHDR (AR_HDR_SIZE - sizeof (member_header._ar_name))
|
||||
nread = read (desc, (char *) &member_header, AR_MEMHDR);
|
||||
#define AR_MEMHDR_SZ(x) (sizeof(x) - sizeof (x._ar_name))
|
||||
|
||||
if (nread != AR_MEMHDR)
|
||||
#ifdef AIAMAGBIG
|
||||
if (big_archive)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
nread = read (desc, (char *) &member_header_big,
|
||||
AR_MEMHDR_SZ(member_header_big) );
|
||||
|
||||
if (nread != AR_MEMHDR_SZ(member_header_big))
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
|
||||
sscanf (member_header_big.ar_namlen, "%4d", &name_len);
|
||||
nread = read (desc, name, name_len);
|
||||
|
||||
if (nread != name_len)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
|
||||
name[name_len] = 0;
|
||||
|
||||
sscanf (member_header_big.ar_date, "%12ld", &dateval);
|
||||
sscanf (member_header_big.ar_uid, "%12d", &uidval);
|
||||
sscanf (member_header_big.ar_gid, "%12d", &gidval);
|
||||
sscanf (member_header_big.ar_mode, "%12o", &eltmode);
|
||||
sscanf (member_header_big.ar_size, "%20ld", &eltsize);
|
||||
|
||||
data_offset = (member_offset + AR_MEMHDR_SZ(member_header_big)
|
||||
+ name_len + 2);
|
||||
}
|
||||
|
||||
sscanf (member_header.ar_namlen, "%4d", &name_len);
|
||||
nread = read (desc, name, name_len);
|
||||
|
||||
if (nread != name_len)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
nread = read (desc, (char *) &member_header,
|
||||
AR_MEMHDR_SZ(member_header) );
|
||||
|
||||
if (nread != AR_MEMHDR_SZ(member_header))
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
|
||||
sscanf (member_header.ar_namlen, "%4d", &name_len);
|
||||
nread = read (desc, name, name_len);
|
||||
|
||||
if (nread != name_len)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
|
||||
name[name_len] = 0;
|
||||
|
||||
sscanf (member_header.ar_date, "%12ld", &dateval);
|
||||
sscanf (member_header.ar_uid, "%12d", &uidval);
|
||||
sscanf (member_header.ar_gid, "%12d", &gidval);
|
||||
sscanf (member_header.ar_mode, "%12o", &eltmode);
|
||||
sscanf (member_header.ar_size, "%12ld", &eltsize);
|
||||
|
||||
data_offset = (member_offset + AR_MEMHDR_SZ(member_header)
|
||||
+ name_len + 2);
|
||||
}
|
||||
|
||||
name[name_len] = 0;
|
||||
|
||||
sscanf (member_header.ar_date, "%12ld", &dateval);
|
||||
sscanf (member_header.ar_uid, "%12d", &uidval);
|
||||
sscanf (member_header.ar_gid, "%12d", &gidval);
|
||||
sscanf (member_header.ar_mode, "%12o", &eltmode);
|
||||
sscanf (member_header.ar_size, "%12ld", &eltsize);
|
||||
|
||||
if ((data_offset = member_offset + AR_MEMHDR + name_len + 2) % 2)
|
||||
++data_offset;
|
||||
data_offset += data_offset % 2;
|
||||
|
||||
fnval =
|
||||
(*function) (desc, name, 0,
|
||||
|
@ -493,7 +597,12 @@ ar_scan (archive, function, arg)
|
|||
/* End of the chain. */
|
||||
break;
|
||||
|
||||
sscanf (member_header.ar_nxtmem, "%12ld", &member_offset);
|
||||
#ifdef AIAMAGBIG
|
||||
if (big_archive)
|
||||
sscanf (member_header_big.ar_nxtmem, "%20ld", &member_offset);
|
||||
else
|
||||
#endif
|
||||
sscanf (member_header.ar_nxtmem, "%12ld", &member_offset);
|
||||
|
||||
if (lseek (desc, member_offset, 0) != member_offset)
|
||||
{
|
||||
|
@ -562,37 +671,6 @@ ar_name_equal (name, mem, truncated)
|
|||
if (p != 0)
|
||||
name = p + 1;
|
||||
|
||||
/* We no longer use this kludge, since we
|
||||
now support long archive member names. */
|
||||
|
||||
#if 0 && !defined (AIAMAG) && !defined (APOLLO)
|
||||
|
||||
{
|
||||
/* `reallylongname.o' matches `reallylongnam.o'.
|
||||
If member names have a trailing slash, that's `reallylongna.o'. */
|
||||
|
||||
struct ar_hdr h;
|
||||
unsigned int max = sizeof (h.ar_name);
|
||||
unsigned int namelen, memlen;
|
||||
|
||||
if (strncmp (name, mem, max - 3))
|
||||
return 0;
|
||||
|
||||
namelen = strlen (name);
|
||||
memlen = strlen (mem);
|
||||
|
||||
if (namelen > memlen && memlen >= max - 1
|
||||
&& name[namelen - 2] == '.' && name[namelen - 1] == 'o'
|
||||
&& mem[memlen - 2] == '.' && mem[memlen - 1] == 'o')
|
||||
return 1;
|
||||
|
||||
if (namelen != memlen)
|
||||
return 0;
|
||||
|
||||
return (namelen < max - 3 || !strcmp (name + max - 3, mem + max - 3));
|
||||
}
|
||||
|
||||
#else /* AIX or APOLLO. */
|
||||
#ifndef VMS
|
||||
if (truncated)
|
||||
{
|
||||
|
@ -611,8 +689,6 @@ ar_name_equal (name, mem, truncated)
|
|||
#endif /* !VMS */
|
||||
|
||||
return !strcmp (name, mem);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef VMS
|
||||
|
|
11
configure.in
11
configure.in
|
@ -154,17 +154,20 @@ rm -f s.conftest conftoast
|
|||
AC_MSG_CHECKING(if system libc has GNU glob)
|
||||
AC_CACHE_VAL(make_cv_sys_gnu_glob, [
|
||||
AC_TRY_CPP([
|
||||
#include <features.h>
|
||||
#include <glob.h>
|
||||
#include <fnmatch.h>
|
||||
|
||||
#define GLOB_INTERFACE_VERSION 1
|
||||
#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
|
||||
#if defined _LIBC || !defined __GNU_LIBRARY__ || __GNU_LIBRARY__ <= 1
|
||||
# error no gnu glob
|
||||
#else
|
||||
# include <gnu-versions.h>
|
||||
# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION
|
||||
# error have gnu glob
|
||||
# if _GNU_GLOB_INTERFACE_VERSION != GLOB_INTERFACE_VERSION
|
||||
# error no gnu glob
|
||||
# endif
|
||||
#endif
|
||||
], make_cv_sys_gnu_glob=no, make_cv_sys_gnu_glob=yes)])
|
||||
], make_cv_sys_gnu_glob=yes, make_cv_sys_gnu_glob=no)])
|
||||
case "$make_cv_sys_gnu_glob" in
|
||||
yes) AC_MSG_RESULT(yes) ;;
|
||||
no) AC_MSG_RESULT([no; using local copy])
|
||||
|
|
10
default.c
10
default.c
|
@ -425,6 +425,16 @@ static char *default_variables[] =
|
|||
"SCCS_OUTPUT_OPTION", "-G$@",
|
||||
#endif
|
||||
|
||||
#ifdef _AMIGA
|
||||
".LIBPATTERNS", "%.lib",
|
||||
#else
|
||||
#ifdef __MSDOS__
|
||||
".LIBPATTERNS", "lib%.a $(DJDIR)/lib/lib%.a",
|
||||
#else
|
||||
".LIBPATTERNS", "lib%.so lib%.a",
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* !VMS */
|
||||
0, 0
|
||||
};
|
||||
|
|
|
@ -876,6 +876,7 @@ expand_function (o, function, text, end)
|
|||
/* Kill the last space. */
|
||||
--o;
|
||||
|
||||
v->value = 0;
|
||||
pop_variable_scope ();
|
||||
|
||||
free (var);
|
||||
|
|
28
make.texinfo
28
make.texinfo
|
@ -1971,16 +1971,19 @@ directory search with no extra effort.
|
|||
@cindex @code{VPATH}, and link libraries
|
||||
@cindex search path for dependencies (@code{VPATH}), and link libraries
|
||||
@cindex @code{-l} (library search)
|
||||
@cindex link libraries, patterns matching
|
||||
@cindex @code{.LIBPATTERNS}, and link libraries
|
||||
@vindex .LIBPATTERNS
|
||||
|
||||
Directory search applies in a special way to libraries used with the
|
||||
linker. This special feature comes into play when you write a dependency
|
||||
whose name is of the form @samp{-l@var{name}}. (You can tell something
|
||||
strange is going on here because the dependency is normally the name of a
|
||||
file, and the @emph{file name} of the library looks like
|
||||
file, and the @emph{file name} of a library generally looks like
|
||||
@file{lib@var{name}.a}, not like @samp{-l@var{name}}.)@refill
|
||||
|
||||
When a dependency's name has the form @samp{-l@var{name}}, @code{make}
|
||||
handles it specially by searching for the file @file{lib@var{name}.a} in
|
||||
handles it specially by searching for the file @file{lib@var{name}.so} in
|
||||
the current directory, in directories specified by matching @code{vpath}
|
||||
search paths and the @code{VPATH} search path, and then in the
|
||||
directories @file{/lib}, @file{/usr/lib}, and @file{@var{prefix}/lib}
|
||||
|
@ -1988,7 +1991,11 @@ directories @file{/lib}, @file{/usr/lib}, and @file{@var{prefix}/lib}
|
|||
@code{make} behave as if @var{prefix} is defined to be the root of the
|
||||
DJGPP installation tree).
|
||||
|
||||
For example,
|
||||
If that file is not found, then the file @file{lib@var{name}.a} is
|
||||
searched for, in the same directories as above.
|
||||
|
||||
For example, if there is a @file{/usr/lib/libcurses.a} library on your
|
||||
system (and no @file{/usr/lib/libcurses.so} file), then
|
||||
|
||||
@example
|
||||
@group
|
||||
|
@ -2002,6 +2009,21 @@ would cause the command @samp{cc foo.c /usr/lib/libcurses.a -o foo} to
|
|||
be executed when @file{foo} is older than @file{foo.c} or than
|
||||
@file{/usr/lib/libcurses.a}.@refill
|
||||
|
||||
Although the default set of files to be searched for is
|
||||
@file{lib@var{name}.so} and @file{lib@var{name}.a}, this is customizable
|
||||
via the @code{.LIBPATTERNS} variable. Each word in the value of this
|
||||
variable is a pattern string. When a dependency like
|
||||
@samp{-l@var{name}} is seen, @code{make} will replace the percent in
|
||||
each pattern in the list with @var{name} and perform the above directory
|
||||
searches using that library filename. If no library is found, the next
|
||||
word in the list will be used.
|
||||
|
||||
The default value for @code{.LIBPATTERNS} is ``@samp{lib%.so lib%.a}'',
|
||||
which provides the default behavior described above.
|
||||
|
||||
You can turn off link library expansion completely by setting this
|
||||
variable to an empty value.
|
||||
|
||||
@node Phony Targets, Force Targets, Directory Search, Rules
|
||||
@section Phony Targets
|
||||
@cindex phony targets
|
||||
|
|
12
read.c
12
read.c
|
@ -18,6 +18,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
#include <glob.h>
|
||||
|
||||
#include "make.h"
|
||||
#include "dep.h"
|
||||
#include "filedef.h"
|
||||
|
@ -26,12 +28,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
#include "variable.h"
|
||||
#include "rule.h"
|
||||
|
||||
/* This is POSIX.2, but most systems using -DPOSIX probably don't have it. */
|
||||
#ifdef HAVE_GLOB_H
|
||||
#include <glob.h>
|
||||
#else
|
||||
#include "glob/glob.h"
|
||||
#endif
|
||||
|
||||
#ifndef WINDOWS32
|
||||
#ifndef _AMIGA
|
||||
|
@ -1564,9 +1560,7 @@ record_files (filenames, pattern, pattern_percent, deps, cmds_started,
|
|||
if (!pattern_matches (pattern, pattern_percent, name))
|
||||
{
|
||||
/* Give a warning if the rule is meaningless. */
|
||||
error (flocp,
|
||||
"target `%s' doesn't match the target pattern",
|
||||
name);
|
||||
error (flocp,"target `%s' doesn't match the target pattern", name);
|
||||
this = 0;
|
||||
}
|
||||
else
|
||||
|
|
137
remake.c
137
remake.c
|
@ -21,6 +21,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
#include "job.h"
|
||||
#include "commands.h"
|
||||
#include "dep.h"
|
||||
#include "variable.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
|
@ -1188,82 +1190,111 @@ library_search (lib, mtime_ptr)
|
|||
0
|
||||
};
|
||||
|
||||
static char *libpatterns = NULL;
|
||||
|
||||
char *libname = &(*lib)[2]; /* Name without the `-l'. */
|
||||
FILE_TIMESTAMP mtime;
|
||||
|
||||
/* Buffer to construct possible names in. */
|
||||
char *buf = xmalloc (sizeof (LIBDIR) + 8 + strlen (libname) + 4 + 2 + 1);
|
||||
/* Loop variables for the libpatterns value. */
|
||||
char *p, *p2;
|
||||
int len;
|
||||
|
||||
char *file, **dp;
|
||||
|
||||
/* Look first for `libNAME.a' in the current directory. */
|
||||
|
||||
#ifndef _AMIGA
|
||||
sprintf (buf, "lib%s.a", libname);
|
||||
#else
|
||||
sprintf (buf, "%s.lib", libname);
|
||||
#endif
|
||||
mtime = name_mtime (buf);
|
||||
if (mtime != (FILE_TIMESTAMP) -1)
|
||||
/* If we don't have libpatterns, get it. */
|
||||
if (!libpatterns)
|
||||
{
|
||||
*lib = buf;
|
||||
if (mtime_ptr != 0)
|
||||
*mtime_ptr = mtime;
|
||||
return 1;
|
||||
int save = warn_undefined_variables_flag;
|
||||
warn_undefined_variables_flag = 0;
|
||||
|
||||
libpatterns = strdup (variable_expand ("$(strip $(.LIBPATTERNS))"));
|
||||
|
||||
warn_undefined_variables_flag = save;
|
||||
}
|
||||
|
||||
/* Now try VPATH search on that. */
|
||||
|
||||
file = buf;
|
||||
if (vpath_search (&file, mtime_ptr))
|
||||
/* Loop through all the patterns in .LIBPATTERNS, and search on each one. */
|
||||
p2 = libpatterns;
|
||||
while ((p = find_next_token (&p2, &len)) != 0)
|
||||
{
|
||||
free (buf);
|
||||
*lib = file;
|
||||
return 1;
|
||||
}
|
||||
static char *buf = NULL;
|
||||
static int buflen = 0;
|
||||
static int libdir_maxlen = -1;
|
||||
char *libbuf = variable_expand ("");
|
||||
|
||||
/* Now try the standard set of directories. */
|
||||
|
||||
#ifdef __MSDOS__
|
||||
{
|
||||
/* The default library directory is at ${DJDIR}/lib. */
|
||||
struct variable *djdir = lookup_variable ("DJDIR", 5);
|
||||
|
||||
if (djdir)
|
||||
/* Expand the pattern using LIBNAME as a replacement. */
|
||||
{
|
||||
size_t djdir_len = strlen (djdir->value);
|
||||
char c = p[len];
|
||||
char *p3, *p4;
|
||||
|
||||
if (djdir_len > sizeof(LIBDIR) + 8 + strlen(libname) + 4 + 2)
|
||||
buf = (char *) xrealloc (djdir_len + 1);
|
||||
sprintf (buf, "%s/lib/lib%s.a", djdir->value, libname);
|
||||
mtime = name_mtime (buf);
|
||||
if (mtime != (FILE_TIMESTAMP) -1)
|
||||
p[len] = '\0';
|
||||
p3 = find_percent (p);
|
||||
if (!p3)
|
||||
{
|
||||
*lib = buf;
|
||||
if (mtime_ptr != 0)
|
||||
*mtime_ptr = mtime;
|
||||
return 1;
|
||||
/* Give a warning if there is no pattern, then remove the
|
||||
pattern so it's ignored next time. */
|
||||
error (NILF, ".LIBPATTERNS element `%s' is not a pattern", p);
|
||||
for (; len; --len, ++p)
|
||||
*p = ' ';
|
||||
*p = c;
|
||||
continue;
|
||||
}
|
||||
p4 = variable_buffer_output (libbuf, p, p3-p);
|
||||
p4 = variable_buffer_output (p4, libname, strlen (libname));
|
||||
p4 = variable_buffer_output (p4, p3+1, len - (p3-p));
|
||||
p[len] = c;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (dp = dirs; *dp != 0; ++dp)
|
||||
{
|
||||
#ifndef _AMIGA
|
||||
sprintf (buf, "%s/lib%s.a", *dp, libname);
|
||||
#else
|
||||
sprintf (buf, "%s/%s.lib", *dp, libname);
|
||||
#endif
|
||||
mtime = name_mtime (buf);
|
||||
/* Look first for `libNAME.a' in the current directory. */
|
||||
mtime = name_mtime (libbuf);
|
||||
if (mtime != (FILE_TIMESTAMP) -1)
|
||||
{
|
||||
*lib = buf;
|
||||
*lib = strdup (libbuf);
|
||||
if (mtime_ptr != 0)
|
||||
*mtime_ptr = mtime;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Now try VPATH search on that. */
|
||||
|
||||
file = libbuf;
|
||||
if (vpath_search (&file, mtime_ptr))
|
||||
{
|
||||
*lib = file;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Now try the standard set of directories. */
|
||||
|
||||
if (!buflen)
|
||||
{
|
||||
for (dp = dirs; *dp != 0; ++dp)
|
||||
{
|
||||
int l = strlen (*dp);
|
||||
if (l > libdir_maxlen)
|
||||
libdir_maxlen = l;
|
||||
}
|
||||
buflen = strlen (libbuf);
|
||||
buf = xmalloc(libdir_maxlen + buflen + 2);
|
||||
}
|
||||
else if (buflen < strlen (libbuf))
|
||||
{
|
||||
buflen = strlen (libbuf);
|
||||
buf = xrealloc (buf, libdir_maxlen + buflen + 2);
|
||||
}
|
||||
|
||||
for (dp = dirs; *dp != 0; ++dp)
|
||||
{
|
||||
sprintf (buf, "%s/%s", *dp, libbuf);
|
||||
mtime = name_mtime (buf);
|
||||
if (mtime != (FILE_TIMESTAMP) -1)
|
||||
{
|
||||
*lib = strdup (buf);
|
||||
if (mtime_ptr != 0)
|
||||
*mtime_ptr = mtime;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free (buf);
|
||||
return 0;
|
||||
}
|
||||
|
|
13
variable.c
13
variable.c
|
@ -265,6 +265,8 @@ pop_variable_scope ()
|
|||
next = v->next;
|
||||
|
||||
free (v->name);
|
||||
if (v->value)
|
||||
free (v->value);
|
||||
free ((char *) v);
|
||||
}
|
||||
}
|
||||
|
@ -687,7 +689,7 @@ try_variable_definition (flocp, line, origin)
|
|||
register char *end;
|
||||
enum { f_bogus,
|
||||
f_simple, f_recursive, f_append, f_conditional } flavor = f_bogus;
|
||||
char *name, *expanded_name, *value;
|
||||
char *name, *expanded_name, *value, *alloc_value=NULL;
|
||||
struct variable *v;
|
||||
|
||||
while (1)
|
||||
|
@ -775,8 +777,11 @@ try_variable_definition (flocp, line, origin)
|
|||
/* Should not be possible. */
|
||||
abort ();
|
||||
case f_simple:
|
||||
/* A simple variable definition "var := value". Expand the value. */
|
||||
value = variable_expand (p);
|
||||
/* A simple variable definition "var := value". Expand the value.
|
||||
We have to allocate memory since otherwise it'll clobber the
|
||||
variable buffer, and we still need that. */
|
||||
alloc_value = allocated_variable_expand (p);
|
||||
value = alloc_value;
|
||||
break;
|
||||
case f_conditional:
|
||||
/* A conditional variable definition "var ?= value".
|
||||
|
@ -931,6 +936,8 @@ try_variable_definition (flocp, line, origin)
|
|||
v = define_variable (expanded_name, strlen (expanded_name),
|
||||
value, origin, flavor == f_recursive);
|
||||
|
||||
if (alloc_value)
|
||||
free (alloc_value);
|
||||
free (expanded_name);
|
||||
|
||||
return v;
|
||||
|
|
Loading…
Reference in a new issue