mirror of
https://github.com/mirror/make.git
synced 2025-04-24 03:50:34 +08:00
Update source file format: remove TABs, use GNU coding styles.
This commit is contained in:
parent
5370238316
commit
96cf67bd29
ChangeLogREADME.AmigaREADME.DOS.templateREADME.W32.templateREADME.gitamiga.car.carscan.ccommands.cconfig.ami.templateconfig.h-vms.templateconfig.h.W32.templatedefault.cdep.hdir.cexpand.cfile.cfiledef.hfunction.cimplicit.cjob.cjob.hload.cmain.cmisc.cread.cremake.cremote-cstms.crule.crule.hsigname.cstrcache.c
tests
variable.cvpath.c@ -1,5 +1,7 @@
|
||||
2013-05-17 Paul Smith <psmith@gnu.org>
|
||||
|
||||
* Source (*.[ch]): Remove TABs, use GNU coding styles.
|
||||
|
||||
* ALL: Update copyright.
|
||||
|
||||
* hash.c (CALLOC): Use xcalloc() to handle out of memory errors.
|
||||
|
12
README.Amiga
12
README.Amiga
@ -11,7 +11,7 @@ GNU make):
|
||||
- Can run multi-line statements
|
||||
- Allows to use Device-Names in targets:
|
||||
|
||||
c:make : make.o
|
||||
c:make : make.o
|
||||
|
||||
is ok. To distinguish between device-names and target : or ::, MAKE
|
||||
looks for spaces. If there are any around :, it's taken as a target
|
||||
@ -19,11 +19,11 @@ GNU make):
|
||||
that "make:make.o" tries to create "make.o" on the device "make:".
|
||||
- Replaces @@ by a newline in any command line:
|
||||
|
||||
if exists make @@\
|
||||
delete make.bak quiet @@\
|
||||
rename make make.bak @@\
|
||||
endif @@\
|
||||
$(CC) Link Make.o To make
|
||||
if exists make @@\
|
||||
delete make.bak quiet @@\
|
||||
rename make make.bak @@\
|
||||
endif @@\
|
||||
$(CC) Link Make.o To make
|
||||
|
||||
works. Note that the @@ must stand alone (i.e., "make@@\" is illegal).
|
||||
Also be careful that there is a space after the "\" (i.e., at the
|
||||
|
@ -62,7 +62,7 @@ To build from sources:
|
||||
[Enter]. Otherwise, you need to supply the path to the source
|
||||
directory as an argument to the batch file, like this:
|
||||
|
||||
c:\djgpp\gnu\make-%VERSION%\configure.bat c:/djgpp/gnu/make-%VERSION%
|
||||
c:\djgpp\gnu\make-%VERSION%\configure.bat c:/djgpp/gnu/make-%VERSION%
|
||||
|
||||
Note the forward slashes in the source path argument: you MUST
|
||||
use them here.
|
||||
@ -84,7 +84,7 @@ To build from sources:
|
||||
If you are building from outside of the source directory, you
|
||||
need to tell Make where the sources are, like this:
|
||||
|
||||
make srcdir=c:/djgpp/gnu/make-%VERSION%
|
||||
make srcdir=c:/djgpp/gnu/make-%VERSION%
|
||||
|
||||
(configure.bat will tell you this when it finishes). You MUST
|
||||
use a full, not relative, name of the source directory here, or
|
||||
@ -99,7 +99,7 @@ To build from sources:
|
||||
area. If you wish to use a different directory, override the
|
||||
DESTDIR variable when invoking "make install", like this:
|
||||
|
||||
make install DESTDIR=c:/other/dir
|
||||
make install DESTDIR=c:/other/dir
|
||||
|
||||
This causes the make executable to be placed in c:/other/dir/bin,
|
||||
the man pages in c:/other/dir/man, etc.
|
||||
@ -110,12 +110,12 @@ To build from sources:
|
||||
file 'dir' in your Info directory by adding the following item
|
||||
to the main menu:
|
||||
|
||||
* Make: (make.info). The GNU make utility.
|
||||
* Make: (make.info). The GNU make utility.
|
||||
|
||||
If you have the 'install-info' program (from the GNU Texinfo
|
||||
package), it will do that for you if you invoke it like this:
|
||||
|
||||
install-info --info-dir=c:/djgpp/info c:/djgpp/info/make.info
|
||||
install-info --info-dir=c:/djgpp/info c:/djgpp/info/make.info
|
||||
|
||||
(If your Info directory is other than C:\DJGPP\INFO, change this
|
||||
command accordingly.)
|
||||
@ -320,7 +320,7 @@ Bug reports:
|
||||
|
||||
|
||||
Enjoy,
|
||||
Eli Zaretskii <eliz@is.elta.co.il>
|
||||
Eli Zaretskii <eliz@is.elta.co.il>
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
@ -55,7 +55,7 @@ Building with (MinGW-)GCC using build_w32.bat
|
||||
2. Open a W32 command prompt for your installed (MinGW-)GCC, setup a
|
||||
correct PATH and other environment variables for it, then execute ...
|
||||
|
||||
build_w32.bat gcc
|
||||
build_w32.bat gcc
|
||||
|
||||
This produces gnumake.exe in the current directory.
|
||||
|
||||
@ -75,13 +75,13 @@ Building with (MSVC++-)cl using build_w32.bat or NMakefile
|
||||
e.g. "%VS71COMNTOOLS%vsvars32.bat"; or using a corresponding start
|
||||
menue entry from the cl-installation), then execute EITHER ...
|
||||
|
||||
build_w32.bat
|
||||
build_w32.bat
|
||||
|
||||
(this produces WinDebug/gnumake.exe and WinRel/gnumake.exe)
|
||||
|
||||
... OR ...
|
||||
|
||||
nmake /f NMakefile
|
||||
nmake /f NMakefile
|
||||
|
||||
(this produces WinDebug/make.exe and WinRel/make.exe).
|
||||
|
||||
@ -97,200 +97,200 @@ Building with (MSVC++-)cl using build_w32.bat or NMakefile
|
||||
|
||||
GNU make on Windows 32-bit platforms:
|
||||
|
||||
This version of make is ported natively to Windows32 platforms
|
||||
(Windows NT 3.51, Windows NT 4.0, Windows 2000, Windows XP,
|
||||
Windows 95, and Windows 98). It does not rely on any 3rd party
|
||||
software or add-on packages for building. The only thing
|
||||
needed is a Windows compiler. Two compilers supported
|
||||
officially are the MinGW port of GNU GCC, and the various
|
||||
versions of the Microsoft C compiler.
|
||||
This version of make is ported natively to Windows32 platforms
|
||||
(Windows NT 3.51, Windows NT 4.0, Windows 2000, Windows XP,
|
||||
Windows 95, and Windows 98). It does not rely on any 3rd party
|
||||
software or add-on packages for building. The only thing
|
||||
needed is a Windows compiler. Two compilers supported
|
||||
officially are the MinGW port of GNU GCC, and the various
|
||||
versions of the Microsoft C compiler.
|
||||
|
||||
Do not confuse this port of GNU make with other Windows32 projects
|
||||
which provide a GNU make binary. These are separate projects
|
||||
and are not connected to this port effort.
|
||||
Do not confuse this port of GNU make with other Windows32 projects
|
||||
which provide a GNU make binary. These are separate projects
|
||||
and are not connected to this port effort.
|
||||
|
||||
GNU make and sh.exe:
|
||||
|
||||
This port prefers if you have a working sh.exe somewhere on
|
||||
your system. If you don't have sh.exe, the port falls back to
|
||||
MSDOS mode for launching programs (via a batch file). The
|
||||
MSDOS mode style execution has not been tested that carefully
|
||||
though (The author uses GNU bash as sh.exe).
|
||||
This port prefers if you have a working sh.exe somewhere on
|
||||
your system. If you don't have sh.exe, the port falls back to
|
||||
MSDOS mode for launching programs (via a batch file). The
|
||||
MSDOS mode style execution has not been tested that carefully
|
||||
though (The author uses GNU bash as sh.exe).
|
||||
|
||||
There are very few true ports of Bourne shell for NT right now.
|
||||
There is a version of GNU bash available from Cygnus "Cygwin"
|
||||
porting effort (http://www.cygwin.com/).
|
||||
Other possibilities are the MKS version of sh.exe, or building
|
||||
There are very few true ports of Bourne shell for NT right now.
|
||||
There is a version of GNU bash available from Cygnus "Cygwin"
|
||||
porting effort (http://www.cygwin.com/).
|
||||
Other possibilities are the MKS version of sh.exe, or building
|
||||
your own with a package like NutCracker (DataFocus) or Portage
|
||||
(Consensys). Also MinGW includes sh (http://mingw.org/).
|
||||
|
||||
GNU make and brain-dead shells (BATCH_MODE_ONLY_SHELL):
|
||||
|
||||
Some versions of Bourne shell do not behave well when invoked
|
||||
as 'sh -c' from CreateProcess(). The main problem is they seem
|
||||
to have a hard time handling quoted strings correctly. This can
|
||||
be circumvented by writing commands to be executed to a batch
|
||||
file and then executing the command by calling 'sh file'.
|
||||
Some versions of Bourne shell do not behave well when invoked
|
||||
as 'sh -c' from CreateProcess(). The main problem is they seem
|
||||
to have a hard time handling quoted strings correctly. This can
|
||||
be circumvented by writing commands to be executed to a batch
|
||||
file and then executing the command by calling 'sh file'.
|
||||
|
||||
To work around this difficulty, this version of make supports
|
||||
a batch mode. When BATCH_MODE_ONLY_SHELL is defined at compile
|
||||
time, make forces all command lines to be executed via script
|
||||
files instead of by command line. In this mode you must have a
|
||||
working sh.exe in order to use parallel builds (-j).
|
||||
To work around this difficulty, this version of make supports
|
||||
a batch mode. When BATCH_MODE_ONLY_SHELL is defined at compile
|
||||
time, make forces all command lines to be executed via script
|
||||
files instead of by command line. In this mode you must have a
|
||||
working sh.exe in order to use parallel builds (-j).
|
||||
|
||||
A native Windows32 system with no Bourne shell will also run
|
||||
in batch mode. All command lines will be put into batch files
|
||||
and executed via $(COMSPEC) (%COMSPEC%). However, parallel
|
||||
builds ARE supported with Windows shells (cmd.exe and
|
||||
command.com). See the next section about some peculiarities
|
||||
of parallel builds on Windows.
|
||||
A native Windows32 system with no Bourne shell will also run
|
||||
in batch mode. All command lines will be put into batch files
|
||||
and executed via $(COMSPEC) (%COMSPEC%). However, parallel
|
||||
builds ARE supported with Windows shells (cmd.exe and
|
||||
command.com). See the next section about some peculiarities
|
||||
of parallel builds on Windows.
|
||||
|
||||
Support for parallel builds
|
||||
|
||||
Parallel builds (-jN) are supported in this port, with 1
|
||||
limitation: The number of concurrent processes has a hard
|
||||
limit of 64, due to the way this port implements waiting for
|
||||
its subprocesses.
|
||||
Parallel builds (-jN) are supported in this port, with 1
|
||||
limitation: The number of concurrent processes has a hard
|
||||
limit of 64, due to the way this port implements waiting for
|
||||
its subprocesses.
|
||||
|
||||
GNU make and Cygnus GNU Windows32 tools:
|
||||
|
||||
Good news! Make now has native support for Cygwin sh. To enable,
|
||||
define the HAVE_CYGWIN_SHELL in config.h and rebuild make
|
||||
from scratch. This version of make tested with B20.1 of Cygwin.
|
||||
Do not define BATCH_MODE_ONLY_SHELL if you use HAVE_CYGWIN_SHELL.
|
||||
Good news! Make now has native support for Cygwin sh. To enable,
|
||||
define the HAVE_CYGWIN_SHELL in config.h and rebuild make
|
||||
from scratch. This version of make tested with B20.1 of Cygwin.
|
||||
Do not define BATCH_MODE_ONLY_SHELL if you use HAVE_CYGWIN_SHELL.
|
||||
|
||||
GNU make and the MKS shell:
|
||||
|
||||
There is now semi-official support for the MKS shell. To turn this
|
||||
support on, define HAVE_MKS_SHELL in the config.h.W32 before you
|
||||
build make. Do not define BATCH_MODE_ONLY_SHELL if you turn
|
||||
on HAVE_MKS_SHELL.
|
||||
There is now semi-official support for the MKS shell. To turn this
|
||||
support on, define HAVE_MKS_SHELL in the config.h.W32 before you
|
||||
build make. Do not define BATCH_MODE_ONLY_SHELL if you turn
|
||||
on HAVE_MKS_SHELL.
|
||||
|
||||
GNU make handling of drive letters in pathnames (PATH, vpath, VPATH):
|
||||
|
||||
There is a caveat that should be noted with respect to handling
|
||||
single character pathnames on Windows systems. When colon is
|
||||
used in PATH variables, make tries to be smart about knowing when
|
||||
you are using colon as a separator versus colon as a drive
|
||||
letter. Unfortunately, something as simple as the string 'x:/'
|
||||
could be interpreted 2 ways: (x and /) or (x:/).
|
||||
There is a caveat that should be noted with respect to handling
|
||||
single character pathnames on Windows systems. When colon is
|
||||
used in PATH variables, make tries to be smart about knowing when
|
||||
you are using colon as a separator versus colon as a drive
|
||||
letter. Unfortunately, something as simple as the string 'x:/'
|
||||
could be interpreted 2 ways: (x and /) or (x:/).
|
||||
|
||||
Make chooses to interpret a letter plus colon (e.g. x:/) as a
|
||||
drive letter pathname. If it is necessary to use single
|
||||
character directories in paths (VPATH, vpath, Path, PATH), the
|
||||
user must do one of two things:
|
||||
Make chooses to interpret a letter plus colon (e.g. x:/) as a
|
||||
drive letter pathname. If it is necessary to use single
|
||||
character directories in paths (VPATH, vpath, Path, PATH), the
|
||||
user must do one of two things:
|
||||
|
||||
a. Use semicolon as the separator to disambiguate colon. For
|
||||
example use 'x;/' if you want to say 'x' and '/' are
|
||||
separate components.
|
||||
a. Use semicolon as the separator to disambiguate colon. For
|
||||
example use 'x;/' if you want to say 'x' and '/' are
|
||||
separate components.
|
||||
|
||||
b. Qualify the directory name so that there is more than
|
||||
one character in the path(s) used. For example, none
|
||||
of these settings are ambiguous:
|
||||
b. Qualify the directory name so that there is more than
|
||||
one character in the path(s) used. For example, none
|
||||
of these settings are ambiguous:
|
||||
|
||||
./x:./y
|
||||
/some/path/x:/some/path/y
|
||||
x:/some/path/x:x:/some/path/y
|
||||
./x:./y
|
||||
/some/path/x:/some/path/y
|
||||
x:/some/path/x:x:/some/path/y
|
||||
|
||||
Please note that you are free to mix colon and semi-colon in the
|
||||
specification of paths. Make is able to figure out the intended
|
||||
result and convert the paths internally to the format needed
|
||||
when interacting with the operating system, providing the path
|
||||
is not within quotes, e.g. "x:/test/test.c".
|
||||
Please note that you are free to mix colon and semi-colon in the
|
||||
specification of paths. Make is able to figure out the intended
|
||||
result and convert the paths internally to the format needed
|
||||
when interacting with the operating system, providing the path
|
||||
is not within quotes, e.g. "x:/test/test.c".
|
||||
|
||||
You are encouraged to use colon as the separator character.
|
||||
This should ease the pain of deciding how to handle various path
|
||||
problems which exist between platforms. If colon is used on
|
||||
both Unix and Windows systems, then no ifdef'ing will be
|
||||
necessary in the makefile source.
|
||||
You are encouraged to use colon as the separator character.
|
||||
This should ease the pain of deciding how to handle various path
|
||||
problems which exist between platforms. If colon is used on
|
||||
both Unix and Windows systems, then no ifdef'ing will be
|
||||
necessary in the makefile source.
|
||||
|
||||
GNU make test suite:
|
||||
|
||||
I verified all functionality with a slightly modified version
|
||||
of make-test-%VERSION% (modifications to get test suite to run
|
||||
on Windows NT). All tests pass in an environment that includes
|
||||
sh.exe. Tests were performed on both Windows NT and Windows 95.
|
||||
I verified all functionality with a slightly modified version
|
||||
of make-test-%VERSION% (modifications to get test suite to run
|
||||
on Windows NT). All tests pass in an environment that includes
|
||||
sh.exe. Tests were performed on both Windows NT and Windows 95.
|
||||
|
||||
Pathnames and white space:
|
||||
|
||||
Unlike Unix, Windows 95/NT systems encourage pathnames which
|
||||
contain white space (e.g. C:\Program Files\). These sorts of
|
||||
pathnames are valid on Unix too, but are never encouraged.
|
||||
There is at least one place in make (VPATH/vpath handling) where
|
||||
paths containing white space will simply not work. There may be
|
||||
others too. I chose to not try and port make in such a way so
|
||||
that these sorts of paths could be handled. I offer these
|
||||
suggestions as workarounds:
|
||||
Unlike Unix, Windows 95/NT systems encourage pathnames which
|
||||
contain white space (e.g. C:\Program Files\). These sorts of
|
||||
pathnames are valid on Unix too, but are never encouraged.
|
||||
There is at least one place in make (VPATH/vpath handling) where
|
||||
paths containing white space will simply not work. There may be
|
||||
others too. I chose to not try and port make in such a way so
|
||||
that these sorts of paths could be handled. I offer these
|
||||
suggestions as workarounds:
|
||||
|
||||
1. Use 8.3 notation. i.e. "x:/long~1/", which is actually
|
||||
"x:\longpathtest". Type "dir /x" to view these filenames
|
||||
within the cmd.exe shell.
|
||||
2. Rename the directory so it does not contain white space.
|
||||
1. Use 8.3 notation. i.e. "x:/long~1/", which is actually
|
||||
"x:\longpathtest". Type "dir /x" to view these filenames
|
||||
within the cmd.exe shell.
|
||||
2. Rename the directory so it does not contain white space.
|
||||
|
||||
If you are unhappy with this choice, this is free software
|
||||
and you are free to take a crack at making this work. The code
|
||||
in w32/pathstuff.c and vpath.c would be the places to start.
|
||||
If you are unhappy with this choice, this is free software
|
||||
and you are free to take a crack at making this work. The code
|
||||
in w32/pathstuff.c and vpath.c would be the places to start.
|
||||
|
||||
Pathnames and Case insensitivity:
|
||||
|
||||
Unlike Unix, Windows 95/NT systems are case insensitive but case
|
||||
preserving. For example if you tell the file system to create a
|
||||
file named "Target", it will preserve the case. Subsequent access to
|
||||
the file with other case permutations will succeed (i.e. opening a
|
||||
file named "target" or "TARGET" will open the file "Target").
|
||||
Unlike Unix, Windows 95/NT systems are case insensitive but case
|
||||
preserving. For example if you tell the file system to create a
|
||||
file named "Target", it will preserve the case. Subsequent access to
|
||||
the file with other case permutations will succeed (i.e. opening a
|
||||
file named "target" or "TARGET" will open the file "Target").
|
||||
|
||||
By default, GNU make retains its case sensitivity when comparing
|
||||
target names and existing files or directories. It can be
|
||||
configured, however, into a case preserving and case insensitive
|
||||
mode by adding a define for HAVE_CASE_INSENSITIVE_FS to
|
||||
config.h.W32.
|
||||
By default, GNU make retains its case sensitivity when comparing
|
||||
target names and existing files or directories. It can be
|
||||
configured, however, into a case preserving and case insensitive
|
||||
mode by adding a define for HAVE_CASE_INSENSITIVE_FS to
|
||||
config.h.W32.
|
||||
|
||||
For example, the following makefile will create a file named
|
||||
Target in the directory subdir which will subsequently be used
|
||||
to satisfy the dependency of SUBDIR/DepTarget on SubDir/TARGET.
|
||||
Without HAVE_CASE_INSENSITIVE_FS configured, the dependency link
|
||||
will not be made:
|
||||
For example, the following makefile will create a file named
|
||||
Target in the directory subdir which will subsequently be used
|
||||
to satisfy the dependency of SUBDIR/DepTarget on SubDir/TARGET.
|
||||
Without HAVE_CASE_INSENSITIVE_FS configured, the dependency link
|
||||
will not be made:
|
||||
|
||||
subdir/Target:
|
||||
touch $@
|
||||
subdir/Target:
|
||||
touch $@
|
||||
|
||||
SUBDIR/DepTarget: SubDir/TARGET
|
||||
cp $^ $@
|
||||
SUBDIR/DepTarget: SubDir/TARGET
|
||||
cp $^ $@
|
||||
|
||||
Reliance on this behavior also eliminates the ability of GNU make
|
||||
to use case in comparison of matching rules. For example, it is
|
||||
not possible to set up a C++ rule using %.C that is different
|
||||
than a C rule using %.c. GNU make will consider these to be the
|
||||
same rule and will issue a warning.
|
||||
Reliance on this behavior also eliminates the ability of GNU make
|
||||
to use case in comparison of matching rules. For example, it is
|
||||
not possible to set up a C++ rule using %.C that is different
|
||||
than a C rule using %.c. GNU make will consider these to be the
|
||||
same rule and will issue a warning.
|
||||
|
||||
SAMBA/NTFS/VFAT:
|
||||
|
||||
I have not had any success building the debug version of this
|
||||
package using SAMBA as my file server. The reason seems to be
|
||||
related to the way VC++ 4.0 changes the case name of the pdb
|
||||
filename it is passed on the command line. It seems to change
|
||||
the name always to to lower case. I contend that the VC++
|
||||
compiler should not change the casename of files that are passed
|
||||
as arguments on the command line. I don't think this was a
|
||||
problem in MSVC 2.x, but I know it is a problem in MSVC 4.x.
|
||||
I have not had any success building the debug version of this
|
||||
package using SAMBA as my file server. The reason seems to be
|
||||
related to the way VC++ 4.0 changes the case name of the pdb
|
||||
filename it is passed on the command line. It seems to change
|
||||
the name always to to lower case. I contend that the VC++
|
||||
compiler should not change the casename of files that are passed
|
||||
as arguments on the command line. I don't think this was a
|
||||
problem in MSVC 2.x, but I know it is a problem in MSVC 4.x.
|
||||
|
||||
The package builds fine on VFAT and NTFS filesystems.
|
||||
The package builds fine on VFAT and NTFS filesystems.
|
||||
|
||||
Most all of the development I have done to date has been using
|
||||
NTFS and long file names. I have not done any considerable work
|
||||
under VFAT. VFAT users may wish to be aware that this port of
|
||||
make does respect case sensitivity.
|
||||
Most all of the development I have done to date has been using
|
||||
NTFS and long file names. I have not done any considerable work
|
||||
under VFAT. VFAT users may wish to be aware that this port of
|
||||
make does respect case sensitivity.
|
||||
|
||||
FAT:
|
||||
|
||||
Version 3.76 added support for FAT filesystems. Make works
|
||||
around some difficulties with stat'ing of files and caching of
|
||||
filenames and directories internally.
|
||||
Version 3.76 added support for FAT filesystems. Make works
|
||||
around some difficulties with stat'ing of files and caching of
|
||||
filenames and directories internally.
|
||||
|
||||
Bug reports:
|
||||
|
||||
Please submit bugs via the normal bug reporting mechanism which
|
||||
is described in the GNU make manual and the base README.
|
||||
Please submit bugs via the normal bug reporting mechanism which
|
||||
is described in the GNU make manual and the base README.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 1996-2013 Free Software Foundation, Inc.
|
||||
|
11
README.git
11
README.git
@ -56,6 +56,17 @@ constructing multiple commits from various files and even from different
|
||||
diff chunks in the same file. There is a video available which helps a lot.
|
||||
|
||||
|
||||
Coding Standards
|
||||
----------------
|
||||
|
||||
GNU make code adheres to the GNU Coding Standards. Additionally, GNU make is
|
||||
a foundational bootstrap package for the GNU project; as such it is very
|
||||
conservative about language features it expects. It should build with any C
|
||||
compiler conforming to the ANSI C89 / ISO C90 standard.
|
||||
|
||||
Please use only spaces and no TAB characters in source code.
|
||||
|
||||
|
||||
Building From Git
|
||||
-----------------
|
||||
|
||||
|
82
amiga.c
82
amiga.c
@ -24,7 +24,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include <proto/dos.h>
|
||||
|
||||
static const char Amiga_version[] = "$VER: Make 3.74.3 (12.05.96) \n"
|
||||
"Amiga Port by A. Digulla (digulla@home.lake.de)";
|
||||
"Amiga Port by A. Digulla (digulla@home.lake.de)";
|
||||
|
||||
int
|
||||
MyExecute (char **argv)
|
||||
@ -36,7 +36,7 @@ MyExecute (char **argv)
|
||||
|
||||
for (aptr=argv; *aptr; aptr++)
|
||||
{
|
||||
len += strlen (*aptr) + 4;
|
||||
len += strlen (*aptr) + 4;
|
||||
}
|
||||
|
||||
buffer = AllocMem (len, MEMF_ANY);
|
||||
@ -48,41 +48,41 @@ MyExecute (char **argv)
|
||||
|
||||
for (aptr=argv; *aptr; aptr++)
|
||||
{
|
||||
if (((*aptr)[0] == ';' && !(*aptr)[1]))
|
||||
{
|
||||
*ptr ++ = '"';
|
||||
strcpy (ptr, *aptr);
|
||||
ptr += strlen (ptr);
|
||||
*ptr ++ = '"';
|
||||
}
|
||||
else if ((*aptr)[0] == '@' && (*aptr)[1] == '@' && !(*aptr)[2])
|
||||
{
|
||||
*ptr ++ = '\n';
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy (ptr, *aptr);
|
||||
ptr += strlen (ptr);
|
||||
}
|
||||
*ptr ++ = ' ';
|
||||
*ptr = 0;
|
||||
if (((*aptr)[0] == ';' && !(*aptr)[1]))
|
||||
{
|
||||
*ptr ++ = '"';
|
||||
strcpy (ptr, *aptr);
|
||||
ptr += strlen (ptr);
|
||||
*ptr ++ = '"';
|
||||
}
|
||||
else if ((*aptr)[0] == '@' && (*aptr)[1] == '@' && !(*aptr)[2])
|
||||
{
|
||||
*ptr ++ = '\n';
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy (ptr, *aptr);
|
||||
ptr += strlen (ptr);
|
||||
}
|
||||
*ptr ++ = ' ';
|
||||
*ptr = 0;
|
||||
}
|
||||
|
||||
ptr[-1] = '\n';
|
||||
|
||||
status = SystemTags (buffer,
|
||||
SYS_UserShell, TRUE,
|
||||
TAG_END);
|
||||
SYS_UserShell, TRUE,
|
||||
TAG_END);
|
||||
|
||||
FreeMem (buffer, len);
|
||||
|
||||
if (SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
|
||||
status = 20;
|
||||
if (SetSignal (0L,0L) & SIGBREAKF_CTRL_C)
|
||||
status = 20;
|
||||
|
||||
/* Warnings don't count */
|
||||
if (status == 5)
|
||||
status = 0;
|
||||
status = 0;
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -90,27 +90,27 @@ MyExecute (char **argv)
|
||||
char *
|
||||
wildcard_expansion (char *wc, char *o)
|
||||
{
|
||||
# define PATH_SIZE 1024
|
||||
# define PATH_SIZE 1024
|
||||
struct AnchorPath * apath;
|
||||
|
||||
if ( (apath = AllocMem (sizeof (struct AnchorPath) + PATH_SIZE,
|
||||
MEMF_CLEAR))
|
||||
)
|
||||
MEMF_CLEAR))
|
||||
)
|
||||
{
|
||||
apath->ap_Strlen = PATH_SIZE;
|
||||
apath->ap_Strlen = PATH_SIZE;
|
||||
|
||||
if (MatchFirst (wc, apath) == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
o = variable_buffer_output (o, apath->ap_Buf,
|
||||
strlen (apath->ap_Buf));
|
||||
o = variable_buffer_output (o, " ",1);
|
||||
} while (MatchNext (apath) == 0);
|
||||
}
|
||||
if (MatchFirst (wc, apath) == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
o = variable_buffer_output (o, apath->ap_Buf,
|
||||
strlen (apath->ap_Buf));
|
||||
o = variable_buffer_output (o, " ",1);
|
||||
} while (MatchNext (apath) == 0);
|
||||
}
|
||||
|
||||
MatchEnd (apath);
|
||||
FreeMem (apath, sizeof (struct AnchorPath) + PATH_SIZE);
|
||||
MatchEnd (apath);
|
||||
FreeMem (apath, sizeof (struct AnchorPath) + PATH_SIZE);
|
||||
}
|
||||
|
||||
return o;
|
||||
|
30
ar.c
30
ar.c
@ -17,7 +17,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "makeint.h"
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
#ifndef NO_ARCHIVES
|
||||
|
||||
#include "filedef.h"
|
||||
#include "dep.h"
|
||||
@ -61,7 +61,7 @@ ar_parse_name (const char *name, char **arname_p, char **memname_p)
|
||||
*arname_p = xstrdup (name);
|
||||
p = strchr (*arname_p, '(');
|
||||
*(p++) = '\0';
|
||||
p[strlen(p) - 1] = '\0';
|
||||
p[strlen (p) - 1] = '\0';
|
||||
*memname_p = p;
|
||||
}
|
||||
|
||||
@ -71,10 +71,10 @@ ar_parse_name (const char *name, char **arname_p, char **memname_p)
|
||||
/* ARGSUSED */
|
||||
static long int
|
||||
ar_member_date_1 (int desc UNUSED, const char *mem, int truncated,
|
||||
long int hdrpos UNUSED, long int datapos UNUSED,
|
||||
long int hdrpos UNUSED, long int datapos UNUSED,
|
||||
long int size UNUSED, long int date,
|
||||
int uid UNUSED, int gid UNUSED, int mode UNUSED,
|
||||
const void *name)
|
||||
const void *name)
|
||||
{
|
||||
return ar_name_equal (name, mem, truncated) ? date : 0;
|
||||
}
|
||||
@ -186,7 +186,7 @@ struct ar_glob_state
|
||||
|
||||
static long int
|
||||
ar_glob_match (int desc UNUSED, const char *mem, int truncated UNUSED,
|
||||
long int hdrpos UNUSED, long int datapos UNUSED,
|
||||
long int hdrpos UNUSED, long int datapos UNUSED,
|
||||
long int size UNUSED, long int date UNUSED, int uid UNUSED,
|
||||
int gid UNUSED, int mode UNUSED, const void *arg)
|
||||
{
|
||||
@ -218,21 +218,21 @@ glob_pattern_p (const char *pattern, int quote)
|
||||
{
|
||||
case '?':
|
||||
case '*':
|
||||
return 1;
|
||||
return 1;
|
||||
|
||||
case '\\':
|
||||
if (quote)
|
||||
++p;
|
||||
break;
|
||||
if (quote)
|
||||
++p;
|
||||
break;
|
||||
|
||||
case '[':
|
||||
opened = 1;
|
||||
break;
|
||||
opened = 1;
|
||||
break;
|
||||
|
||||
case ']':
|
||||
if (opened)
|
||||
return 1;
|
||||
break;
|
||||
if (opened)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -282,4 +282,4 @@ ar_glob (const char *arname, const char *member_pattern, unsigned int size)
|
||||
return state.chain;
|
||||
}
|
||||
|
||||
#endif /* Not NO_ARCHIVES. */
|
||||
#endif /* Not NO_ARCHIVES. */
|
||||
|
526
arscan.c
526
arscan.c
@ -22,7 +22,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
#ifndef NO_ARCHIVES
|
||||
|
||||
#ifdef VMS
|
||||
#include <lbrdef.h>
|
||||
@ -61,11 +61,11 @@ VMS_get_member_info (struct dsc$descriptor_s *module, unsigned long *rfa)
|
||||
bufdesc.dsc$w_length = sizeof (filename);
|
||||
|
||||
status = lbr$set_module (&VMS_lib_idx, rfa, &bufdesc,
|
||||
&bufdesc.dsc$w_length, 0);
|
||||
&bufdesc.dsc$w_length, 0);
|
||||
if (! (status & 1))
|
||||
{
|
||||
error (NILF, _("lbr$set_module() failed to extract module info, status = %d"),
|
||||
status);
|
||||
status);
|
||||
|
||||
lbr$close (&VMS_lib_idx);
|
||||
|
||||
@ -112,7 +112,7 @@ VMS_get_member_info (struct dsc$descriptor_s *module, unsigned long *rfa)
|
||||
|
||||
fnval =
|
||||
(*VMS_function) (-1, filename, 0, 0, 0, 0, val, 0, 0, 0,
|
||||
VMS_saved_memname);
|
||||
VMS_saved_memname);
|
||||
|
||||
if (fnval)
|
||||
{
|
||||
@ -183,7 +183,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
if (! (status & 1))
|
||||
{
|
||||
error (NILF, _("unable to open library '%s' to lookup member '%s'"),
|
||||
archive, (char *)arg);
|
||||
archive, (char *)arg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -212,8 +212,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
#else /* !VMS */
|
||||
|
||||
/* SCO Unix's compiler defines both of these. */
|
||||
#ifdef M_UNIX
|
||||
#undef M_XENIX
|
||||
#ifdef M_UNIX
|
||||
#undef M_XENIX
|
||||
#endif
|
||||
|
||||
/* On the sun386i and in System V rel 3, ar.h defines two different archive
|
||||
@ -222,7 +222,7 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
to have a nonzero value. */
|
||||
|
||||
#if (!defined (PORTAR) || PORTAR == 0) && (!defined (PORT5AR) || PORT5AR == 0)
|
||||
#undef PORTAR
|
||||
#undef PORTAR
|
||||
#ifdef M_XENIX
|
||||
/* According to Jim Sievert <jas1@rsvl.unisys.com>, for SCO XENIX defining
|
||||
PORTAR to 1 gets the wrong archive format, and defining it to 0 gets the
|
||||
@ -257,17 +257,17 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
/* BeOS 5 doesn't have <ar.h> but has archives in the same format
|
||||
* as many other Unices. This was taken from GNU binutils for BeOS.
|
||||
*/
|
||||
# define ARMAG "!<arch>\n" /* String that begins an archive file. */
|
||||
# define SARMAG 8 /* Size of that string. */
|
||||
# define ARFMAG "`\n" /* String in ar_fmag at end of each header. */
|
||||
# define ARMAG "!<arch>\n" /* String that begins an archive file. */
|
||||
# define SARMAG 8 /* Size of that string. */
|
||||
# define ARFMAG "`\n" /* String in ar_fmag at end of each header. */
|
||||
struct ar_hdr
|
||||
{
|
||||
char ar_name[16]; /* Member file name, sometimes / terminated. */
|
||||
char ar_date[12]; /* File date, decimal seconds since Epoch. */
|
||||
char ar_uid[6], ar_gid[6]; /* User and group IDs, in ASCII decimal. */
|
||||
char ar_mode[8]; /* File mode, in ASCII octal. */
|
||||
char ar_size[10]; /* File size, in ASCII decimal. */
|
||||
char ar_fmag[2]; /* Always contains ARFMAG. */
|
||||
char ar_name[16]; /* Member file name, sometimes / terminated. */
|
||||
char ar_date[12]; /* File date, decimal seconds since Epoch. */
|
||||
char ar_uid[6], ar_gid[6]; /* User and group IDs, in ASCII decimal. */
|
||||
char ar_mode[8]; /* File mode, in ASCII octal. */
|
||||
char ar_size[10]; /* File size, in ASCII decimal. */
|
||||
char ar_fmag[2]; /* Always contains ARFMAG. */
|
||||
};
|
||||
# endif
|
||||
# define TOCHAR(_m) (_m)
|
||||
@ -292,8 +292,8 @@ struct ar_hdr
|
||||
#endif
|
||||
|
||||
/* Cray's <ar.h> apparently defines this. */
|
||||
#ifndef AR_HDR_SIZE
|
||||
# define AR_HDR_SIZE (sizeof (struct ar_hdr))
|
||||
#ifndef AR_HDR_SIZE
|
||||
# define AR_HDR_SIZE (sizeof (struct ar_hdr))
|
||||
#endif
|
||||
|
||||
/* Takes three arguments ARCHIVE, FUNCTION and ARG.
|
||||
@ -345,8 +345,8 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
register int nread = read (desc, buf, SARMAG);
|
||||
if (nread != SARMAG || memcmp (buf, ARMAG, SARMAG))
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
#else
|
||||
@ -356,39 +356,39 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
|
||||
if (nread != FL_HSZ)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
(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 (!memcmp (fl_header.fl_magic, AIAMAGBIG, SAIAMAG))
|
||||
{
|
||||
big_archive = 1;
|
||||
big_archive = 1;
|
||||
|
||||
/* seek back to beginning of archive */
|
||||
if (lseek (desc, 0, 0) < 0)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
/* 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, &fl_header_big, FL_HSZ_BIG);
|
||||
if (nread != FL_HSZ_BIG)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
/* re-read the header into the "big" structure */
|
||||
nread = read (desc, &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 (memcmp (fl_header.fl_magic, AIAMAG, SAIAMAG))
|
||||
{
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
@ -397,11 +397,11 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
#else
|
||||
unsigned short int buf;
|
||||
#endif
|
||||
register int nread = read(desc, &buf, sizeof (buf));
|
||||
register int nread = read (desc, &buf, sizeof (buf));
|
||||
if (nread != sizeof (buf) || buf != ARMAG)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -419,143 +419,143 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
#ifdef AIAMAGBIG
|
||||
if ( big_archive )
|
||||
{
|
||||
sscanf (fl_header_big.fl_fstmoff, "%20ld", &member_offset);
|
||||
sscanf (fl_header_big.fl_lstmoff, "%20ld", &last_member_offset);
|
||||
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);
|
||||
sscanf (fl_header.fl_fstmoff, "%12ld", &member_offset);
|
||||
sscanf (fl_header.fl_lstmoff, "%12ld", &last_member_offset);
|
||||
}
|
||||
|
||||
if (member_offset == 0)
|
||||
{
|
||||
/* Empty archive. */
|
||||
close (desc);
|
||||
return 0;
|
||||
/* Empty archive. */
|
||||
close (desc);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#ifndef M_XENIX
|
||||
#ifndef M_XENIX
|
||||
register long int member_offset = sizeof (int);
|
||||
#else /* Xenix. */
|
||||
#else /* Xenix. */
|
||||
register long int member_offset = sizeof (unsigned short int);
|
||||
#endif /* Not Xenix. */
|
||||
#endif /* Not Xenix. */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
while (1)
|
||||
{
|
||||
register int nread;
|
||||
struct ar_hdr member_header;
|
||||
register int nread;
|
||||
struct ar_hdr member_header;
|
||||
#ifdef AIAMAGBIG
|
||||
struct ar_hdr_big member_header_big;
|
||||
struct ar_hdr_big member_header_big;
|
||||
#endif
|
||||
#ifdef AIAMAG
|
||||
char name[256];
|
||||
int name_len;
|
||||
long int dateval;
|
||||
int uidval, gidval;
|
||||
long int data_offset;
|
||||
char name[256];
|
||||
int name_len;
|
||||
long int dateval;
|
||||
int uidval, gidval;
|
||||
long int data_offset;
|
||||
#else
|
||||
char namebuf[sizeof member_header.ar_name + 1];
|
||||
char *name;
|
||||
int is_namemap; /* Nonzero if this entry maps long names. */
|
||||
char namebuf[sizeof member_header.ar_name + 1];
|
||||
char *name;
|
||||
int is_namemap; /* Nonzero if this entry maps long names. */
|
||||
#endif
|
||||
long int eltsize;
|
||||
int eltmode;
|
||||
long int fnval;
|
||||
long int eltsize;
|
||||
int eltmode;
|
||||
long int fnval;
|
||||
|
||||
if (lseek (desc, member_offset, 0) < 0)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
if (lseek (desc, member_offset, 0) < 0)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
|
||||
#ifdef AIAMAG
|
||||
#define AR_MEMHDR_SZ(x) (sizeof(x) - sizeof (x._ar_name))
|
||||
|
||||
#ifdef AIAMAGBIG
|
||||
if (big_archive)
|
||||
{
|
||||
nread = read (desc, &member_header_big,
|
||||
AR_MEMHDR_SZ(member_header_big) );
|
||||
if (big_archive)
|
||||
{
|
||||
nread = read (desc, &member_header_big,
|
||||
AR_MEMHDR_SZ(member_header_big) );
|
||||
|
||||
if (nread != AR_MEMHDR_SZ(member_header_big))
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
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);
|
||||
sscanf (member_header_big.ar_namlen, "%4d", &name_len);
|
||||
nread = read (desc, name, name_len);
|
||||
|
||||
if (nread != name_len)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
if (nread != name_len)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
|
||||
name[name_len] = 0;
|
||||
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);
|
||||
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);
|
||||
}
|
||||
else
|
||||
data_offset = (member_offset + AR_MEMHDR_SZ(member_header_big)
|
||||
+ name_len + 2);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
nread = read (desc, &member_header,
|
||||
AR_MEMHDR_SZ(member_header) );
|
||||
{
|
||||
nread = read (desc, &member_header,
|
||||
AR_MEMHDR_SZ(member_header) );
|
||||
|
||||
if (nread != AR_MEMHDR_SZ(member_header))
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
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);
|
||||
sscanf (member_header.ar_namlen, "%4d", &name_len);
|
||||
nread = read (desc, name, name_len);
|
||||
|
||||
if (nread != name_len)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
if (nread != name_len)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
|
||||
name[name_len] = 0;
|
||||
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);
|
||||
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);
|
||||
}
|
||||
data_offset += data_offset % 2;
|
||||
data_offset = (member_offset + AR_MEMHDR_SZ(member_header)
|
||||
+ name_len + 2);
|
||||
}
|
||||
data_offset += data_offset % 2;
|
||||
|
||||
fnval =
|
||||
(*function) (desc, name, 0,
|
||||
member_offset, data_offset, eltsize,
|
||||
dateval, uidval, gidval,
|
||||
eltmode, arg);
|
||||
fnval =
|
||||
(*function) (desc, name, 0,
|
||||
member_offset, data_offset, eltsize,
|
||||
dateval, uidval, gidval,
|
||||
eltmode, arg);
|
||||
|
||||
#else /* Not AIAMAG. */
|
||||
nread = read (desc, &member_header, AR_HDR_SIZE);
|
||||
if (nread == 0)
|
||||
/* No data left means end of file; that is OK. */
|
||||
break;
|
||||
#else /* Not AIAMAG. */
|
||||
nread = read (desc, &member_header, AR_HDR_SIZE);
|
||||
if (nread == 0)
|
||||
/* No data left means end of file; that is OK. */
|
||||
break;
|
||||
|
||||
if (nread != AR_HDR_SIZE
|
||||
if (nread != AR_HDR_SIZE
|
||||
#if defined(ARFMAG) || defined(ARFZMAG)
|
||||
|| (
|
||||
|| (
|
||||
# ifdef ARFMAG
|
||||
memcmp (member_header.ar_fmag, ARFMAG, 2)
|
||||
# else
|
||||
@ -569,152 +569,152 @@ ar_scan (const char *archive, ar_member_func_t function, const void *arg)
|
||||
# endif
|
||||
)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
|
||||
name = namebuf;
|
||||
memcpy (name, member_header.ar_name, sizeof member_header.ar_name);
|
||||
{
|
||||
register char *p = name + sizeof member_header.ar_name;
|
||||
do
|
||||
*p = '\0';
|
||||
while (p > name && *--p == ' ');
|
||||
name = namebuf;
|
||||
memcpy (name, member_header.ar_name, sizeof member_header.ar_name);
|
||||
{
|
||||
register char *p = name + sizeof member_header.ar_name;
|
||||
do
|
||||
*p = '\0';
|
||||
while (p > name && *--p == ' ');
|
||||
|
||||
#ifndef AIAMAG
|
||||
/* If the member name is "//" or "ARFILENAMES/" this may be
|
||||
a list of file name mappings. The maximum file name
|
||||
length supported by the standard archive format is 14
|
||||
characters. This member will actually always be the
|
||||
first or second entry in the archive, but we don't check
|
||||
that. */
|
||||
is_namemap = (!strcmp (name, "//")
|
||||
|| !strcmp (name, "ARFILENAMES/"));
|
||||
#endif /* Not AIAMAG. */
|
||||
/* On some systems, there is a slash after each member name. */
|
||||
if (*p == '/')
|
||||
*p = '\0';
|
||||
/* If the member name is "//" or "ARFILENAMES/" this may be
|
||||
a list of file name mappings. The maximum file name
|
||||
length supported by the standard archive format is 14
|
||||
characters. This member will actually always be the
|
||||
first or second entry in the archive, but we don't check
|
||||
that. */
|
||||
is_namemap = (!strcmp (name, "//")
|
||||
|| !strcmp (name, "ARFILENAMES/"));
|
||||
#endif /* Not AIAMAG. */
|
||||
/* On some systems, there is a slash after each member name. */
|
||||
if (*p == '/')
|
||||
*p = '\0';
|
||||
|
||||
#ifndef AIAMAG
|
||||
/* If the member name starts with a space or a slash, this
|
||||
is an index into the file name mappings (used by GNU ar).
|
||||
Otherwise if the member name looks like #1/NUMBER the
|
||||
real member name appears in the element data (used by
|
||||
4.4BSD). */
|
||||
if (! is_namemap
|
||||
&& (name[0] == ' ' || name[0] == '/')
|
||||
&& namemap != 0)
|
||||
{
|
||||
name = namemap + atoi (name + 1);
|
||||
long_name = 1;
|
||||
}
|
||||
else if (name[0] == '#'
|
||||
&& name[1] == '1'
|
||||
&& name[2] == '/')
|
||||
{
|
||||
int namesize = atoi (name + 3);
|
||||
/* If the member name starts with a space or a slash, this
|
||||
is an index into the file name mappings (used by GNU ar).
|
||||
Otherwise if the member name looks like #1/NUMBER the
|
||||
real member name appears in the element data (used by
|
||||
4.4BSD). */
|
||||
if (! is_namemap
|
||||
&& (name[0] == ' ' || name[0] == '/')
|
||||
&& namemap != 0)
|
||||
{
|
||||
name = namemap + atoi (name + 1);
|
||||
long_name = 1;
|
||||
}
|
||||
else if (name[0] == '#'
|
||||
&& name[1] == '1'
|
||||
&& name[2] == '/')
|
||||
{
|
||||
int namesize = atoi (name + 3);
|
||||
|
||||
name = alloca (namesize + 1);
|
||||
nread = read (desc, name, namesize);
|
||||
if (nread != namesize)
|
||||
{
|
||||
close (desc);
|
||||
return -2;
|
||||
}
|
||||
name[namesize] = '\0';
|
||||
name = alloca (namesize + 1);
|
||||
nread = read (desc, name, namesize);
|
||||
if (nread != namesize)
|
||||
{
|
||||
close (desc);
|
||||
return -2;
|
||||
}
|
||||
name[namesize] = '\0';
|
||||
|
||||
long_name = 1;
|
||||
}
|
||||
long_name = 1;
|
||||
}
|
||||
#endif /* Not AIAMAG. */
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef M_XENIX
|
||||
sscanf (TOCHAR (member_header.ar_mode), "%o", &eltmode);
|
||||
eltsize = atol (TOCHAR (member_header.ar_size));
|
||||
#else /* Xenix. */
|
||||
eltmode = (unsigned short int) member_header.ar_mode;
|
||||
eltsize = member_header.ar_size;
|
||||
#endif /* Not Xenix. */
|
||||
#ifndef M_XENIX
|
||||
sscanf (TOCHAR (member_header.ar_mode), "%o", &eltmode);
|
||||
eltsize = atol (TOCHAR (member_header.ar_size));
|
||||
#else /* Xenix. */
|
||||
eltmode = (unsigned short int) member_header.ar_mode;
|
||||
eltsize = member_header.ar_size;
|
||||
#endif /* Not Xenix. */
|
||||
|
||||
fnval =
|
||||
(*function) (desc, name, ! long_name, member_offset,
|
||||
member_offset + AR_HDR_SIZE, eltsize,
|
||||
#ifndef M_XENIX
|
||||
atol (TOCHAR (member_header.ar_date)),
|
||||
atoi (TOCHAR (member_header.ar_uid)),
|
||||
atoi (TOCHAR (member_header.ar_gid)),
|
||||
#else /* Xenix. */
|
||||
member_header.ar_date,
|
||||
member_header.ar_uid,
|
||||
member_header.ar_gid,
|
||||
#endif /* Not Xenix. */
|
||||
eltmode, arg);
|
||||
fnval =
|
||||
(*function) (desc, name, ! long_name, member_offset,
|
||||
member_offset + AR_HDR_SIZE, eltsize,
|
||||
#ifndef M_XENIX
|
||||
atol (TOCHAR (member_header.ar_date)),
|
||||
atoi (TOCHAR (member_header.ar_uid)),
|
||||
atoi (TOCHAR (member_header.ar_gid)),
|
||||
#else /* Xenix. */
|
||||
member_header.ar_date,
|
||||
member_header.ar_uid,
|
||||
member_header.ar_gid,
|
||||
#endif /* Not Xenix. */
|
||||
eltmode, arg);
|
||||
|
||||
#endif /* AIAMAG. */
|
||||
|
||||
if (fnval)
|
||||
{
|
||||
(void) close (desc);
|
||||
return fnval;
|
||||
}
|
||||
if (fnval)
|
||||
{
|
||||
(void) close (desc);
|
||||
return fnval;
|
||||
}
|
||||
|
||||
#ifdef AIAMAG
|
||||
if (member_offset == last_member_offset)
|
||||
/* End of the chain. */
|
||||
break;
|
||||
if (member_offset == last_member_offset)
|
||||
/* End of the chain. */
|
||||
break;
|
||||
|
||||
#ifdef AIAMAGBIG
|
||||
if (big_archive)
|
||||
if (big_archive)
|
||||
sscanf (member_header_big.ar_nxtmem, "%20ld", &member_offset);
|
||||
else
|
||||
else
|
||||
#endif
|
||||
sscanf (member_header.ar_nxtmem, "%12ld", &member_offset);
|
||||
sscanf (member_header.ar_nxtmem, "%12ld", &member_offset);
|
||||
|
||||
if (lseek (desc, member_offset, 0) != member_offset)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
if (lseek (desc, member_offset, 0) != member_offset)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
#else
|
||||
|
||||
/* If this member maps archive names, we must read it in. The
|
||||
name map will always precede any members whose names must
|
||||
be mapped. */
|
||||
if (is_namemap)
|
||||
{
|
||||
char *clear;
|
||||
char *limit;
|
||||
/* If this member maps archive names, we must read it in. The
|
||||
name map will always precede any members whose names must
|
||||
be mapped. */
|
||||
if (is_namemap)
|
||||
{
|
||||
char *clear;
|
||||
char *limit;
|
||||
|
||||
namemap = alloca (eltsize);
|
||||
nread = read (desc, namemap, eltsize);
|
||||
if (nread != eltsize)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
namemap = alloca (eltsize);
|
||||
nread = read (desc, namemap, eltsize);
|
||||
if (nread != eltsize)
|
||||
{
|
||||
(void) close (desc);
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* The names are separated by newlines. Some formats have
|
||||
a trailing slash. Null terminate the strings for
|
||||
convenience. */
|
||||
limit = namemap + eltsize;
|
||||
for (clear = namemap; clear < limit; clear++)
|
||||
{
|
||||
if (*clear == '\n')
|
||||
{
|
||||
*clear = '\0';
|
||||
if (clear[-1] == '/')
|
||||
clear[-1] = '\0';
|
||||
}
|
||||
}
|
||||
/* The names are separated by newlines. Some formats have
|
||||
a trailing slash. Null terminate the strings for
|
||||
convenience. */
|
||||
limit = namemap + eltsize;
|
||||
for (clear = namemap; clear < limit; clear++)
|
||||
{
|
||||
if (*clear == '\n')
|
||||
{
|
||||
*clear = '\0';
|
||||
if (clear[-1] == '/')
|
||||
clear[-1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
is_namemap = 0;
|
||||
}
|
||||
is_namemap = 0;
|
||||
}
|
||||
|
||||
member_offset += AR_HDR_SIZE + eltsize;
|
||||
if (member_offset % 2 != 0)
|
||||
member_offset++;
|
||||
member_offset += AR_HDR_SIZE + eltsize;
|
||||
if (member_offset % 2 != 0)
|
||||
member_offset++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -746,9 +746,9 @@ ar_name_equal (const char *name, const char *mem, int truncated)
|
||||
#else
|
||||
struct ar_hdr hdr;
|
||||
#if !defined (__hpux) && !defined (cray)
|
||||
return strneq (name, mem, sizeof(hdr.ar_name) - 1);
|
||||
return strneq (name, mem, sizeof (hdr.ar_name) - 1);
|
||||
#else
|
||||
return strneq (name, mem, sizeof(hdr.ar_name) - 2);
|
||||
return strneq (name, mem, sizeof (hdr.ar_name) - 2);
|
||||
#endif /* !__hpux && !cray */
|
||||
#endif /* !AIAMAG */
|
||||
}
|
||||
@ -761,7 +761,7 @@ ar_name_equal (const char *name, const char *mem, int truncated)
|
||||
/* ARGSUSED */
|
||||
static long int
|
||||
ar_member_pos (int desc UNUSED, const char *mem, int truncated,
|
||||
long int hdrpos, long int datapos UNUSED, long int size UNUSED,
|
||||
long int hdrpos, long int datapos UNUSED, long int size UNUSED,
|
||||
long int date UNUSED, int uid UNUSED, int gid UNUSED,
|
||||
int mode UNUSED, const void *name)
|
||||
{
|
||||
@ -815,7 +815,7 @@ ar_member_touch (const char *arname, const char *memname)
|
||||
ar_hdr.ar_date[ui] = ' ';
|
||||
sprintf (TOCHAR (ar_hdr.ar_date), "%ld", (long int) statbuf.st_mtime);
|
||||
#ifdef AIAMAG
|
||||
ar_hdr.ar_date[strlen(ar_hdr.ar_date)] = ' ';
|
||||
ar_hdr.ar_date[strlen (ar_hdr.ar_date)] = ' ';
|
||||
#endif
|
||||
#else
|
||||
ar_hdr.ar_date = statbuf.st_mtime;
|
||||
@ -840,14 +840,14 @@ ar_member_touch (const char *arname, const char *memname)
|
||||
|
||||
long int
|
||||
describe_member (int desc, const char *name, int truncated,
|
||||
long int hdrpos, long int datapos, long int size,
|
||||
long int hdrpos, long int datapos, long int size,
|
||||
long int date, int uid, int gid, int mode, const void *arg)
|
||||
{
|
||||
extern char *ctime ();
|
||||
|
||||
printf (_("Member '%s'%s: %ld bytes at %ld (%ld).\n"),
|
||||
name, truncated ? _(" (name might be truncated)") : "",
|
||||
size, hdrpos, datapos);
|
||||
name, truncated ? _(" (name might be truncated)") : "",
|
||||
size, hdrpos, datapos);
|
||||
printf (_(" Date %s"), ctime (&date));
|
||||
printf (_(" uid = %d, gid = %d, mode = 0%o.\n"), uid, gid, mode);
|
||||
|
||||
@ -861,5 +861,5 @@ main (int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* TEST. */
|
||||
#endif /* NO_ARCHIVES. */
|
||||
#endif /* TEST. */
|
||||
#endif /* NO_ARCHIVES. */
|
||||
|
134
commands.c
134
commands.c
@ -35,7 +35,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
int remote_kill (int id, int sig);
|
||||
|
||||
#ifndef HAVE_UNISTD_H
|
||||
#ifndef HAVE_UNISTD_H
|
||||
int getpid ();
|
||||
#endif
|
||||
|
||||
@ -70,7 +70,7 @@ set_file_variables (struct file *file)
|
||||
struct dep *d;
|
||||
const char *at, *percent, *star, *less;
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
#ifndef NO_ARCHIVES
|
||||
/* If the target is an archive member 'lib(member)',
|
||||
then $@ is 'lib' and $% is 'member'. */
|
||||
|
||||
@ -92,7 +92,7 @@ set_file_variables (struct file *file)
|
||||
percent = p;
|
||||
}
|
||||
else
|
||||
#endif /* NO_ARCHIVES. */
|
||||
#endif /* NO_ARCHIVES. */
|
||||
{
|
||||
at = file->name;
|
||||
percent = "";
|
||||
@ -102,35 +102,35 @@ set_file_variables (struct file *file)
|
||||
if (file->stem == 0)
|
||||
{
|
||||
/* In Unix make, $* is set to the target name with
|
||||
any suffix in the .SUFFIXES list stripped off for
|
||||
explicit rules. We store this in the 'stem' member. */
|
||||
any suffix in the .SUFFIXES list stripped off for
|
||||
explicit rules. We store this in the 'stem' member. */
|
||||
const char *name;
|
||||
unsigned int len;
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
#ifndef NO_ARCHIVES
|
||||
if (ar_name (file->name))
|
||||
{
|
||||
name = strchr (file->name, '(') + 1;
|
||||
len = strlen (name) - 1;
|
||||
}
|
||||
{
|
||||
name = strchr (file->name, '(') + 1;
|
||||
len = strlen (name) - 1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
name = file->name;
|
||||
len = strlen (name);
|
||||
}
|
||||
{
|
||||
name = file->name;
|
||||
len = strlen (name);
|
||||
}
|
||||
|
||||
for (d = enter_file (strcache_add (".SUFFIXES"))->deps; d ; d = d->next)
|
||||
{
|
||||
unsigned int slen = strlen (dep_name (d));
|
||||
if (len > slen && strneq (dep_name (d), name + (len - slen), slen))
|
||||
{
|
||||
file->stem = strcache_add_len (name, len - slen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
{
|
||||
unsigned int slen = strlen (dep_name (d));
|
||||
if (len > slen && strneq (dep_name (d), name + (len - slen), slen))
|
||||
{
|
||||
file->stem = strcache_add_len (name, len - slen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (d == 0)
|
||||
file->stem = "";
|
||||
file->stem = "";
|
||||
}
|
||||
star = file->stem;
|
||||
|
||||
@ -149,7 +149,7 @@ set_file_variables (struct file *file)
|
||||
In this case $< is the same as $@. */
|
||||
less = at;
|
||||
|
||||
#define DEFINE_VARIABLE(name, len, value) \
|
||||
#define DEFINE_VARIABLE(name, len, value) \
|
||||
(void) define_variable_for_file (name,len,value,o_automatic,0,file)
|
||||
|
||||
/* Define the variables. */
|
||||
@ -202,13 +202,13 @@ set_file_variables (struct file *file)
|
||||
|
||||
cp = plus_value;
|
||||
|
||||
qmark_len = plus_len + 1; /* Will be this or less. */
|
||||
qmark_len = plus_len + 1; /* Will be this or less. */
|
||||
for (d = file->deps; d != 0; d = d->next)
|
||||
if (! d->ignore_mtime && ! d->need_2nd_expansion)
|
||||
{
|
||||
const char *c = dep_name (d);
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
#ifndef NO_ARCHIVES
|
||||
if (ar_name (c))
|
||||
{
|
||||
c = strchr (c, '(') + 1;
|
||||
@ -222,7 +222,7 @@ set_file_variables (struct file *file)
|
||||
cp += len;
|
||||
*cp++ = FILE_LIST_SEPARATOR;
|
||||
if (! (d->changed || always_make_flag))
|
||||
qmark_len -= len + 1; /* Don't space in $? for this one. */
|
||||
qmark_len -= len + 1; /* Don't space in $? for this one. */
|
||||
}
|
||||
|
||||
/* Kill the last space and define the variable. */
|
||||
@ -277,23 +277,23 @@ set_file_variables (struct file *file)
|
||||
continue;
|
||||
|
||||
c = dep_name (d);
|
||||
#ifndef NO_ARCHIVES
|
||||
#ifndef NO_ARCHIVES
|
||||
if (ar_name (c))
|
||||
{
|
||||
c = strchr (c, '(') + 1;
|
||||
len = strlen (c) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = strchr (c, '(') + 1;
|
||||
len = strlen (c) - 1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
len = strlen (c);
|
||||
len = strlen (c);
|
||||
|
||||
if (d->ignore_mtime)
|
||||
{
|
||||
memcpy (bp, c, len);
|
||||
bp += len;
|
||||
*bp++ = FILE_LIST_SEPARATOR;
|
||||
}
|
||||
else
|
||||
bp += len;
|
||||
*bp++ = FILE_LIST_SEPARATOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (cp, c, len);
|
||||
cp += len;
|
||||
@ -321,7 +321,7 @@ set_file_variables (struct file *file)
|
||||
DEFINE_VARIABLE ("|", 1, bar_value);
|
||||
}
|
||||
|
||||
#undef DEFINE_VARIABLE
|
||||
#undef DEFINE_VARIABLE
|
||||
}
|
||||
|
||||
/* Chop CMDS up into individual command lines if necessary.
|
||||
@ -519,14 +519,14 @@ fatal_error_signal (int sig)
|
||||
DWORD susp_count = SuspendThread (main_thread);
|
||||
|
||||
if (susp_count != 0)
|
||||
fprintf (stderr, "SuspendThread: suspend count = %ld\n", susp_count);
|
||||
fprintf (stderr, "SuspendThread: suspend count = %ld\n", susp_count);
|
||||
else if (susp_count == (DWORD)-1)
|
||||
{
|
||||
DWORD ierr = GetLastError ();
|
||||
{
|
||||
DWORD ierr = GetLastError ();
|
||||
|
||||
fprintf (stderr, "SuspendThread: error %ld: %s\n",
|
||||
ierr, map_windows32_error_to_string (ierr));
|
||||
}
|
||||
fprintf (stderr, "SuspendThread: error %ld: %s\n",
|
||||
ierr, map_windows32_error_to_string (ierr));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
handling_fatal_signal = 1;
|
||||
@ -542,8 +542,8 @@ fatal_error_signal (int sig)
|
||||
{
|
||||
struct child *c;
|
||||
for (c = children; c != 0; c = c->next)
|
||||
if (!c->remote)
|
||||
(void) kill (c->pid, SIGTERM);
|
||||
if (!c->remote)
|
||||
(void) kill (c->pid, SIGTERM);
|
||||
}
|
||||
|
||||
/* If we got a signal that means the user
|
||||
@ -561,18 +561,18 @@ fatal_error_signal (int sig)
|
||||
struct child *c;
|
||||
|
||||
/* Remote children won't automatically get signals sent
|
||||
to the process group, so we must send them. */
|
||||
to the process group, so we must send them. */
|
||||
for (c = children; c != 0; c = c->next)
|
||||
if (c->remote)
|
||||
(void) remote_kill (c->pid, sig);
|
||||
if (c->remote)
|
||||
(void) remote_kill (c->pid, sig);
|
||||
|
||||
for (c = children; c != 0; c = c->next)
|
||||
delete_child_targets (c);
|
||||
delete_child_targets (c);
|
||||
|
||||
/* Clean up the children. We don't just use the call below because
|
||||
we don't want to print the "Waiting for children" message. */
|
||||
we don't want to print the "Waiting for children" message. */
|
||||
while (job_slots_used > 0)
|
||||
reap_children (1, 0);
|
||||
reap_children (1, 0);
|
||||
}
|
||||
else
|
||||
/* Wait for our children to die. */
|
||||
@ -622,17 +622,17 @@ delete_target (struct file *file, const char *on_behalf_of)
|
||||
if (ar_name (file->name))
|
||||
{
|
||||
time_t file_date = (file->last_mtime == NONEXISTENT_MTIME
|
||||
? (time_t) -1
|
||||
: (time_t) FILE_TIMESTAMP_S (file->last_mtime));
|
||||
? (time_t) -1
|
||||
: (time_t) FILE_TIMESTAMP_S (file->last_mtime));
|
||||
if (ar_member_date (file->name) != file_date)
|
||||
{
|
||||
if (on_behalf_of)
|
||||
error (NILF, _("*** [%s] Archive member '%s' may be bogus; not deleted"),
|
||||
on_behalf_of, file->name);
|
||||
else
|
||||
error (NILF, _("*** Archive member '%s' may be bogus; not deleted"),
|
||||
file->name);
|
||||
}
|
||||
{
|
||||
if (on_behalf_of)
|
||||
error (NILF, _("*** [%s] Archive member '%s' may be bogus; not deleted"),
|
||||
on_behalf_of, file->name);
|
||||
else
|
||||
error (NILF, _("*** Archive member '%s' may be bogus; not deleted"),
|
||||
file->name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -643,12 +643,12 @@ delete_target (struct file *file, const char *on_behalf_of)
|
||||
&& FILE_TIMESTAMP_STAT_MODTIME (file->name, st) != file->last_mtime)
|
||||
{
|
||||
if (on_behalf_of)
|
||||
error (NILF, _("*** [%s] Deleting file '%s'"), on_behalf_of, file->name);
|
||||
error (NILF, _("*** [%s] Deleting file '%s'"), on_behalf_of, file->name);
|
||||
else
|
||||
error (NILF, _("*** Deleting file '%s'"), file->name);
|
||||
error (NILF, _("*** Deleting file '%s'"), file->name);
|
||||
if (unlink (file->name) < 0
|
||||
&& errno != ENOENT) /* It disappeared; so what. */
|
||||
perror_with_name ("unlink: ", file->name);
|
||||
&& errno != ENOENT) /* It disappeared; so what. */
|
||||
perror_with_name ("unlink: ", file->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Define if on AIX 3.
|
||||
System headers sometimes define this.
|
||||
We just want to avoid a redefinition error message. */
|
||||
We just want to avoid a redefinition error message. */
|
||||
#ifndef _ALL_SOURCE
|
||||
/* #undef _ALL_SOURCE */
|
||||
#endif
|
||||
@ -68,7 +68,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* Define if the 'long double' type works. */
|
||||
/* #undef HAVE_LONG_DOUBLE */
|
||||
|
||||
/* Define if you support file names longer than 14 characters. */
|
||||
/* Define if you support file names longer than 14 characters. */
|
||||
#define HAVE_LONG_FILE_NAMES 1
|
||||
|
||||
/* Define if you have a working 'mmap' system call. */
|
||||
@ -84,7 +84,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* Define if your struct stat has st_blocks. */
|
||||
/* #undef HAVE_ST_BLOCKS */
|
||||
|
||||
/* Define if you have the strcoll function and it is properly defined. */
|
||||
/* Define if you have the strcoll function and it is properly defined. */
|
||||
#define HAVE_STRCOLL 1
|
||||
|
||||
/* Define if your struct stat has st_rdev. */
|
||||
@ -93,7 +93,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* Define if you have the strftime function. */
|
||||
#define HAVE_STRFTIME 1
|
||||
|
||||
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||
/* #undef HAVE_SYS_WAIT_H */
|
||||
|
||||
/* Define if your struct tm has tm_zone. */
|
||||
@ -112,7 +112,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* Define if you have the wait3 system call. */
|
||||
/* #undef HAVE_WAIT3 */
|
||||
|
||||
/* Define if on MINIX. */
|
||||
/* Define if on MINIX. */
|
||||
/* #undef _MINIX */
|
||||
|
||||
/* Define if your struct nlist has an n_un member. */
|
||||
@ -145,16 +145,16 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at run-time.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown
|
||||
*/
|
||||
#define STACK_DIRECTION -1
|
||||
|
||||
/* Define if the 'S_IS*' macros in <sys/stat.h> do not work properly. */
|
||||
/* #undef STAT_MACROS_BROKEN */
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS
|
||||
|
||||
/* Define on System V Release 4. */
|
||||
@ -234,7 +234,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* Define if you have the seteuid function. */
|
||||
/* #undef HAVE_SETEUID */
|
||||
|
||||
/* Define if you have the setlinebuf function. */
|
||||
/* Define if you have the setlinebuf function. */
|
||||
/* #undef HAVE_SETLINEBUF */
|
||||
|
||||
/* Define if you have the setregid function. */
|
||||
@ -243,7 +243,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* Define if you have the setreuid function. */
|
||||
/* #undef HAVE_SETREUID */
|
||||
|
||||
/* Define if you have the sigsetmask function. */
|
||||
/* Define if you have the sigsetmask function. */
|
||||
/* #undef HAVE_SIGSETMASK */
|
||||
|
||||
/* Define if you have the socket function. */
|
||||
|
@ -177,9 +177,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at run-time.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown
|
||||
*/
|
||||
/* #undef STACK_DIRECTION */
|
||||
|
||||
@ -407,8 +407,8 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* Define if using alloca.c. */
|
||||
/* #undef C_ALLOCA */
|
||||
/* maybe this should be placed into makeint.h */
|
||||
#if defined(__VAX) && defined(__DECC)
|
||||
#define alloca(n) __ALLOCA(n)
|
||||
#if defined(__VAX) && defined(__DECC)
|
||||
#define alloca(n) __ALLOCA(n)
|
||||
#endif
|
||||
|
||||
/* Build host information. */
|
||||
|
@ -399,9 +399,9 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at run time.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
/* #undef STACK_DIRECTION */
|
||||
|
||||
/* Define to 1 if the 'S_IS*' macros in <sys/stat.h> do not work properly. */
|
||||
|
@ -547,8 +547,8 @@ set_default_suffixes (void)
|
||||
{
|
||||
struct dep *d;
|
||||
char *p = default_suffixes;
|
||||
suffix_file->deps = enter_prereqs(PARSE_FILE_SEQ (&p, struct dep, '\0',
|
||||
NULL, 0),
|
||||
suffix_file->deps = enter_prereqs (PARSE_FILE_SEQ (&p, struct dep, '\0',
|
||||
NULL, 0),
|
||||
NULL);
|
||||
for (d = suffix_file->deps; d; d = d->next)
|
||||
d->file->builtin = 1;
|
||||
|
10
dep.h
10
dep.h
@ -18,11 +18,11 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
These flags are saved in the 'changed' field of each
|
||||
'struct dep' in the chain returned by 'read_all_makefiles'. */
|
||||
|
||||
#define RM_NO_DEFAULT_GOAL (1 << 0) /* Do not set default goal. */
|
||||
#define RM_INCLUDED (1 << 1) /* Search makefile search path. */
|
||||
#define RM_DONTCARE (1 << 2) /* No error if it doesn't exist. */
|
||||
#define RM_NO_TILDE (1 << 3) /* Don't expand ~ in file name. */
|
||||
#define RM_NOFLAG 0
|
||||
#define RM_NO_DEFAULT_GOAL (1 << 0) /* Do not set default goal. */
|
||||
#define RM_INCLUDED (1 << 1) /* Search makefile search path. */
|
||||
#define RM_DONTCARE (1 << 2) /* No error if it doesn't exist. */
|
||||
#define RM_NO_TILDE (1 << 3) /* Don't expand ~ in file name. */
|
||||
#define RM_NOFLAG 0
|
||||
|
||||
/* Structure representing one dependency of a file.
|
||||
Each struct file's 'deps' points to a chain of these,
|
||||
|
441
dir.c
441
dir.c
@ -17,7 +17,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#include "makeint.h"
|
||||
#include "hash.h"
|
||||
|
||||
#ifdef HAVE_DIRENT_H
|
||||
#ifdef HAVE_DIRENT_H
|
||||
# include <dirent.h>
|
||||
# define NAMLEN(dirent) strlen((dirent)->d_name)
|
||||
# ifdef VMS
|
||||
@ -94,7 +94,7 @@ dosify (const char *filename)
|
||||
{
|
||||
*df++ = *filename++;
|
||||
for (i = 0; *filename != '\0' && i < 3 && *filename != '.'; ++i)
|
||||
*df++ = tolower ((unsigned char)*filename++);
|
||||
*df++ = tolower ((unsigned char)*filename++);
|
||||
}
|
||||
|
||||
/* Look for more dots. */
|
||||
@ -157,10 +157,10 @@ vms_hash (const char *name)
|
||||
name++;
|
||||
g = h & 0xf0000000;
|
||||
if (g)
|
||||
{
|
||||
h = h ^ (g >> 24);
|
||||
h = h ^ g;
|
||||
}
|
||||
{
|
||||
h = h ^ (g >> 24);
|
||||
h = h ^ g;
|
||||
}
|
||||
}
|
||||
return h;
|
||||
}
|
||||
@ -177,7 +177,7 @@ vmsstat_dir (const char *name, struct stat *st)
|
||||
if (dir == 0)
|
||||
return -1;
|
||||
closedir (dir);
|
||||
s = strchr (name, ':'); /* find device */
|
||||
s = strchr (name, ':'); /* find device */
|
||||
if (s)
|
||||
{
|
||||
/* to keep the compiler happy we said "const char *name", now we cheat */
|
||||
@ -202,13 +202,13 @@ vmsstat_dir (const char *name, struct stat *st)
|
||||
|
||||
/* Hash table of directories. */
|
||||
|
||||
#ifndef DIRECTORY_BUCKETS
|
||||
#ifndef DIRECTORY_BUCKETS
|
||||
#define DIRECTORY_BUCKETS 199
|
||||
#endif
|
||||
|
||||
struct directory_contents
|
||||
{
|
||||
dev_t dev; /* Device and inode numbers of this dir. */
|
||||
dev_t dev; /* Device and inode numbers of this dir. */
|
||||
#ifdef WINDOWS32
|
||||
/* Inode means nothing on WINDOWS32. Even file key information is
|
||||
* unreliable because it is random per file open and undefined for remote
|
||||
@ -229,8 +229,8 @@ struct directory_contents
|
||||
ino_t ino;
|
||||
# endif
|
||||
#endif /* WINDOWS32 */
|
||||
struct hash_table dirfiles; /* Files in this directory. */
|
||||
DIR *dirstream; /* Stream reading this directory. */
|
||||
struct hash_table dirfiles; /* Files in this directory. */
|
||||
DIR *dirstream; /* Stream reading this directory. */
|
||||
};
|
||||
|
||||
static unsigned long
|
||||
@ -246,9 +246,9 @@ directory_contents_hash_1 (const void *key_0)
|
||||
#else
|
||||
# ifdef VMS
|
||||
hash = (((unsigned int) key->dev << 4)
|
||||
^ ((unsigned int) key->ino[0]
|
||||
+ (unsigned int) key->ino[1]
|
||||
+ (unsigned int) key->ino[2]));
|
||||
^ ((unsigned int) key->ino[0]
|
||||
+ (unsigned int) key->ino[1]
|
||||
+ (unsigned int) key->ino[2]));
|
||||
# else
|
||||
hash = ((unsigned int) key->dev << 4) ^ (unsigned int) key->ino;
|
||||
# endif
|
||||
@ -269,9 +269,9 @@ directory_contents_hash_2 (const void *key_0)
|
||||
#else
|
||||
# ifdef VMS
|
||||
hash = (((unsigned int) key->dev << 4)
|
||||
^ ~((unsigned int) key->ino[0]
|
||||
+ (unsigned int) key->ino[1]
|
||||
+ (unsigned int) key->ino[2]));
|
||||
^ ~((unsigned int) key->ino[0]
|
||||
+ (unsigned int) key->ino[1]
|
||||
+ (unsigned int) key->ino[2]));
|
||||
# else
|
||||
hash = ((unsigned int) key->dev << 4) ^ (unsigned int) ~key->ino;
|
||||
# endif
|
||||
@ -331,7 +331,7 @@ static struct hash_table directory_contents;
|
||||
|
||||
struct directory
|
||||
{
|
||||
const char *name; /* Name of the directory. */
|
||||
const char *name; /* Name of the directory. */
|
||||
|
||||
/* The directory's contents. This data may be shared by several
|
||||
entries in the hash table, which refer to the same directory
|
||||
@ -355,7 +355,7 @@ static int
|
||||
directory_hash_cmp (const void *x, const void *y)
|
||||
{
|
||||
return_ISTRING_COMPARE (((const struct directory *) x)->name,
|
||||
((const struct directory *) y)->name);
|
||||
((const struct directory *) y)->name);
|
||||
}
|
||||
|
||||
/* Table of directories hashed by name. */
|
||||
@ -372,9 +372,9 @@ static unsigned int open_directories = 0;
|
||||
|
||||
struct dirfile
|
||||
{
|
||||
const char *name; /* Name of the file. */
|
||||
const char *name; /* Name of the file. */
|
||||
short length;
|
||||
short impossible; /* This file is impossible. */
|
||||
short impossible; /* This file is impossible. */
|
||||
};
|
||||
|
||||
static unsigned long
|
||||
@ -400,7 +400,7 @@ dirfile_hash_cmp (const void *xv, const void *yv)
|
||||
return_ISTRING_COMPARE (x->name, y->name);
|
||||
}
|
||||
|
||||
#ifndef DIRFILE_BUCKETS
|
||||
#ifndef DIRFILE_BUCKETS
|
||||
#define DIRFILE_BUCKETS 107
|
||||
#endif
|
||||
|
||||
@ -446,13 +446,13 @@ find_directory (const char *name)
|
||||
p = name + strlen (name);
|
||||
dir = xmalloc (sizeof (struct directory));
|
||||
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
|
||||
dir->name = strcache_add_len (downcase(name), p - name);
|
||||
dir->name = strcache_add_len (downcase (name), p - name);
|
||||
#else
|
||||
dir->name = strcache_add_len (name, p - name);
|
||||
#endif
|
||||
hash_insert_at (&directories, dir, dir_slot);
|
||||
/* The directory is not in the name hash table.
|
||||
Find its device and inode numbers, and look it up by them. */
|
||||
Find its device and inode numbers, and look it up by them. */
|
||||
|
||||
#ifdef VMS
|
||||
r = vmsstat_dir (name, &st);
|
||||
@ -479,46 +479,46 @@ find_directory (const char *name)
|
||||
|
||||
if (r < 0)
|
||||
{
|
||||
/* Couldn't stat the directory. Mark this by
|
||||
setting the 'contents' member to a nil pointer. */
|
||||
dir->contents = 0;
|
||||
}
|
||||
/* Couldn't stat the directory. Mark this by
|
||||
setting the 'contents' member to a nil pointer. */
|
||||
dir->contents = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Search the contents hash table; device and inode are the key. */
|
||||
{
|
||||
/* Search the contents hash table; device and inode are the key. */
|
||||
|
||||
struct directory_contents *dc;
|
||||
struct directory_contents **dc_slot;
|
||||
struct directory_contents dc_key;
|
||||
struct directory_contents *dc;
|
||||
struct directory_contents **dc_slot;
|
||||
struct directory_contents dc_key;
|
||||
|
||||
dc_key.dev = st.st_dev;
|
||||
dc_key.dev = st.st_dev;
|
||||
#ifdef WINDOWS32
|
||||
dc_key.path_key = w32_path = w32ify (name, 1);
|
||||
dc_key.ctime = st.st_ctime;
|
||||
dc_key.path_key = w32_path = w32ify (name, 1);
|
||||
dc_key.ctime = st.st_ctime;
|
||||
#else
|
||||
# ifdef VMS
|
||||
dc_key.ino[0] = st.st_ino[0];
|
||||
dc_key.ino[1] = st.st_ino[1];
|
||||
dc_key.ino[2] = st.st_ino[2];
|
||||
dc_key.ino[0] = st.st_ino[0];
|
||||
dc_key.ino[1] = st.st_ino[1];
|
||||
dc_key.ino[2] = st.st_ino[2];
|
||||
# else
|
||||
dc_key.ino = st.st_ino;
|
||||
dc_key.ino = st.st_ino;
|
||||
# endif
|
||||
#endif
|
||||
dc_slot = (struct directory_contents **) hash_find_slot (&directory_contents, &dc_key);
|
||||
dc = *dc_slot;
|
||||
dc_slot = (struct directory_contents **) hash_find_slot (&directory_contents, &dc_key);
|
||||
dc = *dc_slot;
|
||||
|
||||
if (HASH_VACANT (dc))
|
||||
{
|
||||
/* Nope; this really is a directory we haven't seen before. */
|
||||
if (HASH_VACANT (dc))
|
||||
{
|
||||
/* Nope; this really is a directory we haven't seen before. */
|
||||
|
||||
dc = (struct directory_contents *)
|
||||
xmalloc (sizeof (struct directory_contents));
|
||||
dc = (struct directory_contents *)
|
||||
xmalloc (sizeof (struct directory_contents));
|
||||
|
||||
/* Enter it in the contents hash table. */
|
||||
dc->dev = st.st_dev;
|
||||
/* Enter it in the contents hash table. */
|
||||
dc->dev = st.st_dev;
|
||||
#ifdef WINDOWS32
|
||||
dc->path_key = xstrdup (w32_path);
|
||||
dc->ctime = st.st_ctime;
|
||||
dc->ctime = st.st_ctime;
|
||||
dc->mtime = st.st_mtime;
|
||||
|
||||
/*
|
||||
@ -527,48 +527,47 @@ find_directory (const char *name)
|
||||
* a directory.
|
||||
*/
|
||||
w32_path[3] = '\0';
|
||||
if (GetVolumeInformation(w32_path,
|
||||
fs_label, sizeof (fs_label),
|
||||
&fs_serno, &fs_len,
|
||||
&fs_flags, fs_type, sizeof (fs_type)) == FALSE)
|
||||
if (GetVolumeInformation (w32_path, fs_label, sizeof (fs_label),
|
||||
&fs_serno, &fs_len, &fs_flags, fs_type,
|
||||
sizeof (fs_type)) == FALSE)
|
||||
dc->fs_flags = FS_UNKNOWN;
|
||||
else if (!strcmp(fs_type, "FAT"))
|
||||
else if (!strcmp (fs_type, "FAT"))
|
||||
dc->fs_flags = FS_FAT;
|
||||
else if (!strcmp(fs_type, "NTFS"))
|
||||
else if (!strcmp (fs_type, "NTFS"))
|
||||
dc->fs_flags = FS_NTFS;
|
||||
else
|
||||
dc->fs_flags = FS_UNKNOWN;
|
||||
#else
|
||||
# ifdef VMS
|
||||
dc->ino[0] = st.st_ino[0];
|
||||
dc->ino[1] = st.st_ino[1];
|
||||
dc->ino[2] = st.st_ino[2];
|
||||
dc->ino[0] = st.st_ino[0];
|
||||
dc->ino[1] = st.st_ino[1];
|
||||
dc->ino[2] = st.st_ino[2];
|
||||
# else
|
||||
dc->ino = st.st_ino;
|
||||
dc->ino = st.st_ino;
|
||||
# endif
|
||||
#endif /* WINDOWS32 */
|
||||
hash_insert_at (&directory_contents, dc, dc_slot);
|
||||
ENULLLOOP (dc->dirstream, opendir (name));
|
||||
if (dc->dirstream == 0)
|
||||
hash_insert_at (&directory_contents, dc, dc_slot);
|
||||
ENULLLOOP (dc->dirstream, opendir (name));
|
||||
if (dc->dirstream == 0)
|
||||
/* Couldn't open the directory. Mark this by setting the
|
||||
'files' member to a nil pointer. */
|
||||
dc->dirfiles.ht_vec = 0;
|
||||
else
|
||||
{
|
||||
hash_init (&dc->dirfiles, DIRFILE_BUCKETS,
|
||||
dirfile_hash_1, dirfile_hash_2, dirfile_hash_cmp);
|
||||
/* Keep track of how many directories are open. */
|
||||
++open_directories;
|
||||
if (open_directories == MAX_OPEN_DIRECTORIES)
|
||||
/* We have too many directories open already.
|
||||
Read the entire directory and then close it. */
|
||||
dir_contents_file_exists_p (dc, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hash_init (&dc->dirfiles, DIRFILE_BUCKETS,
|
||||
dirfile_hash_1, dirfile_hash_2, dirfile_hash_cmp);
|
||||
/* Keep track of how many directories are open. */
|
||||
++open_directories;
|
||||
if (open_directories == MAX_OPEN_DIRECTORIES)
|
||||
/* We have too many directories open already.
|
||||
Read the entire directory and then close it. */
|
||||
dir_contents_file_exists_p (dc, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Point the name-hashed entry for DIR at its contents data. */
|
||||
dir->contents = dc;
|
||||
}
|
||||
/* Point the name-hashed entry for DIR at its contents data. */
|
||||
dir->contents = dc;
|
||||
}
|
||||
}
|
||||
|
||||
return dir;
|
||||
@ -614,10 +613,10 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||||
struct dirfile dirfile_key;
|
||||
|
||||
if (*filename == '\0')
|
||||
{
|
||||
/* Checking if the directory exists. */
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
/* Checking if the directory exists. */
|
||||
return 1;
|
||||
}
|
||||
dirfile_key.name = filename;
|
||||
dirfile_key.length = strlen (filename);
|
||||
df = hash_find_item (&dir->dirfiles, &dirfile_key);
|
||||
@ -637,32 +636,32 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||||
* on directories (ugh!).
|
||||
*/
|
||||
if (dir->path_key)
|
||||
{
|
||||
{
|
||||
if ((dir->fs_flags & FS_FAT) != 0)
|
||||
{
|
||||
dir->mtime = time ((time_t *) 0);
|
||||
rehash = 1;
|
||||
}
|
||||
else if (stat (dir->path_key, &st) == 0 && st.st_mtime > dir->mtime)
|
||||
{
|
||||
/* reset date stamp to show most recent re-process. */
|
||||
dir->mtime = st.st_mtime;
|
||||
rehash = 1;
|
||||
}
|
||||
{
|
||||
dir->mtime = time ((time_t *) 0);
|
||||
rehash = 1;
|
||||
}
|
||||
else if (stat (dir->path_key, &st) == 0 && st.st_mtime > dir->mtime)
|
||||
{
|
||||
/* reset date stamp to show most recent re-process. */
|
||||
dir->mtime = st.st_mtime;
|
||||
rehash = 1;
|
||||
}
|
||||
|
||||
/* If it has been already read in, all done. */
|
||||
if (!rehash)
|
||||
return 0;
|
||||
if (!rehash)
|
||||
return 0;
|
||||
|
||||
/* make sure directory can still be opened; if not return. */
|
||||
dir->dirstream = opendir (dir->path_key);
|
||||
if (!dir->dirstream)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
/* The directory has been all read in. */
|
||||
return 0;
|
||||
/* The directory has been all read in. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (1)
|
||||
@ -689,7 +688,7 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||||
}
|
||||
#endif
|
||||
if (!REAL_DIR_ENTRY (d))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
len = NAMLEN (d);
|
||||
dirfile_key.name = d->d_name;
|
||||
@ -702,17 +701,17 @@ dir_contents_file_exists_p (struct directory_contents *dir,
|
||||
*/
|
||||
if (! rehash || HASH_VACANT (*dirfile_slot))
|
||||
#endif
|
||||
{
|
||||
df = xmalloc (sizeof (struct dirfile));
|
||||
{
|
||||
df = xmalloc (sizeof (struct dirfile));
|
||||
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
|
||||
df->name = strcache_add_len (downcase(d->d_name), len);
|
||||
df->name = strcache_add_len (downcase (d->d_name), len);
|
||||
#else
|
||||
df->name = strcache_add_len (d->d_name, len);
|
||||
df->name = strcache_add_len (d->d_name, len);
|
||||
#endif
|
||||
df->length = len;
|
||||
df->impossible = 0;
|
||||
hash_insert_at (&dir->dirfiles, df, dirfile_slot);
|
||||
}
|
||||
df->length = len;
|
||||
df->impossible = 0;
|
||||
hash_insert_at (&dir->dirfiles, df, dirfile_slot);
|
||||
}
|
||||
/* Check if the name matches the one we're searching for. */
|
||||
if (filename != 0 && patheq (d->d_name, filename))
|
||||
return 1;
|
||||
@ -737,7 +736,7 @@ int
|
||||
dir_file_exists_p (const char *dirname, const char *filename)
|
||||
{
|
||||
return dir_contents_file_exists_p (find_directory (dirname)->contents,
|
||||
filename);
|
||||
filename);
|
||||
}
|
||||
|
||||
/* Return 1 if the file named NAME exists. */
|
||||
@ -749,7 +748,7 @@ file_exists_p (const char *name)
|
||||
const char *dirname;
|
||||
const char *slash;
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
#ifndef NO_ARCHIVES
|
||||
if (ar_name (name))
|
||||
return ar_member_date (name) != (time_t) -1;
|
||||
#endif
|
||||
@ -765,7 +764,7 @@ file_exists_p (const char *name)
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* Forward and backslashes might be mixed. We need the rightmost one. */
|
||||
{
|
||||
const char *bslash = strrchr(name, '\\');
|
||||
const char *bslash = strrchr (name, '\\');
|
||||
if (!dirend || bslash > dirend)
|
||||
dirend = bslash;
|
||||
/* The case of "d:file". */
|
||||
@ -790,8 +789,8 @@ file_exists_p (const char *name)
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* d:/ and d: are *very* different... */
|
||||
if (dirend < name + 3 && name[1] == ':' &&
|
||||
(*dirend == '/' || *dirend == '\\' || *dirend == ':'))
|
||||
dirend++;
|
||||
(*dirend == '/' || *dirend == '\\' || *dirend == ':'))
|
||||
dirend++;
|
||||
#endif
|
||||
p = alloca (dirend - name + 1);
|
||||
memcpy (p, name, dirend - name);
|
||||
@ -825,7 +824,7 @@ file_impossible (const char *filename)
|
||||
# ifdef HAVE_DOS_PATHS
|
||||
/* Forward and backslashes might be mixed. We need the rightmost one. */
|
||||
{
|
||||
const char *bslash = strrchr(p, '\\');
|
||||
const char *bslash = strrchr (p, '\\');
|
||||
if (!dirend || bslash > dirend)
|
||||
dirend = bslash;
|
||||
/* The case of "d:file". */
|
||||
@ -845,21 +844,21 @@ file_impossible (const char *filename)
|
||||
const char *dirname;
|
||||
const char *slash = dirend;
|
||||
if (dirend == p)
|
||||
dirname = "/";
|
||||
dirname = "/";
|
||||
else
|
||||
{
|
||||
{
|
||||
char *cp;
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* d:/ and d: are *very* different... */
|
||||
if (dirend < p + 3 && p[1] == ':' &&
|
||||
(*dirend == '/' || *dirend == '\\' || *dirend == ':'))
|
||||
dirend++;
|
||||
/* d:/ and d: are *very* different... */
|
||||
if (dirend < p + 3 && p[1] == ':' &&
|
||||
(*dirend == '/' || *dirend == '\\' || *dirend == ':'))
|
||||
dirend++;
|
||||
#endif
|
||||
cp = alloca (dirend - p + 1);
|
||||
memcpy (cp, p, dirend - p);
|
||||
cp[dirend - p] = '\0';
|
||||
cp = alloca (dirend - p + 1);
|
||||
memcpy (cp, p, dirend - p);
|
||||
cp[dirend - p] = '\0';
|
||||
dirname = cp;
|
||||
}
|
||||
}
|
||||
dir = find_directory (dirname);
|
||||
filename = p = slash + 1;
|
||||
}
|
||||
@ -872,7 +871,7 @@ file_impossible (const char *filename)
|
||||
if (dir->contents->dirfiles.ht_vec == 0)
|
||||
{
|
||||
hash_init (&dir->contents->dirfiles, DIRFILE_BUCKETS,
|
||||
dirfile_hash_1, dirfile_hash_2, dirfile_hash_cmp);
|
||||
dirfile_hash_1, dirfile_hash_2, dirfile_hash_cmp);
|
||||
}
|
||||
|
||||
/* Make a new entry and put it in the table. */
|
||||
@ -880,7 +879,7 @@ file_impossible (const char *filename)
|
||||
new = xmalloc (sizeof (struct dirfile));
|
||||
new->length = strlen (filename);
|
||||
#if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
|
||||
new->name = strcache_add_len (downcase(filename), new->length);
|
||||
new->name = strcache_add_len (downcase (filename), new->length);
|
||||
#else
|
||||
new->name = strcache_add_len (filename, new->length);
|
||||
#endif
|
||||
@ -908,7 +907,7 @@ file_impossible_p (const char *filename)
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* Forward and backslashes might be mixed. We need the rightmost one. */
|
||||
{
|
||||
const char *bslash = strrchr(filename, '\\');
|
||||
const char *bslash = strrchr (filename, '\\');
|
||||
if (!dirend || bslash > dirend)
|
||||
dirend = bslash;
|
||||
/* The case of "d:file". */
|
||||
@ -928,21 +927,21 @@ file_impossible_p (const char *filename)
|
||||
const char *dirname;
|
||||
const char *slash = dirend;
|
||||
if (dirend == filename)
|
||||
dirname = "/";
|
||||
dirname = "/";
|
||||
else
|
||||
{
|
||||
{
|
||||
char *cp;
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* d:/ and d: are *very* different... */
|
||||
if (dirend < filename + 3 && filename[1] == ':' &&
|
||||
(*dirend == '/' || *dirend == '\\' || *dirend == ':'))
|
||||
dirend++;
|
||||
/* d:/ and d: are *very* different... */
|
||||
if (dirend < filename + 3 && filename[1] == ':' &&
|
||||
(*dirend == '/' || *dirend == '\\' || *dirend == ':'))
|
||||
dirend++;
|
||||
#endif
|
||||
cp = alloca (dirend - filename + 1);
|
||||
memcpy (cp, p, dirend - p);
|
||||
cp[dirend - p] = '\0';
|
||||
cp = alloca (dirend - filename + 1);
|
||||
memcpy (cp, p, dirend - p);
|
||||
cp[dirend - p] = '\0';
|
||||
dirname = cp;
|
||||
}
|
||||
}
|
||||
dir = find_directory (dirname)->contents;
|
||||
p = filename = slash + 1;
|
||||
}
|
||||
@ -999,80 +998,80 @@ print_dir_data_base (void)
|
||||
{
|
||||
struct directory *dir = *dir_slot;
|
||||
if (! HASH_VACANT (dir))
|
||||
{
|
||||
if (dir->contents == 0)
|
||||
printf (_("# %s: could not be stat'd.\n"), dir->name);
|
||||
else if (dir->contents->dirfiles.ht_vec == 0)
|
||||
{
|
||||
{
|
||||
if (dir->contents == 0)
|
||||
printf (_("# %s: could not be stat'd.\n"), dir->name);
|
||||
else if (dir->contents->dirfiles.ht_vec == 0)
|
||||
{
|
||||
#ifdef WINDOWS32
|
||||
printf (_("# %s (key %s, mtime %d): could not be opened.\n"),
|
||||
dir->name, dir->contents->path_key,dir->contents->mtime);
|
||||
printf (_("# %s (key %s, mtime %d): could not be opened.\n"),
|
||||
dir->name, dir->contents->path_key,dir->contents->mtime);
|
||||
#else /* WINDOWS32 */
|
||||
#ifdef VMS
|
||||
printf (_("# %s (device %d, inode [%d,%d,%d]): could not be opened.\n"),
|
||||
dir->name, dir->contents->dev,
|
||||
dir->contents->ino[0], dir->contents->ino[1],
|
||||
dir->contents->ino[2]);
|
||||
printf (_("# %s (device %d, inode [%d,%d,%d]): could not be opened.\n"),
|
||||
dir->name, dir->contents->dev,
|
||||
dir->contents->ino[0], dir->contents->ino[1],
|
||||
dir->contents->ino[2]);
|
||||
#else
|
||||
printf (_("# %s (device %ld, inode %ld): could not be opened.\n"),
|
||||
dir->name, (long int) dir->contents->dev,
|
||||
(long int) dir->contents->ino);
|
||||
printf (_("# %s (device %ld, inode %ld): could not be opened.\n"),
|
||||
dir->name, (long int) dir->contents->dev,
|
||||
(long int) dir->contents->ino);
|
||||
#endif
|
||||
#endif /* WINDOWS32 */
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int f = 0;
|
||||
unsigned int im = 0;
|
||||
struct dirfile **files_slot;
|
||||
struct dirfile **files_end;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int f = 0;
|
||||
unsigned int im = 0;
|
||||
struct dirfile **files_slot;
|
||||
struct dirfile **files_end;
|
||||
|
||||
files_slot = (struct dirfile **) dir->contents->dirfiles.ht_vec;
|
||||
files_end = files_slot + dir->contents->dirfiles.ht_size;
|
||||
for ( ; files_slot < files_end; files_slot++)
|
||||
{
|
||||
struct dirfile *df = *files_slot;
|
||||
if (! HASH_VACANT (df))
|
||||
{
|
||||
if (df->impossible)
|
||||
++im;
|
||||
else
|
||||
++f;
|
||||
}
|
||||
}
|
||||
files_slot = (struct dirfile **) dir->contents->dirfiles.ht_vec;
|
||||
files_end = files_slot + dir->contents->dirfiles.ht_size;
|
||||
for ( ; files_slot < files_end; files_slot++)
|
||||
{
|
||||
struct dirfile *df = *files_slot;
|
||||
if (! HASH_VACANT (df))
|
||||
{
|
||||
if (df->impossible)
|
||||
++im;
|
||||
else
|
||||
++f;
|
||||
}
|
||||
}
|
||||
#ifdef WINDOWS32
|
||||
printf (_("# %s (key %s, mtime %d): "),
|
||||
dir->name, dir->contents->path_key, dir->contents->mtime);
|
||||
printf (_("# %s (key %s, mtime %d): "),
|
||||
dir->name, dir->contents->path_key, dir->contents->mtime);
|
||||
#else /* WINDOWS32 */
|
||||
#ifdef VMS
|
||||
printf (_("# %s (device %d, inode [%d,%d,%d]): "),
|
||||
dir->name, dir->contents->dev,
|
||||
dir->contents->ino[0], dir->contents->ino[1],
|
||||
dir->contents->ino[2]);
|
||||
printf (_("# %s (device %d, inode [%d,%d,%d]): "),
|
||||
dir->name, dir->contents->dev,
|
||||
dir->contents->ino[0], dir->contents->ino[1],
|
||||
dir->contents->ino[2]);
|
||||
#else
|
||||
printf (_("# %s (device %ld, inode %ld): "),
|
||||
dir->name,
|
||||
(long)dir->contents->dev, (long)dir->contents->ino);
|
||||
printf (_("# %s (device %ld, inode %ld): "),
|
||||
dir->name,
|
||||
(long)dir->contents->dev, (long)dir->contents->ino);
|
||||
#endif
|
||||
#endif /* WINDOWS32 */
|
||||
if (f == 0)
|
||||
fputs (_("No"), stdout);
|
||||
else
|
||||
printf ("%u", f);
|
||||
fputs (_(" files, "), stdout);
|
||||
if (im == 0)
|
||||
fputs (_("no"), stdout);
|
||||
else
|
||||
printf ("%u", im);
|
||||
fputs (_(" impossibilities"), stdout);
|
||||
if (dir->contents->dirstream == 0)
|
||||
puts (".");
|
||||
else
|
||||
puts (_(" so far."));
|
||||
files += f;
|
||||
impossible += im;
|
||||
}
|
||||
}
|
||||
if (f == 0)
|
||||
fputs (_("No"), stdout);
|
||||
else
|
||||
printf ("%u", f);
|
||||
fputs (_(" files, "), stdout);
|
||||
if (im == 0)
|
||||
fputs (_("no"), stdout);
|
||||
else
|
||||
printf ("%u", im);
|
||||
fputs (_(" impossibilities"), stdout);
|
||||
if (dir->contents->dirstream == 0)
|
||||
puts (".");
|
||||
else
|
||||
puts (_(" so far."));
|
||||
files += f;
|
||||
impossible += im;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fputs ("\n# ", stdout);
|
||||
@ -1141,35 +1140,35 @@ read_dirstream (__ptr_t stream)
|
||||
{
|
||||
struct dirfile *df = *ds->dirfile_slot++;
|
||||
if (! HASH_VACANT (df) && !df->impossible)
|
||||
{
|
||||
/* The glob interface wants a 'struct dirent', so mock one up. */
|
||||
struct dirent *d;
|
||||
unsigned int len = df->length + 1;
|
||||
{
|
||||
/* The glob interface wants a 'struct dirent', so mock one up. */
|
||||
struct dirent *d;
|
||||
unsigned int len = df->length + 1;
|
||||
unsigned int sz = sizeof (*d) - sizeof (d->d_name) + len;
|
||||
if (sz > bufsz)
|
||||
{
|
||||
bufsz *= 2;
|
||||
if (sz > bufsz)
|
||||
bufsz = sz;
|
||||
buf = xrealloc (buf, bufsz);
|
||||
}
|
||||
d = (struct dirent *) buf;
|
||||
if (sz > bufsz)
|
||||
{
|
||||
bufsz *= 2;
|
||||
if (sz > bufsz)
|
||||
bufsz = sz;
|
||||
buf = xrealloc (buf, bufsz);
|
||||
}
|
||||
d = (struct dirent *) buf;
|
||||
#ifdef __MINGW32__
|
||||
# if __MINGW32_MAJOR_VERSION < 3 || (__MINGW32_MAJOR_VERSION == 3 && \
|
||||
__MINGW32_MINOR_VERSION == 0)
|
||||
d->d_name = xmalloc(len);
|
||||
__MINGW32_MINOR_VERSION == 0)
|
||||
d->d_name = xmalloc (len);
|
||||
# endif
|
||||
#endif
|
||||
FAKE_DIR_ENTRY (d);
|
||||
FAKE_DIR_ENTRY (d);
|
||||
#ifdef _DIRENT_HAVE_D_NAMLEN
|
||||
d->d_namlen = len - 1;
|
||||
d->d_namlen = len - 1;
|
||||
#endif
|
||||
#ifdef _DIRENT_HAVE_D_TYPE
|
||||
d->d_type = DT_UNKNOWN;
|
||||
d->d_type = DT_UNKNOWN;
|
||||
#endif
|
||||
memcpy (d->d_name, df->name, len);
|
||||
return d;
|
||||
}
|
||||
memcpy (d->d_name, df->name, len);
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1179,7 +1178,7 @@ static void
|
||||
ansi_free (void *p)
|
||||
{
|
||||
if (p)
|
||||
free(p);
|
||||
free (p);
|
||||
}
|
||||
|
||||
/* On 64 bit ReliantUNIX (5.44 and above) in LFS mode, stat() is actually a
|
||||
@ -1213,7 +1212,7 @@ local_stat (const char *path, struct stat *buf)
|
||||
strncpy (parent, path, plen - 2);
|
||||
parent[plen - 2] = '\0';
|
||||
if (stat (parent, buf) < 0 || !_S_ISDIR (buf->st_mode))
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1237,8 +1236,8 @@ void
|
||||
hash_init_directories (void)
|
||||
{
|
||||
hash_init (&directories, DIRECTORY_BUCKETS,
|
||||
directory_hash_1, directory_hash_2, directory_hash_cmp);
|
||||
directory_hash_1, directory_hash_2, directory_hash_cmp);
|
||||
hash_init (&directory_contents, DIRECTORY_BUCKETS,
|
||||
directory_contents_hash_1, directory_contents_hash_2,
|
||||
directory_contents_hash_1, directory_contents_hash_2,
|
||||
directory_contents_hash_cmp);
|
||||
}
|
||||
|
228
expand.c
228
expand.c
@ -61,8 +61,8 @@ variable_buffer_output (char *ptr, const char *string, unsigned int length)
|
||||
{
|
||||
unsigned int offset = ptr - variable_buffer;
|
||||
variable_buffer_length = (newlen + 100 > 2 * variable_buffer_length
|
||||
? newlen + 100
|
||||
: 2 * variable_buffer_length);
|
||||
? newlen + 100
|
||||
: 2 * variable_buffer_length);
|
||||
variable_buffer = xrealloc (variable_buffer, variable_buffer_length);
|
||||
ptr = variable_buffer + offset;
|
||||
}
|
||||
@ -200,7 +200,7 @@ variable_expand_string (char *line, const char *string, long length)
|
||||
unsigned int line_offset;
|
||||
|
||||
if (!line)
|
||||
line = initialize_variable_output();
|
||||
line = initialize_variable_output ();
|
||||
o = line;
|
||||
line_offset = line - variable_buffer;
|
||||
|
||||
@ -220,118 +220,118 @@ variable_expand_string (char *line, const char *string, long length)
|
||||
{
|
||||
/* Copy all following uninteresting chars all at once to the
|
||||
variable output buffer, and skip them. Uninteresting chars end
|
||||
at the next $ or the end of the input. */
|
||||
at the next $ or the end of the input. */
|
||||
|
||||
p1 = strchr (p, '$');
|
||||
|
||||
o = variable_buffer_output (o, p, p1 != 0 ? (unsigned int)(p1 - p) : strlen (p) + 1);
|
||||
|
||||
if (p1 == 0)
|
||||
break;
|
||||
break;
|
||||
p = p1 + 1;
|
||||
|
||||
/* Dispatch on the char that follows the $. */
|
||||
|
||||
switch (*p)
|
||||
{
|
||||
case '$':
|
||||
/* $$ seen means output one $ to the variable output buffer. */
|
||||
o = variable_buffer_output (o, p, 1);
|
||||
break;
|
||||
{
|
||||
case '$':
|
||||
/* $$ seen means output one $ to the variable output buffer. */
|
||||
o = variable_buffer_output (o, p, 1);
|
||||
break;
|
||||
|
||||
case '(':
|
||||
case '{':
|
||||
/* $(...) or ${...} is the general case of substitution. */
|
||||
{
|
||||
char openparen = *p;
|
||||
char closeparen = (openparen == '(') ? ')' : '}';
|
||||
case '(':
|
||||
case '{':
|
||||
/* $(...) or ${...} is the general case of substitution. */
|
||||
{
|
||||
char openparen = *p;
|
||||
char closeparen = (openparen == '(') ? ')' : '}';
|
||||
const char *begp;
|
||||
const char *beg = p + 1;
|
||||
char *op;
|
||||
const char *beg = p + 1;
|
||||
char *op;
|
||||
char *abeg = NULL;
|
||||
const char *end, *colon;
|
||||
const char *end, *colon;
|
||||
|
||||
op = o;
|
||||
begp = p;
|
||||
if (handle_function (&op, &begp))
|
||||
{
|
||||
o = op;
|
||||
p = begp;
|
||||
break;
|
||||
}
|
||||
op = o;
|
||||
begp = p;
|
||||
if (handle_function (&op, &begp))
|
||||
{
|
||||
o = op;
|
||||
p = begp;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Is there a variable reference inside the parens or braces?
|
||||
If so, expand it before expanding the entire reference. */
|
||||
/* Is there a variable reference inside the parens or braces?
|
||||
If so, expand it before expanding the entire reference. */
|
||||
|
||||
end = strchr (beg, closeparen);
|
||||
if (end == 0)
|
||||
end = strchr (beg, closeparen);
|
||||
if (end == 0)
|
||||
/* Unterminated variable reference. */
|
||||
fatal (*expanding_var, _("unterminated variable reference"));
|
||||
p1 = lindex (beg, end, '$');
|
||||
if (p1 != 0)
|
||||
{
|
||||
/* BEG now points past the opening paren or brace.
|
||||
Count parens or braces until it is matched. */
|
||||
int count = 0;
|
||||
for (p = beg; *p != '\0'; ++p)
|
||||
{
|
||||
if (*p == openparen)
|
||||
++count;
|
||||
else if (*p == closeparen && --count < 0)
|
||||
break;
|
||||
}
|
||||
/* If COUNT is >= 0, there were unmatched opening parens
|
||||
or braces, so we go to the simple case of a variable name
|
||||
such as '$($(a)'. */
|
||||
if (count < 0)
|
||||
{
|
||||
abeg = expand_argument (beg, p); /* Expand the name. */
|
||||
beg = abeg;
|
||||
end = strchr (beg, '\0');
|
||||
}
|
||||
}
|
||||
else
|
||||
/* Advance P to the end of this reference. After we are
|
||||
p1 = lindex (beg, end, '$');
|
||||
if (p1 != 0)
|
||||
{
|
||||
/* BEG now points past the opening paren or brace.
|
||||
Count parens or braces until it is matched. */
|
||||
int count = 0;
|
||||
for (p = beg; *p != '\0'; ++p)
|
||||
{
|
||||
if (*p == openparen)
|
||||
++count;
|
||||
else if (*p == closeparen && --count < 0)
|
||||
break;
|
||||
}
|
||||
/* If COUNT is >= 0, there were unmatched opening parens
|
||||
or braces, so we go to the simple case of a variable name
|
||||
such as '$($(a)'. */
|
||||
if (count < 0)
|
||||
{
|
||||
abeg = expand_argument (beg, p); /* Expand the name. */
|
||||
beg = abeg;
|
||||
end = strchr (beg, '\0');
|
||||
}
|
||||
}
|
||||
else
|
||||
/* Advance P to the end of this reference. After we are
|
||||
finished expanding this one, P will be incremented to
|
||||
continue the scan. */
|
||||
p = end;
|
||||
p = end;
|
||||
|
||||
/* This is not a reference to a built-in function and
|
||||
any variable references inside are now expanded.
|
||||
Is the resultant text a substitution reference? */
|
||||
/* This is not a reference to a built-in function and
|
||||
any variable references inside are now expanded.
|
||||
Is the resultant text a substitution reference? */
|
||||
|
||||
colon = lindex (beg, end, ':');
|
||||
if (colon)
|
||||
{
|
||||
/* This looks like a substitution reference: $(FOO:A=B). */
|
||||
const char *subst_beg, *subst_end, *replace_beg, *replace_end;
|
||||
colon = lindex (beg, end, ':');
|
||||
if (colon)
|
||||
{
|
||||
/* This looks like a substitution reference: $(FOO:A=B). */
|
||||
const char *subst_beg, *subst_end, *replace_beg, *replace_end;
|
||||
|
||||
subst_beg = colon + 1;
|
||||
subst_end = lindex (subst_beg, end, '=');
|
||||
if (subst_end == 0)
|
||||
/* There is no = in sight. Punt on the substitution
|
||||
reference and treat this as a variable name containing
|
||||
a colon, in the code below. */
|
||||
colon = 0;
|
||||
else
|
||||
{
|
||||
replace_beg = subst_end + 1;
|
||||
replace_end = end;
|
||||
subst_beg = colon + 1;
|
||||
subst_end = lindex (subst_beg, end, '=');
|
||||
if (subst_end == 0)
|
||||
/* There is no = in sight. Punt on the substitution
|
||||
reference and treat this as a variable name containing
|
||||
a colon, in the code below. */
|
||||
colon = 0;
|
||||
else
|
||||
{
|
||||
replace_beg = subst_end + 1;
|
||||
replace_end = end;
|
||||
|
||||
/* Extract the variable name before the colon
|
||||
and look up that variable. */
|
||||
v = lookup_variable (beg, colon - beg);
|
||||
if (v == 0)
|
||||
warn_undefined (beg, colon - beg);
|
||||
/* Extract the variable name before the colon
|
||||
and look up that variable. */
|
||||
v = lookup_variable (beg, colon - beg);
|
||||
if (v == 0)
|
||||
warn_undefined (beg, colon - beg);
|
||||
|
||||
/* If the variable is not empty, perform the
|
||||
substitution. */
|
||||
if (v != 0 && *v->value != '\0')
|
||||
{
|
||||
char *pattern, *replace, *ppercent, *rpercent;
|
||||
char *value = (v->recursive
|
||||
if (v != 0 && *v->value != '\0')
|
||||
{
|
||||
char *pattern, *replace, *ppercent, *rpercent;
|
||||
char *value = (v->recursive
|
||||
? recursively_expand (v)
|
||||
: v->value);
|
||||
: v->value);
|
||||
|
||||
/* Copy the pattern and the replacement. Add in an
|
||||
extra % at the beginning to use in case there
|
||||
@ -349,15 +349,15 @@ variable_expand_string (char *line, const char *string, long length)
|
||||
|
||||
/* Look for %. Set the percent pointers properly
|
||||
based on whether we find one or not. */
|
||||
ppercent = find_percent (pattern);
|
||||
if (ppercent)
|
||||
ppercent = find_percent (pattern);
|
||||
if (ppercent)
|
||||
{
|
||||
++ppercent;
|
||||
rpercent = find_percent (replace);
|
||||
if (rpercent)
|
||||
++rpercent;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
ppercent = pattern;
|
||||
rpercent = replace;
|
||||
@ -368,38 +368,38 @@ variable_expand_string (char *line, const char *string, long length)
|
||||
o = patsubst_expand_pat (o, value, pattern, replace,
|
||||
ppercent, rpercent);
|
||||
|
||||
if (v->recursive)
|
||||
free (value);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (v->recursive)
|
||||
free (value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (colon == 0)
|
||||
/* This is an ordinary variable reference.
|
||||
Look up the value of the variable. */
|
||||
o = reference_variable (o, beg, end - beg);
|
||||
if (colon == 0)
|
||||
/* This is an ordinary variable reference.
|
||||
Look up the value of the variable. */
|
||||
o = reference_variable (o, beg, end - beg);
|
||||
|
||||
if (abeg)
|
||||
free (abeg);
|
||||
}
|
||||
break;
|
||||
if (abeg)
|
||||
free (abeg);
|
||||
}
|
||||
break;
|
||||
|
||||
case '\0':
|
||||
break;
|
||||
case '\0':
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isblank ((unsigned char)p[-1]))
|
||||
break;
|
||||
default:
|
||||
if (isblank ((unsigned char)p[-1]))
|
||||
break;
|
||||
|
||||
/* A $ followed by a random char is a variable reference:
|
||||
$a is equivalent to $(a). */
|
||||
/* A $ followed by a random char is a variable reference:
|
||||
$a is equivalent to $(a). */
|
||||
o = reference_variable (o, p, 1);
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (*p == '\0')
|
||||
break;
|
||||
break;
|
||||
|
||||
++p;
|
||||
}
|
||||
@ -418,7 +418,7 @@ variable_expand_string (char *line, const char *string, long length)
|
||||
char *
|
||||
variable_expand (const char *line)
|
||||
{
|
||||
return variable_expand_string(NULL, line, (long)-1);
|
||||
return variable_expand_string (NULL, line, (long)-1);
|
||||
}
|
||||
|
||||
/* Expand an argument for an expansion function.
|
||||
@ -434,7 +434,7 @@ expand_argument (const char *str, const char *end)
|
||||
char *r;
|
||||
|
||||
if (str == end)
|
||||
return xstrdup("");
|
||||
return xstrdup ("");
|
||||
|
||||
if (!end || *end == '\0')
|
||||
return allocated_variable_expand (str);
|
||||
|
200
file.c
200
file.c
@ -54,11 +54,11 @@ static int
|
||||
file_hash_cmp (const void *x, const void *y)
|
||||
{
|
||||
return_ISTRING_COMPARE (((struct file const *) x)->hname,
|
||||
((struct file const *) y)->hname);
|
||||
((struct file const *) y)->hname);
|
||||
}
|
||||
|
||||
#ifndef FILE_BUCKETS
|
||||
#define FILE_BUCKETS 1007
|
||||
#ifndef FILE_BUCKETS
|
||||
#define FILE_BUCKETS 1007
|
||||
#endif
|
||||
static struct hash_table files;
|
||||
|
||||
@ -103,20 +103,20 @@ lookup_file (const char *name)
|
||||
#endif
|
||||
while (name[0] == '.'
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
&& (name[1] == '/' || name[1] == '\\')
|
||||
&& (name[1] == '/' || name[1] == '\\')
|
||||
#else
|
||||
&& name[1] == '/'
|
||||
&& name[1] == '/'
|
||||
#endif
|
||||
&& name[2] != '\0')
|
||||
&& name[2] != '\0')
|
||||
{
|
||||
name += 2;
|
||||
while (*name == '/'
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
|| *name == '\\'
|
||||
|| *name == '\\'
|
||||
#endif
|
||||
)
|
||||
/* Skip following slashes: ".//foo" is "foo", not "/foo". */
|
||||
++name;
|
||||
)
|
||||
/* Skip following slashes: ".//foo" is "foo", not "/foo". */
|
||||
++name;
|
||||
}
|
||||
|
||||
if (*name == '\0')
|
||||
@ -369,52 +369,52 @@ remove_intermediates (int sig)
|
||||
for ( ; file_slot < file_end; file_slot++)
|
||||
if (! HASH_VACANT (*file_slot))
|
||||
{
|
||||
struct file *f = *file_slot;
|
||||
struct file *f = *file_slot;
|
||||
/* Is this file eligible for automatic deletion?
|
||||
Yes, IFF: it's marked intermediate, it's not secondary, it wasn't
|
||||
given on the command line, and it's either a -include makefile or
|
||||
it's not precious. */
|
||||
if (f->intermediate && (f->dontcare || !f->precious)
|
||||
&& !f->secondary && !f->cmd_target)
|
||||
{
|
||||
int status;
|
||||
if (f->update_status == -1)
|
||||
/* If nothing would have created this file yet,
|
||||
don't print an "rm" command for it. */
|
||||
continue;
|
||||
if (just_print_flag)
|
||||
status = 0;
|
||||
else
|
||||
{
|
||||
status = unlink (f->name);
|
||||
if (status < 0 && errno == ENOENT)
|
||||
continue;
|
||||
}
|
||||
if (!f->dontcare)
|
||||
{
|
||||
if (sig)
|
||||
error (NILF, _("*** Deleting intermediate file '%s'"), f->name);
|
||||
else
|
||||
{
|
||||
if (! doneany)
|
||||
DB (DB_BASIC, (_("Removing intermediate files...\n")));
|
||||
if (!silent_flag)
|
||||
{
|
||||
if (! doneany)
|
||||
{
|
||||
fputs ("rm ", stdout);
|
||||
doneany = 1;
|
||||
}
|
||||
else
|
||||
putchar (' ');
|
||||
fputs (f->name, stdout);
|
||||
fflush (stdout);
|
||||
}
|
||||
}
|
||||
if (status < 0)
|
||||
perror_with_name ("unlink: ", f->name);
|
||||
}
|
||||
}
|
||||
if (f->intermediate && (f->dontcare || !f->precious)
|
||||
&& !f->secondary && !f->cmd_target)
|
||||
{
|
||||
int status;
|
||||
if (f->update_status == -1)
|
||||
/* If nothing would have created this file yet,
|
||||
don't print an "rm" command for it. */
|
||||
continue;
|
||||
if (just_print_flag)
|
||||
status = 0;
|
||||
else
|
||||
{
|
||||
status = unlink (f->name);
|
||||
if (status < 0 && errno == ENOENT)
|
||||
continue;
|
||||
}
|
||||
if (!f->dontcare)
|
||||
{
|
||||
if (sig)
|
||||
error (NILF, _("*** Deleting intermediate file '%s'"), f->name);
|
||||
else
|
||||
{
|
||||
if (! doneany)
|
||||
DB (DB_BASIC, (_("Removing intermediate files...\n")));
|
||||
if (!silent_flag)
|
||||
{
|
||||
if (! doneany)
|
||||
{
|
||||
fputs ("rm ", stdout);
|
||||
doneany = 1;
|
||||
}
|
||||
else
|
||||
putchar (' ');
|
||||
fputs (f->name, stdout);
|
||||
fflush (stdout);
|
||||
}
|
||||
}
|
||||
if (status < 0)
|
||||
perror_with_name ("unlink: ", f->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (doneany && !sig)
|
||||
@ -696,23 +696,23 @@ snap_deps (void)
|
||||
for (f = lookup_file (".PRECIOUS"); f != 0; f = f->prev)
|
||||
for (d = f->deps; d != 0; d = d->next)
|
||||
for (f2 = d->file; f2 != 0; f2 = f2->prev)
|
||||
f2->precious = 1;
|
||||
f2->precious = 1;
|
||||
|
||||
for (f = lookup_file (".LOW_RESOLUTION_TIME"); f != 0; f = f->prev)
|
||||
for (d = f->deps; d != 0; d = d->next)
|
||||
for (f2 = d->file; f2 != 0; f2 = f2->prev)
|
||||
f2->low_resolution_time = 1;
|
||||
f2->low_resolution_time = 1;
|
||||
|
||||
for (f = lookup_file (".PHONY"); f != 0; f = f->prev)
|
||||
for (d = f->deps; d != 0; d = d->next)
|
||||
for (f2 = d->file; f2 != 0; f2 = f2->prev)
|
||||
{
|
||||
/* Mark this file as phony nonexistent target. */
|
||||
f2->phony = 1;
|
||||
{
|
||||
/* Mark this file as phony nonexistent target. */
|
||||
f2->phony = 1;
|
||||
f2->is_target = 1;
|
||||
f2->last_mtime = NONEXISTENT_MTIME;
|
||||
f2->mtime_before_update = NONEXISTENT_MTIME;
|
||||
}
|
||||
f2->last_mtime = NONEXISTENT_MTIME;
|
||||
f2->mtime_before_update = NONEXISTENT_MTIME;
|
||||
}
|
||||
|
||||
for (f = lookup_file (".INTERMEDIATE"); f != 0; f = f->prev)
|
||||
/* Mark .INTERMEDIATE deps as intermediate files. */
|
||||
@ -744,22 +744,22 @@ snap_deps (void)
|
||||
if (f != 0 && f->is_target)
|
||||
{
|
||||
if (f->deps == 0)
|
||||
ignore_errors_flag = 1;
|
||||
ignore_errors_flag = 1;
|
||||
else
|
||||
for (d = f->deps; d != 0; d = d->next)
|
||||
for (f2 = d->file; f2 != 0; f2 = f2->prev)
|
||||
f2->command_flags |= COMMANDS_NOERROR;
|
||||
for (d = f->deps; d != 0; d = d->next)
|
||||
for (f2 = d->file; f2 != 0; f2 = f2->prev)
|
||||
f2->command_flags |= COMMANDS_NOERROR;
|
||||
}
|
||||
|
||||
f = lookup_file (".SILENT");
|
||||
if (f != 0 && f->is_target)
|
||||
{
|
||||
if (f->deps == 0)
|
||||
silent_flag = 1;
|
||||
silent_flag = 1;
|
||||
else
|
||||
for (d = f->deps; d != 0; d = d->next)
|
||||
for (f2 = d->file; f2 != 0; f2 = f2->prev)
|
||||
f2->command_flags |= COMMANDS_SILENT;
|
||||
for (d = f->deps; d != 0; d = d->next)
|
||||
for (f2 = d->file; f2 != 0; f2 = f2->prev)
|
||||
f2->command_flags |= COMMANDS_SILENT;
|
||||
}
|
||||
|
||||
f = lookup_file (".NOTPARALLEL");
|
||||
@ -799,13 +799,13 @@ file_timestamp_cons (const char *fname, time_t stamp, long int ns)
|
||||
FILE_TIMESTAMP ts = product + offset;
|
||||
|
||||
if (! (s <= FILE_TIMESTAMP_S (ORDINARY_MTIME_MAX)
|
||||
&& product <= ts && ts <= ORDINARY_MTIME_MAX))
|
||||
&& product <= ts && ts <= ORDINARY_MTIME_MAX))
|
||||
{
|
||||
char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1];
|
||||
ts = s <= OLD_MTIME ? ORDINARY_MTIME_MIN : ORDINARY_MTIME_MAX;
|
||||
file_timestamp_sprintf (buf, ts);
|
||||
error (NILF, _("%s: Timestamp out of range; substituting %s"),
|
||||
fname ? fname : _("Current time"), buf);
|
||||
fname ? fname : _("Current time"), buf);
|
||||
}
|
||||
|
||||
return ts;
|
||||
@ -829,10 +829,10 @@ file_timestamp_now (int *resolution)
|
||||
struct timespec timespec;
|
||||
if (clock_gettime (CLOCK_REALTIME, ×pec) == 0)
|
||||
{
|
||||
r = 1;
|
||||
s = timespec.tv_sec;
|
||||
ns = timespec.tv_nsec;
|
||||
goto got_time;
|
||||
r = 1;
|
||||
s = timespec.tv_sec;
|
||||
ns = timespec.tv_nsec;
|
||||
goto got_time;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
@ -841,10 +841,10 @@ file_timestamp_now (int *resolution)
|
||||
struct timeval timeval;
|
||||
if (gettimeofday (&timeval, 0) == 0)
|
||||
{
|
||||
r = 1000;
|
||||
s = timeval.tv_sec;
|
||||
ns = timeval.tv_usec * 1000;
|
||||
goto got_time;
|
||||
r = 1000;
|
||||
s = timeval.tv_sec;
|
||||
ns = timeval.tv_usec * 1000;
|
||||
goto got_time;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
@ -871,8 +871,8 @@ file_timestamp_sprintf (char *p, FILE_TIMESTAMP ts)
|
||||
|
||||
if (tm)
|
||||
sprintf (p, "%04d-%02d-%02d %02d:%02d:%02d",
|
||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
else if (t < 0)
|
||||
sprintf (p, "%ld", (long) t);
|
||||
else
|
||||
@ -971,7 +971,7 @@ print_file (const void *item)
|
||||
const struct dep *d;
|
||||
fputs (_("# Also makes:"), stdout);
|
||||
for (d = f->also_make; d != 0; d = d->next)
|
||||
printf (" %s", dep_name (d));
|
||||
printf (" %s", dep_name (d));
|
||||
putchar ('\n');
|
||||
}
|
||||
if (f->last_mtime == UNKNOWN_MTIME)
|
||||
@ -999,25 +999,25 @@ print_file (const void *item)
|
||||
case cs_not_started:
|
||||
case cs_finished:
|
||||
switch (f->update_status)
|
||||
{
|
||||
case -1:
|
||||
break;
|
||||
case 0:
|
||||
puts (_("# Successfully updated."));
|
||||
break;
|
||||
case 1:
|
||||
assert (question_flag);
|
||||
puts (_("# Needs to be updated (-q is set)."));
|
||||
break;
|
||||
case 2:
|
||||
puts (_("# Failed to be updated."));
|
||||
break;
|
||||
default:
|
||||
puts (_("# Invalid value in 'update_status' member!"));
|
||||
fflush (stdout);
|
||||
fflush (stderr);
|
||||
abort ();
|
||||
}
|
||||
{
|
||||
case -1:
|
||||
break;
|
||||
case 0:
|
||||
puts (_("# Successfully updated."));
|
||||
break;
|
||||
case 1:
|
||||
assert (question_flag);
|
||||
puts (_("# Needs to be updated (-q is set)."));
|
||||
break;
|
||||
case 2:
|
||||
puts (_("# Failed to be updated."));
|
||||
break;
|
||||
default:
|
||||
puts (_("# Invalid value in 'update_status' member!"));
|
||||
fflush (stdout);
|
||||
fflush (stderr);
|
||||
abort ();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
puts (_("# Invalid value in 'command_state' member!"));
|
||||
|
68
filedef.h
68
filedef.h
@ -26,14 +26,14 @@ struct file
|
||||
const char *name;
|
||||
const char *hname; /* Hashed filename */
|
||||
const char *vpath; /* VPATH/vpath pathname */
|
||||
struct dep *deps; /* all dependencies, including duplicates */
|
||||
struct commands *cmds; /* Commands to execute for this target. */
|
||||
const char *stem; /* Implicit stem, if an implicit
|
||||
struct dep *deps; /* all dependencies, including duplicates */
|
||||
struct commands *cmds; /* Commands to execute for this target. */
|
||||
const char *stem; /* Implicit stem, if an implicit
|
||||
rule has been used */
|
||||
struct dep *also_make; /* Targets that are made by making this. */
|
||||
struct file *prev; /* Previous entry for same file name;
|
||||
used when there are multiple double-colon
|
||||
entries for the same file. */
|
||||
struct dep *also_make; /* Targets that are made by making this. */
|
||||
struct file *prev; /* Previous entry for same file name;
|
||||
used when there are multiple double-colon
|
||||
entries for the same file. */
|
||||
struct file *last; /* Last entry for the same file name. */
|
||||
|
||||
/* File that this file was renamed to. After any time that a
|
||||
@ -55,39 +55,39 @@ struct file
|
||||
the same file. Otherwise this is null. */
|
||||
struct file *double_colon;
|
||||
|
||||
FILE_TIMESTAMP last_mtime; /* File's modtime, if already known. */
|
||||
FILE_TIMESTAMP mtime_before_update; /* File's modtime before any updating
|
||||
FILE_TIMESTAMP last_mtime; /* File's modtime, if already known. */
|
||||
FILE_TIMESTAMP mtime_before_update; /* File's modtime before any updating
|
||||
has been performed. */
|
||||
int command_flags; /* Flags OR'd in for cmds; see commands.h. */
|
||||
int command_flags; /* Flags OR'd in for cmds; see commands.h. */
|
||||
char update_status; /* Status of the last attempt to update,
|
||||
or -1 if none has been made. */
|
||||
enum cmd_state /* State of the commands. */
|
||||
{ /* Note: It is important that cs_not_started be zero. */
|
||||
cs_not_started, /* Not yet started. */
|
||||
cs_deps_running, /* Dep commands running. */
|
||||
cs_running, /* Commands running. */
|
||||
cs_finished /* Commands finished. */
|
||||
or -1 if none has been made. */
|
||||
enum cmd_state /* State of the commands. */
|
||||
{ /* Note: It is important that cs_not_started be zero. */
|
||||
cs_not_started, /* Not yet started. */
|
||||
cs_deps_running, /* Dep commands running. */
|
||||
cs_running, /* Commands running. */
|
||||
cs_finished /* Commands finished. */
|
||||
} command_state ENUM_BITFIELD (2);
|
||||
|
||||
unsigned int builtin:1; /* True if the file is a builtin rule. */
|
||||
unsigned int precious:1; /* Non-0 means don't delete file on quit */
|
||||
unsigned int precious:1; /* Non-0 means don't delete file on quit */
|
||||
unsigned int loaded:1; /* True if the file is a loaded object. */
|
||||
unsigned int low_resolution_time:1; /* Nonzero if this file's time stamp
|
||||
has only one-second resolution. */
|
||||
unsigned int low_resolution_time:1; /* Nonzero if this file's time stamp
|
||||
has only one-second resolution. */
|
||||
unsigned int tried_implicit:1; /* Nonzero if have searched
|
||||
for implicit rule for making
|
||||
this file; don't search again. */
|
||||
unsigned int updating:1; /* Nonzero while updating deps of this file */
|
||||
unsigned int updated:1; /* Nonzero if this file has been remade. */
|
||||
unsigned int is_target:1; /* Nonzero if file is described as target. */
|
||||
unsigned int cmd_target:1; /* Nonzero if file was given on cmd line. */
|
||||
unsigned int phony:1; /* Nonzero if this is a phony file
|
||||
i.e., a prerequisite of .PHONY. */
|
||||
for implicit rule for making
|
||||
this file; don't search again. */
|
||||
unsigned int updating:1; /* Nonzero while updating deps of this file */
|
||||
unsigned int updated:1; /* Nonzero if this file has been remade. */
|
||||
unsigned int is_target:1; /* Nonzero if file is described as target. */
|
||||
unsigned int cmd_target:1; /* Nonzero if file was given on cmd line. */
|
||||
unsigned int phony:1; /* Nonzero if this is a phony file
|
||||
i.e., a prerequisite of .PHONY. */
|
||||
unsigned int intermediate:1;/* Nonzero if this is an intermediate file. */
|
||||
unsigned int secondary:1; /* Nonzero means remove_intermediates should
|
||||
not delete it. */
|
||||
unsigned int dontcare:1; /* Nonzero if no complaint is to be made if
|
||||
this target cannot be remade. */
|
||||
unsigned int dontcare:1; /* Nonzero if no complaint is to be made if
|
||||
this target cannot be remade. */
|
||||
unsigned int ignore_vpath:1;/* Nonzero if we threw out VPATH name. */
|
||||
unsigned int pat_searched:1;/* Nonzero if we already searched for
|
||||
pattern-specific variables. */
|
||||
@ -133,9 +133,9 @@ void print_file_data_base (void);
|
||||
#define FILE_TIMESTAMP_LO_BITS (FILE_TIMESTAMP_HI_RES ? 30 : 0)
|
||||
|
||||
#define FILE_TIMESTAMP_S(ts) (((ts) - ORDINARY_MTIME_MIN) \
|
||||
>> FILE_TIMESTAMP_LO_BITS)
|
||||
>> FILE_TIMESTAMP_LO_BITS)
|
||||
#define FILE_TIMESTAMP_NS(ts) ((int) (((ts) - ORDINARY_MTIME_MIN) \
|
||||
& ((1 << FILE_TIMESTAMP_LO_BITS) - 1)))
|
||||
& ((1 << FILE_TIMESTAMP_LO_BITS) - 1)))
|
||||
|
||||
/* Upper bound on length of string "YYYY-MM-DD HH:MM:SS.NNNNNNNNN"
|
||||
representing a file timestamp. The upper bound is not necessarily 19,
|
||||
@ -186,8 +186,8 @@ FILE_TIMESTAMP f_mtime (struct file *file, int search);
|
||||
/* The smallest and largest ordinary timestamps. */
|
||||
#define ORDINARY_MTIME_MIN (OLD_MTIME + 1)
|
||||
#define ORDINARY_MTIME_MAX ((FILE_TIMESTAMP_S (NEW_MTIME) \
|
||||
<< FILE_TIMESTAMP_LO_BITS) \
|
||||
+ ORDINARY_MTIME_MIN + FILE_TIMESTAMPS_PER_S - 1)
|
||||
<< FILE_TIMESTAMP_LO_BITS) \
|
||||
+ ORDINARY_MTIME_MIN + FILE_TIMESTAMPS_PER_S - 1)
|
||||
|
||||
/* Modtime value to use for 'infinitely new'. We used to get the current time
|
||||
from the system and use that whenever we wanted 'new'. But that causes
|
||||
|
671
function.c
671
function.c
File diff suppressed because it is too large
Load Diff
@ -397,10 +397,10 @@ pattern_search (struct file *file, int archive,
|
||||
target in MATCHES. If several targets of the same rule match,
|
||||
that rule will be in TRYRULES more than once. */
|
||||
tryrules[nrules].rule = rule;
|
||||
tryrules[nrules].matches = ti;
|
||||
tryrules[nrules].matches = ti;
|
||||
tryrules[nrules].stemlen = stemlen + (check_lastslash ? pathlen : 0);
|
||||
tryrules[nrules].order = nrules;
|
||||
tryrules[nrules].checked_lastslash = check_lastslash;
|
||||
tryrules[nrules].checked_lastslash = check_lastslash;
|
||||
++nrules;
|
||||
}
|
||||
}
|
||||
|
57
job.h
57
job.h
@ -49,13 +49,14 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
# define F_WRLCK 1
|
||||
# define F_UNLCK 2
|
||||
|
||||
struct flock {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
off_t l_start;
|
||||
off_t l_len;
|
||||
pid_t l_pid;
|
||||
};
|
||||
struct flock
|
||||
{
|
||||
short l_type;
|
||||
short l_whence;
|
||||
off_t l_start;
|
||||
off_t l_len;
|
||||
pid_t l_pid;
|
||||
};
|
||||
|
||||
/* This type is actually a HANDLE, but we want to avoid including
|
||||
windows.h as much as possible. */
|
||||
@ -70,42 +71,42 @@ int same_stream (FILE *f1, FILE *f2);
|
||||
void record_sync_mutex (const char *str);
|
||||
void prepare_mutex_handle_string (intptr_t hdl);
|
||||
|
||||
# else /* !WINDOWS32 */
|
||||
# else /* !WINDOWS32 */
|
||||
|
||||
typedef int sync_handle_t; /* file descriptor */
|
||||
typedef int sync_handle_t; /* file descriptor */
|
||||
|
||||
# define RECORD_SYNC_MUTEX(m) (void)(m)
|
||||
|
||||
# endif
|
||||
#endif /* OUTPUT_SYNC */
|
||||
#endif /* OUTPUT_SYNC */
|
||||
|
||||
/* Structure describing a running or dead child process. */
|
||||
|
||||
struct child
|
||||
{
|
||||
struct child *next; /* Link in the chain. */
|
||||
struct child *next; /* Link in the chain. */
|
||||
|
||||
struct file *file; /* File being remade. */
|
||||
struct file *file; /* File being remade. */
|
||||
|
||||
char **environment; /* Environment for commands. */
|
||||
char **environment; /* Environment for commands. */
|
||||
char *sh_batch_file; /* Script file for shell commands */
|
||||
char **command_lines; /* Array of variable-expanded cmd lines. */
|
||||
char *command_ptr; /* Ptr into command_lines[command_line]. */
|
||||
char **command_lines; /* Array of variable-expanded cmd lines. */
|
||||
char *command_ptr; /* Ptr into command_lines[command_line]. */
|
||||
|
||||
#ifdef VMS
|
||||
char *comname; /* Temporary command file name */
|
||||
int efn; /* Completion event flag number */
|
||||
int cstatus; /* Completion status */
|
||||
int efn; /* Completion event flag number */
|
||||
int cstatus; /* Completion status */
|
||||
#endif
|
||||
|
||||
unsigned int command_line; /* Index into command_lines. */
|
||||
int outfd; /* File descriptor for saving stdout */
|
||||
int errfd; /* File descriptor for saving stderr */
|
||||
pid_t pid; /* Child process's ID number. */
|
||||
unsigned int remote:1; /* Nonzero if executing remotely. */
|
||||
unsigned int noerror:1; /* Nonzero if commands contained a '-'. */
|
||||
unsigned int good_stdin:1; /* Nonzero if this child has a good stdin. */
|
||||
unsigned int deleted:1; /* Nonzero if targets have been deleted. */
|
||||
unsigned int command_line; /* Index into command_lines. */
|
||||
int outfd; /* File descriptor for saving stdout */
|
||||
int errfd; /* File descriptor for saving stderr */
|
||||
pid_t pid; /* Child process's ID number. */
|
||||
unsigned int remote:1; /* Nonzero if executing remotely. */
|
||||
unsigned int noerror:1; /* Nonzero if commands contained a '-'. */
|
||||
unsigned int good_stdin:1; /* Nonzero if this child has a good stdin. */
|
||||
unsigned int deleted:1; /* Nonzero if targets have been deleted. */
|
||||
unsigned int dontcare:1; /* Saved dontcare flag. */
|
||||
};
|
||||
|
||||
@ -139,11 +140,11 @@ void block_sigs (void);
|
||||
#ifdef POSIX
|
||||
void unblock_sigs (void);
|
||||
#else
|
||||
#ifdef HAVE_SIGSETMASK
|
||||
#ifdef HAVE_SIGSETMASK
|
||||
extern int fatal_signal_mask;
|
||||
#define unblock_sigs() sigsetmask (0)
|
||||
#define unblock_sigs() sigsetmask (0)
|
||||
#else
|
||||
#define unblock_sigs()
|
||||
#define unblock_sigs()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
95
load.c
95
load.c
@ -50,56 +50,57 @@ load_object (const gmk_floc *flocp, int noerror,
|
||||
{
|
||||
global_dl = dlopen (NULL, RTLD_NOW|RTLD_GLOBAL);
|
||||
if (! global_dl)
|
||||
fatal (flocp, _("Failed to open global symbol table: %s"), dlerror());
|
||||
fatal (flocp, _("Failed to open global symbol table: %s"), dlerror ());
|
||||
}
|
||||
|
||||
symp = (load_func_t) dlsym (global_dl, symname);
|
||||
if (! symp) {
|
||||
struct load_list *new;
|
||||
void *dlp = NULL;
|
||||
if (! symp)
|
||||
{
|
||||
struct load_list *new;
|
||||
void *dlp = NULL;
|
||||
|
||||
/* If the path has no "/", try the current directory first. */
|
||||
if (! strchr (ldname, '/')
|
||||
if (! strchr (ldname, '/')
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
&& ! strchr (ldname, '\\')
|
||||
&& ! strchr (ldname, '\\')
|
||||
#endif
|
||||
)
|
||||
dlp = dlopen (concat (2, "./", ldname), RTLD_LAZY|RTLD_GLOBAL);
|
||||
)
|
||||
dlp = dlopen (concat (2, "./", ldname), RTLD_LAZY|RTLD_GLOBAL);
|
||||
|
||||
/* If we haven't opened it yet, try the default search path. */
|
||||
if (! dlp)
|
||||
dlp = dlopen (ldname, RTLD_LAZY|RTLD_GLOBAL);
|
||||
/* If we haven't opened it yet, try the default search path. */
|
||||
if (! dlp)
|
||||
dlp = dlopen (ldname, RTLD_LAZY|RTLD_GLOBAL);
|
||||
|
||||
/* Still no? Then fail. */
|
||||
if (! dlp)
|
||||
{
|
||||
if (noerror)
|
||||
DB (DB_BASIC, ("%s", dlerror()));
|
||||
else
|
||||
error (flocp, "%s", dlerror());
|
||||
return NULL;
|
||||
}
|
||||
/* Still no? Then fail. */
|
||||
if (! dlp)
|
||||
{
|
||||
if (noerror)
|
||||
DB (DB_BASIC, ("%s", dlerror ()));
|
||||
else
|
||||
error (flocp, "%s", dlerror ());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Assert that the GPL license symbol is defined. */
|
||||
symp = dlsym (dlp, "plugin_is_GPL_compatible");
|
||||
if (! symp)
|
||||
fatal (flocp, _("Loaded object %s is not declared to be GPL compatible"),
|
||||
ldname);
|
||||
/* Assert that the GPL license symbol is defined. */
|
||||
symp = dlsym (dlp, "plugin_is_GPL_compatible");
|
||||
if (! symp)
|
||||
fatal (flocp, _("Loaded object %s is not declared to be GPL compatible"),
|
||||
ldname);
|
||||
|
||||
symp = dlsym (dlp, symname);
|
||||
if (! symp)
|
||||
fatal (flocp, _("Failed to load symbol %s from %s: %s"),
|
||||
symname, ldname, dlerror());
|
||||
symp = dlsym (dlp, symname);
|
||||
if (! symp)
|
||||
fatal (flocp, _("Failed to load symbol %s from %s: %s"),
|
||||
symname, ldname, dlerror ());
|
||||
|
||||
/* Add this symbol to a trivial lookup table. This is not efficient but
|
||||
it's highly unlikely we'll be loading lots of objects, and we only need
|
||||
it to look them up on unload, if we rebuild them. */
|
||||
new = xmalloc (sizeof (struct load_list));
|
||||
new->name = xstrdup (ldname);
|
||||
new->dlp = dlp;
|
||||
new->next = loaded_syms;
|
||||
loaded_syms = new;
|
||||
}
|
||||
/* Add this symbol to a trivial lookup table. This is not efficient but
|
||||
it's highly unlikely we'll be loading lots of objects, and we only
|
||||
need it to look them up on unload, if we rebuild them. */
|
||||
new = xmalloc (sizeof (struct load_list));
|
||||
new->name = xstrdup (ldname);
|
||||
new->dlp = dlp;
|
||||
new->next = loaded_syms;
|
||||
loaded_syms = new;
|
||||
}
|
||||
|
||||
return symp;
|
||||
}
|
||||
@ -150,7 +151,7 @@ load_file (const gmk_floc *flocp, const char **ldname, int noerror)
|
||||
*ldname = strcache_add (*ldname);
|
||||
|
||||
/* If this object has been loaded, we're done. */
|
||||
loaded = allocated_variable_expand("$(.LOADED)");
|
||||
loaded = allocated_variable_expand ("$(.LOADED)");
|
||||
fp = strstr (loaded, *ldname);
|
||||
r = fp && (fp==loaded || fp[-1]==' ') && (fp[nmlen]=='\0' || fp[nmlen]==' ');
|
||||
free (loaded);
|
||||
@ -165,17 +166,17 @@ load_file (const gmk_floc *flocp, const char **ldname, int noerror)
|
||||
fp = strrchr (*ldname, '/');
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
if (fp)
|
||||
{
|
||||
const char *fp2 = strchr (fp, '\\');
|
||||
{
|
||||
const char *fp2 = strchr (fp, '\\');
|
||||
|
||||
if (fp2 > fp)
|
||||
fp = fp2;
|
||||
}
|
||||
if (fp2 > fp)
|
||||
fp = fp2;
|
||||
}
|
||||
else
|
||||
fp = strrchr (*ldname, '\\');
|
||||
fp = strrchr (*ldname, '\\');
|
||||
/* The (improbable) case of d:foo. */
|
||||
if (fp && *fp && fp[1] == ':')
|
||||
fp++;
|
||||
fp++;
|
||||
#endif
|
||||
if (!fp)
|
||||
fp = *ldname;
|
||||
@ -190,7 +191,7 @@ load_file (const gmk_floc *flocp, const char **ldname, int noerror)
|
||||
DB (DB_VERBOSE, (_("Loading symbol %s from %s\n"), symname, *ldname));
|
||||
|
||||
/* Load it! */
|
||||
symp = load_object(flocp, noerror, *ldname, symname);
|
||||
symp = load_object (flocp, noerror, *ldname, symname);
|
||||
if (! symp)
|
||||
return 0;
|
||||
|
||||
|
286
main.c
286
main.c
@ -785,11 +785,11 @@ prepare_mutex_handle_string (sync_handle_t handle)
|
||||
* debuggers can attach.
|
||||
*/
|
||||
LONG WINAPI
|
||||
handle_runtime_exceptions( struct _EXCEPTION_POINTERS *exinfo )
|
||||
handle_runtime_exceptions (struct _EXCEPTION_POINTERS *exinfo)
|
||||
{
|
||||
PEXCEPTION_RECORD exrec = exinfo->ExceptionRecord;
|
||||
LPSTR cmdline = GetCommandLine();
|
||||
LPSTR prg = strtok(cmdline, " ");
|
||||
LPSTR cmdline = GetCommandLine ();
|
||||
LPSTR prg = strtok (cmdline, " ");
|
||||
CHAR errmsg[1024];
|
||||
#ifdef USE_EVENT_LOG
|
||||
HANDLE hEventSource;
|
||||
@ -798,54 +798,54 @@ handle_runtime_exceptions( struct _EXCEPTION_POINTERS *exinfo )
|
||||
|
||||
if (! ISDB (DB_VERBOSE))
|
||||
{
|
||||
sprintf(errmsg,
|
||||
_("%s: Interrupt/Exception caught (code = 0x%lx, addr = 0x%p)\n"),
|
||||
prg, exrec->ExceptionCode, exrec->ExceptionAddress);
|
||||
fprintf(stderr, errmsg);
|
||||
exit(255);
|
||||
sprintf (errmsg,
|
||||
_("%s: Interrupt/Exception caught (code = 0x%lx, addr = 0x%p)\n"),
|
||||
prg, exrec->ExceptionCode, exrec->ExceptionAddress);
|
||||
fprintf (stderr, errmsg);
|
||||
exit (255);
|
||||
}
|
||||
|
||||
sprintf(errmsg,
|
||||
_("\nUnhandled exception filter called from program %s\nExceptionCode = %lx\nExceptionFlags = %lx\nExceptionAddress = 0x%p\n"),
|
||||
prg, exrec->ExceptionCode, exrec->ExceptionFlags,
|
||||
exrec->ExceptionAddress);
|
||||
sprintf (errmsg,
|
||||
_("\nUnhandled exception filter called from program %s\nExceptionCode = %lx\nExceptionFlags = %lx\nExceptionAddress = 0x%p\n"),
|
||||
prg, exrec->ExceptionCode, exrec->ExceptionFlags,
|
||||
exrec->ExceptionAddress);
|
||||
|
||||
if (exrec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION
|
||||
&& exrec->NumberParameters >= 2)
|
||||
sprintf(&errmsg[strlen(errmsg)],
|
||||
(exrec->ExceptionInformation[0]
|
||||
? _("Access violation: write operation at address 0x%p\n")
|
||||
: _("Access violation: read operation at address 0x%p\n")),
|
||||
(PVOID)exrec->ExceptionInformation[1]);
|
||||
sprintf (&errmsg[strlen(errmsg)],
|
||||
(exrec->ExceptionInformation[0]
|
||||
? _("Access violation: write operation at address 0x%p\n")
|
||||
: _("Access violation: read operation at address 0x%p\n")),
|
||||
(PVOID)exrec->ExceptionInformation[1]);
|
||||
|
||||
/* turn this on if we want to put stuff in the event log too */
|
||||
#ifdef USE_EVENT_LOG
|
||||
hEventSource = RegisterEventSource(NULL, "GNU Make");
|
||||
hEventSource = RegisterEventSource (NULL, "GNU Make");
|
||||
lpszStrings[0] = errmsg;
|
||||
|
||||
if (hEventSource != NULL)
|
||||
{
|
||||
ReportEvent(hEventSource, /* handle of event source */
|
||||
EVENTLOG_ERROR_TYPE, /* event type */
|
||||
0, /* event category */
|
||||
0, /* event ID */
|
||||
NULL, /* current user's SID */
|
||||
1, /* strings in lpszStrings */
|
||||
0, /* no bytes of raw data */
|
||||
lpszStrings, /* array of error strings */
|
||||
NULL); /* no raw data */
|
||||
ReportEvent (hEventSource, /* handle of event source */
|
||||
EVENTLOG_ERROR_TYPE, /* event type */
|
||||
0, /* event category */
|
||||
0, /* event ID */
|
||||
NULL, /* current user's SID */
|
||||
1, /* strings in lpszStrings */
|
||||
0, /* no bytes of raw data */
|
||||
lpszStrings, /* array of error strings */
|
||||
NULL); /* no raw data */
|
||||
|
||||
(VOID) DeregisterEventSource(hEventSource);
|
||||
(VOID) DeregisterEventSource (hEventSource);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Write the error to stderr too */
|
||||
fprintf(stderr, errmsg);
|
||||
fprintf (stderr, errmsg);
|
||||
|
||||
#ifdef DEBUG
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
#else
|
||||
exit(255);
|
||||
exit (255);
|
||||
return (255); /* not reached */
|
||||
#endif
|
||||
}
|
||||
@ -885,75 +885,89 @@ find_and_set_default_shell (const char *token)
|
||||
|| ((tokend - 4 == search_token
|
||||
|| (tokend - 4 > search_token
|
||||
&& (tokend[-5] == '/' || tokend[-5] == '\\')))
|
||||
&& !strcasecmp (tokend - 4, "cmd.exe"))) {
|
||||
batch_mode_shell = 1;
|
||||
unixy_shell = 0;
|
||||
sprintf (sh_path, "%s", search_token);
|
||||
default_shell = xstrdup (w32ify (sh_path, 0));
|
||||
DB (DB_VERBOSE, (_("find_and_set_shell() setting default_shell = %s\n"),
|
||||
default_shell));
|
||||
sh_found = 1;
|
||||
} else if (!no_default_sh_exe &&
|
||||
(token == NULL || !strcmp (search_token, default_shell))) {
|
||||
/* no new information, path already set or known */
|
||||
sh_found = 1;
|
||||
} else if (file_exists_p (search_token)) {
|
||||
/* search token path was found */
|
||||
sprintf (sh_path, "%s", search_token);
|
||||
default_shell = xstrdup (w32ify (sh_path, 0));
|
||||
DB (DB_VERBOSE, (_("find_and_set_shell() setting default_shell = %s\n"),
|
||||
default_shell));
|
||||
sh_found = 1;
|
||||
} else {
|
||||
char *p;
|
||||
struct variable *v = lookup_variable (STRING_SIZE_TUPLE ("PATH"));
|
||||
|
||||
/* Search Path for shell */
|
||||
if (v && v->value) {
|
||||
char *ep;
|
||||
|
||||
p = v->value;
|
||||
ep = strchr (p, PATH_SEPARATOR_CHAR);
|
||||
|
||||
while (ep && *ep) {
|
||||
*ep = '\0';
|
||||
|
||||
if (dir_file_exists_p (p, search_token)) {
|
||||
sprintf (sh_path, "%s/%s", p, search_token);
|
||||
default_shell = xstrdup (w32ify (sh_path, 0));
|
||||
sh_found = 1;
|
||||
*ep = PATH_SEPARATOR_CHAR;
|
||||
|
||||
/* terminate loop */
|
||||
p += strlen (p);
|
||||
} else {
|
||||
*ep = PATH_SEPARATOR_CHAR;
|
||||
p = ++ep;
|
||||
}
|
||||
|
||||
ep = strchr (p, PATH_SEPARATOR_CHAR);
|
||||
}
|
||||
|
||||
/* be sure to check last element of Path */
|
||||
if (p && *p && dir_file_exists_p (p, search_token)) {
|
||||
sprintf (sh_path, "%s/%s", p, search_token);
|
||||
default_shell = xstrdup (w32ify (sh_path, 0));
|
||||
sh_found = 1;
|
||||
}
|
||||
|
||||
if (sh_found)
|
||||
DB (DB_VERBOSE,
|
||||
(_("find_and_set_shell() path search set default_shell = %s\n"),
|
||||
default_shell));
|
||||
&& !strcasecmp (tokend - 4, "cmd.exe")))
|
||||
{
|
||||
batch_mode_shell = 1;
|
||||
unixy_shell = 0;
|
||||
sprintf (sh_path, "%s", search_token);
|
||||
default_shell = xstrdup (w32ify (sh_path, 0));
|
||||
DB (DB_VERBOSE, (_("find_and_set_shell() setting default_shell = %s\n"),
|
||||
default_shell));
|
||||
sh_found = 1;
|
||||
}
|
||||
else if (!no_default_sh_exe
|
||||
&& (token == NULL || !strcmp (search_token, default_shell)))
|
||||
{
|
||||
/* no new information, path already set or known */
|
||||
sh_found = 1;
|
||||
}
|
||||
else if (file_exists_p (search_token))
|
||||
{
|
||||
/* search token path was found */
|
||||
sprintf (sh_path, "%s", search_token);
|
||||
default_shell = xstrdup (w32ify (sh_path, 0));
|
||||
DB (DB_VERBOSE, (_("find_and_set_shell() setting default_shell = %s\n"),
|
||||
default_shell));
|
||||
sh_found = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *p;
|
||||
struct variable *v = lookup_variable (STRING_SIZE_TUPLE ("PATH"));
|
||||
|
||||
/* Search Path for shell */
|
||||
if (v && v->value)
|
||||
{
|
||||
char *ep;
|
||||
|
||||
p = v->value;
|
||||
ep = strchr (p, PATH_SEPARATOR_CHAR);
|
||||
|
||||
while (ep && *ep)
|
||||
{
|
||||
*ep = '\0';
|
||||
|
||||
if (dir_file_exists_p (p, search_token))
|
||||
{
|
||||
sprintf (sh_path, "%s/%s", p, search_token);
|
||||
default_shell = xstrdup (w32ify (sh_path, 0));
|
||||
sh_found = 1;
|
||||
*ep = PATH_SEPARATOR_CHAR;
|
||||
|
||||
/* terminate loop */
|
||||
p += strlen (p);
|
||||
}
|
||||
else
|
||||
{
|
||||
*ep = PATH_SEPARATOR_CHAR;
|
||||
p = ++ep;
|
||||
}
|
||||
|
||||
ep = strchr (p, PATH_SEPARATOR_CHAR);
|
||||
}
|
||||
|
||||
/* be sure to check last element of Path */
|
||||
if (p && *p && dir_file_exists_p (p, search_token))
|
||||
{
|
||||
sprintf (sh_path, "%s/%s", p, search_token);
|
||||
default_shell = xstrdup (w32ify (sh_path, 0));
|
||||
sh_found = 1;
|
||||
}
|
||||
|
||||
if (sh_found)
|
||||
DB (DB_VERBOSE,
|
||||
(_("find_and_set_shell() path search set default_shell = %s\n"),
|
||||
default_shell));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* naive test */
|
||||
if (!unixy_shell && sh_found &&
|
||||
(strstr (default_shell, "sh") || strstr (default_shell, "SH"))) {
|
||||
unixy_shell = 1;
|
||||
batch_mode_shell = 0;
|
||||
}
|
||||
if (!unixy_shell && sh_found
|
||||
&& (strstr (default_shell, "sh") || strstr (default_shell, "SH")))
|
||||
{
|
||||
unixy_shell = 1;
|
||||
batch_mode_shell = 0;
|
||||
}
|
||||
|
||||
#ifdef BATCH_MODE_ONLY_SHELL
|
||||
batch_mode_shell = 1;
|
||||
@ -992,7 +1006,7 @@ main (int argc, char **argv, char **envp)
|
||||
char *unix_path = NULL;
|
||||
char *windows32_path = NULL;
|
||||
|
||||
SetUnhandledExceptionFilter(handle_runtime_exceptions);
|
||||
SetUnhandledExceptionFilter (handle_runtime_exceptions);
|
||||
|
||||
/* start off assuming we have no shell */
|
||||
unixy_shell = 0;
|
||||
@ -1253,11 +1267,12 @@ main (int argc, char **argv, char **envp)
|
||||
#ifdef WINDOWS32
|
||||
if (!unix_path && strneq (envp[i], "PATH=", 5))
|
||||
unix_path = ep+1;
|
||||
else if (!strnicmp (envp[i], "Path=", 5)) {
|
||||
do_not_define = 1; /* it gets defined after loop exits */
|
||||
if (!windows32_path)
|
||||
windows32_path = ep+1;
|
||||
}
|
||||
else if (!strnicmp (envp[i], "Path=", 5))
|
||||
{
|
||||
do_not_define = 1; /* it gets defined after loop exits */
|
||||
if (!windows32_path)
|
||||
windows32_path = ep+1;
|
||||
}
|
||||
#endif
|
||||
/* The result of pointer arithmetic is cast to unsigned int for
|
||||
machines where ptrdiff_t is a different size that doesn't widen
|
||||
@ -1316,7 +1331,7 @@ main (int argc, char **argv, char **envp)
|
||||
env = Lock ("ENV:", ACCESS_READ);
|
||||
if (env)
|
||||
{
|
||||
old = CurrentDir (DupLock(env));
|
||||
old = CurrentDir (DupLock (env));
|
||||
Examine (env, &fib);
|
||||
|
||||
while (ExNext (env, &fib))
|
||||
@ -1332,7 +1347,7 @@ main (int argc, char **argv, char **envp)
|
||||
}
|
||||
}
|
||||
UnLock (env);
|
||||
UnLock(CurrentDir(old));
|
||||
UnLock (CurrentDir (old));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1352,12 +1367,13 @@ main (int argc, char **argv, char **envp)
|
||||
decode_switches (argc, argv, 0);
|
||||
|
||||
#ifdef WINDOWS32
|
||||
if (suspend_flag) {
|
||||
fprintf(stderr, "%s (pid = %ld)\n", argv[0], GetCurrentProcessId());
|
||||
fprintf(stderr, _("%s is suspending for 30 seconds..."), argv[0]);
|
||||
Sleep(30 * 1000);
|
||||
fprintf(stderr, _("done sleep(30). Continuing.\n"));
|
||||
}
|
||||
if (suspend_flag)
|
||||
{
|
||||
fprintf (stderr, "%s (pid = %ld)\n", argv[0], GetCurrentProcessId ());
|
||||
fprintf (stderr, _("%s is suspending for 30 seconds..."), argv[0]);
|
||||
Sleep (30 * 1000);
|
||||
fprintf (stderr, _("done sleep(30). Continuing.\n"));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set always_make_flag if -B was given and we've not restarted already. */
|
||||
@ -1386,10 +1402,9 @@ main (int argc, char **argv, char **envp)
|
||||
* matter if the path is one way or the other for
|
||||
* CreateProcess().
|
||||
*/
|
||||
if (strpbrk(argv[0], "/:\\") ||
|
||||
strstr(argv[0], "..") ||
|
||||
strneq(argv[0], "//", 2))
|
||||
argv[0] = xstrdup(w32ify(argv[0],1));
|
||||
if (strpbrk (argv[0], "/:\\") || strstr (argv[0], "..")
|
||||
|| strneq (argv[0], "//", 2))
|
||||
argv[0] = xstrdup (w32ify (argv[0], 1));
|
||||
#else /* WINDOWS32 */
|
||||
#if defined (__MSDOS__) || defined (__EMX__)
|
||||
if (strchr (argv[0], '\\'))
|
||||
@ -1511,7 +1526,7 @@ main (int argc, char **argv, char **envp)
|
||||
* lookups to fail because the current directory (.) was pointing
|
||||
* at the wrong place when it was first evaluated.
|
||||
*/
|
||||
no_default_sh_exe = !find_and_set_default_shell(NULL);
|
||||
no_default_sh_exe = !find_and_set_default_shell (NULL);
|
||||
|
||||
#endif /* WINDOWS32 */
|
||||
/* Figure out the level of recursion. */
|
||||
@ -1742,7 +1757,7 @@ main (int argc, char **argv, char **envp)
|
||||
#ifdef WINDOWS32
|
||||
/* look one last time after reading all Makefiles */
|
||||
if (no_default_sh_exe)
|
||||
no_default_sh_exe = !find_and_set_default_shell(NULL);
|
||||
no_default_sh_exe = !find_and_set_default_shell (NULL);
|
||||
#endif /* WINDOWS32 */
|
||||
|
||||
#if defined (__MSDOS__) || defined (__EMX__)
|
||||
@ -1755,7 +1770,7 @@ main (int argc, char **argv, char **envp)
|
||||
|
||||
if (shv && *shv->value)
|
||||
{
|
||||
char *shell_path = recursively_expand(shv);
|
||||
char *shell_path = recursively_expand (shv);
|
||||
|
||||
if (shell_path && _is_unixy_shell (shell_path))
|
||||
unixy_shell = 1;
|
||||
@ -1825,11 +1840,11 @@ main (int argc, char **argv, char **envp)
|
||||
cp = jobserver_fds->list[0];
|
||||
|
||||
#ifdef WINDOWS32
|
||||
if (! open_jobserver_semaphore(cp))
|
||||
if (! open_jobserver_semaphore (cp))
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
DWORD err = GetLastError ();
|
||||
fatal (NILF, _("internal error: unable to open jobserver semaphore '%s': (Error %ld: %s)"),
|
||||
cp, err, map_windows32_error_to_string(err));
|
||||
cp, err, map_windows32_error_to_string (err));
|
||||
}
|
||||
DB (DB_JOBS, (_("Jobserver client (semaphore %s)\n"), cp));
|
||||
#else
|
||||
@ -1900,11 +1915,11 @@ main (int argc, char **argv, char **envp)
|
||||
DB (DB_JOBS, (_("Jobserver slots limited to %d\n"), job_slots));
|
||||
}
|
||||
|
||||
if (! create_jobserver_semaphore(job_slots - 1))
|
||||
if (! create_jobserver_semaphore (job_slots - 1))
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
DWORD err = GetLastError ();
|
||||
fatal (NILF, _("creating jobserver semaphore: (Error %ld: %s)"),
|
||||
err, map_windows32_error_to_string(err));
|
||||
err, map_windows32_error_to_string (err));
|
||||
}
|
||||
#else
|
||||
char c = '+';
|
||||
@ -1938,7 +1953,7 @@ main (int argc, char **argv, char **envp)
|
||||
|
||||
#ifdef WINDOWS32
|
||||
cp = xmalloc (MAX_PATH + 1);
|
||||
strcpy (cp, get_jobserver_semaphore_name());
|
||||
strcpy (cp, get_jobserver_semaphore_name ());
|
||||
#else
|
||||
cp = xmalloc ((CSTRLEN ("1024") * 2) + 2);
|
||||
sprintf (cp, "%d,%d", job_fds[0], job_fds[1]);
|
||||
@ -2461,7 +2476,7 @@ main (int argc, char **argv, char **envp)
|
||||
}
|
||||
|
||||
/* NOTREACHED */
|
||||
exit(0);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
/* Parsing of arguments, decoding of switches. */
|
||||
@ -2553,12 +2568,13 @@ handle_non_switch_argument (char *arg, int env)
|
||||
if (cv->variable == v)
|
||||
break;
|
||||
|
||||
if (! cv) {
|
||||
cv = xmalloc (sizeof (*cv));
|
||||
cv->variable = v;
|
||||
cv->next = command_variables;
|
||||
command_variables = cv;
|
||||
}
|
||||
if (! cv)
|
||||
{
|
||||
cv = xmalloc (sizeof (*cv));
|
||||
cv->variable = v;
|
||||
cv->next = command_variables;
|
||||
command_variables = cv;
|
||||
}
|
||||
}
|
||||
else if (! env)
|
||||
{
|
||||
@ -3262,7 +3278,7 @@ clean_jobserver (int status)
|
||||
after any other error code, that's bad. */
|
||||
|
||||
#ifdef WINDOWS32
|
||||
if (has_jobserver_semaphore() && jobserver_tokens)
|
||||
if (has_jobserver_semaphore () && jobserver_tokens)
|
||||
#else
|
||||
char token = '+';
|
||||
|
||||
@ -3278,7 +3294,7 @@ clean_jobserver (int status)
|
||||
while (--jobserver_tokens)
|
||||
{
|
||||
#ifdef WINDOWS32
|
||||
if (! release_jobserver_semaphore())
|
||||
if (! release_jobserver_semaphore ())
|
||||
perror_with_name ("release_jobserver_semaphore", "");
|
||||
#else
|
||||
int r;
|
||||
@ -3299,7 +3315,7 @@ clean_jobserver (int status)
|
||||
unsigned int tcnt = 1;
|
||||
|
||||
#ifdef WINDOWS32
|
||||
while (acquire_jobserver_semaphore())
|
||||
while (acquire_jobserver_semaphore ())
|
||||
++tcnt;
|
||||
#else
|
||||
/* Close the write side, so the read() won't hang. */
|
||||
@ -3315,7 +3331,7 @@ clean_jobserver (int status)
|
||||
tcnt, master_job_slots);
|
||||
|
||||
#ifdef WINDOWS32
|
||||
free_jobserver_semaphore();
|
||||
free_jobserver_semaphore ();
|
||||
#else
|
||||
close (job_fds[0]);
|
||||
#endif
|
||||
|
166
misc.c
166
misc.c
@ -60,64 +60,64 @@ collapse_continuations (char *line)
|
||||
while (*in != '\0')
|
||||
{
|
||||
/* BS_WRITE gets the number of quoted backslashes at
|
||||
the end just before IN, and BACKSLASH gets nonzero
|
||||
if the next character is quoted. */
|
||||
the end just before IN, and BACKSLASH gets nonzero
|
||||
if the next character is quoted. */
|
||||
backslash = 0;
|
||||
bs_write = 0;
|
||||
for (p = in - 1; p >= line && *p == '\\'; --p)
|
||||
{
|
||||
if (backslash)
|
||||
++bs_write;
|
||||
backslash = !backslash;
|
||||
{
|
||||
if (backslash)
|
||||
++bs_write;
|
||||
backslash = !backslash;
|
||||
|
||||
/* It should be impossible to go back this far without exiting,
|
||||
but if we do, we can't get the right answer. */
|
||||
if (in == out - 1)
|
||||
abort ();
|
||||
}
|
||||
/* It should be impossible to go back this far without exiting,
|
||||
but if we do, we can't get the right answer. */
|
||||
if (in == out - 1)
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Output the appropriate number of backslashes. */
|
||||
while (bs_write-- > 0)
|
||||
*out++ = '\\';
|
||||
*out++ = '\\';
|
||||
|
||||
/* Skip the newline. */
|
||||
++in;
|
||||
|
||||
if (backslash)
|
||||
{
|
||||
{
|
||||
/* Backslash/newline handling:
|
||||
In traditional GNU make all trailing whitespace, consecutive
|
||||
backslash/newlines, and any leading whitespace on the next line
|
||||
is reduced to a single space.
|
||||
In POSIX, each backslash/newline and is replaced by a space. */
|
||||
in = next_token (in);
|
||||
in = next_token (in);
|
||||
if (! posix_pedantic)
|
||||
while (out > line && isblank ((unsigned char)out[-1]))
|
||||
--out;
|
||||
*out++ = ' ';
|
||||
}
|
||||
*out++ = ' ';
|
||||
}
|
||||
else
|
||||
/* If the newline isn't quoted, put it in the output. */
|
||||
*out++ = '\n';
|
||||
/* If the newline isn't quoted, put it in the output. */
|
||||
*out++ = '\n';
|
||||
|
||||
/* Now copy the following line to the output.
|
||||
Stop when we find backslashes followed by a newline. */
|
||||
Stop when we find backslashes followed by a newline. */
|
||||
while (*in != '\0')
|
||||
if (*in == '\\')
|
||||
{
|
||||
p = in + 1;
|
||||
while (*p == '\\')
|
||||
++p;
|
||||
if (*p == '\n')
|
||||
{
|
||||
in = p;
|
||||
break;
|
||||
}
|
||||
while (in < p)
|
||||
*out++ = *in++;
|
||||
}
|
||||
else
|
||||
*out++ = *in++;
|
||||
if (*in == '\\')
|
||||
{
|
||||
p = in + 1;
|
||||
while (*p == '\\')
|
||||
++p;
|
||||
if (*p == '\n')
|
||||
{
|
||||
in = p;
|
||||
break;
|
||||
}
|
||||
while (in < p)
|
||||
*out++ = *in++;
|
||||
}
|
||||
else
|
||||
*out++ = *in++;
|
||||
}
|
||||
|
||||
*out = '\0';
|
||||
@ -267,12 +267,12 @@ message (int prefix, const char *fmt, ...)
|
||||
if (fmt != 0)
|
||||
{
|
||||
if (prefix)
|
||||
{
|
||||
if (makelevel == 0)
|
||||
printf ("%s: ", program);
|
||||
else
|
||||
printf ("%s[%u]: ", program, makelevel);
|
||||
}
|
||||
{
|
||||
if (makelevel == 0)
|
||||
printf ("%s: ", program);
|
||||
else
|
||||
printf ("%s[%u]: ", program, makelevel);
|
||||
}
|
||||
va_start (args, fmt);
|
||||
vfprintf (stdout, fmt, args);
|
||||
va_end (args);
|
||||
@ -335,7 +335,7 @@ fatal (const gmk_floc *flocp, const char *fmt, ...)
|
||||
|
||||
#ifndef HAVE_STRERROR
|
||||
|
||||
#undef strerror
|
||||
#undef strerror
|
||||
|
||||
char *
|
||||
strerror (int errnum)
|
||||
@ -499,7 +499,7 @@ end_of_token_w32 (const char *s, char stopchar)
|
||||
int backslash = 0;
|
||||
|
||||
while (*p != '\0' && *p != stopchar
|
||||
&& (backslash || !isblank ((unsigned char)*p)))
|
||||
&& (backslash || !isblank ((unsigned char)*p)))
|
||||
{
|
||||
if (*p++ == '\\')
|
||||
{
|
||||
@ -566,9 +566,9 @@ copy_dep_chain (const struct dep *d)
|
||||
|
||||
c->next = 0;
|
||||
if (firstnew == 0)
|
||||
firstnew = lastnew = c;
|
||||
firstnew = lastnew = c;
|
||||
else
|
||||
lastnew = lastnew->next = c;
|
||||
lastnew = lastnew->next = c;
|
||||
|
||||
d = d->next;
|
||||
}
|
||||
@ -658,7 +658,7 @@ strncasecmp (const char *s1, const char *s2, int n)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef GETLOADAVG_PRIVILEGED
|
||||
#ifdef GETLOADAVG_PRIVILEGED
|
||||
|
||||
#ifdef POSIX
|
||||
|
||||
@ -671,7 +671,7 @@ strncasecmp (const char *s1, const char *s2, int n)
|
||||
#undef HAVE_SETREUID
|
||||
#undef HAVE_SETREGID
|
||||
|
||||
#else /* Not POSIX. */
|
||||
#else /* Not POSIX. */
|
||||
|
||||
/* Some POSIX.1 systems have the seteuid and setegid functions. In a
|
||||
POSIX-like system, they are the best thing to use. However, some
|
||||
@ -681,30 +681,30 @@ strncasecmp (const char *s1, const char *s2, int n)
|
||||
#undef HAVE_SETEUID
|
||||
#undef HAVE_SETEGID
|
||||
|
||||
#endif /* POSIX. */
|
||||
#endif /* POSIX. */
|
||||
|
||||
#ifndef HAVE_UNISTD_H
|
||||
#ifndef HAVE_UNISTD_H
|
||||
extern int getuid (), getgid (), geteuid (), getegid ();
|
||||
extern int setuid (), setgid ();
|
||||
#ifdef HAVE_SETEUID
|
||||
extern int seteuid ();
|
||||
#else
|
||||
#ifdef HAVE_SETREUID
|
||||
#ifdef HAVE_SETREUID
|
||||
extern int setreuid ();
|
||||
#endif /* Have setreuid. */
|
||||
#endif /* Have seteuid. */
|
||||
#endif /* Have setreuid. */
|
||||
#endif /* Have seteuid. */
|
||||
#ifdef HAVE_SETEGID
|
||||
extern int setegid ();
|
||||
#else
|
||||
#ifdef HAVE_SETREGID
|
||||
#ifdef HAVE_SETREGID
|
||||
extern int setregid ();
|
||||
#endif /* Have setregid. */
|
||||
#endif /* Have setegid. */
|
||||
#endif /* No <unistd.h>. */
|
||||
#endif /* Have setregid. */
|
||||
#endif /* Have setegid. */
|
||||
#endif /* No <unistd.h>. */
|
||||
|
||||
/* Keep track of the user and group IDs for user- and make- access. */
|
||||
static int user_uid = -1, user_gid = -1, make_uid = -1, make_gid = -1;
|
||||
#define access_inited (user_uid != -1)
|
||||
#define access_inited (user_uid != -1)
|
||||
static enum { make, user } current_access;
|
||||
|
||||
|
||||
@ -721,7 +721,7 @@ log_access (const char *flavor)
|
||||
run in a child fork whose stdout is piped. */
|
||||
|
||||
fprintf (stderr, _("%s: user %lu (real %lu), group %lu (real %lu)\n"),
|
||||
flavor, (unsigned long) geteuid (), (unsigned long) getuid (),
|
||||
flavor, (unsigned long) geteuid (), (unsigned long) getuid (),
|
||||
(unsigned long) getegid (), (unsigned long) getgid ());
|
||||
fflush (stderr);
|
||||
}
|
||||
@ -747,14 +747,14 @@ init_access (void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* GETLOADAVG_PRIVILEGED */
|
||||
#endif /* GETLOADAVG_PRIVILEGED */
|
||||
|
||||
/* Give the process appropriate permissions for access to
|
||||
user data (i.e., to stat files, or to spawn a child process). */
|
||||
void
|
||||
user_access (void)
|
||||
{
|
||||
#ifdef GETLOADAVG_PRIVILEGED
|
||||
#ifdef GETLOADAVG_PRIVILEGED
|
||||
|
||||
if (!access_inited)
|
||||
init_access ();
|
||||
@ -767,7 +767,7 @@ user_access (void)
|
||||
We now want to set the effective user and group IDs to the real IDs,
|
||||
which are the IDs of the process that exec'd make. */
|
||||
|
||||
#ifdef HAVE_SETEUID
|
||||
#ifdef HAVE_SETEUID
|
||||
|
||||
/* Modern systems have the seteuid/setegid calls which set only the
|
||||
effective IDs, which is ideal. */
|
||||
@ -775,9 +775,9 @@ user_access (void)
|
||||
if (seteuid (user_uid) < 0)
|
||||
pfatal_with_name ("user_access: seteuid");
|
||||
|
||||
#else /* Not HAVE_SETEUID. */
|
||||
#else /* Not HAVE_SETEUID. */
|
||||
|
||||
#ifndef HAVE_SETREUID
|
||||
#ifndef HAVE_SETREUID
|
||||
|
||||
/* System V has only the setuid/setgid calls to set user/group IDs.
|
||||
There is an effective ID, which can be set by setuid/setgid.
|
||||
@ -790,7 +790,7 @@ user_access (void)
|
||||
if (setuid (user_uid) < 0)
|
||||
pfatal_with_name ("user_access: setuid");
|
||||
|
||||
#else /* HAVE_SETREUID. */
|
||||
#else /* HAVE_SETREUID. */
|
||||
|
||||
/* In 4BSD, the setreuid/setregid calls set both the real and effective IDs.
|
||||
They may be set to themselves or each other. So you have two alternatives
|
||||
@ -802,14 +802,14 @@ user_access (void)
|
||||
if (setreuid (make_uid, user_uid) < 0)
|
||||
pfatal_with_name ("user_access: setreuid");
|
||||
|
||||
#endif /* Not HAVE_SETREUID. */
|
||||
#endif /* HAVE_SETEUID. */
|
||||
#endif /* Not HAVE_SETREUID. */
|
||||
#endif /* HAVE_SETEUID. */
|
||||
|
||||
#ifdef HAVE_SETEGID
|
||||
#ifdef HAVE_SETEGID
|
||||
if (setegid (user_gid) < 0)
|
||||
pfatal_with_name ("user_access: setegid");
|
||||
#else
|
||||
#ifndef HAVE_SETREGID
|
||||
#ifndef HAVE_SETREGID
|
||||
if (setgid (user_gid) < 0)
|
||||
pfatal_with_name ("user_access: setgid");
|
||||
#else
|
||||
@ -822,7 +822,7 @@ user_access (void)
|
||||
|
||||
log_access (_("User access"));
|
||||
|
||||
#endif /* GETLOADAVG_PRIVILEGED */
|
||||
#endif /* GETLOADAVG_PRIVILEGED */
|
||||
}
|
||||
|
||||
/* Give the process appropriate permissions for access to
|
||||
@ -830,7 +830,7 @@ user_access (void)
|
||||
void
|
||||
make_access (void)
|
||||
{
|
||||
#ifdef GETLOADAVG_PRIVILEGED
|
||||
#ifdef GETLOADAVG_PRIVILEGED
|
||||
|
||||
if (!access_inited)
|
||||
init_access ();
|
||||
@ -840,11 +840,11 @@ make_access (void)
|
||||
|
||||
/* See comments in user_access, above. */
|
||||
|
||||
#ifdef HAVE_SETEUID
|
||||
#ifdef HAVE_SETEUID
|
||||
if (seteuid (make_uid) < 0)
|
||||
pfatal_with_name ("make_access: seteuid");
|
||||
#else
|
||||
#ifndef HAVE_SETREUID
|
||||
#ifndef HAVE_SETREUID
|
||||
if (setuid (make_uid) < 0)
|
||||
pfatal_with_name ("make_access: setuid");
|
||||
#else
|
||||
@ -853,11 +853,11 @@ make_access (void)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SETEGID
|
||||
#ifdef HAVE_SETEGID
|
||||
if (setegid (make_gid) < 0)
|
||||
pfatal_with_name ("make_access: setegid");
|
||||
#else
|
||||
#ifndef HAVE_SETREGID
|
||||
#ifndef HAVE_SETREGID
|
||||
if (setgid (make_gid) < 0)
|
||||
pfatal_with_name ("make_access: setgid");
|
||||
#else
|
||||
@ -870,7 +870,7 @@ make_access (void)
|
||||
|
||||
log_access (_("Make access"));
|
||||
|
||||
#endif /* GETLOADAVG_PRIVILEGED */
|
||||
#endif /* GETLOADAVG_PRIVILEGED */
|
||||
}
|
||||
|
||||
/* Give the process appropriate permissions for a child process.
|
||||
@ -878,7 +878,7 @@ make_access (void)
|
||||
void
|
||||
child_access (void)
|
||||
{
|
||||
#ifdef GETLOADAVG_PRIVILEGED
|
||||
#ifdef GETLOADAVG_PRIVILEGED
|
||||
|
||||
if (!access_inited)
|
||||
abort ();
|
||||
@ -886,7 +886,7 @@ child_access (void)
|
||||
/* Set both the real and effective UID and GID to the user's.
|
||||
They cannot be changed back to make's. */
|
||||
|
||||
#ifndef HAVE_SETREUID
|
||||
#ifndef HAVE_SETREUID
|
||||
if (setuid (user_uid) < 0)
|
||||
pfatal_with_name ("child_access: setuid");
|
||||
#else
|
||||
@ -894,7 +894,7 @@ child_access (void)
|
||||
pfatal_with_name ("child_access: setreuid");
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SETREGID
|
||||
#ifndef HAVE_SETREGID
|
||||
if (setgid (user_gid) < 0)
|
||||
pfatal_with_name ("child_access: setgid");
|
||||
#else
|
||||
@ -904,7 +904,7 @@ child_access (void)
|
||||
|
||||
log_access (_("Child access"));
|
||||
|
||||
#endif /* GETLOADAVG_PRIVILEGED */
|
||||
#endif /* GETLOADAVG_PRIVILEGED */
|
||||
}
|
||||
|
||||
#ifdef NEED_GET_PATH_MAX
|
||||
@ -917,9 +917,9 @@ get_path_max (void)
|
||||
{
|
||||
long int x = pathconf ("/", _PC_PATH_MAX);
|
||||
if (x > 0)
|
||||
value = x;
|
||||
value = x;
|
||||
else
|
||||
return MAXPATHLEN;
|
||||
return MAXPATHLEN;
|
||||
}
|
||||
|
||||
return value;
|
||||
@ -943,10 +943,10 @@ char *mktemp (char *template);
|
||||
/* Returns a file descriptor to a temporary file. The file is automatically
|
||||
closed/deleted on exit. Don't use a FILE* stream. */
|
||||
int
|
||||
open_tmpfd()
|
||||
open_tmpfd ()
|
||||
{
|
||||
int fd = -1;
|
||||
FILE *tfile = tmpfile();
|
||||
FILE *tfile = tmpfile ();
|
||||
|
||||
if (! tfile)
|
||||
pfatal_with_name ("tmpfile");
|
||||
@ -964,7 +964,7 @@ open_tmpfd()
|
||||
#endif
|
||||
|
||||
FILE *
|
||||
open_tmpfile(char **name, const char *template)
|
||||
open_tmpfile (char **name, const char *template)
|
||||
{
|
||||
#ifdef HAVE_FDOPEN
|
||||
int fd;
|
||||
|
28
read.c
28
read.c
@ -705,7 +705,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
|
||||
/* See if this is a variable assignment. We need to do this early, to
|
||||
allow variables with names like 'ifdef', 'export', 'private', etc. */
|
||||
p = parse_var_assignment(p, &vmod);
|
||||
p = parse_var_assignment (p, &vmod);
|
||||
if (vmod.assign_v)
|
||||
{
|
||||
struct variable *v;
|
||||
@ -960,7 +960,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
was no preceding target, and the line might have been usable as a
|
||||
variable definition. But now we know it is definitely lossage. */
|
||||
if (line[0] == cmd_prefix)
|
||||
fatal(fstart, _("recipe commences before first target"));
|
||||
fatal (fstart, _("recipe commences before first target"));
|
||||
|
||||
/* This line describes some target files. This is complicated by
|
||||
the existence of target-specific variables, because we can't
|
||||
@ -1004,12 +1004,12 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
variable we don't want to expand it. So, walk from the
|
||||
beginning, expanding as we go, and looking for "interesting"
|
||||
chars. The first word is always expandable. */
|
||||
wtype = get_next_mword(line, NULL, &lb_next, &wlen);
|
||||
wtype = get_next_mword (line, NULL, &lb_next, &wlen);
|
||||
switch (wtype)
|
||||
{
|
||||
case w_eol:
|
||||
if (cmdleft != 0)
|
||||
fatal(fstart, _("missing rule before recipe"));
|
||||
fatal (fstart, _("missing rule before recipe"));
|
||||
/* This line contained something but turned out to be nothing
|
||||
but whitespace (a comment?). */
|
||||
continue;
|
||||
@ -1025,7 +1025,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
break;
|
||||
}
|
||||
|
||||
p2 = variable_expand_string(NULL, lb_next, wlen);
|
||||
p2 = variable_expand_string (NULL, lb_next, wlen);
|
||||
|
||||
while (1)
|
||||
{
|
||||
@ -1039,7 +1039,7 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
{
|
||||
unsigned long p2_off = p2 - variable_buffer;
|
||||
unsigned long cmd_off = cmdleft - variable_buffer;
|
||||
char *pend = p2 + strlen(p2);
|
||||
char *pend = p2 + strlen (p2);
|
||||
|
||||
/* Append any remnants of lb, then cut the line short
|
||||
at the semicolon. */
|
||||
@ -1053,14 +1053,14 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
entirely consistent, since we do an unconditional
|
||||
expand below once we know we don't have a
|
||||
target-specific variable. */
|
||||
(void)variable_expand_string(pend, lb_next, (long)-1);
|
||||
lb_next += strlen(lb_next);
|
||||
(void)variable_expand_string (pend, lb_next, (long)-1);
|
||||
lb_next += strlen (lb_next);
|
||||
p2 = variable_buffer + p2_off;
|
||||
cmdleft = variable_buffer + cmd_off + 1;
|
||||
}
|
||||
}
|
||||
|
||||
colonp = find_char_unquote(p2, ':', 0, 0, 0);
|
||||
colonp = find_char_unquote (p2, ':', 0, 0, 0);
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* The drive spec brain-damage strikes again... */
|
||||
/* Note that the only separators of targets in this context
|
||||
@ -1069,18 +1069,18 @@ eval (struct ebuffer *ebuf, int set_default)
|
||||
while (colonp && (colonp[1] == '/' || colonp[1] == '\\') &&
|
||||
colonp > p2 && isalpha ((unsigned char)colonp[-1]) &&
|
||||
(colonp == p2 + 1 || strchr (" \t(", colonp[-2]) != 0))
|
||||
colonp = find_char_unquote(colonp + 1, ':', 0, 0, 0);
|
||||
colonp = find_char_unquote (colonp + 1, ':', 0, 0, 0);
|
||||
#endif
|
||||
if (colonp != 0)
|
||||
break;
|
||||
|
||||
wtype = get_next_mword(lb_next, NULL, &lb_next, &wlen);
|
||||
wtype = get_next_mword (lb_next, NULL, &lb_next, &wlen);
|
||||
if (wtype == w_eol)
|
||||
break;
|
||||
|
||||
p2 += strlen(p2);
|
||||
p2 += strlen (p2);
|
||||
*(p2++) = ' ';
|
||||
p2 = variable_expand_string(p2, lb_next, wlen);
|
||||
p2 = variable_expand_string (p2, lb_next, wlen);
|
||||
/* We don't need to worry about cmdleft here, because if it was
|
||||
found in the variable_buffer the entire buffer has already
|
||||
been expanded... we'll never get here. */
|
||||
@ -1880,7 +1880,7 @@ record_target_var (struct nameseq *filenames, char *defn,
|
||||
if (v->origin != o_override)
|
||||
{
|
||||
struct variable *gv;
|
||||
int len = strlen(v->name);
|
||||
int len = strlen (v->name);
|
||||
|
||||
gv = lookup_variable (v->name, len);
|
||||
if (gv && v != gv
|
||||
|
588
remake.c
588
remake.c
@ -82,8 +82,8 @@ update_goal_chain (struct dep *goals)
|
||||
int t = touch_flag, q = question_flag, n = just_print_flag;
|
||||
int status = -1;
|
||||
|
||||
#define MTIME(file) (rebuilding_makefiles ? file_mtime_no_search (file) \
|
||||
: file_mtime (file))
|
||||
#define MTIME(file) (rebuilding_makefiles ? file_mtime_no_search (file) \
|
||||
: file_mtime (file))
|
||||
|
||||
/* Duplicate the chain so we can remove things from it. */
|
||||
|
||||
@ -120,44 +120,44 @@ update_goal_chain (struct dep *goals)
|
||||
lastgoal = 0;
|
||||
g = goals;
|
||||
while (g != 0)
|
||||
{
|
||||
/* Iterate over all double-colon entries for this file. */
|
||||
struct file *file;
|
||||
int stop = 0, any_not_updated = 0;
|
||||
{
|
||||
/* Iterate over all double-colon entries for this file. */
|
||||
struct file *file;
|
||||
int stop = 0, any_not_updated = 0;
|
||||
|
||||
for (file = g->file->double_colon ? g->file->double_colon : g->file;
|
||||
file != NULL;
|
||||
file = file->prev)
|
||||
{
|
||||
unsigned int ocommands_started;
|
||||
int x;
|
||||
for (file = g->file->double_colon ? g->file->double_colon : g->file;
|
||||
file != NULL;
|
||||
file = file->prev)
|
||||
{
|
||||
unsigned int ocommands_started;
|
||||
int x;
|
||||
|
||||
file->dontcare = g->dontcare;
|
||||
|
||||
check_renamed (file);
|
||||
if (rebuilding_makefiles)
|
||||
{
|
||||
if (file->cmd_target)
|
||||
{
|
||||
touch_flag = t;
|
||||
question_flag = q;
|
||||
just_print_flag = n;
|
||||
}
|
||||
else
|
||||
touch_flag = question_flag = just_print_flag = 0;
|
||||
}
|
||||
check_renamed (file);
|
||||
if (rebuilding_makefiles)
|
||||
{
|
||||
if (file->cmd_target)
|
||||
{
|
||||
touch_flag = t;
|
||||
question_flag = q;
|
||||
just_print_flag = n;
|
||||
}
|
||||
else
|
||||
touch_flag = question_flag = just_print_flag = 0;
|
||||
}
|
||||
|
||||
/* Save the old value of 'commands_started' so we can compare
|
||||
later. It will be incremented when any commands are
|
||||
actually run. */
|
||||
ocommands_started = commands_started;
|
||||
/* Save the old value of 'commands_started' so we can compare
|
||||
later. It will be incremented when any commands are
|
||||
actually run. */
|
||||
ocommands_started = commands_started;
|
||||
|
||||
x = update_file (file, rebuilding_makefiles ? 1 : 0);
|
||||
check_renamed (file);
|
||||
x = update_file (file, rebuilding_makefiles ? 1 : 0);
|
||||
check_renamed (file);
|
||||
|
||||
/* Set the goal's 'changed' flag if any commands were started
|
||||
by calling update_file above. We check this flag below to
|
||||
decide when to give an "up to date" diagnostic. */
|
||||
/* Set the goal's 'changed' flag if any commands were started
|
||||
by calling update_file above. We check this flag below to
|
||||
decide when to give an "up to date" diagnostic. */
|
||||
if (commands_started > ocommands_started)
|
||||
g->changed = 1;
|
||||
|
||||
@ -165,8 +165,8 @@ update_goal_chain (struct dep *goals)
|
||||
1 if updating failed, or to 0 if updating succeeded. Leave
|
||||
STATUS as it is if no updating was done. */
|
||||
|
||||
stop = 0;
|
||||
if ((x != 0 || file->updated) && status < 1)
|
||||
stop = 0;
|
||||
if ((x != 0 || file->updated) && status < 1)
|
||||
{
|
||||
if (file->update_status != 0)
|
||||
{
|
||||
@ -203,56 +203,56 @@ update_goal_chain (struct dep *goals)
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep track if any double-colon entry is not finished.
|
||||
/* Keep track if any double-colon entry is not finished.
|
||||
When they are all finished, the goal is finished. */
|
||||
any_not_updated |= !file->updated;
|
||||
any_not_updated |= !file->updated;
|
||||
|
||||
file->dontcare = 0;
|
||||
|
||||
if (stop)
|
||||
break;
|
||||
}
|
||||
if (stop)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Reset FILE since it is null at the end of the loop. */
|
||||
file = g->file;
|
||||
/* Reset FILE since it is null at the end of the loop. */
|
||||
file = g->file;
|
||||
|
||||
if (stop || !any_not_updated)
|
||||
{
|
||||
/* If we have found nothing whatever to do for the goal,
|
||||
print a message saying nothing needs doing. */
|
||||
if (stop || !any_not_updated)
|
||||
{
|
||||
/* If we have found nothing whatever to do for the goal,
|
||||
print a message saying nothing needs doing. */
|
||||
|
||||
if (!rebuilding_makefiles
|
||||
/* If the update_status is zero, we updated successfully
|
||||
or not at all. G->changed will have been set above if
|
||||
any commands were actually started for this goal. */
|
||||
&& file->update_status == 0 && !g->changed
|
||||
/* Never give a message under -s or -q. */
|
||||
&& !silent_flag && !question_flag)
|
||||
message (1, ((file->phony || file->cmds == 0)
|
||||
? _("Nothing to be done for '%s'.")
|
||||
: _("'%s' is up to date.")),
|
||||
file->name);
|
||||
if (!rebuilding_makefiles
|
||||
/* If the update_status is zero, we updated successfully
|
||||
or not at all. G->changed will have been set above if
|
||||
any commands were actually started for this goal. */
|
||||
&& file->update_status == 0 && !g->changed
|
||||
/* Never give a message under -s or -q. */
|
||||
&& !silent_flag && !question_flag)
|
||||
message (1, ((file->phony || file->cmds == 0)
|
||||
? _("Nothing to be done for '%s'.")
|
||||
: _("'%s' is up to date.")),
|
||||
file->name);
|
||||
|
||||
/* This goal is finished. Remove it from the chain. */
|
||||
if (lastgoal == 0)
|
||||
goals = g->next;
|
||||
else
|
||||
lastgoal->next = g->next;
|
||||
/* This goal is finished. Remove it from the chain. */
|
||||
if (lastgoal == 0)
|
||||
goals = g->next;
|
||||
else
|
||||
lastgoal->next = g->next;
|
||||
|
||||
/* Free the storage. */
|
||||
free (g);
|
||||
/* Free the storage. */
|
||||
free (g);
|
||||
|
||||
g = lastgoal == 0 ? goals : lastgoal->next;
|
||||
g = lastgoal == 0 ? goals : lastgoal->next;
|
||||
|
||||
if (stop)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastgoal = g;
|
||||
g = g->next;
|
||||
}
|
||||
}
|
||||
if (stop)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastgoal = g;
|
||||
g = g->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we reached the end of the dependency graph toggle the considered
|
||||
flag for the next pass. */
|
||||
@ -325,8 +325,8 @@ update_file (struct file *file, unsigned int depth)
|
||||
if (f->command_state == cs_running
|
||||
|| f->command_state == cs_deps_running)
|
||||
{
|
||||
/* Don't run the other :: rules for this
|
||||
file until this rule is finished. */
|
||||
/* Don't run the other :: rules for this
|
||||
file until this rule is finished. */
|
||||
status = 0;
|
||||
break;
|
||||
}
|
||||
@ -413,8 +413,8 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
if (file->updated)
|
||||
{
|
||||
if (file->update_status > 0)
|
||||
{
|
||||
DBF (DB_VERBOSE,
|
||||
{
|
||||
DBF (DB_VERBOSE,
|
||||
_("Recently tried and failed to update file '%s'.\n"));
|
||||
|
||||
/* If the file we tried to make is marked no_diag then no message
|
||||
@ -424,8 +424,8 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
if (file->no_diag && !file->dontcare)
|
||||
complain (file);
|
||||
|
||||
return file->update_status;
|
||||
}
|
||||
return file->update_status;
|
||||
}
|
||||
|
||||
DBF (DB_VERBOSE, _("File '%s' was considered already.\n"));
|
||||
return 0;
|
||||
@ -471,13 +471,13 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
if (noexist)
|
||||
DBF (DB_BASIC, _("File '%s' does not exist.\n"));
|
||||
else if (ORDINARY_MTIME_MIN <= this_mtime && this_mtime <= ORDINARY_MTIME_MAX
|
||||
&& file->low_resolution_time)
|
||||
&& file->low_resolution_time)
|
||||
{
|
||||
/* Avoid spurious rebuilds due to low resolution time stamps. */
|
||||
int ns = FILE_TIMESTAMP_NS (this_mtime);
|
||||
if (ns != 0)
|
||||
error (NILF, _("*** Warning: .LOW_RESOLUTION_TIME file '%s' has a high resolution time stamp"),
|
||||
file->name);
|
||||
error (NILF, _("*** Warning: .LOW_RESOLUTION_TIME file '%s' has a high resolution time stamp"),
|
||||
file->name);
|
||||
this_mtime += FILE_TIMESTAMPS_PER_S - 1 - ns;
|
||||
}
|
||||
|
||||
@ -489,9 +489,9 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
if (!file->phony && file->cmds == 0 && !file->tried_implicit)
|
||||
{
|
||||
if (try_implicit_rule (file, depth))
|
||||
DBF (DB_IMPLICIT, _("Found an implicit rule for '%s'.\n"));
|
||||
DBF (DB_IMPLICIT, _("Found an implicit rule for '%s'.\n"));
|
||||
else
|
||||
DBF (DB_IMPLICIT, _("No implicit rule found for '%s'.\n"));
|
||||
DBF (DB_IMPLICIT, _("No implicit rule found for '%s'.\n"));
|
||||
file->tried_implicit = 1;
|
||||
}
|
||||
if (file->cmds == 0 && !file->is_target
|
||||
@ -597,13 +597,13 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
if (must_make || always_make_flag)
|
||||
{
|
||||
for (d = file->deps; d != 0; d = d->next)
|
||||
if (d->file->intermediate)
|
||||
{
|
||||
if (d->file->intermediate)
|
||||
{
|
||||
int dontcare = 0;
|
||||
|
||||
FILE_TIMESTAMP mtime = file_mtime (d->file);
|
||||
check_renamed (d->file);
|
||||
d->file->parent = file;
|
||||
FILE_TIMESTAMP mtime = file_mtime (d->file);
|
||||
check_renamed (d->file);
|
||||
d->file->parent = file;
|
||||
|
||||
/* Inherit dontcare flag from our parent. */
|
||||
if (rebuilding_makefiles)
|
||||
@ -617,34 +617,34 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
not prune it. */
|
||||
d->file->considered = !considered;
|
||||
|
||||
dep_status |= update_file (d->file, depth);
|
||||
dep_status |= update_file (d->file, depth);
|
||||
|
||||
/* Restore original dontcare flag. */
|
||||
if (rebuilding_makefiles)
|
||||
d->file->dontcare = dontcare;
|
||||
|
||||
check_renamed (d->file);
|
||||
check_renamed (d->file);
|
||||
|
||||
{
|
||||
register struct file *f = d->file;
|
||||
if (f->double_colon)
|
||||
f = f->double_colon;
|
||||
do
|
||||
{
|
||||
running |= (f->command_state == cs_running
|
||||
|| f->command_state == cs_deps_running);
|
||||
f = f->prev;
|
||||
}
|
||||
while (f != 0);
|
||||
}
|
||||
{
|
||||
register struct file *f = d->file;
|
||||
if (f->double_colon)
|
||||
f = f->double_colon;
|
||||
do
|
||||
{
|
||||
running |= (f->command_state == cs_running
|
||||
|| f->command_state == cs_deps_running);
|
||||
f = f->prev;
|
||||
}
|
||||
while (f != 0);
|
||||
}
|
||||
|
||||
if (dep_status != 0 && !keep_going_flag)
|
||||
break;
|
||||
if (dep_status != 0 && !keep_going_flag)
|
||||
break;
|
||||
|
||||
if (!running)
|
||||
d->changed = ((file->phony && file->cmds != 0)
|
||||
|| file_mtime (d->file) != mtime);
|
||||
}
|
||||
if (!running)
|
||||
d->changed = ((file->phony && file->cmds != 0)
|
||||
|| file_mtime (d->file) != mtime);
|
||||
}
|
||||
}
|
||||
|
||||
finish_updating (file);
|
||||
@ -672,8 +672,8 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
DBF (DB_VERBOSE, _("Giving up on target file '%s'.\n"));
|
||||
|
||||
if (depth == 0 && keep_going_flag
|
||||
&& !just_print_flag && !question_flag)
|
||||
error (NILF,
|
||||
&& !just_print_flag && !question_flag)
|
||||
error (NILF,
|
||||
_("Target '%s' not remade because of errors."), file->name);
|
||||
|
||||
return dep_status;
|
||||
@ -703,8 +703,8 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
{
|
||||
#if 1
|
||||
/* %%% In version 4, remove this code completely to
|
||||
implement not remaking deps if their deps are newer
|
||||
than their parents. */
|
||||
implement not remaking deps if their deps are newer
|
||||
than their parents. */
|
||||
if (d_mtime == NONEXISTENT_MTIME && !d->file->intermediate)
|
||||
/* We must remake if this dep does not
|
||||
exist and is not intermediate. */
|
||||
@ -716,11 +716,11 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
}
|
||||
|
||||
/* Set D->changed if either this dep actually changed,
|
||||
or its dependent, FILE, is older or does not exist. */
|
||||
or its dependent, FILE, is older or does not exist. */
|
||||
d->changed |= noexist || d_mtime > this_mtime;
|
||||
|
||||
if (!noexist && ISDB (DB_BASIC|DB_VERBOSE))
|
||||
{
|
||||
{
|
||||
const char *fmt = 0;
|
||||
|
||||
if (d->ignore_mtime)
|
||||
@ -733,7 +733,7 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
if (ISDB (DB_BASIC))
|
||||
fmt = _("Prerequisite '%s' of target '%s' does not exist.\n");
|
||||
}
|
||||
else if (d->changed)
|
||||
else if (d->changed)
|
||||
{
|
||||
if (ISDB (DB_BASIC))
|
||||
fmt = _("Prerequisite '%s' is newer than target '%s'.\n");
|
||||
@ -747,7 +747,7 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
printf (fmt, dep_name (d), file->name);
|
||||
fflush (stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Here depth returns to the value it had when we were called. */
|
||||
@ -803,7 +803,7 @@ update_file_1 (struct file *file, unsigned int depth)
|
||||
|
||||
/* It needs to be remade. If it's VPATH and not reset via GPATH, toss the
|
||||
VPATH. */
|
||||
if (!streq(file->name, file->hname))
|
||||
if (!streq (file->name, file->hname))
|
||||
{
|
||||
DB (DB_BASIC, (_(" Ignoring VPATH name '%s'.\n"), file->hname));
|
||||
file->ignore_vpath = 1;
|
||||
@ -856,29 +856,29 @@ notice_finished_file (struct file *file)
|
||||
|
||||
if (touch_flag
|
||||
/* The update status will be:
|
||||
-1 if this target was not remade;
|
||||
0 if 0 or more commands (+ or ${MAKE}) were run and won;
|
||||
1 if some commands were run and lost.
|
||||
We touch the target if it has commands which either were not run
|
||||
or won when they ran (i.e. status is 0). */
|
||||
-1 if this target was not remade;
|
||||
0 if 0 or more commands (+ or ${MAKE}) were run and won;
|
||||
1 if some commands were run and lost.
|
||||
We touch the target if it has commands which either were not run
|
||||
or won when they ran (i.e. status is 0). */
|
||||
&& file->update_status == 0)
|
||||
{
|
||||
if (file->cmds != 0 && file->cmds->any_recurse)
|
||||
{
|
||||
/* If all the command lines were recursive,
|
||||
we don't want to do the touching. */
|
||||
unsigned int i;
|
||||
for (i = 0; i < file->cmds->ncommand_lines; ++i)
|
||||
if (!(file->cmds->lines_flags[i] & COMMANDS_RECURSE))
|
||||
goto have_nonrecursing;
|
||||
}
|
||||
{
|
||||
/* If all the command lines were recursive,
|
||||
we don't want to do the touching. */
|
||||
unsigned int i;
|
||||
for (i = 0; i < file->cmds->ncommand_lines; ++i)
|
||||
if (!(file->cmds->lines_flags[i] & COMMANDS_RECURSE))
|
||||
goto have_nonrecursing;
|
||||
}
|
||||
else
|
||||
{
|
||||
have_nonrecursing:
|
||||
if (file->phony)
|
||||
file->update_status = 0;
|
||||
{
|
||||
have_nonrecursing:
|
||||
if (file->phony)
|
||||
file->update_status = 0;
|
||||
/* According to POSIX, -t doesn't affect targets with no cmds. */
|
||||
else if (file->cmds != 0)
|
||||
else if (file->cmds != 0)
|
||||
{
|
||||
/* Should set file's modification date and do nothing else. */
|
||||
file->update_status = touch_file (file);
|
||||
@ -893,7 +893,7 @@ notice_finished_file (struct file *file)
|
||||
updating logic below. */
|
||||
touched = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (file->mtime_before_update == UNKNOWN_MTIME)
|
||||
@ -917,7 +917,7 @@ notice_finished_file (struct file *file)
|
||||
/* If there were no commands at all, it's always new. */
|
||||
|
||||
else if (file->is_target && file->cmds == 0)
|
||||
i = 1;
|
||||
i = 1;
|
||||
|
||||
file->last_mtime = i == 0 ? UNKNOWN_MTIME : NEW_MTIME;
|
||||
}
|
||||
@ -957,16 +957,16 @@ notice_finished_file (struct file *file)
|
||||
So mark them as updated with the same status. */
|
||||
for (d = file->also_make; d != 0; d = d->next)
|
||||
{
|
||||
d->file->command_state = cs_finished;
|
||||
d->file->updated = 1;
|
||||
d->file->update_status = file->update_status;
|
||||
d->file->command_state = cs_finished;
|
||||
d->file->updated = 1;
|
||||
d->file->update_status = file->update_status;
|
||||
|
||||
if (ran && !d->file->phony)
|
||||
/* Fetch the new modification time.
|
||||
We do this instead of just invalidating the cached time
|
||||
so that a vpath_search can happen. Otherwise, it would
|
||||
never be done because the target is already updated. */
|
||||
f_mtime (d->file, 0);
|
||||
if (ran && !d->file->phony)
|
||||
/* Fetch the new modification time.
|
||||
We do this instead of just invalidating the cached time
|
||||
so that a vpath_search can happen. Otherwise, it would
|
||||
never be done because the target is already updated. */
|
||||
f_mtime (d->file, 0);
|
||||
}
|
||||
else if (file->update_status == -1)
|
||||
/* Nothing was done for FILE, but it needed nothing done.
|
||||
@ -1005,7 +1005,7 @@ check_dep (struct file *file, unsigned int depth,
|
||||
mtime = file_mtime (file);
|
||||
check_renamed (file);
|
||||
if (mtime == NONEXISTENT_MTIME || mtime > this_mtime)
|
||||
*must_make_ptr = 1;
|
||||
*must_make_ptr = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1013,19 +1013,19 @@ check_dep (struct file *file, unsigned int depth,
|
||||
FILE_TIMESTAMP mtime;
|
||||
|
||||
if (!file->phony && file->cmds == 0 && !file->tried_implicit)
|
||||
{
|
||||
if (try_implicit_rule (file, depth))
|
||||
DBF (DB_IMPLICIT, _("Found an implicit rule for '%s'.\n"));
|
||||
else
|
||||
DBF (DB_IMPLICIT, _("No implicit rule found for '%s'.\n"));
|
||||
file->tried_implicit = 1;
|
||||
}
|
||||
{
|
||||
if (try_implicit_rule (file, depth))
|
||||
DBF (DB_IMPLICIT, _("Found an implicit rule for '%s'.\n"));
|
||||
else
|
||||
DBF (DB_IMPLICIT, _("No implicit rule found for '%s'.\n"));
|
||||
file->tried_implicit = 1;
|
||||
}
|
||||
if (file->cmds == 0 && !file->is_target
|
||||
&& default_file != 0 && default_file->cmds != 0)
|
||||
{
|
||||
DBF (DB_IMPLICIT, _("Using default commands for '%s'.\n"));
|
||||
file->cmds = default_file->cmds;
|
||||
}
|
||||
&& default_file != 0 && default_file->cmds != 0)
|
||||
{
|
||||
DBF (DB_IMPLICIT, _("Using default commands for '%s'.\n"));
|
||||
file->cmds = default_file->cmds;
|
||||
}
|
||||
|
||||
check_renamed (file);
|
||||
mtime = file_mtime (file);
|
||||
@ -1033,13 +1033,13 @@ check_dep (struct file *file, unsigned int depth,
|
||||
if (mtime != NONEXISTENT_MTIME && mtime > this_mtime)
|
||||
/* If the intermediate file actually exists and is newer, then we
|
||||
should remake from it. */
|
||||
*must_make_ptr = 1;
|
||||
*must_make_ptr = 1;
|
||||
else
|
||||
{
|
||||
{
|
||||
/* Otherwise, update all non-intermediate files we depend on, if
|
||||
necessary, and see whether any of them is more recent than the
|
||||
file on whose behalf we are checking. */
|
||||
struct dep *ld;
|
||||
struct dep *ld;
|
||||
int deps_running = 0;
|
||||
|
||||
/* If this target is not running, set it's state so that we check it
|
||||
@ -1055,55 +1055,55 @@ check_dep (struct file *file, unsigned int depth,
|
||||
set_command_state (file, cs_not_started);
|
||||
}
|
||||
|
||||
ld = 0;
|
||||
d = file->deps;
|
||||
while (d != 0)
|
||||
{
|
||||
ld = 0;
|
||||
d = file->deps;
|
||||
while (d != 0)
|
||||
{
|
||||
int maybe_make;
|
||||
|
||||
if (is_updating (d->file))
|
||||
{
|
||||
error (NILF, _("Circular %s <- %s dependency dropped."),
|
||||
file->name, d->file->name);
|
||||
if (ld == 0)
|
||||
{
|
||||
file->deps = d->next;
|
||||
if (is_updating (d->file))
|
||||
{
|
||||
error (NILF, _("Circular %s <- %s dependency dropped."),
|
||||
file->name, d->file->name);
|
||||
if (ld == 0)
|
||||
{
|
||||
file->deps = d->next;
|
||||
free_dep (d);
|
||||
d = file->deps;
|
||||
}
|
||||
else
|
||||
{
|
||||
ld->next = d->next;
|
||||
d = file->deps;
|
||||
}
|
||||
else
|
||||
{
|
||||
ld->next = d->next;
|
||||
free_dep (d);
|
||||
d = ld->next;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
d = ld->next;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
d->file->parent = file;
|
||||
d->file->parent = file;
|
||||
maybe_make = *must_make_ptr;
|
||||
dep_status |= check_dep (d->file, depth, this_mtime,
|
||||
dep_status |= check_dep (d->file, depth, this_mtime,
|
||||
&maybe_make);
|
||||
if (! d->ignore_mtime)
|
||||
*must_make_ptr = maybe_make;
|
||||
check_renamed (d->file);
|
||||
if (dep_status != 0 && !keep_going_flag)
|
||||
break;
|
||||
check_renamed (d->file);
|
||||
if (dep_status != 0 && !keep_going_flag)
|
||||
break;
|
||||
|
||||
if (d->file->command_state == cs_running
|
||||
|| d->file->command_state == cs_deps_running)
|
||||
deps_running = 1;
|
||||
if (d->file->command_state == cs_running
|
||||
|| d->file->command_state == cs_deps_running)
|
||||
deps_running = 1;
|
||||
|
||||
ld = d;
|
||||
d = d->next;
|
||||
}
|
||||
ld = d;
|
||||
d = d->next;
|
||||
}
|
||||
|
||||
if (deps_running)
|
||||
/* Record that some of FILE's deps are still being made.
|
||||
This tells the upper levels to wait on processing it until the
|
||||
commands are finished. */
|
||||
set_command_state (file, cs_deps_running);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
finish_updating (file);
|
||||
@ -1126,7 +1126,7 @@ touch_file (struct file *file)
|
||||
if (just_print_flag)
|
||||
return 0;
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
#ifndef NO_ARCHIVES
|
||||
if (ar_name (file->name))
|
||||
return ar_touch (file->name);
|
||||
else
|
||||
@ -1135,34 +1135,34 @@ touch_file (struct file *file)
|
||||
int fd = open (file->name, O_RDWR | O_CREAT, 0666);
|
||||
|
||||
if (fd < 0)
|
||||
TOUCH_ERROR ("touch: open: ");
|
||||
TOUCH_ERROR ("touch: open: ");
|
||||
else
|
||||
{
|
||||
struct stat statbuf;
|
||||
char buf = 'x';
|
||||
{
|
||||
struct stat statbuf;
|
||||
char buf = 'x';
|
||||
int e;
|
||||
|
||||
EINTRLOOP (e, fstat (fd, &statbuf));
|
||||
if (e < 0)
|
||||
TOUCH_ERROR ("touch: fstat: ");
|
||||
/* Rewrite character 0 same as it already is. */
|
||||
if (read (fd, &buf, 1) < 0)
|
||||
TOUCH_ERROR ("touch: read: ");
|
||||
if (lseek (fd, 0L, 0) < 0L)
|
||||
TOUCH_ERROR ("touch: lseek: ");
|
||||
if (write (fd, &buf, 1) < 0)
|
||||
TOUCH_ERROR ("touch: write: ");
|
||||
/* If file length was 0, we just
|
||||
changed it, so change it back. */
|
||||
if (statbuf.st_size == 0)
|
||||
{
|
||||
(void) close (fd);
|
||||
fd = open (file->name, O_RDWR | O_TRUNC, 0666);
|
||||
if (fd < 0)
|
||||
TOUCH_ERROR ("touch: open: ");
|
||||
}
|
||||
(void) close (fd);
|
||||
}
|
||||
if (e < 0)
|
||||
TOUCH_ERROR ("touch: fstat: ");
|
||||
/* Rewrite character 0 same as it already is. */
|
||||
if (read (fd, &buf, 1) < 0)
|
||||
TOUCH_ERROR ("touch: read: ");
|
||||
if (lseek (fd, 0L, 0) < 0L)
|
||||
TOUCH_ERROR ("touch: lseek: ");
|
||||
if (write (fd, &buf, 1) < 0)
|
||||
TOUCH_ERROR ("touch: write: ");
|
||||
/* If file length was 0, we just
|
||||
changed it, so change it back. */
|
||||
if (statbuf.st_size == 0)
|
||||
{
|
||||
(void) close (fd);
|
||||
fd = open (file->name, O_RDWR | O_TRUNC, 0666);
|
||||
if (fd < 0)
|
||||
TOUCH_ERROR ("touch: open: ");
|
||||
}
|
||||
(void) close (fd);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1178,12 +1178,12 @@ remake_file (struct file *file)
|
||||
if (file->cmds == 0)
|
||||
{
|
||||
if (file->phony)
|
||||
/* Phony target. Pretend it succeeded. */
|
||||
file->update_status = 0;
|
||||
/* Phony target. Pretend it succeeded. */
|
||||
file->update_status = 0;
|
||||
else if (file->is_target)
|
||||
/* This is a nonexistent target file we cannot make.
|
||||
Pretend it was successfully remade. */
|
||||
file->update_status = 0;
|
||||
/* This is a nonexistent target file we cannot make.
|
||||
Pretend it was successfully remade. */
|
||||
file->update_status = 0;
|
||||
else
|
||||
{
|
||||
/* This is a dependency file we cannot remake. Fail. */
|
||||
@ -1198,10 +1198,10 @@ remake_file (struct file *file)
|
||||
|
||||
/* The normal case: start some commands. */
|
||||
if (!touch_flag || file->cmds->any_recurse)
|
||||
{
|
||||
execute_file_commands (file);
|
||||
return;
|
||||
}
|
||||
{
|
||||
execute_file_commands (file);
|
||||
return;
|
||||
}
|
||||
|
||||
/* This tells notice_finished_file it is ok to touch the file. */
|
||||
file->update_status = 0;
|
||||
@ -1226,7 +1226,7 @@ f_mtime (struct file *file, int search)
|
||||
|
||||
/* File's mtime is not known; must get it from the system. */
|
||||
|
||||
#ifndef NO_ARCHIVES
|
||||
#ifndef NO_ARCHIVES
|
||||
if (ar_name (file->name))
|
||||
{
|
||||
/* This file is an archive-member reference. */
|
||||
@ -1239,29 +1239,29 @@ f_mtime (struct file *file, int search)
|
||||
ar_parse_name (file->name, &arname, &memname);
|
||||
|
||||
/* Find the modification time of the archive itself.
|
||||
Also allow for its name to be changed via VPATH search. */
|
||||
Also allow for its name to be changed via VPATH search. */
|
||||
arfile = lookup_file (arname);
|
||||
if (arfile == 0)
|
||||
arfile = enter_file (strcache_add (arname));
|
||||
mtime = f_mtime (arfile, search);
|
||||
check_renamed (arfile);
|
||||
if (search && strcmp (arfile->hname, arname))
|
||||
{
|
||||
/* The archive's name has changed.
|
||||
Change the archive-member reference accordingly. */
|
||||
{
|
||||
/* The archive's name has changed.
|
||||
Change the archive-member reference accordingly. */
|
||||
|
||||
char *name;
|
||||
unsigned int arlen, memlen;
|
||||
unsigned int arlen, memlen;
|
||||
|
||||
arlen = strlen (arfile->hname);
|
||||
memlen = strlen (memname);
|
||||
arlen = strlen (arfile->hname);
|
||||
memlen = strlen (memname);
|
||||
|
||||
name = xmalloc (arlen + 1 + memlen + 2);
|
||||
memcpy (name, arfile->hname, arlen);
|
||||
name[arlen] = '(';
|
||||
memcpy (name + arlen + 1, memname, memlen);
|
||||
name[arlen + 1 + memlen] = ')';
|
||||
name[arlen + 1 + memlen + 1] = '\0';
|
||||
name = xmalloc (arlen + 1 + memlen + 2);
|
||||
memcpy (name, arfile->hname, arlen);
|
||||
name[arlen] = '(';
|
||||
memcpy (name + arlen + 1, memname, memlen);
|
||||
name[arlen + 1 + memlen] = ')';
|
||||
name[arlen + 1 + memlen + 1] = '\0';
|
||||
|
||||
/* If the archive was found with GPATH, make the change permanent;
|
||||
otherwise defer it until later. */
|
||||
@ -1270,15 +1270,15 @@ f_mtime (struct file *file, int search)
|
||||
else
|
||||
rehash_file (file, name);
|
||||
check_renamed (file);
|
||||
}
|
||||
}
|
||||
|
||||
free (arname);
|
||||
|
||||
file->low_resolution_time = 1;
|
||||
|
||||
if (mtime == NONEXISTENT_MTIME)
|
||||
/* The archive doesn't exist, so its members don't exist either. */
|
||||
return NONEXISTENT_MTIME;
|
||||
/* The archive doesn't exist, so its members don't exist either. */
|
||||
return NONEXISTENT_MTIME;
|
||||
|
||||
member_date = ar_member_date (file->hname);
|
||||
mtime = (member_date == (time_t) -1
|
||||
@ -1291,37 +1291,37 @@ f_mtime (struct file *file, int search)
|
||||
mtime = name_mtime (file->name);
|
||||
|
||||
if (mtime == NONEXISTENT_MTIME && search && !file->ignore_vpath)
|
||||
{
|
||||
/* If name_mtime failed, search VPATH. */
|
||||
const char *name = vpath_search (file->name, &mtime, NULL, NULL);
|
||||
if (name
|
||||
/* Last resort, is it a library (-lxxx)? */
|
||||
|| (file->name[0] == '-' && file->name[1] == 'l'
|
||||
&& (name = library_search (file->name, &mtime)) != 0))
|
||||
{
|
||||
if (mtime != UNKNOWN_MTIME)
|
||||
/* vpath_search and library_search store UNKNOWN_MTIME
|
||||
if they didn't need to do a stat call for their work. */
|
||||
file->last_mtime = mtime;
|
||||
{
|
||||
/* If name_mtime failed, search VPATH. */
|
||||
const char *name = vpath_search (file->name, &mtime, NULL, NULL);
|
||||
if (name
|
||||
/* Last resort, is it a library (-lxxx)? */
|
||||
|| (file->name[0] == '-' && file->name[1] == 'l'
|
||||
&& (name = library_search (file->name, &mtime)) != 0))
|
||||
{
|
||||
if (mtime != UNKNOWN_MTIME)
|
||||
/* vpath_search and library_search store UNKNOWN_MTIME
|
||||
if they didn't need to do a stat call for their work. */
|
||||
file->last_mtime = mtime;
|
||||
|
||||
/* If we found it in VPATH, see if it's in GPATH too; if so,
|
||||
change the name right now; if not, defer until after the
|
||||
dependencies are updated. */
|
||||
if (gpath_search (name, strlen(name) - strlen(file->name) - 1))
|
||||
if (gpath_search (name, strlen (name) - strlen (file->name) - 1))
|
||||
{
|
||||
rename_file (file, name);
|
||||
check_renamed (file);
|
||||
return file_mtime (file);
|
||||
}
|
||||
|
||||
rehash_file (file, name);
|
||||
check_renamed (file);
|
||||
rehash_file (file, name);
|
||||
check_renamed (file);
|
||||
/* If the result of a vpath search is -o or -W, preserve it.
|
||||
Otherwise, find the mtime of the resulting file. */
|
||||
if (mtime != OLD_MTIME && mtime != NEW_MTIME)
|
||||
mtime = name_mtime (name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Files can have bogus timestamps that nothing newly made will be
|
||||
@ -1395,14 +1395,14 @@ f_mtime (struct file *file, int search)
|
||||
do
|
||||
{
|
||||
/* If this file is not implicit but it is intermediate then it was
|
||||
made so by the .INTERMEDIATE target. If this file has never
|
||||
been built by us but was found now, it existed before make
|
||||
started. So, turn off the intermediate bit so make doesn't
|
||||
delete it, since it didn't create it. */
|
||||
made so by the .INTERMEDIATE target. If this file has never
|
||||
been built by us but was found now, it existed before make
|
||||
started. So, turn off the intermediate bit so make doesn't
|
||||
delete it, since it didn't create it. */
|
||||
if (mtime != NONEXISTENT_MTIME && file->command_state == cs_not_started
|
||||
&& file->command_state == cs_not_started
|
||||
&& !file->tried_implicit && file->intermediate)
|
||||
file->intermediate = 0;
|
||||
&& file->command_state == cs_not_started
|
||||
&& !file->tried_implicit && file->intermediate)
|
||||
file->intermediate = 0;
|
||||
|
||||
file->last_mtime = mtime;
|
||||
file = file->prev;
|
||||
@ -1532,7 +1532,7 @@ library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr)
|
||||
*/
|
||||
#define LIBDIR "."
|
||||
#endif
|
||||
LIBDIR, /* Defined by configuration. */
|
||||
LIBDIR, /* Defined by configuration. */
|
||||
0
|
||||
};
|
||||
|
||||
@ -1571,34 +1571,34 @@ library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr)
|
||||
|
||||
/* Expand the pattern using LIB as a replacement. */
|
||||
{
|
||||
char c = p[len];
|
||||
char *p3, *p4;
|
||||
char c = p[len];
|
||||
char *p3, *p4;
|
||||
|
||||
p[len] = '\0';
|
||||
p3 = find_percent (p);
|
||||
if (!p3)
|
||||
{
|
||||
/* Give a warning if there is no pattern. */
|
||||
error (NILF, _(".LIBPATTERNS element '%s' is not a pattern"), p);
|
||||
p[len] = '\0';
|
||||
p3 = find_percent (p);
|
||||
if (!p3)
|
||||
{
|
||||
/* Give a warning if there is no pattern. */
|
||||
error (NILF, _(".LIBPATTERNS element '%s' is not a pattern"), p);
|
||||
p[len] = c;
|
||||
continue;
|
||||
}
|
||||
p4 = variable_buffer_output (libbuf, p, p3-p);
|
||||
p4 = variable_buffer_output (p4, lib, liblen);
|
||||
p4 = variable_buffer_output (p4, p3+1, len - (p3-p));
|
||||
p[len] = c;
|
||||
continue;
|
||||
}
|
||||
p4 = variable_buffer_output (libbuf, p, p3-p);
|
||||
p4 = variable_buffer_output (p4, lib, liblen);
|
||||
p4 = variable_buffer_output (p4, p3+1, len - (p3-p));
|
||||
p[len] = c;
|
||||
}
|
||||
|
||||
/* Look first for 'libNAME.a' in the current directory. */
|
||||
mtime = name_mtime (libbuf);
|
||||
if (mtime != NONEXISTENT_MTIME)
|
||||
{
|
||||
if (mtime_ptr != 0)
|
||||
*mtime_ptr = mtime;
|
||||
file = strcache_add (libbuf);
|
||||
{
|
||||
if (mtime_ptr != 0)
|
||||
*mtime_ptr = mtime;
|
||||
file = strcache_add (libbuf);
|
||||
/* This by definition will have the best index, so stop now. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now try VPATH search on that. */
|
||||
|
||||
@ -1635,7 +1635,7 @@ library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr)
|
||||
std_dirs++;
|
||||
}
|
||||
buflen = strlen (libbuf);
|
||||
buf = xmalloc(libdir_maxlen + buflen + 2);
|
||||
buf = xmalloc (libdir_maxlen + buflen + 2);
|
||||
}
|
||||
else if (buflen < strlen (libbuf))
|
||||
{
|
||||
@ -1649,11 +1649,11 @@ library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr)
|
||||
unsigned int vpath_index = ~((unsigned int)0) - std_dirs;
|
||||
|
||||
for (dp = dirs; *dp != 0; ++dp)
|
||||
{
|
||||
{
|
||||
sprintf (buf, "%s/%s", *dp, libbuf);
|
||||
mtime = name_mtime (buf);
|
||||
if (mtime != NONEXISTENT_MTIME)
|
||||
{
|
||||
{
|
||||
if (file == 0 || vpath_index < best_vpath)
|
||||
{
|
||||
file = strcache_add (buf);
|
||||
|
@ -34,7 +34,7 @@ char *remote_description = "Customs";
|
||||
|
||||
/* File name of the Customs 'export' client command.
|
||||
A full path name can be used to avoid some path-searching overhead. */
|
||||
#define EXPORT_COMMAND "/usr/local/bin/export"
|
||||
#define EXPORT_COMMAND "/usr/local/bin/export"
|
||||
|
||||
/* ExportPermit gotten by start_remote_job_p, and used by start_remote_job. */
|
||||
static ExportPermit permit;
|
||||
@ -76,11 +76,11 @@ start_remote_job_p (int first_p)
|
||||
}
|
||||
|
||||
/* For secure Customs, make is installed setuid root and
|
||||
Customs requires a privileged source port be used. */
|
||||
Customs requires a privileged source port be used. */
|
||||
make_access ();
|
||||
|
||||
if (ISDB (DB_JOBS))
|
||||
Rpc_Debug(1);
|
||||
Rpc_Debug (1);
|
||||
|
||||
/* Ping the daemon once to see if it is there. */
|
||||
inited = Customs_Ping () == RPC_SUCCESS ? 1 : -1;
|
||||
@ -89,20 +89,20 @@ start_remote_job_p (int first_p)
|
||||
user_access ();
|
||||
|
||||
if (starting_directory == 0)
|
||||
/* main couldn't figure it out. */
|
||||
inited = -1;
|
||||
/* main couldn't figure it out. */
|
||||
inited = -1;
|
||||
else
|
||||
{
|
||||
/* Normalize the current directory path name to something
|
||||
that should work on all machines exported to. */
|
||||
{
|
||||
/* Normalize the current directory path name to something
|
||||
that should work on all machines exported to. */
|
||||
|
||||
normalized_cwd = xmalloc (GET_PATH_MAX);
|
||||
strcpy (normalized_cwd, starting_directory);
|
||||
if (Customs_NormPath (normalized_cwd, GET_PATH_MAX) < 0)
|
||||
/* Path normalization failure means using Customs
|
||||
won't work, but it's not really an error. */
|
||||
inited = -1;
|
||||
}
|
||||
normalized_cwd = xmalloc (GET_PATH_MAX);
|
||||
strcpy (normalized_cwd, starting_directory);
|
||||
if (Customs_NormPath (normalized_cwd, GET_PATH_MAX) < 0)
|
||||
/* Path normalization failure means using Customs
|
||||
won't work, but it's not really an error. */
|
||||
inited = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (inited < 0)
|
||||
@ -110,7 +110,7 @@ start_remote_job_p (int first_p)
|
||||
|
||||
njobs = job_slots_used;
|
||||
if (!first_p)
|
||||
njobs -= 1; /* correction for being called from reap_children() */
|
||||
njobs -= 1; /* correction for being called from reap_children() */
|
||||
|
||||
/* the first job should run locally, or, if the -l flag is given, we use
|
||||
that as clue as to how many local jobs should be scheduled locally */
|
||||
@ -171,7 +171,7 @@ start_remote_job (char **argv, char **envp, int stdin_fd,
|
||||
|
||||
/* Create a WayBill to give to the server. */
|
||||
len = Customs_MakeWayBill (&permit, normalized_cwd, argv[0], argv,
|
||||
envp, retport, waybill);
|
||||
envp, retport, waybill);
|
||||
|
||||
/* Modify the waybill as if the remote child had done 'child_access ()'. */
|
||||
{
|
||||
@ -187,11 +187,11 @@ start_remote_job (char **argv, char **envp, int stdin_fd,
|
||||
sin.sin_port = htons (Customs_Port ());
|
||||
sin.sin_addr = permit.addr;
|
||||
status = Rpc_Call (sock, &sin, (Rpc_Proc) CUSTOMS_IMPORT,
|
||||
len, (Rpc_Opaque) waybill,
|
||||
sizeof(msg), (Rpc_Opaque) msg,
|
||||
1, &timeout);
|
||||
len, (Rpc_Opaque) waybill,
|
||||
sizeof (msg), (Rpc_Opaque) msg,
|
||||
1, &timeout);
|
||||
|
||||
host = gethostbyaddr((char *)&permit.addr, sizeof(permit.addr), AF_INET);
|
||||
host = gethostbyaddr ((char *)&permit.addr, sizeof(permit.addr), AF_INET);
|
||||
|
||||
if (status != RPC_SUCCESS)
|
||||
{
|
||||
@ -214,8 +214,8 @@ start_remote_job (char **argv, char **envp, int stdin_fd,
|
||||
else
|
||||
{
|
||||
error (NILF, "*** exported to %s (id %u)",
|
||||
host ? host->h_name : inet_ntoa (permit.addr),
|
||||
permit.id);
|
||||
host ? host->h_name : inet_ntoa (permit.addr),
|
||||
permit.id);
|
||||
}
|
||||
|
||||
fflush (stdout);
|
||||
@ -233,7 +233,7 @@ start_remote_job (char **argv, char **envp, int stdin_fd,
|
||||
/* Child side. Run 'export' to handle the connection. */
|
||||
static char sock_buf[20], retsock_buf[20], id_buf[20];
|
||||
static char *new_argv[6] =
|
||||
{ EXPORT_COMMAND, "-id", sock_buf, retsock_buf, id_buf, 0 };
|
||||
{ EXPORT_COMMAND, "-id", sock_buf, retsock_buf, id_buf, 0 };
|
||||
|
||||
/* Set up the arguments. */
|
||||
(void) sprintf (sock_buf, "%d", sock);
|
||||
@ -242,7 +242,7 @@ start_remote_job (char **argv, char **envp, int stdin_fd,
|
||||
|
||||
/* Get the right stdin. */
|
||||
if (stdin_fd != 0)
|
||||
(void) dup2 (stdin_fd, 0);
|
||||
(void) dup2 (stdin_fd, 0);
|
||||
|
||||
/* Unblock signals in the child. */
|
||||
unblock_sigs ();
|
||||
|
182
rule.c
182
rule.c
@ -87,10 +87,10 @@ count_implicit_rule_limits (void)
|
||||
++num_pattern_rules;
|
||||
|
||||
if (rule->num > max_pattern_targets)
|
||||
max_pattern_targets = rule->num;
|
||||
max_pattern_targets = rule->num;
|
||||
|
||||
for (dep = rule->deps; dep != 0; dep = dep->next)
|
||||
{
|
||||
{
|
||||
const char *dname = dep_name (dep);
|
||||
unsigned int len = strlen (dname);
|
||||
|
||||
@ -106,36 +106,36 @@ count_implicit_rule_limits (void)
|
||||
#endif
|
||||
ndeps++;
|
||||
|
||||
if (len > max_pattern_dep_length)
|
||||
max_pattern_dep_length = len;
|
||||
if (len > max_pattern_dep_length)
|
||||
max_pattern_dep_length = len;
|
||||
|
||||
if (p != 0 && p2 > p)
|
||||
{
|
||||
/* There is a slash before the % in the dep name.
|
||||
Extract the directory name. */
|
||||
if (p == dname)
|
||||
++p;
|
||||
if (p - dname > namelen)
|
||||
{
|
||||
namelen = p - dname;
|
||||
name = xrealloc (name, namelen + 1);
|
||||
}
|
||||
memcpy (name, dname, p - dname);
|
||||
name[p - dname] = '\0';
|
||||
if (p != 0 && p2 > p)
|
||||
{
|
||||
/* There is a slash before the % in the dep name.
|
||||
Extract the directory name. */
|
||||
if (p == dname)
|
||||
++p;
|
||||
if (p - dname > namelen)
|
||||
{
|
||||
namelen = p - dname;
|
||||
name = xrealloc (name, namelen + 1);
|
||||
}
|
||||
memcpy (name, dname, p - dname);
|
||||
name[p - dname] = '\0';
|
||||
|
||||
/* In the deps of an implicit rule the 'changed' flag
|
||||
actually indicates that the dependency is in a
|
||||
nonexistent subdirectory. */
|
||||
/* In the deps of an implicit rule the 'changed' flag
|
||||
actually indicates that the dependency is in a
|
||||
nonexistent subdirectory. */
|
||||
|
||||
dep->changed = !dir_file_exists_p (name, "");
|
||||
}
|
||||
else
|
||||
/* This dependency does not reside in a subdirectory. */
|
||||
dep->changed = 0;
|
||||
}
|
||||
dep->changed = !dir_file_exists_p (name, "");
|
||||
}
|
||||
else
|
||||
/* This dependency does not reside in a subdirectory. */
|
||||
dep->changed = 0;
|
||||
}
|
||||
|
||||
if (ndeps > max_pattern_deps)
|
||||
max_pattern_deps = ndeps;
|
||||
max_pattern_deps = ndeps;
|
||||
|
||||
rule = next;
|
||||
}
|
||||
@ -217,7 +217,7 @@ convert_to_pattern (void)
|
||||
{
|
||||
unsigned int l = strlen (dep_name (d));
|
||||
if (l > maxsuffix)
|
||||
maxsuffix = l;
|
||||
maxsuffix = l;
|
||||
}
|
||||
|
||||
/* Space to construct the suffix rule target name. */
|
||||
@ -228,12 +228,12 @@ convert_to_pattern (void)
|
||||
unsigned int slen;
|
||||
|
||||
/* Make a rule that is just the suffix, with no deps or commands.
|
||||
This rule exists solely to disqualify match-anything rules. */
|
||||
This rule exists solely to disqualify match-anything rules. */
|
||||
convert_suffix_rule (dep_name (d), 0, 0);
|
||||
|
||||
if (d->file->cmds != 0)
|
||||
/* Record a pattern for this suffix's null-suffix rule. */
|
||||
convert_suffix_rule ("", dep_name (d), d->file->cmds);
|
||||
/* Record a pattern for this suffix's null-suffix rule. */
|
||||
convert_suffix_rule ("", dep_name (d), d->file->cmds);
|
||||
|
||||
/* Add every other suffix to this one and see if it exists as a
|
||||
two-suffix rule. */
|
||||
@ -241,32 +241,32 @@ convert_to_pattern (void)
|
||||
memcpy (rulename, dep_name (d), slen);
|
||||
|
||||
for (d2 = suffix_file->deps; d2 != 0; d2 = d2->next)
|
||||
{
|
||||
{
|
||||
struct file *f;
|
||||
unsigned int s2len;
|
||||
|
||||
s2len = strlen (dep_name (d2));
|
||||
s2len = strlen (dep_name (d2));
|
||||
|
||||
/* Can't build something from itself. */
|
||||
if (slen == s2len && streq (dep_name (d), dep_name (d2)))
|
||||
continue;
|
||||
if (slen == s2len && streq (dep_name (d), dep_name (d2)))
|
||||
continue;
|
||||
|
||||
memcpy (rulename + slen, dep_name (d2), s2len + 1);
|
||||
f = lookup_file (rulename);
|
||||
if (f == 0 || f->cmds == 0)
|
||||
continue;
|
||||
memcpy (rulename + slen, dep_name (d2), s2len + 1);
|
||||
f = lookup_file (rulename);
|
||||
if (f == 0 || f->cmds == 0)
|
||||
continue;
|
||||
|
||||
if (s2len == 2 && rulename[slen] == '.' && rulename[slen + 1] == 'a')
|
||||
/* A suffix rule '.X.a:' generates the pattern rule '(%.o): %.X'.
|
||||
It also generates a normal '%.a: %.X' rule below. */
|
||||
convert_suffix_rule (NULL, /* Indicates '(%.o)'. */
|
||||
dep_name (d),
|
||||
f->cmds);
|
||||
if (s2len == 2 && rulename[slen] == '.' && rulename[slen + 1] == 'a')
|
||||
/* A suffix rule '.X.a:' generates the pattern rule '(%.o): %.X'.
|
||||
It also generates a normal '%.a: %.X' rule below. */
|
||||
convert_suffix_rule (NULL, /* Indicates '(%.o)'. */
|
||||
dep_name (d),
|
||||
f->cmds);
|
||||
|
||||
/* The suffix rule '.X.Y:' is converted
|
||||
to the pattern rule '%.Y: %.X'. */
|
||||
convert_suffix_rule (dep_name (d2), dep_name (d), f->cmds);
|
||||
}
|
||||
/* The suffix rule '.X.Y:' is converted
|
||||
to the pattern rule '%.Y: %.X'. */
|
||||
convert_suffix_rule (dep_name (d2), dep_name (d), f->cmds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,42 +294,42 @@ new_pattern_rule (struct rule *rule, int override)
|
||||
for (r = pattern_rules; r != 0; lastrule = r, r = r->next)
|
||||
for (i = 0; i < rule->num; ++i)
|
||||
{
|
||||
for (j = 0; j < r->num; ++j)
|
||||
if (!streq (rule->targets[i], r->targets[j]))
|
||||
break;
|
||||
for (j = 0; j < r->num; ++j)
|
||||
if (!streq (rule->targets[i], r->targets[j]))
|
||||
break;
|
||||
/* If all the targets matched... */
|
||||
if (j == r->num)
|
||||
{
|
||||
struct dep *d, *d2;
|
||||
for (d = rule->deps, d2 = r->deps;
|
||||
d != 0 && d2 != 0; d = d->next, d2 = d2->next)
|
||||
if (!streq (dep_name (d), dep_name (d2)))
|
||||
break;
|
||||
if (d == 0 && d2 == 0)
|
||||
{
|
||||
/* All the dependencies matched. */
|
||||
if (override)
|
||||
{
|
||||
/* Remove the old rule. */
|
||||
freerule (r, lastrule);
|
||||
/* Install the new one. */
|
||||
if (pattern_rules == 0)
|
||||
pattern_rules = rule;
|
||||
else
|
||||
last_pattern_rule->next = rule;
|
||||
last_pattern_rule = rule;
|
||||
if (j == r->num)
|
||||
{
|
||||
struct dep *d, *d2;
|
||||
for (d = rule->deps, d2 = r->deps;
|
||||
d != 0 && d2 != 0; d = d->next, d2 = d2->next)
|
||||
if (!streq (dep_name (d), dep_name (d2)))
|
||||
break;
|
||||
if (d == 0 && d2 == 0)
|
||||
{
|
||||
/* All the dependencies matched. */
|
||||
if (override)
|
||||
{
|
||||
/* Remove the old rule. */
|
||||
freerule (r, lastrule);
|
||||
/* Install the new one. */
|
||||
if (pattern_rules == 0)
|
||||
pattern_rules = rule;
|
||||
else
|
||||
last_pattern_rule->next = rule;
|
||||
last_pattern_rule = rule;
|
||||
|
||||
/* We got one. Stop looking. */
|
||||
goto matched;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The old rule stays intact. Destroy the new one. */
|
||||
freerule (rule, (struct rule *) 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* We got one. Stop looking. */
|
||||
goto matched;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The old rule stays intact. Destroy the new one. */
|
||||
freerule (rule, (struct rule *) 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
matched:;
|
||||
@ -338,9 +338,9 @@ new_pattern_rule (struct rule *rule, int override)
|
||||
{
|
||||
/* There was no rule to replace. */
|
||||
if (pattern_rules == 0)
|
||||
pattern_rules = rule;
|
||||
pattern_rules = rule;
|
||||
else
|
||||
last_pattern_rule->next = rule;
|
||||
last_pattern_rule->next = rule;
|
||||
last_pattern_rule = rule;
|
||||
}
|
||||
|
||||
@ -382,7 +382,7 @@ install_pattern_rule (struct pspec *p, int terminal)
|
||||
r->cmds->fileinfo.filenm = 0;
|
||||
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. */
|
||||
anyway because somebody might want to free them later. */
|
||||
r->cmds->commands = xstrdup (p->commands);
|
||||
r->cmds->command_lines = 0;
|
||||
r->cmds->recipe_prefix = RECIPEPREFIX_DEFAULT;
|
||||
@ -468,7 +468,7 @@ create_pattern_rule (const char **targets, const char **target_percents,
|
||||
|
||||
/* Print the data base of rules. */
|
||||
|
||||
static void /* Useful to call from gdb. */
|
||||
static void /* Useful to call from gdb. */
|
||||
print_rule (struct rule *r)
|
||||
{
|
||||
unsigned int i;
|
||||
@ -504,7 +504,7 @@ print_rule_data_base (void)
|
||||
print_rule (r);
|
||||
|
||||
if (r->terminal)
|
||||
++terminal;
|
||||
++terminal;
|
||||
}
|
||||
|
||||
if (rules == 0)
|
||||
@ -512,12 +512,12 @@ print_rule_data_base (void)
|
||||
else
|
||||
{
|
||||
printf (_("\n# %u implicit rules, %u"), rules, terminal);
|
||||
#ifndef NO_FLOAT
|
||||
#ifndef NO_FLOAT
|
||||
printf (" (%.1f%%)", (double) terminal / (double) rules * 100.0);
|
||||
#else
|
||||
{
|
||||
int f = (terminal * 1000 + 5) / rules;
|
||||
printf (" (%d.%d%%)", f/10, f%10);
|
||||
int f = (terminal * 1000 + 5) / rules;
|
||||
printf (" (%d.%d%%)", f/10, f%10);
|
||||
}
|
||||
#endif
|
||||
puts (_(" terminal."));
|
||||
|
14
rule.h
14
rule.h
@ -20,14 +20,14 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
struct rule
|
||||
{
|
||||
struct rule *next;
|
||||
const char **targets; /* Targets of the rule. */
|
||||
unsigned int *lens; /* Lengths of each target. */
|
||||
const char **suffixes; /* Suffixes (after '%') of each target. */
|
||||
struct dep *deps; /* Dependencies of the rule. */
|
||||
struct commands *cmds; /* Commands to execute. */
|
||||
const char **targets; /* Targets of the rule. */
|
||||
unsigned int *lens; /* Lengths of each target. */
|
||||
const char **suffixes; /* Suffixes (after '%') of each target. */
|
||||
struct dep *deps; /* Dependencies of the rule. */
|
||||
struct commands *cmds; /* Commands to execute. */
|
||||
unsigned short num; /* Number of targets. */
|
||||
char terminal; /* If terminal (double-colon). */
|
||||
char in_use; /* If in use by a parent pattern_search. */
|
||||
char terminal; /* If terminal (double-colon). */
|
||||
char in_use; /* If in use by a parent pattern_search. */
|
||||
};
|
||||
|
||||
/* For calling install_pattern_rule. */
|
||||
|
@ -27,11 +27,11 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#if !HAVE_DECL_SYS_SIGLIST
|
||||
|
||||
/* Some systems do not define NSIG in <signal.h>. */
|
||||
#ifndef NSIG
|
||||
#ifdef _NSIG
|
||||
#define NSIG _NSIG
|
||||
#ifndef NSIG
|
||||
#ifdef _NSIG
|
||||
#define NSIG _NSIG
|
||||
#else
|
||||
#define NSIG 32
|
||||
#define NSIG 32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -57,7 +57,7 @@ static unsigned long total_size = 0;
|
||||
that this doesn't seem to be much of an issue in practice.
|
||||
*/
|
||||
static struct strcache *
|
||||
new_cache()
|
||||
new_cache ()
|
||||
{
|
||||
struct strcache *new;
|
||||
new = xmalloc (bufsize + CACHE_BUFFER_OFFSET);
|
||||
@ -208,7 +208,7 @@ strcache_add_len (const char *str, unsigned int len)
|
||||
}
|
||||
|
||||
int
|
||||
strcache_setbufsize(unsigned int size)
|
||||
strcache_setbufsize (unsigned int size)
|
||||
{
|
||||
if (size > bufsize)
|
||||
bufsize = size;
|
||||
@ -233,7 +233,7 @@ strcache_print_stats (const char *prefix)
|
||||
|
||||
if (! strcache)
|
||||
{
|
||||
printf(_("\n%s No strcache buffers\n"), prefix);
|
||||
printf (_("\n%s No strcache buffers\n"), prefix);
|
||||
return;
|
||||
}
|
||||
|
||||
|
0
tests/run_make_tests.pl
Executable file → Normal file
0
tests/run_make_tests.pl
Executable file → Normal file
@ -165,7 +165,7 @@ sub toplevel
|
||||
$dir = $1;
|
||||
push (@rmdirs, $dir);
|
||||
-d "$workpath/$dir"
|
||||
|| mkdir ("$workpath/$dir", 0777)
|
||||
|| mkdir ("$workpath/$dir", 0777)
|
||||
|| &error ("Couldn't mkdir $workpath/$dir: $!\n");
|
||||
}
|
||||
}
|
||||
@ -174,7 +174,7 @@ sub toplevel
|
||||
{
|
||||
print "Finding tests...\n";
|
||||
opendir (SCRIPTDIR, $scriptpath)
|
||||
|| &error ("Couldn't opendir $scriptpath: $!\n");
|
||||
|| &error ("Couldn't opendir $scriptpath: $!\n");
|
||||
@dirs = grep (!/^(\..*|CVS|RCS)$/, readdir (SCRIPTDIR) );
|
||||
closedir (SCRIPTDIR);
|
||||
foreach $dir (@dirs)
|
||||
@ -184,13 +184,13 @@ sub toplevel
|
||||
mkdir ("$workpath/$dir", 0777)
|
||||
|| &error ("Couldn't mkdir $workpath/$dir: $!\n");
|
||||
opendir (SCRIPTDIR, "$scriptpath/$dir")
|
||||
|| &error ("Couldn't opendir $scriptpath/$dir: $!\n");
|
||||
|| &error ("Couldn't opendir $scriptpath/$dir: $!\n");
|
||||
@files = grep (!/^(\..*|CVS|RCS|.*~)$/, readdir (SCRIPTDIR) );
|
||||
closedir (SCRIPTDIR);
|
||||
foreach $test (@files)
|
||||
{
|
||||
-d $test and next;
|
||||
push (@TESTS, "$dir/$test");
|
||||
push (@TESTS, "$dir/$test");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -275,15 +275,15 @@ sub get_osname
|
||||
eval "chop (\$osname = `sh -c 'uname -nmsr 2>&1'`)";
|
||||
if ($osname =~ /not found/i)
|
||||
{
|
||||
$osname = "(something posixy with no uname)";
|
||||
$osname = "(something posixy with no uname)";
|
||||
}
|
||||
elsif ($@ ne "" || $?)
|
||||
{
|
||||
eval "chop (\$osname = `sh -c 'uname -a 2>&1'`)";
|
||||
if ($@ ne "" || $?)
|
||||
{
|
||||
$osname = "(something posixy)";
|
||||
}
|
||||
$osname = "(something posixy)";
|
||||
}
|
||||
}
|
||||
$vos = 0;
|
||||
$pathsep = "/";
|
||||
@ -941,7 +941,7 @@ sub touch
|
||||
|
||||
foreach $file (@_) {
|
||||
(open(T, ">> $file") && print(T "\n") && close(T))
|
||||
|| &error("Couldn't touch $file: $!\n", 1);
|
||||
|| &error("Couldn't touch $file: $!\n", 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
438
variable.c
438
variable.c
@ -98,7 +98,7 @@ static struct pattern_var *
|
||||
lookup_pattern_var (struct pattern_var *start, const char *target)
|
||||
{
|
||||
struct pattern_var *p;
|
||||
unsigned int targlen = strlen(target);
|
||||
unsigned int targlen = strlen (target);
|
||||
|
||||
for (p = start ? start->next : pattern_vars; p != 0; p = p->next)
|
||||
{
|
||||
@ -158,14 +158,14 @@ variable_hash_cmp (const void *xv, const void *yv)
|
||||
return_STRING_N_COMPARE (x->name, y->name, x->length);
|
||||
}
|
||||
|
||||
#ifndef VARIABLE_BUCKETS
|
||||
#define VARIABLE_BUCKETS 523
|
||||
#ifndef VARIABLE_BUCKETS
|
||||
#define VARIABLE_BUCKETS 523
|
||||
#endif
|
||||
#ifndef PERFILE_VARIABLE_BUCKETS
|
||||
#define PERFILE_VARIABLE_BUCKETS 23
|
||||
#ifndef PERFILE_VARIABLE_BUCKETS
|
||||
#define PERFILE_VARIABLE_BUCKETS 23
|
||||
#endif
|
||||
#ifndef SMALL_SCOPE_VARIABLE_BUCKETS
|
||||
#define SMALL_SCOPE_VARIABLE_BUCKETS 13
|
||||
#ifndef SMALL_SCOPE_VARIABLE_BUCKETS
|
||||
#define SMALL_SCOPE_VARIABLE_BUCKETS 13
|
||||
#endif
|
||||
|
||||
static struct variable_set global_variable_set;
|
||||
@ -179,7 +179,7 @@ void
|
||||
init_hash_global_variable_set (void)
|
||||
{
|
||||
hash_init (&global_variable_set.table, VARIABLE_BUCKETS,
|
||||
variable_hash_1, variable_hash_2, variable_hash_cmp);
|
||||
variable_hash_1, variable_hash_2, variable_hash_cmp);
|
||||
}
|
||||
|
||||
/* Define variable named NAME with value VALUE in SET. VALUE is copied.
|
||||
@ -213,25 +213,25 @@ define_variable_in_set (const char *name, unsigned int length,
|
||||
if (! HASH_VACANT (v))
|
||||
{
|
||||
if (env_overrides && v->origin == o_env)
|
||||
/* V came from in the environment. Since it was defined
|
||||
before the switches were parsed, it wasn't affected by -e. */
|
||||
v->origin = o_env_override;
|
||||
/* V came from in the environment. Since it was defined
|
||||
before the switches were parsed, it wasn't affected by -e. */
|
||||
v->origin = o_env_override;
|
||||
|
||||
/* A variable of this name is already defined.
|
||||
If the old definition is from a stronger source
|
||||
than this one, don't redefine it. */
|
||||
If the old definition is from a stronger source
|
||||
than this one, don't redefine it. */
|
||||
if ((int) origin >= (int) v->origin)
|
||||
{
|
||||
if (v->value != 0)
|
||||
free (v->value);
|
||||
v->value = xstrdup (value);
|
||||
{
|
||||
if (v->value != 0)
|
||||
free (v->value);
|
||||
v->value = xstrdup (value);
|
||||
if (flocp != 0)
|
||||
v->fileinfo = *flocp;
|
||||
else
|
||||
v->fileinfo.filenm = 0;
|
||||
v->origin = origin;
|
||||
v->recursive = recursive;
|
||||
}
|
||||
v->origin = origin;
|
||||
v->recursive = recursive;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
@ -445,7 +445,7 @@ lookup_variable (const char *name, unsigned int length)
|
||||
|
||||
v = (struct variable *) hash_find_item ((struct hash_table *) &set->table, &var_key);
|
||||
if (v && (!is_parent || !v->private_var))
|
||||
return v->special ? lookup_special_var (v) : v;
|
||||
return v->special ? lookup_special_var (v) : v;
|
||||
|
||||
is_parent |= setlist->next_is_parent;
|
||||
}
|
||||
@ -543,7 +543,7 @@ initialize_file_variables (struct file *file, int reading)
|
||||
if (l == 0)
|
||||
{
|
||||
l = (struct variable_set_list *)
|
||||
xmalloc (sizeof (struct variable_set_list));
|
||||
xmalloc (sizeof (struct variable_set_list));
|
||||
l->set = xmalloc (sizeof (struct variable_set));
|
||||
hash_init (&l->set->table, PERFILE_VARIABLE_BUCKETS,
|
||||
variable_hash_1, variable_hash_2, variable_hash_cmp);
|
||||
@ -646,7 +646,7 @@ create_new_variable_set (void)
|
||||
|
||||
set = xmalloc (sizeof (struct variable_set));
|
||||
hash_init (&set->table, SMALL_SCOPE_VARIABLE_BUCKETS,
|
||||
variable_hash_1, variable_hash_2, variable_hash_cmp);
|
||||
variable_hash_1, variable_hash_2, variable_hash_cmp);
|
||||
|
||||
setlist = (struct variable_set_list *)
|
||||
xmalloc (sizeof (struct variable_set_list));
|
||||
@ -666,7 +666,7 @@ create_new_variable_set (void)
|
||||
struct variable_set_list *
|
||||
push_new_variable_scope (void)
|
||||
{
|
||||
current_variable_set_list = create_new_variable_set();
|
||||
current_variable_set_list = create_new_variable_set ();
|
||||
if (current_variable_set_list->next == &global_setlist)
|
||||
{
|
||||
/* It was the global, so instead of new -> &global we want to replace
|
||||
@ -689,7 +689,7 @@ pop_variable_scope (void)
|
||||
struct variable_set *set;
|
||||
|
||||
/* Can't call this if there's no scope to pop! */
|
||||
assert(current_variable_set_list->next != NULL);
|
||||
assert (current_variable_set_list->next != NULL);
|
||||
|
||||
if (current_variable_set_list != &global_setlist)
|
||||
{
|
||||
@ -729,17 +729,17 @@ merge_variable_sets (struct variable_set *to_set,
|
||||
for ( ; from_var_slot < from_var_end; from_var_slot++)
|
||||
if (! HASH_VACANT (*from_var_slot))
|
||||
{
|
||||
struct variable *from_var = *from_var_slot;
|
||||
struct variable **to_var_slot
|
||||
= (struct variable **) hash_find_slot (&to_set->table, *from_var_slot);
|
||||
if (HASH_VACANT (*to_var_slot))
|
||||
hash_insert_at (&to_set->table, from_var, to_var_slot);
|
||||
else
|
||||
{
|
||||
/* GKM FIXME: delete in from_set->table */
|
||||
free (from_var->value);
|
||||
free (from_var);
|
||||
}
|
||||
struct variable *from_var = *from_var_slot;
|
||||
struct variable **to_var_slot
|
||||
= (struct variable **) hash_find_slot (&to_set->table, *from_var_slot);
|
||||
if (HASH_VACANT (*to_var_slot))
|
||||
hash_insert_at (&to_set->table, from_var, to_var_slot);
|
||||
else
|
||||
{
|
||||
/* GKM FIXME: delete in from_set->table */
|
||||
free (from_var->value);
|
||||
free (from_var);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -773,9 +773,9 @@ merge_variable_set_lists (struct variable_set_list **setlist0,
|
||||
if (setlist1 != &global_setlist)
|
||||
{
|
||||
if (last0 == 0)
|
||||
*setlist0 = setlist1;
|
||||
*setlist0 = setlist1;
|
||||
else
|
||||
last0->next = setlist1;
|
||||
last0->next = setlist1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -797,11 +797,11 @@ define_automatic_variables (void)
|
||||
define_variable_cname (MAKELEVEL_NAME, buf, o_env, 0);
|
||||
|
||||
sprintf (buf, "%s%s%s",
|
||||
version_string,
|
||||
(remote_description == 0 || remote_description[0] == '\0')
|
||||
? "" : "-",
|
||||
(remote_description == 0 || remote_description[0] == '\0')
|
||||
? "" : remote_description);
|
||||
version_string,
|
||||
(remote_description == 0 || remote_description[0] == '\0')
|
||||
? "" : "-",
|
||||
(remote_description == 0 || remote_description[0] == '\0')
|
||||
? "" : remote_description);
|
||||
define_variable_cname ("MAKE_VERSION", buf, o_default, 0);
|
||||
|
||||
#ifdef __MSDOS__
|
||||
@ -816,14 +816,14 @@ define_automatic_variables (void)
|
||||
/* $(MAKESHELL) overrides $(SHELL) even if -e is in effect. */
|
||||
if (mshp)
|
||||
(void) define_variable (shell_str, shlen,
|
||||
mshp->value, o_env_override, 0);
|
||||
mshp->value, o_env_override, 0);
|
||||
else if (comp)
|
||||
{
|
||||
/* $(COMSPEC) shouldn't override $(SHELL). */
|
||||
struct variable *shp = lookup_variable (shell_str, shlen);
|
||||
/* $(COMSPEC) shouldn't override $(SHELL). */
|
||||
struct variable *shp = lookup_variable (shell_str, shlen);
|
||||
|
||||
if (!shp)
|
||||
(void) define_variable (shell_str, shlen, comp->value, o_env, 0);
|
||||
if (!shp)
|
||||
(void) define_variable (shell_str, shlen, comp->value, o_env, 0);
|
||||
}
|
||||
}
|
||||
#elif defined(__EMX__)
|
||||
@ -841,13 +841,13 @@ define_automatic_variables (void)
|
||||
did not come from the environment */
|
||||
if (!replace || !*replace->value)
|
||||
if (shell && *shell->value && (shell->origin == o_env
|
||||
|| shell->origin == o_env_override))
|
||||
{
|
||||
/* overwrite whatever we got from the environment */
|
||||
free(shell->value);
|
||||
shell->value = xstrdup (default_shell);
|
||||
shell->origin = o_default;
|
||||
}
|
||||
|| shell->origin == o_env_override))
|
||||
{
|
||||
/* overwrite whatever we got from the environment */
|
||||
free (shell->value);
|
||||
shell->value = xstrdup (default_shell);
|
||||
shell->origin = o_default;
|
||||
}
|
||||
|
||||
/* Some people do not like cmd to be used as the default
|
||||
if $SHELL is not defined in the Makefile.
|
||||
@ -867,11 +867,11 @@ define_automatic_variables (void)
|
||||
if (replace && *replace->value)
|
||||
/* overwrite $SHELL */
|
||||
(void) define_variable (shell_str, shlen, replace->value,
|
||||
replace->origin, 0);
|
||||
replace->origin, 0);
|
||||
else
|
||||
/* provide a definition if there is none */
|
||||
(void) define_variable (shell_str, shlen, default_shell,
|
||||
o_default, 0);
|
||||
o_default, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -915,19 +915,19 @@ define_automatic_variables (void)
|
||||
#elif defined(__MSDOS__) || defined(WINDOWS32)
|
||||
/* For consistency, remove the trailing backslash as well as slash. */
|
||||
define_variable_cname ("@D", "$(patsubst %/,%,$(patsubst %\\,%,$(dir $@)))",
|
||||
o_automatic, 1);
|
||||
o_automatic, 1);
|
||||
define_variable_cname ("%D", "$(patsubst %/,%,$(patsubst %\\,%,$(dir $%)))",
|
||||
o_automatic, 1);
|
||||
o_automatic, 1);
|
||||
define_variable_cname ("*D", "$(patsubst %/,%,$(patsubst %\\,%,$(dir $*)))",
|
||||
o_automatic, 1);
|
||||
o_automatic, 1);
|
||||
define_variable_cname ("<D", "$(patsubst %/,%,$(patsubst %\\,%,$(dir $<)))",
|
||||
o_automatic, 1);
|
||||
o_automatic, 1);
|
||||
define_variable_cname ("?D", "$(patsubst %/,%,$(patsubst %\\,%,$(dir $?)))",
|
||||
o_automatic, 1);
|
||||
o_automatic, 1);
|
||||
define_variable_cname ("^D", "$(patsubst %/,%,$(patsubst %\\,%,$(dir $^)))",
|
||||
o_automatic, 1);
|
||||
o_automatic, 1);
|
||||
define_variable_cname ("+D", "$(patsubst %/,%,$(patsubst %\\,%,$(dir $+)))",
|
||||
o_automatic, 1);
|
||||
o_automatic, 1);
|
||||
#else /* not __MSDOS__, not WINDOWS32 */
|
||||
define_variable_cname ("@D", "$(patsubst %/,%,$(dir $@))", o_automatic, 1);
|
||||
define_variable_cname ("%D", "$(patsubst %/,%,$(dir $%))", o_automatic, 1);
|
||||
@ -970,7 +970,7 @@ target_environment (struct file *file)
|
||||
set_list = file->variables;
|
||||
|
||||
hash_init (&table, VARIABLE_BUCKETS,
|
||||
variable_hash_1, variable_hash_2, variable_hash_cmp);
|
||||
variable_hash_1, variable_hash_2, variable_hash_cmp);
|
||||
|
||||
/* Run through all the variable sets in the list,
|
||||
accumulating variables in TABLE. */
|
||||
@ -980,68 +980,68 @@ target_environment (struct file *file)
|
||||
v_slot = (struct variable **) set->table.ht_vec;
|
||||
v_end = v_slot + set->table.ht_size;
|
||||
for ( ; v_slot < v_end; v_slot++)
|
||||
if (! HASH_VACANT (*v_slot))
|
||||
{
|
||||
struct variable **new_slot;
|
||||
struct variable *v = *v_slot;
|
||||
if (! HASH_VACANT (*v_slot))
|
||||
{
|
||||
struct variable **new_slot;
|
||||
struct variable *v = *v_slot;
|
||||
|
||||
/* If this is a per-target variable and it hasn't been touched
|
||||
already then look up the global version and take its export
|
||||
value. */
|
||||
if (v->per_target && v->export == v_default)
|
||||
{
|
||||
struct variable *gv;
|
||||
/* If this is a per-target variable and it hasn't been touched
|
||||
already then look up the global version and take its export
|
||||
value. */
|
||||
if (v->per_target && v->export == v_default)
|
||||
{
|
||||
struct variable *gv;
|
||||
|
||||
gv = lookup_variable_in_set (v->name, strlen(v->name),
|
||||
gv = lookup_variable_in_set (v->name, strlen (v->name),
|
||||
&global_variable_set);
|
||||
if (gv)
|
||||
v->export = gv->export;
|
||||
}
|
||||
if (gv)
|
||||
v->export = gv->export;
|
||||
}
|
||||
|
||||
switch (v->export)
|
||||
{
|
||||
case v_default:
|
||||
if (v->origin == o_default || v->origin == o_automatic)
|
||||
/* Only export default variables by explicit request. */
|
||||
continue;
|
||||
switch (v->export)
|
||||
{
|
||||
case v_default:
|
||||
if (v->origin == o_default || v->origin == o_automatic)
|
||||
/* Only export default variables by explicit request. */
|
||||
continue;
|
||||
|
||||
/* The variable doesn't have a name that can be exported. */
|
||||
if (! v->exportable)
|
||||
continue;
|
||||
|
||||
if (! export_all_variables
|
||||
&& v->origin != o_command
|
||||
&& v->origin != o_env && v->origin != o_env_override)
|
||||
continue;
|
||||
break;
|
||||
if (! export_all_variables
|
||||
&& v->origin != o_command
|
||||
&& v->origin != o_env && v->origin != o_env_override)
|
||||
continue;
|
||||
break;
|
||||
|
||||
case v_export:
|
||||
break;
|
||||
case v_export:
|
||||
break;
|
||||
|
||||
case v_noexport:
|
||||
{
|
||||
/* If this is the SHELL variable and it's not exported,
|
||||
then add the value from our original environment, if
|
||||
the original environment defined a value for SHELL. */
|
||||
extern struct variable shell_var;
|
||||
if (streq (v->name, "SHELL") && shell_var.value)
|
||||
{
|
||||
v = &shell_var;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
case v_noexport:
|
||||
{
|
||||
/* If this is the SHELL variable and it's not exported,
|
||||
then add the value from our original environment, if
|
||||
the original environment defined a value for SHELL. */
|
||||
extern struct variable shell_var;
|
||||
if (streq (v->name, "SHELL") && shell_var.value)
|
||||
{
|
||||
v = &shell_var;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
case v_ifset:
|
||||
if (v->origin == o_default)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
case v_ifset:
|
||||
if (v->origin == o_default)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
new_slot = (struct variable **) hash_find_slot (&table, v);
|
||||
if (HASH_VACANT (*new_slot))
|
||||
hash_insert_at (&table, v, new_slot);
|
||||
}
|
||||
new_slot = (struct variable **) hash_find_slot (&table, v);
|
||||
if (HASH_VACANT (*new_slot))
|
||||
hash_insert_at (&table, v, new_slot);
|
||||
}
|
||||
}
|
||||
|
||||
makelevel_key.name = MAKELEVEL_NAME;
|
||||
@ -1055,32 +1055,32 @@ target_environment (struct file *file)
|
||||
for ( ; v_slot < v_end; v_slot++)
|
||||
if (! HASH_VACANT (*v_slot))
|
||||
{
|
||||
struct variable *v = *v_slot;
|
||||
struct variable *v = *v_slot;
|
||||
|
||||
/* If V is recursively expanded and didn't come from the environment,
|
||||
expand its value. If it came from the environment, it should
|
||||
go back into the environment unchanged. */
|
||||
if (v->recursive
|
||||
&& v->origin != o_env && v->origin != o_env_override)
|
||||
{
|
||||
char *value = recursively_expand_for_file (v, file);
|
||||
/* If V is recursively expanded and didn't come from the environment,
|
||||
expand its value. If it came from the environment, it should
|
||||
go back into the environment unchanged. */
|
||||
if (v->recursive
|
||||
&& v->origin != o_env && v->origin != o_env_override)
|
||||
{
|
||||
char *value = recursively_expand_for_file (v, file);
|
||||
#ifdef WINDOWS32
|
||||
if (strcmp(v->name, "Path") == 0 ||
|
||||
strcmp(v->name, "PATH") == 0)
|
||||
convert_Path_to_windows32(value, ';');
|
||||
if (strcmp (v->name, "Path") == 0 ||
|
||||
strcmp (v->name, "PATH") == 0)
|
||||
convert_Path_to_windows32 (value, ';');
|
||||
#endif
|
||||
*result++ = xstrdup (concat (3, v->name, "=", value));
|
||||
free (value);
|
||||
}
|
||||
else
|
||||
{
|
||||
*result++ = xstrdup (concat (3, v->name, "=", value));
|
||||
free (value);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef WINDOWS32
|
||||
if (strcmp(v->name, "Path") == 0 ||
|
||||
strcmp(v->name, "PATH") == 0)
|
||||
convert_Path_to_windows32(v->value, ';');
|
||||
if (strcmp (v->name, "Path") == 0 ||
|
||||
strcmp (v->name, "PATH") == 0)
|
||||
convert_Path_to_windows32 (v->value, ';');
|
||||
#endif
|
||||
*result++ = xstrdup (concat (3, v->name, "=", v->value));
|
||||
}
|
||||
*result++ = xstrdup (concat (3, v->name, "=", v->value));
|
||||
}
|
||||
}
|
||||
|
||||
*result = xmalloc (100);
|
||||
@ -1154,7 +1154,7 @@ do_variable_definition (const gmk_floc *flocp, const char *varname,
|
||||
case f_simple:
|
||||
/* A simple variable definition "var := value". Expand the value.
|
||||
We have to allocate memory since otherwise it'll clobber the
|
||||
variable buffer, and we may still need that if we're looking at a
|
||||
variable buffer, and we may still need that if we're looking at a
|
||||
target-specific variable. */
|
||||
p = alloc_value = allocated_variable_expand (value);
|
||||
break;
|
||||
@ -1180,7 +1180,7 @@ do_variable_definition (const gmk_floc *flocp, const char *varname,
|
||||
/* FALLTHROUGH */
|
||||
case f_recursive:
|
||||
/* A recursive variable definition "var = value".
|
||||
The value is used verbatim. */
|
||||
The value is used verbatim. */
|
||||
p = value;
|
||||
break;
|
||||
case f_append:
|
||||
@ -1264,62 +1264,62 @@ do_variable_definition (const gmk_floc *flocp, const char *varname,
|
||||
|
||||
/* See if we can find "/bin/sh.exe", "/bin/sh.com", etc. */
|
||||
if (__dosexec_find_on_path (p, NULL, shellpath))
|
||||
{
|
||||
char *tp;
|
||||
{
|
||||
char *tp;
|
||||
|
||||
for (tp = shellpath; *tp; tp++)
|
||||
for (tp = shellpath; *tp; tp++)
|
||||
if (*tp == '\\')
|
||||
*tp = '/';
|
||||
|
||||
v = define_variable_loc (varname, strlen (varname),
|
||||
v = define_variable_loc (varname, strlen (varname),
|
||||
shellpath, origin, flavor == f_recursive,
|
||||
flocp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *shellbase, *bslash;
|
||||
struct variable *pathv = lookup_variable ("PATH", 4);
|
||||
char *path_string;
|
||||
char *fake_env[2];
|
||||
size_t pathlen = 0;
|
||||
{
|
||||
const char *shellbase, *bslash;
|
||||
struct variable *pathv = lookup_variable ("PATH", 4);
|
||||
char *path_string;
|
||||
char *fake_env[2];
|
||||
size_t pathlen = 0;
|
||||
|
||||
shellbase = strrchr (p, '/');
|
||||
bslash = strrchr (p, '\\');
|
||||
if (!shellbase || bslash > shellbase)
|
||||
shellbase = bslash;
|
||||
if (!shellbase && p[1] == ':')
|
||||
shellbase = p + 1;
|
||||
if (shellbase)
|
||||
shellbase++;
|
||||
else
|
||||
shellbase = p;
|
||||
shellbase = strrchr (p, '/');
|
||||
bslash = strrchr (p, '\\');
|
||||
if (!shellbase || bslash > shellbase)
|
||||
shellbase = bslash;
|
||||
if (!shellbase && p[1] == ':')
|
||||
shellbase = p + 1;
|
||||
if (shellbase)
|
||||
shellbase++;
|
||||
else
|
||||
shellbase = p;
|
||||
|
||||
/* Search for the basename of the shell (with standard
|
||||
executable extensions) along the $PATH. */
|
||||
if (pathv)
|
||||
pathlen = strlen (pathv->value);
|
||||
path_string = xmalloc (5 + pathlen + 2 + 1);
|
||||
/* On MSDOS, current directory is considered as part of $PATH. */
|
||||
sprintf (path_string, "PATH=.;%s", pathv ? pathv->value : "");
|
||||
fake_env[0] = path_string;
|
||||
fake_env[1] = 0;
|
||||
if (__dosexec_find_on_path (shellbase, fake_env, shellpath))
|
||||
{
|
||||
char *tp;
|
||||
/* Search for the basename of the shell (with standard
|
||||
executable extensions) along the $PATH. */
|
||||
if (pathv)
|
||||
pathlen = strlen (pathv->value);
|
||||
path_string = xmalloc (5 + pathlen + 2 + 1);
|
||||
/* On MSDOS, current directory is considered as part of $PATH. */
|
||||
sprintf (path_string, "PATH=.;%s", pathv ? pathv->value : "");
|
||||
fake_env[0] = path_string;
|
||||
fake_env[1] = 0;
|
||||
if (__dosexec_find_on_path (shellbase, fake_env, shellpath))
|
||||
{
|
||||
char *tp;
|
||||
|
||||
for (tp = shellpath; *tp; tp++)
|
||||
for (tp = shellpath; *tp; tp++)
|
||||
if (*tp == '\\')
|
||||
*tp = '/';
|
||||
|
||||
v = define_variable_loc (varname, strlen (varname),
|
||||
v = define_variable_loc (varname, strlen (varname),
|
||||
shellpath, origin,
|
||||
flavor == f_recursive, flocp);
|
||||
}
|
||||
else
|
||||
v = lookup_variable (varname, strlen (varname));
|
||||
}
|
||||
else
|
||||
v = lookup_variable (varname, strlen (varname));
|
||||
|
||||
free (path_string);
|
||||
}
|
||||
free (path_string);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* __MSDOS__ */
|
||||
@ -1330,7 +1330,7 @@ do_variable_definition (const gmk_floc *flocp, const char *varname,
|
||||
extern char *default_shell;
|
||||
|
||||
/* Call shell locator function. If it returns TRUE, then
|
||||
set no_default_sh_exe to indicate sh was found and
|
||||
set no_default_sh_exe to indicate sh was found and
|
||||
set new value for SHELL variable. */
|
||||
|
||||
if (find_and_set_default_shell (p))
|
||||
@ -1419,38 +1419,38 @@ parse_variable_definition (const char *p, struct variable *var)
|
||||
|
||||
/* If we find a comment or EOS, it's not a variable definition. */
|
||||
if (c == '\0' || c == '#')
|
||||
return NULL;
|
||||
return NULL;
|
||||
|
||||
if (c == '$')
|
||||
{
|
||||
/* This begins a variable expansion reference. Make sure we don't
|
||||
treat chars inside the reference as assignment tokens. */
|
||||
char closeparen;
|
||||
int count;
|
||||
c = *p++;
|
||||
if (c == '(')
|
||||
closeparen = ')';
|
||||
else if (c == '{')
|
||||
closeparen = '}';
|
||||
else
|
||||
{
|
||||
/* This begins a variable expansion reference. Make sure we don't
|
||||
treat chars inside the reference as assignment tokens. */
|
||||
char closeparen;
|
||||
int count;
|
||||
c = *p++;
|
||||
if (c == '(')
|
||||
closeparen = ')';
|
||||
else if (c == '{')
|
||||
closeparen = '}';
|
||||
else
|
||||
/* '$$' or '$X'. Either way, nothing special to do here. */
|
||||
continue;
|
||||
continue;
|
||||
|
||||
/* P now points past the opening paren or brace.
|
||||
Count parens or braces until it is matched. */
|
||||
count = 0;
|
||||
for (; *p != '\0'; ++p)
|
||||
{
|
||||
if (*p == c)
|
||||
++count;
|
||||
else if (*p == closeparen && --count < 0)
|
||||
{
|
||||
++p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* P now points past the opening paren or brace.
|
||||
Count parens or braces until it is matched. */
|
||||
count = 0;
|
||||
for (; *p != '\0'; ++p)
|
||||
{
|
||||
if (*p == c)
|
||||
++count;
|
||||
else if (*p == closeparen && --count < 0)
|
||||
{
|
||||
++p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we find whitespace skip it, and remember we found it. */
|
||||
if (isblank ((unsigned char)c))
|
||||
@ -1466,12 +1466,12 @@ parse_variable_definition (const char *p, struct variable *var)
|
||||
|
||||
|
||||
if (c == '=')
|
||||
{
|
||||
var->flavor = f_recursive;
|
||||
{
|
||||
var->flavor = f_recursive;
|
||||
if (! e)
|
||||
e = p - 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Match assignment variants (:=, +=, ?=, !=) */
|
||||
if (*p == '=')
|
||||
@ -1649,18 +1649,18 @@ print_variable (const void *item, void *arg)
|
||||
/* Check if the value is just whitespace. */
|
||||
p = next_token (v->value);
|
||||
if (p != v->value && *p == '\0')
|
||||
/* All whitespace. */
|
||||
printf ("$(subst ,,%s)", v->value);
|
||||
/* All whitespace. */
|
||||
printf ("$(subst ,,%s)", v->value);
|
||||
else if (v->recursive)
|
||||
fputs (v->value, stdout);
|
||||
fputs (v->value, stdout);
|
||||
else
|
||||
/* Double up dollar signs. */
|
||||
for (p = v->value; *p != '\0'; ++p)
|
||||
{
|
||||
if (*p == '$')
|
||||
putchar ('$');
|
||||
putchar (*p);
|
||||
}
|
||||
/* Double up dollar signs. */
|
||||
for (p = v->value; *p != '\0'; ++p)
|
||||
{
|
||||
if (*p == '$')
|
||||
putchar ('$');
|
||||
putchar (*p);
|
||||
}
|
||||
putchar ('\n');
|
||||
}
|
||||
}
|
||||
|
190
vpath.c
190
vpath.c
@ -26,7 +26,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
struct vpath
|
||||
{
|
||||
struct vpath *next; /* Pointer to next struct in the linked list. */
|
||||
struct vpath *next; /* Pointer to next struct in the linked list. */
|
||||
const char *pattern;/* The pattern to match. */
|
||||
const char *percent;/* Pointer into 'pattern' where the '%' is. */
|
||||
unsigned int patlen;/* Length of the pattern. */
|
||||
@ -89,14 +89,14 @@ build_vpath_lists ()
|
||||
char gp[] = "%";
|
||||
|
||||
/* Empty 'vpaths' so the new one will have no next, and 'vpaths'
|
||||
will still be nil if P contains no existing directories. */
|
||||
will still be nil if P contains no existing directories. */
|
||||
vpaths = 0;
|
||||
|
||||
/* Parse P. */
|
||||
construct_vpath_list (gp, p);
|
||||
|
||||
/* Store the created path as the general path,
|
||||
and restore the old list of vpaths. */
|
||||
and restore the old list of vpaths. */
|
||||
general_vpath = vpaths;
|
||||
vpaths = save_vpaths;
|
||||
}
|
||||
@ -122,14 +122,14 @@ build_vpath_lists ()
|
||||
char gp[] = "%";
|
||||
|
||||
/* Empty 'vpaths' so the new one will have no next, and 'vpaths'
|
||||
will still be nil if P contains no existing directories. */
|
||||
will still be nil if P contains no existing directories. */
|
||||
vpaths = 0;
|
||||
|
||||
/* Parse P. */
|
||||
construct_vpath_list (gp, p);
|
||||
|
||||
/* Store the created path as the GPATH,
|
||||
and restore the old list of vpaths. */
|
||||
and restore the old list of vpaths. */
|
||||
gpaths = vpaths;
|
||||
vpaths = save_vpaths;
|
||||
}
|
||||
@ -175,36 +175,36 @@ construct_vpath_list (char *pattern, char *dirpath)
|
||||
lastpath = 0;
|
||||
path = vpaths;
|
||||
while (path != 0)
|
||||
{
|
||||
struct vpath *next = path->next;
|
||||
{
|
||||
struct vpath *next = path->next;
|
||||
|
||||
if (pattern == 0
|
||||
|| (((percent == 0 && path->percent == 0)
|
||||
|| (percent - pattern == path->percent - path->pattern))
|
||||
&& streq (pattern, path->pattern)))
|
||||
{
|
||||
/* Remove it from the linked list. */
|
||||
if (lastpath == 0)
|
||||
vpaths = path->next;
|
||||
else
|
||||
lastpath->next = next;
|
||||
if (pattern == 0
|
||||
|| (((percent == 0 && path->percent == 0)
|
||||
|| (percent - pattern == path->percent - path->pattern))
|
||||
&& streq (pattern, path->pattern)))
|
||||
{
|
||||
/* Remove it from the linked list. */
|
||||
if (lastpath == 0)
|
||||
vpaths = path->next;
|
||||
else
|
||||
lastpath->next = next;
|
||||
|
||||
/* Free its unused storage. */
|
||||
/* Free its unused storage. */
|
||||
/* MSVC erroneously warns without a cast here. */
|
||||
free ((void *)path->searchpath);
|
||||
free (path);
|
||||
}
|
||||
else
|
||||
lastpath = path;
|
||||
free ((void *)path->searchpath);
|
||||
free (path);
|
||||
}
|
||||
else
|
||||
lastpath = path;
|
||||
|
||||
path = next;
|
||||
}
|
||||
path = next;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef WINDOWS32
|
||||
convert_vpath_to_windows32(dirpath, ';');
|
||||
convert_vpath_to_windows32 (dirpath, ';');
|
||||
#endif
|
||||
|
||||
/* Skip over any initial separators and blanks. */
|
||||
@ -235,49 +235,49 @@ construct_vpath_list (char *pattern, char *dirpath)
|
||||
v = p;
|
||||
while (*p != '\0'
|
||||
#if defined(HAVE_DOS_PATHS) && (PATH_SEPARATOR_CHAR == ':')
|
||||
/* Platforms whose PATH_SEPARATOR_CHAR is ':' and which
|
||||
also define HAVE_DOS_PATHS would like us to recognize
|
||||
colons after the drive letter in the likes of
|
||||
"D:/foo/bar:C:/xyzzy". */
|
||||
&& (*p != PATH_SEPARATOR_CHAR
|
||||
|| (p == v + 1 && (p[1] == '/' || p[1] == '\\')))
|
||||
/* Platforms whose PATH_SEPARATOR_CHAR is ':' and which
|
||||
also define HAVE_DOS_PATHS would like us to recognize
|
||||
colons after the drive letter in the likes of
|
||||
"D:/foo/bar:C:/xyzzy". */
|
||||
&& (*p != PATH_SEPARATOR_CHAR
|
||||
|| (p == v + 1 && (p[1] == '/' || p[1] == '\\')))
|
||||
#else
|
||||
&& *p != PATH_SEPARATOR_CHAR
|
||||
&& *p != PATH_SEPARATOR_CHAR
|
||||
#endif
|
||||
&& !isblank ((unsigned char)*p))
|
||||
++p;
|
||||
&& !isblank ((unsigned char)*p))
|
||||
++p;
|
||||
|
||||
len = p - v;
|
||||
/* Make sure there's no trailing slash,
|
||||
but still allow "/" as a directory. */
|
||||
but still allow "/" as a directory. */
|
||||
#if defined(__MSDOS__) || defined(__EMX__) || defined(HAVE_DOS_PATHS)
|
||||
/* We need also to leave alone a trailing slash in "d:/". */
|
||||
if (len > 3 || (len > 1 && v[1] != ':'))
|
||||
#endif
|
||||
if (len > 1 && p[-1] == '/')
|
||||
--len;
|
||||
--len;
|
||||
|
||||
/* Put the directory on the vpath list. */
|
||||
if (len > 1 || *v != '.')
|
||||
{
|
||||
{
|
||||
vpath[elem++] = dir_name (strcache_add_len (v, len));
|
||||
if (len > maxvpath)
|
||||
maxvpath = len;
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip over separators and blanks between entries. */
|
||||
while (*p == PATH_SEPARATOR_CHAR || isblank ((unsigned char)*p))
|
||||
++p;
|
||||
++p;
|
||||
}
|
||||
|
||||
if (elem > 0)
|
||||
{
|
||||
struct vpath *path;
|
||||
/* ELEM is now incremented one element past the last
|
||||
entry, to where the nil-pointer terminator goes.
|
||||
Usually this is maxelem - 1. If not, shrink down. */
|
||||
entry, to where the nil-pointer terminator goes.
|
||||
Usually this is maxelem - 1. If not, shrink down. */
|
||||
if (elem < (maxelem - 1))
|
||||
vpath = xrealloc (vpath, (elem+1) * sizeof (const char *));
|
||||
vpath = xrealloc (vpath, (elem+1) * sizeof (const char *));
|
||||
|
||||
/* Put the nil-pointer terminator on the end of the VPATH list. */
|
||||
vpath[elem] = NULL;
|
||||
@ -355,7 +355,7 @@ selective_vpath_search (struct vpath *path, const char *file,
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* We need the rightmost slash or backslash. */
|
||||
{
|
||||
const char *bslash = strrchr(file, '\\');
|
||||
const char *bslash = strrchr (file, '\\');
|
||||
if (!n || bslash > n)
|
||||
n = bslash;
|
||||
}
|
||||
@ -385,43 +385,43 @@ selective_vpath_search (struct vpath *path, const char *file,
|
||||
|
||||
/* Add the directory prefix already in *FILE. */
|
||||
if (name_dplen > 0)
|
||||
{
|
||||
{
|
||||
#ifndef VMS
|
||||
*p++ = '/';
|
||||
*p++ = '/';
|
||||
#endif
|
||||
memcpy (p, file, name_dplen);
|
||||
p += name_dplen;
|
||||
}
|
||||
memcpy (p, file, name_dplen);
|
||||
p += name_dplen;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DOS_PATHS
|
||||
/* Cause the next if to treat backslash and slash alike. */
|
||||
if (p != name && p[-1] == '\\' )
|
||||
p[-1] = '/';
|
||||
p[-1] = '/';
|
||||
#endif
|
||||
/* Now add the name-within-directory at the end of NAME. */
|
||||
#ifndef VMS
|
||||
if (p != name && p[-1] != '/')
|
||||
{
|
||||
*p = '/';
|
||||
memcpy (p + 1, filename, flen + 1);
|
||||
}
|
||||
{
|
||||
*p = '/';
|
||||
memcpy (p + 1, filename, flen + 1);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
memcpy (p, filename, flen + 1);
|
||||
memcpy (p, filename, flen + 1);
|
||||
|
||||
/* Check if the file is mentioned in a makefile. If *FILE is not
|
||||
a target, that is enough for us to decide this file exists.
|
||||
If *FILE is a target, then the file must be mentioned in the
|
||||
makefile also as a target to be chosen.
|
||||
a target, that is enough for us to decide this file exists.
|
||||
If *FILE is a target, then the file must be mentioned in the
|
||||
makefile also as a target to be chosen.
|
||||
|
||||
The restriction that *FILE must not be a target for a
|
||||
makefile-mentioned file to be chosen was added by an
|
||||
inadequately commented change in July 1990; I am not sure off
|
||||
hand what problem it fixes.
|
||||
The restriction that *FILE must not be a target for a
|
||||
makefile-mentioned file to be chosen was added by an
|
||||
inadequately commented change in July 1990; I am not sure off
|
||||
hand what problem it fixes.
|
||||
|
||||
In December 1993 I loosened this restriction to allow a file
|
||||
to be chosen if it is mentioned as a target in a makefile. This
|
||||
seem logical.
|
||||
In December 1993 I loosened this restriction to allow a file
|
||||
to be chosen if it is mentioned as a target in a makefile. This
|
||||
seem logical.
|
||||
|
||||
Special handling for -W / -o: make sure we preserve the special
|
||||
values here. Actually this whole thing is a little bogus: I think
|
||||
@ -431,8 +431,8 @@ selective_vpath_search (struct vpath *path, const char *file,
|
||||
we use it.
|
||||
*/
|
||||
{
|
||||
struct file *f = lookup_file (name);
|
||||
if (f != 0)
|
||||
struct file *f = lookup_file (name);
|
||||
if (f != 0)
|
||||
{
|
||||
exists = not_target || f->is_target;
|
||||
if (exists && mtime_ptr
|
||||
@ -445,41 +445,41 @@ selective_vpath_search (struct vpath *path, const char *file,
|
||||
}
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
/* That file wasn't mentioned in the makefile.
|
||||
See if it actually exists. */
|
||||
{
|
||||
/* That file wasn't mentioned in the makefile.
|
||||
See if it actually exists. */
|
||||
|
||||
#ifdef VMS
|
||||
exists_in_cache = exists = dir_file_exists_p (vpath[i], filename);
|
||||
exists_in_cache = exists = dir_file_exists_p (vpath[i], filename);
|
||||
#else
|
||||
/* Clobber a null into the name at the last slash.
|
||||
Now NAME is the name of the directory to look in. */
|
||||
*p = '\0';
|
||||
/* Clobber a null into the name at the last slash.
|
||||
Now NAME is the name of the directory to look in. */
|
||||
*p = '\0';
|
||||
|
||||
/* We know the directory is in the hash table now because either
|
||||
construct_vpath_list or the code just above put it there.
|
||||
Does the file we seek exist in it? */
|
||||
exists_in_cache = exists = dir_file_exists_p (name, filename);
|
||||
/* We know the directory is in the hash table now because either
|
||||
construct_vpath_list or the code just above put it there.
|
||||
Does the file we seek exist in it? */
|
||||
exists_in_cache = exists = dir_file_exists_p (name, filename);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (exists)
|
||||
{
|
||||
/* The file is in the directory cache.
|
||||
Now check that it actually exists in the filesystem.
|
||||
The cache may be out of date. When vpath thinks a file
|
||||
exists, but stat fails for it, confusion results in the
|
||||
higher levels. */
|
||||
{
|
||||
/* The file is in the directory cache.
|
||||
Now check that it actually exists in the filesystem.
|
||||
The cache may be out of date. When vpath thinks a file
|
||||
exists, but stat fails for it, confusion results in the
|
||||
higher levels. */
|
||||
|
||||
struct stat st;
|
||||
struct stat st;
|
||||
|
||||
#ifndef VMS
|
||||
/* Put the slash back in NAME. */
|
||||
*p = '/';
|
||||
/* Put the slash back in NAME. */
|
||||
*p = '/';
|
||||
#endif
|
||||
|
||||
if (exists_in_cache) /* Makefile-mentioned file need not exist. */
|
||||
{
|
||||
if (exists_in_cache) /* Makefile-mentioned file need not exist. */
|
||||
{
|
||||
int e;
|
||||
|
||||
EINTRLOOP (e, stat (name, &st)); /* Does it really exist? */
|
||||
@ -509,7 +509,7 @@ selective_vpath_search (struct vpath *path, const char *file,
|
||||
*path_index = i;
|
||||
|
||||
return strcache_add_len (name, (p + 1 - name) + flen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -593,8 +593,8 @@ print_vpath_data_base (void)
|
||||
printf ("vpath %s ", v->pattern);
|
||||
|
||||
for (i = 0; v->searchpath[i] != 0; ++i)
|
||||
printf ("%s%c", v->searchpath[i],
|
||||
v->searchpath[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR);
|
||||
printf ("%s%c", v->searchpath[i],
|
||||
v->searchpath[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR);
|
||||
}
|
||||
|
||||
if (vpaths == 0)
|
||||
@ -612,7 +612,7 @@ print_vpath_data_base (void)
|
||||
fputs (_("\n# General ('VPATH' variable) search path:\n# "), stdout);
|
||||
|
||||
for (i = 0; path[i] != 0; ++i)
|
||||
printf ("%s%c", path[i],
|
||||
path[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR);
|
||||
printf ("%s%c", path[i],
|
||||
path[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user