Compare commits

...

23 Commits

Author SHA1 Message Date
Paul Smith
17f2dda0ac * Fix for dir.c from Andreas Schwab.
* Fix += target-specific variables: if your direct parent doesn't have a
  setting for the variable but his parent does, you'll get recursive
  expansion errors.
2000-02-07 19:54:04 +00:00
Paul Smith
90f23f1ea6 * Updates for VMS, Windows, and DOS ports.
* Clean up some warnings.
2000-02-05 07:50:47 +00:00
Paul Smith
9b0a3d91ea * Fix PR/1407.
* Keep filename/lineno information for variables, for debugging.
2000-02-05 07:37:40 +00:00
Paul Smith
95a09e94f7 * Some pre-pretest release cleanup. 2000-01-27 00:00:27 +00:00
Paul Smith
de2a8fc730 * Updated gettext to use more advanced libit 0.7 version.
* Various cleanups.
2000-01-25 07:42:51 +00:00
Paul Smith
447c76f601 * A few fixes. 2000-01-23 07:05:16 +00:00
Paul Smith
24aec1878b * Mention it in NEWS. 2000-01-22 08:59:09 +00:00
Paul Smith
2fd5b943d1 * Implement GNU gettext internationalization support in GNU make. 2000-01-22 08:57:17 +00:00
Paul Smith
74fca88bf3 * More fixes to VMS by Hartmut Becker. 2000-01-22 05:59:28 +00:00
Paul Smith
5577cdc261 * Merge VMS patches by Hartmut Becker. 2000-01-22 05:43:03 +00:00
Paul Smith
b7b83d6398 * Change $(call...) to not expand arguments by default.
* Unify the way arguments are passed to builtin functions in function.c.
2000-01-11 07:31:42 +00:00
Paul Smith
af44f16799 * Fix problems with double-colon rules.
* Fix problems with INTERMEDIATE rules.
1999-12-18 17:43:47 +00:00
Paul Smith
1a35bfb45b * Various changes and fixes. See ChangeLog. 1999-12-08 20:13:50 +00:00
Paul Smith
4d5c556f00 * Update debugging to use string flags instead of integers. 1999-11-27 08:09:42 +00:00
Paul Smith
ce3413f883 * Add new debug header file. 1999-11-22 06:16:48 +00:00
Paul Smith
217ca5d910 * Add new debugging output level selection feature. 1999-11-22 06:15:35 +00:00
Paul Smith
ebb733c0f9 * Many cleanups and bugfixes.
* New handling of += in target-specific variables.
1999-11-17 07:33:47 +00:00
Paul Smith
3e26bde6db * Fix PR/1394.
* Apply changes from Paul Eggert.
* Many other cleanups (index/rindex --> strchr/strrchr, etc.)
1999-10-15 07:00:58 +00:00
Paul Smith
c71200d022 * Ensure -Iglob comes before any user-specified CPPFLAGS. 1999-10-14 23:20:12 +00:00
Paul Smith
281951154b * Fix PR/1379: -n/-q behaves correctly when all commands are recursive. 1999-10-13 07:00:23 +00:00
Paul Smith
829f4fd04b * Fix test suite on DOS (PR/1344)
* Fix target-specific vars bug (PR/1378)
1999-10-08 06:32:24 +00:00
Paul Smith
f26e413b12 * Fix for DOS short filenames. 1999-09-29 06:29:38 +00:00
Paul Smith
dbb8f3e30b * Ouch: found a bug where re-exec from changed makefiles turned off
jobserver :(.
1999-09-23 18:23:33 +00:00
72 changed files with 17425 additions and 1296 deletions

View File

@@ -12,11 +12,14 @@ makebook*
*.cp *.cps *.fn *.fns *.vr *.vrs *.tp *.tps *.ky *.kys *.pg *.pgs
README README.DOS README.W32
aclocal.m4 config.h.in config.h configure Makefile.in
aclocal.m4 config.h.in config.h config.status config.cache configure
Makefile.in Makefile
build.sh.in build.sh
SMakefile NMakefile Makefile.DOS
config.ami configh.dos config.h.W32 config.h-vms
loadavg loadavg.c make
.deps .dep_segment
_*

226
ABOUT-NLS Normal file
View File

@@ -0,0 +1,226 @@
Notes on the Free Translation Project
*************************************
Free software is going international! The Free Translation Project
is a way to get maintainers of free software, translators, and users all
together, so that will gradually become able to speak many languages.
A few packages already provide translations for their messages.
If you found this `ABOUT-NLS' file inside a distribution, you may
assume that the distributed package does use GNU `gettext' internally,
itself available at your nearest GNU archive site. But you do *not*
need to install GNU `gettext' prior to configuring, installing or using
this package with messages translated.
Installers will find here some useful hints. These notes also
explain how users should proceed for getting the programs to use the
available translations. They tell how people wanting to contribute and
work at translations should contact the appropriate team.
When reporting bugs in the `intl/' directory or bugs which may be
related to internationalization, you should tell about the version of
`gettext' which is used. The information can be found in the
`intl/VERSION' file, in internationalized packages.
One advise in advance
=====================
If you want to exploit the full power of internationalization, you
should configure it using
./configure --with-included-gettext
to force usage of internationalizing routines provided within this
package, despite the existence of internationalizing capabilities in the
operating system where this package is being installed. So far, only
the `gettext' implementation in the GNU C library version 2 provides as
many features (such as locale alias or message inheritance) as the
implementation here. It is also not possible to offer this additional
functionality on top of a `catgets' implementation. Future versions of
GNU `gettext' will very likely convey even more functionality. So it
might be a good idea to change to GNU `gettext' as soon as possible.
So you need not provide this option if you are using GNU libc 2 or
you have installed a recent copy of the GNU gettext package with the
included `libintl'.
INSTALL Matters
===============
Some packages are "localizable" when properly installed; the
programs they contain can be made to speak your own native language.
Most such packages use GNU `gettext'. Other packages have their own
ways to internationalization, predating GNU `gettext'.
By default, this package will be installed to allow translation of
messages. It will automatically detect whether the system provides
usable `catgets' (if using this is selected by the installer) or
`gettext' functions. If neither is available, the GNU `gettext' own
library will be used. This library is wholly contained within this
package, usually in the `intl/' subdirectory, so prior installation of
the GNU `gettext' package is *not* required. Installers may use
special options at configuration time for changing the default
behaviour. The commands:
./configure --with-included-gettext
./configure --with-catgets
./configure --disable-nls
will respectively bypass any pre-existing `catgets' or `gettext' to use
the internationalizing routines provided within this package, enable
the use of the `catgets' functions (if found on the locale system), or
else, *totally* disable translation of messages.
When you already have GNU `gettext' installed on your system and run
configure without an option for your new package, `configure' will
probably detect the previously built and installed `libintl.a' file and
will decide to use this. This might be not what is desirable. You
should use the more recent version of the GNU `gettext' library. I.e.
if the file `intl/VERSION' shows that the library which comes with this
package is more recent, you should use
./configure --with-included-gettext
to prevent auto-detection.
By default the configuration process will not test for the `catgets'
function and therefore they will not be used. The reasons are already
given above: the emulation on top of `catgets' cannot provide all the
extensions provided by the GNU `gettext' library. If you nevertheless
want to use the `catgets' functions use
./configure --with-catgets
to enable the test for `catgets' (this causes no harm if `catgets' is
not available on your system). If you really select this option we
would like to hear about the reasons because we cannot think of any
good one ourself.
Internationalized packages have usually many `po/LL.po' files, where
LL gives an ISO 639 two-letter code identifying the language. Unless
translations have been forbidden at `configure' time by using the
`--disable-nls' switch, all available translations are installed
together with the package. However, the environment variable `LINGUAS'
may be set, prior to configuration, to limit the installed set.
`LINGUAS' should then contain a space separated list of two-letter
codes, stating which languages are allowed.
Using This Package
==================
As a user, if your language has been installed for this package, you
only have to set the `LANG' environment variable to the appropriate
ISO 639 `LL' two-letter code prior to using the programs in the
package. For example, let's suppose that you speak German. At the
shell prompt, merely execute `setenv LANG de' (in `csh'),
`export LANG; LANG=de' (in `sh') or `export LANG=de' (in `bash'). This
can be done from your `.login' or `.profile' file, once and for all.
An operating system might already offer message localization for
many of its programs, while other programs have been installed locally
with the full capabilities of GNU `gettext'. Just using `gettext'
extended syntax for `LANG' would break proper localization of already
available operating system programs. In this case, users should set
both `LANGUAGE' and `LANG' variables in their environment, as programs
using GNU `gettext' give preference to `LANGUAGE'. For example, some
Swedish users would rather read translations in German than English for
when Swedish is not available. This is easily accomplished by setting
`LANGUAGE' to `sv:de' while leaving `LANG' to `sv'.
Translating Teams
=================
For the Free Translation Project to be a success, we need interested
people who like their own language and write it well, and who are also
able to synergize with other translators speaking the same language.
Each translation team has its own mailing list, courtesy of Linux
International. You may reach your translation team at the address
`LL@li.org', replacing LL by the two-letter ISO 639 code for your
language. Language codes are *not* the same as the country codes given
in ISO 3166. The following translation teams exist, as of December
1997:
Chinese `zh', Czech `cs', Danish `da', Dutch `nl', English `en',
Esperanto `eo', Finnish `fi', French `fr', German `de', Hungarian
`hu', Irish `ga', Italian `it', Indonesian `id', Japanese `ja',
Korean `ko', Latin `la', Norwegian `no', Persian `fa', Polish
`pl', Portuguese `pt', Russian `ru', Slovenian `sl', Spanish `es',
Swedish `sv', and Turkish `tr'.
For example, you may reach the Chinese translation team by writing to
`zh@li.org'.
If you'd like to volunteer to *work* at translating messages, you
should become a member of the translating team for your own language.
The subscribing address is *not* the same as the list itself, it has
`-request' appended. For example, speakers of Swedish can send a
message to `sv-request@li.org', having this message body:
subscribe
Keep in mind that team members are expected to participate
*actively* in translations, or at solving translational difficulties,
rather than merely lurking around. If your team does not exist yet and
you want to start one, or if you are unsure about what to do or how to
get started, please write to `translation@iro.umontreal.ca' to reach the
coordinator for all translator teams.
The English team is special. It works at improving and uniformizing
the terminology in use. Proven linguistic skill are praised more than
programming skill, here.
Available Packages
==================
Languages are not equally supported in all packages. The following
matrix shows the current state of internationalization, as of December
1997. The matrix shows, in regard of each package, for which languages
PO files have been submitted to translation coordination.
Ready PO files cs da de en es fi fr it ja ko nl no pl pt ru sl sv
.----------------------------------------------------.
bash | [] [] [] | 3
bison | [] [] [] | 3
clisp | [] [] [] [] | 4
cpio | [] [] [] [] [] [] | 6
diffutils | [] [] [] [] [] | 5
enscript | [] [] [] [] [] [] | 6
fileutils | [] [] [] [] [] [] [] [] [] [] | 10
findutils | [] [] [] [] [] [] [] [] [] | 9
flex | [] [] [] [] | 4
gcal | [] [] [] [] [] | 5
gettext | [] [] [] [] [] [] [] [] [] [] [] | 12
grep | [] [] [] [] [] [] [] [] [] [] | 10
hello | [] [] [] [] [] [] [] [] [] [] [] | 11
id-utils | [] [] [] | 3
indent | [] [] [] [] [] | 5
libc | [] [] [] [] [] [] [] | 7
m4 | [] [] [] [] [] [] | 6
make | [] [] [] [] [] [] | 6
music | [] [] | 2
ptx | [] [] [] [] [] [] [] [] | 8
recode | [] [] [] [] [] [] [] [] [] | 9
sh-utils | [] [] [] [] [] [] [] [] | 8
sharutils | [] [] [] [] [] [] | 6
tar | [] [] [] [] [] [] [] [] [] [] [] | 11
texinfo | [] [] [] | 3
textutils | [] [] [] [] [] [] [] [] [] | 9
wdiff | [] [] [] [] [] [] [] [] | 8
`----------------------------------------------------'
17 languages cs da de en es fi fr it ja ko nl no pl pt ru sl sv
27 packages 6 4 25 1 18 1 26 2 1 12 20 9 19 7 4 7 17 179
Some counters in the preceding matrix are higher than the number of
visible blocks let us expect. This is because a few extra PO files are
used for implementing regional variants of languages, or language
dialects.
For a PO file in the matrix above to be effective, the package to
which it applies should also have been internationalized and
distributed as such by its maintainer. There might be an observable
lag between the mere existence a PO file and its wide availability in a
distribution.
If December 1997 seems to be old, you may fetch a more recent copy
of this `ABOUT-NLS' file on most GNU archive sites.

392
ChangeLog
View File

@@ -1,3 +1,389 @@
2000-02-07 Paul D. Smith <psmith@gnu.org>
For += target-specific variables we need to remember which
variable set we found the variable in, so we can start looking
there in the next iteration (otherwise we'll see it again in
recursively_expand and fail!). This is getting to be a hack; if
it gets any worse we'll have to rethink this entire algorithm;
probably implementing expansion of these separately from the
"normal" expansion, instead of alongside.
* variable.h (recursively_expand_setlist): Rename
recursively_expand to add a struct variable_set_list argument, and
make a macro for recursively_expand.
(lookup_variable_setlist): Rename lookup_variable to add a struct
variable_set_list argument, and make a macro for lookup_variable.
* expand.c (recursively_expand_setlist): Take an extra struct
variable_set_list argument and pass it to
allocated_variable_append().
(reference_variable): Use lookup_variable_setlist() and pass the
returned variable_set_list to recursively_expand_setlist.
(allocated_variable_append): Take an extra setlist argument and
use this as the starting place when searching for the appended
expansion. If it's null, use current_variable_set_list as before.
* variable.c (lookup_variable_setlist): If the LISTP argument is
not nil, return the list where we found the variable in it.
2000-02-04 Paul D. Smith <psmith@gnu.org>
* variable.c (print_variable): Write out filename/linenumber
information for the variable definition if present.
(define_variable_in_set): Store filename information if provided.
(define_variable, define_variable_for_file): Removed.
(try_variable_definition): Use define_variable_loc() to keep
variable definition location information.
* read.c (read_makefile): Keep variable definition location info.
(do_define): Ditto.
(record_target_var): Ditto.
* variable.h (define_variable_in_set): New fileinfo argument.
(define_variable, define_variable_loc, define_variable_for_file):
Declare new macros.
Fix PR/1407:
* filedef.h (struct file): Rename patvar to pat_variables and make
it just a variable_set_list; we need our own copy of the pattern
variable's variable set list here to avoid overwriting the global
one.
* variable.c (initialize_file_variables): Move the instantiation
of the pat_variables pointer here. Only do the search after we're
done reading the makefiles so we don't search too early. If
there's a pat_variables value, set up the variables next ptr.
* expand.c (variable_expand_for_file): Remove the setup of the
pat_variables info; it's done earlier now to ensure the parent's
pattern variables are set up correctly as well.
2000-02-03 Paul D. Smith <psmith@gnu.org>
* job.c (sh_chars_dos) [WINDOWS32]: Add "&" as a shell
metacharacter for the W32 DOS shell.
Reported by Warren Jones <wjones@tc.fluke.com>.
2000-02-02 Paul D. Smith <psmith@gnu.org>
Fixes for the OpenVMS port from Hartmut Becker <becker@rto.dec.com>
* config.h-vms [VMS]: Define LOCALEDIR to something; needed for
the expansion of bindtextdomain() even though it's a no-op.
* vmsfunctions.c (strcmpi): Remove duplicate definition of strcmpi().
(readdir): Use DB() instead of testing debug_flag.
* dir.c (file_impossible) [VMS]: Search "p" not "name".
* job.c [VMS]: Switch from debug_flag to the new DB macro. Add
some i18n _() macros (even though VMS doesn't yet support it).
* function.c (patsubst_expand): Change "len" to not be unsigned to
avoid type mismatches.
* main.c (main): Declare signame_init() if we're going to call it.
2000-01-29 Eli Zaretskii <eliz@is.elta.co.il>
* Makefile.DOS.template: Track changes in Makefile.in
(install-recursive, uninstall-recursive): Add missing targets.
(DESTDIR): Define.
(install-binPROGRAMS, uninstall-binPROGRAMS): Use $(DESTDIR).
* default.c (default_variables) [__MSDOS__]: Define CXX to gpp.
2000-01-25 Paul D. Smith <psmith@gnu.org>
Change gettext support to use the simplified version in libit 0.7.
* getopt.c, make.h: Use gettext.h instead of libintl.h.
* ABOUT-NLS, gettext.h, gettext.c: New files from libit 0.7.
Modified to remove some static declarations which aren't defined.
* acconfig.h: Use new gettext #defines.
* acinclude.m4: Add fp_WITH_GETTEXT; remove AM_GNU_GETTEXT.
* configure.in: Call fp_WITH_GETTEXT instead.
* Makefile.am: New gettext stuff. Also force inclusion of glob
files for systems which have LIBC glob.
* i18n/Makefile.am, i18n/.cvsignore: New dir for translation files.
* i18n/de.po, i18n/es.po, i18n/fr.po, i18n/ko.po, i18n/nl.po:
* i18n/pl.po, i18n/ru.po: Import translations already done for
earlier versions of GNU make. Thanks for that work!!
* po/Makefile.in.in, po/POTFILES.in: Removed.
2000-01-23 Paul D. Smith <psmith@gnu.org>
* main.c (decode_debug_flags): If debug_flag is set, enable all
debugging levels.
(debug_flag): Resurrect this flag variable.
(switches): Make -d give the old behavior of turning on all
debugging. Change --debug alone to emit basic debugging and take
optional arguments to expand debugging.
* NEWS: Document the new debugging options.
* remake.c (no_rule_error): Remove this function. This tries to
fix a real problem--see the description with the introduction of
this function below. However, the cure is worse than the disease
and this approach won't work.
(remake_file): Put the code from no_rule_error back here.
(update_file_1): Remove call to no_rule_error.
* filedef.h (struct file): Remove mfile_status field.
2000-01-22 Paul D. Smith <psmith@gnu.org>
Integrate GNU gettext support.
* configure.in: Add AM_GNU_GETTEXT.
* Makefile.am: Add options for setting LOCALEDIR, -Iintl, etc.
* acinclude.m4: Add gettext autoconf macros.
* acconfig.h: Add new gettext #defines.
* make.h: Include libintl.h. Make sure _() and N_() macros are
declared. Make gettext() an empty macro is NLS is disabled.
* main.c (struct command_switch switches[]): Can't initialize
static data with _() (gettext calls), so use N_() there then use
gettext() directly when printing the strings.
* remake.c (no_rule_error): The string constants can't be static
when initializing _() macros.
* file.c (print_file): Reformat a few strings to work better for
translation.
* po/POTFILES.in, po/Makefile.in.in: New files. Take
Makefile.in.in from the latest GNU tar distribution, as that
version works better than the one that comes with gettext.
* NEWS: Mention i18n ability.
2000-01-21 Paul D. Smith <psmith@gnu.org>
Installed patches for the VMS port.
Patches provided by: Hartmut Becker <Hartmut.Becker@compaq.com>
* readme.vms, arscan.c, config.h-vms, default.c, dir.c, file.c:
* implicit.c, job.c, make.h, makefile.com, makefile.vms, rule.c:
* variable.c, vmsdir.h, vmsfunctions.c, vmsify.c, glob/glob.c:
* glob/glob.h: Installed patches. See readme.vms for details.
2000-01-14 Andreas Schwab <schwab@suse.de>
* dir.c (read_dirstream): Initialize d_type if it exists.
2000-01-11 Paul D. Smith <psmith@gnu.org>
Resolve PR/xxxx: don't automatically evaluate the $(call ...)
function's arguments. While we're here, clean up argument passing
protocol to always use simple nul-terminated strings, instead of
sometimes using offset pointers to mark the end of arguments.
This change also fixes PR/1517.
Reported by Damien GIBOU <damien.gibou@st.com>.
* function.c (struct function_table_entry): Remove the negative
required_args hack; put in explicit min and max # of arguments.
(function_table): Add in the max value. Turn off the expand bit
for func_call.
(expand_builtin_function): Test against minimum_args instead of
the obsolete required_args.
(handle_function): Rewrite this. We don't try to be fancy and
pass one style of arguments to expanded functions and another
style to non-expanded functions: pass pointers to nul-terminated
strings to all functions.
(func_call): Rewrite this. If we are invoking a builtin function
and it's supposed to have its arguments expanded, do that (since
it's not done by handle_function for $(call ...) anymore). For
non-builtins, just add the variables as before but mark them as
recursive so they'll be expanded later, as needed.
(func_if): All arguments are vanilla nul-terminated strings:
remove trickery with "argv[1]-1".
(func_foreach): Ditto.
* expand.c (expand_argument): If the second arg is NULL, expand
the entire first argument.
* job.c (new_job): Zero the child struct. This change was just
made to keep some heap checking software happy, not because there
was an actual bug (the important memory was being cleared properly).
1999-12-15 Paul D. Smith <psmith@gnu.org>
* variable.c (print_variable): Print the variable with += if the
append flag is set.
* implicit.c (pattern_search): Remove the extra check of the
implicit flag added on 8/24/1998. This causes problems and the
reason for the change was better resolved by the change made to
check_deps() on 1998-08-26. This fixes PR/1423.
1999-12-08 Paul D. Smith <psmith@gnu.org>
* dir.c (dir_setup_glob): On 64 bit ReliantUNIX (5.44 and above)
in LFS mode, stat() is actually a macro for stat64(). Assignment
doesn't work in that case. So, stat is a macro, make a local
wrapper function to invoke it.
(local_stat): Wrapper function, if needed.
Reported by Andrej Borsenkow <Andrej.Borsenkow@mow.siemens.ru>.
1999-12-02 Paul D. Smith <psmith@gnu.org>
* remake.c (update_file): Move the considered test outside the
double-colon loop, _but_ make sure we test the double_colon target
not the "current" target. If we stop early because one
double-colon target is running, mark all the rest considered and
try to start their prerequisites (so they're marked considered).
Fix for PR/1476 suggested by Tim Magill <tim.magill@telops.gte.com>.
1999-11-22 Rob Tulloh <rob_tulloh@dev.tivoli.com>
* function.c (windows32_openpipe, func_shell): Correct Windows32
problem where $(shell nosuchfile) would incorrectly exit make. The
fix is to print the error and let make continue.
Reported by David Masterson <David.Masterson@kla-tencor.com>.
* w32/subproc/misc.c (arr2envblk): Memory leak fix.
1999-11-21 Paul D. Smith <psmith@gnu.org>
Rework GNU make debugging to provide different levels of output.
* NEWS: mention it.
* debug.h: New file. Define various debugging levels and macros.
* function.c, implicit.c, job.c, main.c, misc.c, read.c, remake.c
* remote-cstms.c, vmsfunctions.c: Replace all code depending on
debug_flag with invocations of debugging macros.
* make.h: Remove debug_flag and DEBUGPR, add db_level.
1999-11-18 Paul Eggert <eggert@twinsun.com>
* acinclude.m4 (AC_SYS_LARGEFILE_FLAGS): Work around a problem
with the QNX 4.25 shell, which doesn't propagate exit status of
failed commands inside shell assignments.
1999-11-17 Paul D. Smith <psmith@gnu.org>
* function.c (func_if): Find the end of the arg list by testing
the next item for NULL; any other test is not correct.
Reported by Graham Reed <grahamr@algorithmics.com> (PR/1429).
Fix += when used in a target-specific variable context.
* variable.h: New bitfield APPEND set if we have a +=
target-specific variable.
* variable.c (try_variable_definition): Add an argument to specify
if we're trying a target-specific variable. If we are and it's an
append style, don't append it, record it as normal recursive, but
set the APPEND flag so it'll be expanded later.
* main.c (handle_non_switch_argument): Use new
try_variable_definition() signature.
* read.c (read_makefile,record_target_var): Ditto.
* expand.c (allocated_variable_append): New function: like
allocated_variable_expand(), but we expand the same variable name
in the context of the ``next'' variable set, then we append this
expanded value.
(recursively_expand): Invoke it, if the APPEND bit is set.
1999-11-10 Paul D. Smith <psmith@gnu.org>
* file.c (snap_deps): If the .NOTPARALLEL target is defined, turn
off parallel builds for this make only (still allow submakes to be
run in parallel).
* main.c: New variable, ``not_parallel''.
* make.h: Add an extern for it.
* job.c (new_job): Test NOT_PARALLEL as well as JOB_SLOTS.
* NEWS: Add info on .NOTPARALLEL.
* make.texinfo (Special Targets): Document it.
* configure.in (GLOBDIR): Set to "glob" if we need to build the
glob library.
* Makefile.am (SUBDIRS): Use the GLOBDIR variable instead of
"glob" so we don't try to build glob if we don't need to (if we
have GLIBC glob). Reported by Lars Hecking <lhecking@nmrc.ucc.ie>.
* main.c (main): Don't put "***" in the clock skew warning
message. Reported by karl@gnu.org.
* make.h: Remove unneeded signal setup.
* signame.c: Remove extraneous #includes; some versions of Ultrix
don't protect against multiple inclusions and it causes compile
errors. Reported by Simon Burge <simonb@thistledown.com.au>.
1999-10-15 Paul D. Smith <psmith@gnu.org>
* main.c (quote_for_env): Rename from quote_as_word().
* make.h, *.c: Prefer strchr() and strrchr() in the code
rather than index() and rindex(). Define strchr/strrchr in terms
of index/rindex if the former aren't supported.
* default.c (CHECKOUT,v): Replace the fancy, complicated
patsubst/filter expression with a simple $(if ...) expression.
* main.c (print_usage): Add the bug reporting mailing address to
the --help output, as per the GNU coding standards.
Reported by Paul Eggert <eggert@twinsun.com>.
* README.customs: Installed information on running Customs-ized
GNU make and setuid root, collected by Ted Stern <stern@tera.com>.
* read.c (read_all_makefiles): PR/1394: Mark the end of the next
token in the MAKEFILES value string _before_ we dup it.
1999-10-13 Paul D. Smith <psmith@gnu.org>
* configure.in (make_cv_sys_gnu_glob): We used to add the -Iglob
flag to CPPFLAGS, but that loses if the user specifies his own
CPPFLAGS; this one gets added _after_ his and if he happens to
have an old or broken glob.h--boom. Instead, put it in GLOBINC
and SUBST it.
* Makefile.am (INCLUDES): Add @GLOBINC@ to the INCLUDES macro;
these things get on the compile line well before the user's
CPPFLAGS.
1999-10-12 Paul D. Smith <psmith@gnu.org>
* remake.c (notice_finished_file): If we get here and -n is set,
see if all the command lines are marked recursive. If so, then we
ran every command there is, so check the mtime on this file just
like we would normally. If not, we assume the command we didn't
run would updates the target and set mtime of the target to "very new".
* job.c (start_job_command): Update lines_flags in the file's cmds
structure with any per-line tokens we found (`@', `-', `+').
1999-10-08 Paul D. Smith <psmith@gnu.org>
* variable.c (initialize_file_variables): Always recurse to
initialize the parent's file variables: the parent might not have
any rules to run so it might not have been initialized before
this--we need this to set up the chain properly for
target-specific variables.
1999-09-29 Paul Eggert <eggert@twinsun.com>
* main.c (quote_as_word): Always quote for decode_env_switches
instead of for the shell, so that arguments with strange
characters are are passed to submakes correctly. Remove
double_dollars arg; we always double dollars now. All callers
changed.
(decode_env_switches): Don't run off the end of an environment
variable whose contents ends in a unescaped backslash.
1999-09-23 Paul D. Smith <psmith@gnu.org>
* commands.c, function.c, job.c, read.c: Cast arguments to
ctype.h functions/macros to _unsigned_ char for portability.
* remake.c, function.c: Compiler warning fixes: the second
argument to find_next_token() should be an _unsigned_ int*.
Reported by Han-Wen Nienhuys <hanwen@cs.uu.nl>.
1999-09-23 Paul D. Smith <psmith@gnu.org>
* Version 3.78.1 released.
* make.texinfo: Update version/date stamp.
* main.c (main): Argh. For some reason we were closing _all_ the
jobserver pipes before we re-exec'd due to changed makefiles.
This means that any re-exec got a "jobserver unavailable" error :-/.
I can't believe we didn't notice this before.
1999-09-22 Paul D. Smith <psmith@gnu.org>
* Version 3.78 released.
@@ -764,9 +1150,9 @@
a bit saying whether we've seen this target in this pass or not.
(update_goal_chain): Initially set the global considered toggle to
1, since all targets initialize their boolean to 0. At the end of
each pass, toggle the global considered variable. * filedef.h
(struct file): Per-file considered toggle bit. * file.c: New
global toggle variable considered.
each pass, toggle the global considered variable.
* filedef.h (struct file): Per-file considered toggle bit.
* file.c: New global toggle variable considered.
1999-04-05 Paul D. Smith <psmith@gnu.org>

View File

@@ -5,8 +5,6 @@
# This Makefile.DOS is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
# -*-Makefile-*-, or close enough
SHELL = /bin/sh
@@ -14,7 +12,7 @@ srcdir = .
VPATH = $(srcdir)
# $DJDIR is defined automatically by DJGPP to point
# to the root of the DJGPP installation tree.
prefix = ${DJDIR}
prefix = /dev/env/DJDIR
exec_prefix = ${prefix}
bindir = ${exec_prefix}/bin
@@ -26,9 +24,12 @@ mandir = ${prefix}/info
includedir = ${prefix}/include
oldincludedir = c:/djgpp/include
DESTDIR =
pkgdatadir = $(datadir)/make
pkglibdir = $(libdir)/make
pkgincludedir = $(includedir)/make
localedir = $(prefix)/share/locale
INSTALL = ${bindir}/ginstall -c
INSTALL_PROGRAM = ${bindir}/ginstall -c
@@ -70,11 +71,11 @@ make_LDADD = glob/libglob.a
info_TEXINFOS = make.texinfo
man_MANS = make.1
INCLUDES = -I$(srcdir)/glob -DLIBDIR=\"c:/djgpp/lib\" -DINCLUDEDIR=\"c:/djgpp/include\"
INCLUDES = -I$(srcdir)/glob -DLIBDIR=\"c:/djgpp/lib\" -DINCLUDEDIR=\"c:/djgpp/include\" -DLOCALEDIR=\"$(localedir)\"
BUILT_SOURCES = README build.sh.in
BUILT_SOURCES = README build.sh-in
EXTRA_DIST = $(BUILT_SOURCES) $(man_MANS) README.customs remote-cstms.c make-stds.texi texinfo.tex SCOPTIONS SMakefile Makefile.ami README.Amiga config.ami amiga.c amiga.h NMakefile README.DOS configh.dos configure.bat makefile.com README.W32 build_w32.bat config.h.W32 subproc.bat make.lnk config.h-vms makefile.vms readme.vms vmsdir.h vmsfunctions.c vmsify.c
EXTRA_DIST = $(BUILT_SOURCES) $(man_MANS) README.customs remote-cstms.c make-stds.texi texinfo.tex SCOPTIONS SMakefile Makefile.ami README.Amiga config.ami amiga.c amiga.h NMakefile README.DOS configh.dos configure.bat makefile.com README.W32 build_w32.bat config.h-W32 subproc.bat make.lnk config.h-vms makefile.vms readme.vms vmsdir.h vmsfunctions.c vmsify.c
SUBDIRS = glob
mkinstalldirs = ${bindir}/gmkdir -p
@@ -107,7 +108,7 @@ man1dir = $(mandir)/man1
MANS = $(man_MANS)
NROFF = nroff
DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am Makefile.in NEWS acconfig.h aclocal.m4 alloca.c build.sh.in config.h.in configure configure.in getloadavg.c install-sh missing mkinstalldirs stamp-h.in texinfo.tex
DIST_COMMON = README ABOUT-NLS AUTHORS COPYING ChangeLog INSTALL Makefile.am Makefile.in NEWS acconfig.h aclocal.m4 alloca.c build.sh.in config.h.in configure configure.in getloadavg.c gettext.c install-sh missing mkinstalldirs stamp-h.in texinfo.tex
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
@@ -144,11 +145,11 @@ maintainer-clean-binPROGRAMS:
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(bindir)
@list='$(bin_PROGRAMS)'; for p in $$list; do if test -f $$p; then echo " $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p | sed '$(transform)'`"; $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p | sed '$(transform)'`; else :; fi; done
@list='$(bin_PROGRAMS)'; for p in $$list; do if test -f $$p; then echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p | sed '$(transform)'`"; $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p | sed '$(transform)'`; else :; fi; done
uninstall-binPROGRAMS:
$(NORMAL_UNINSTALL)
list='$(bin_PROGRAMS)'; for p in $$list; do rm -f $(bindir)/`echo $$p|sed '$(transform)'`.exe; done
list='$(bin_PROGRAMS)'; for p in $$list; do rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`.exe; done
.c.o:
$(COMPILE) -c $<
@@ -388,6 +389,9 @@ install-exec: install-exec-recursive install-exec-am
install-data: install-data-recursive install-data-am
@$(NORMAL_INSTALL)
install-recursive uninstall-recursive:
@:
install: install-recursive install-exec-am install-data-am
@:

View File

@@ -2,35 +2,60 @@
AUTOMAKE_OPTIONS = 1.4
SUBDIRS = $(GLOBDIR) i18n
bin_PROGRAMS = make
make_SOURCES = main.c commands.c job.c dir.c file.c misc.c read.c remake.c \
rule.c implicit.c default.c variable.c expand.c function.c \
vpath.c version.c ar.c arscan.c remote-$(REMOTE).c \
commands.h dep.h filedef.h job.h make.h rule.h variable.h \
signame.c signame.h \
getopt.c getopt1.c getopt.h
make_LDADD = @LIBOBJS@ @ALLOCA@ @GLOBLIB@
# These source files also have gettext references
SRCS = ar.c arscan.c commands.c dir.c expand.c file.c function.c \
getopt.c implicit.c job.c main.c misc.c read.c remake.c \
rule.c signame.c variable.c vpath.c
make_SOURCES = $(SRCS) default.c remote-$(REMOTE).c version.c \
getopt1.c
noinst_HEADERS = commands.h dep.h filedef.h job.h make.h rule.h variable.h \
debug.h signame.h getopt.h gettext.h
make_LDADD = $(LIBOBJS) @ALLOCA@ $(GLOBLIB)
info_TEXINFOS = make.texinfo
man_MANS = make.1
info_TEXINFOS = make.texinfo
INCLUDES = -DLIBDIR=\"$(libdir)\" -DINCLUDEDIR=\"$(includedir)\"
DEFS = -DALIASPATH=\"$(aliaspath)\" -DLOCALEDIR=\"$(localedir)\" -DLIBDIR=\"$(libdir)\" -DINCLUDEDIR=\"$(includedir)\" @DEFS@
INCLUDES = -I. -I$(srcdir) $(GLOBINC)
EXTRA_DIST = README build.sh.in $(man_MANS) README.customs remote-cstms.c\
make-stds.texi texinfo.tex SCOPTIONS SMakefile\
make-stds.texi SCOPTIONS SMakefile\
README.Amiga Makefile.ami config.ami make.lnk amiga.c amiga.h\
README.DOS Makefile.DOS configure.bat dosbuild.bat configh.dos\
README.W32 NMakefile config.h.W32 build_w32.bat subproc.bat\
readme.vms makefile.vms makefile.com config.h-vms vmsdir.h\
vmsfunctions.c vmsify.c
SUBDIRS = glob
vmsfunctions.c vmsify.c\
gettext.c\
glob/COPYING.LIB glob/ChangeLog glob/Makefile.am\
glob/Makefile.ami glob/Makefile.in glob/SCOPTIONS\
glob/SMakefile glob/configure.bat glob/fnmatch.c\
glob/fnmatch.h glob/glob.c glob/glob.h
MOSTLYCLEANFILES = loadavg.c
CLEANFILES = loadavg
MAKE_HOST = @MAKE_HOST@
MAKE_HOST = @MAKE_HOST@
# --------------- Internationalization Section
POTFILES = $(SRCS) remote-cstms.c vmsfunctions.c
localedir = $(prefix)/share/locale
aliaspath = $(localedir):.
all-local: $(srcdir)/stamp-pot
$(srcdir)/stamp-pot: $(POTFILES)
@echo "$(POTFILES)" > $@
# --------------- Local INSTALL Section
@@ -90,7 +115,7 @@ check-local: check-regression check-loadavg
#
loadavg: loadavg.c config.h
@rm -f loadavg
$(LINK) $(DEFS) $(CPPFLAGS) -DTEST $(make_LDFLAGS) loadavg.c $(LIBS)
$(LINK) -DTEST $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(make_LDFLAGS) loadavg.c $(LIBS)
# We copy getloadavg.c into a different file rather than compiling it
# directly because some compilers clobber getloadavg.o in the process.

51
NEWS
View File

@@ -1,17 +1,62 @@
GNU make NEWS -*-indented-text-*-
History of user-visible changes.
17 Sep 1999
25 Jan 2000
Copyright (C) 1992,93,94,95,96,97,98,1999 Free Software Foundation, Inc.
Copyright (C) 1992,93,94,95,96,97,98,99,2000 Free Software Foundation, Inc.
See the end for copying conditions.
All changes mentioned here are more fully described in the GNU make
manual, which is contained in this distribution as the file make.texinfo.
Please send GNU make bug reports to bug-make@gnu.org.
Please send GNU make bug reports to <bug-make@gnu.org>.
See the README file and the GNU make manual for details on sending bug
reports.
Version 3.79
* GNU make optionally supports internationalization and locales via the
GNU gettext (or local gettext if suitable) package. See the ABOUT-NLS
file for more information on configuring GNU make for NLS.
* Previously, GNU make quoted variables such as MAKEFLAGS and
MAKEOVERRIDES for proper parsing by the shell. This allowed them to
be used within make build scripts. However, using them there is not
proper behavior: they are meant to be passed to subshells via the
environment. Unfortunately the values were not quoted properly to be
passed through the environment. This meant that make didn't properly
pass some types of command line values to submakes.
With this version we change that behavior: now these variables are
quoted properly for passing through the environment, which is the
correct way to do it. If you previously used these variables
explicitly within a make rule you may need to re-examine your use for
correctness given this change.
* A new psuedo-target .NOTPARALLEL is available. If defined, the
current makefile is run serially regardless of the value of -j.
However, submakes are still eligible for parallel execution.
* The $(call ...) function doesn't expand its arguments automatically
anymore. This allows you to put builtin functions like "if" and
"foreach", which also have special expansion rules, in a $(call ...)
function and have it work properly. This was suggested by Damien
GIBOU <damien.gibou@st.com>.
* The --debug option has changed: it now allows optional flags
controlling the amount and type of debugging output. By default only
a minimal amount information is generated, displaying the names of
"normal" targets (not makefiles) were deemed out of date and in need
of being rebuilt.
Note that the -d option behaves as before: it takes no arguments and
all debugging information is generated.
* The `-p' (print database) output now includes filename and linenumber
information for variable definitions, to help debugging.
* Hartmut Becker provided many updates for the VMS port of GNU make.
See the readme.vms file for more details.
Version 3.78
* Two new functions, $(error ...) and $(warning ...) are available. The

View File

@@ -56,6 +56,28 @@ See the documentation for Customs for information on starting and
configuring Customs.
INVOKING CUSTOMS-IZED GNU MAKE
-----------------------------
One thing you should be aware of is that the default build environment
for Customs requires root permissions. Practically, this means that GNU
make must be installed setuid root to use Customs.
If you don't want to do this, you can build Customs such that root
permissions are not necessary. Andreas Stolcke <stolcke@speech.sri.com>
writes:
> pmake, gnumake or any other customs client program is not required to
> be suid root if customs was compiled WITHOUT the USE_RESERVED_PORTS
> option in customs/config.h. Make sure the "customs" service in
> /etc/services is defined accordingly (port 8231 instead of 1001).
> Not using USE_RESERVED_PORTS means that a user with programming
> skills could impersonate another user by writing a fake customs
> client that pretends to be someone other than himself. See the
> discussion in etc/SECURITY.
PROBLEMS
--------

View File

@@ -4,6 +4,24 @@
/* Version of this package (needed by automake) */
#undef VERSION
/* Define to 1 if NLS is requested. */
#undef ENABLE_NLS
/* Define as 1 if you have dcgettext. */
#undef HAVE_DCGETTEXT
/* Define as 1 if you have gettext and don't want to use GNU gettext. */
#undef HAVE_GETTEXT
/* Define if your locale.h file contains LC_MESSAGES. */
#undef HAVE_LC_MESSAGES
/* Define to the installation directory for locales. */
#undef LOCALEDIR
/* Define as 1 if you have the stpcpy function. */
#undef HAVE_STPCPY
/* Define to the name of the SCCS `get' command. */
#undef SCCS_GET

View File

@@ -101,7 +101,10 @@ dnl AC_SYS_LARGEFILE_FLAGS(FLAGSNAME)
AC_DEFUN(AC_SYS_LARGEFILE_FLAGS,
[AC_CACHE_CHECK([for $1 value to request large file support],
ac_cv_sys_largefile_$1,
[ac_cv_sys_largefile_$1=`($GETCONF LFS_$1) 2>/dev/null` || {
[if ($GETCONF LFS_$1) >conftest.1 2>conftest.2 && test ! -s conftest.2
then
ac_cv_sys_largefile_$1=`cat conftest.1`
else
ac_cv_sys_largefile_$1=no
ifelse($1, CFLAGS,
[case "$host_os" in
@@ -127,7 +130,8 @@ changequote([, ])dnl
AC_TRY_LINK(, , , ac_cv_sys_largefile_CFLAGS=no)
CC="$ac_save_CC"
fi])
}])])
fi
rm -f conftest*])])
dnl Internal subroutine of AC_SYS_LARGEFILE.
dnl AC_SYS_LARGEFILE_SPACE_APPEND(VAR, VAL)
@@ -478,3 +482,93 @@ case "x$am_cv_prog_cc_stdc" in
*) CC="$CC $am_cv_prog_cc_stdc" ;;
esac
])
dnl ---------------------------------------------------------------------------
dnl Enable internationalization support for GNU make.
dnl Obtained from the libit 0.7 distribution
dnl
AC_DEFUN(fp_WITH_GETTEXT, [
AC_MSG_CHECKING(whether NLS is wanted)
AC_ARG_ENABLE(nls,
[ --disable-nls disallow Native Language Support],
enable_nls=$enableval, enable_nls=yes)
AC_MSG_RESULT($enable_nls)
use_nls=$enable_nls
AM_CONDITIONAL(USE_NLS, test $use_nls = yes)
if test $enable_nls = yes; then
AC_DEFINE(ENABLE_NLS)
AC_ARG_WITH(catgets,
[ --with-catgets say that catgets is not supported],
[AC_MSG_WARN([catgets not supported, --with-catgets ignored])])
AC_CHECK_FUNCS(gettext)
AC_CHECK_LIB(intl, gettext, :)
if test $ac_cv_lib_intl_gettext$ac_cv_func_gettext != nono; then
AC_MSG_CHECKING(whether the included gettext is preferred)
AC_ARG_WITH(included-gettext,
[ --without-included-gettext avoid our provided version of gettext],
with_included_gettext=$withval, with_included_gettext=yes)
AC_MSG_RESULT($with_included_gettext)
if test $with_included_gettext$ac_cv_func_gettext = nono; then
LIBS="$LIBS -lintl"
fi
else
with_included_gettext=yes
fi
if test $with_included_gettext = yes; then
LIBOBJS="$LIBOBJS gettext.o"
AC_DEFINE(HAVE_GETTEXT)
AC_DEFINE(HAVE_DCGETTEXT)
else
AC_CHECK_HEADERS(libintl.h)
AC_CHECK_FUNCS(dcgettext gettext)
fi
AC_CHECK_HEADERS(locale.h)
AC_CHECK_FUNCS(getcwd setlocale stpcpy)
AM_LC_MESSAGES
if test -z "$ALL_LINGUAS"; then
AC_MSG_WARN(This package does not install translations yet.)
else
ac_items="$ALL_LINGUAS"
for ac_item in $ac_items; do
ALL_POFILES="$ALL_POFILES $ac_item.po"
ALL_MOFILES="$ALL_MOFILES $ac_item.mo"
done
fi
AC_SUBST(ALL_LINGUAS)
AC_SUBST(ALL_POFILES)
AC_SUBST(ALL_MOFILES)
AC_MSG_CHECKING(which translations to install)
if test -z "$LINGUAS"; then
ac_print="$ALL_LINGUAS"
MOFILES="$ALL_MOFILES"
else
ac_items="$LINGUAS"
for ac_item in $ac_items; do
case "$ALL_LINGUAS" in
*$ac_item*)
ac_print="$ac_print $ac_item"
MOFILES="$MOFILES $ac_item.mo"
;;
esac
done
fi
AC_SUBST(MOFILES)
if test -z "$ac_print"; then
AC_MSG_RESULT(none)
else
AC_MSG_RESULT($ac_print)
fi
if test "x$prefix" = xNONE; then
AC_DEFINE_UNQUOTED(LOCALEDIR, "$ac_default_prefix/share/locale")
else
AC_DEFINE_UNQUOTED(LOCALEDIR, "$prefix/share/locale")
fi
fi])

4
ar.c
View File

@@ -41,7 +41,7 @@ int
ar_name (name)
char *name;
{
char *p = index (name, '('), *end = name + strlen (name) - 1;
char *p = strchr (name, '('), *end = name + strlen (name) - 1;
if (p == 0 || p == name || *end != ')')
return 0;
@@ -61,7 +61,7 @@ void
ar_parse_name (name, arname_p, memname_p)
char *name, **arname_p, **memname_p;
{
char *p = index (name, '('), *end = name + strlen (name) - 1;
char *p = strchr (name, '('), *end = name + strlen (name) - 1;
if (arname_p != 0)
*arname_p = savestring (name, p - name);

View File

@@ -37,8 +37,6 @@ USA. */
#include <lbr$routines.h>
#endif
#define uppercasify(str) {char *str1; for (str1 = str; *str1; str1++) *str1 = _toupper(*str1);}
static void *VMS_lib_idx;
static char *VMS_saved_memname;
@@ -80,10 +78,12 @@ VMS_get_member_info (module, rfa)
mhd = (struct mhddef *) filename;
#ifdef __DECC
val = decc$fix_time (&mhd->mhd$l_datim);
#endif
for (i = 0; i < module->dsc$w_length; i++)
filename[i] = _tolower (module->dsc$a_pointer[i]);
filename[i] = _tolower ((unsigned char)module->dsc$a_pointer[i]);
filename[i] = '\0';
@@ -172,7 +172,7 @@ ar_scan (archive, function, arg)
/* For comparison, delete .obj from arg name. */
p = rindex (VMS_saved_memname, '.');
p = strrchr (VMS_saved_memname, '.');
if (p)
*p = '\0';
@@ -698,7 +698,7 @@ ar_name_equal (name, mem, truncated)
{
char *p;
p = rindex (name, '/');
p = strrchr (name, '/');
if (p != 0)
name = p + 1;

View File

@@ -46,7 +46,7 @@ set_file_variables (file)
if (ar_name (file->name))
{
unsigned int len;
p = index (file->name, '(');
p = strchr (file->name, '(');
at = (char *) alloca (p - file->name + 1);
bcopy (file->name, at, p - file->name);
at[p - file->name] = '\0';
@@ -75,7 +75,7 @@ set_file_variables (file)
#ifndef NO_ARCHIVES
if (ar_name (file->name))
{
name = index (file->name, '(') + 1;
name = strchr (file->name, '(') + 1;
len = strlen (name) - 1;
}
else
@@ -108,7 +108,7 @@ set_file_variables (file)
less = at;
#define DEFINE_VARIABLE(name, len, value) \
(void) define_variable_for_file (name, len, value, o_automatic, 0, file)
(void) define_variable_for_file (name,len,value,o_automatic,0,file)
/* Define the variables. */
@@ -146,7 +146,7 @@ set_file_variables (file)
#ifndef NO_ARCHIVES
if (ar_name (c))
{
c = index (c, '(') + 1;
c = strchr (c, '(') + 1;
len = strlen (c) - 1;
}
else
@@ -188,7 +188,7 @@ set_file_variables (file)
#ifndef NO_ARCHIVES
if (ar_name (c))
{
c = index (c, '(') + 1;
c = strchr (c, '(') + 1;
len = strlen (c) - 1;
}
else
@@ -233,93 +233,97 @@ void
chop_commands (cmds)
register struct commands *cmds;
{
if (cmds != 0 && cmds->command_lines == 0)
{
/* Chop CMDS->commands up into lines in CMDS->command_lines.
register char *p;
unsigned int nlines, idx;
char **lines;
/* If we don't have any commands,
or we already parsed them, never mind. */
if (!cmds || cmds->command_lines != 0)
return;
/* Chop CMDS->commands up into lines in CMDS->command_lines.
Also set the corresponding CMDS->lines_flags elements,
and the CMDS->any_recurse flag. */
register char *p;
unsigned int nlines, idx;
char **lines;
nlines = 5;
lines = (char **) xmalloc (5 * sizeof (char *));
idx = 0;
p = cmds->commands;
while (*p != '\0')
{
char *end = p;
find_end:;
end = index (end, '\n');
if (end == 0)
end = p + strlen (p);
else if (end > p && end[-1] == '\\')
{
int backslash = 1;
register char *b;
for (b = end - 2; b >= p && *b == '\\'; --b)
backslash = !backslash;
if (backslash)
{
++end;
goto find_end;
}
}
nlines = 5;
lines = (char **) xmalloc (5 * sizeof (char *));
idx = 0;
p = cmds->commands;
while (*p != '\0')
{
char *end = p;
find_end:;
end = strchr (end, '\n');
if (end == 0)
end = p + strlen (p);
else if (end > p && end[-1] == '\\')
{
int backslash = 1;
register char *b;
for (b = end - 2; b >= p && *b == '\\'; --b)
backslash = !backslash;
if (backslash)
{
++end;
goto find_end;
}
}
if (idx == nlines)
{
nlines += 2;
lines = (char **) xrealloc ((char *) lines,
nlines * sizeof (char *));
}
lines[idx++] = savestring (p, end - p);
p = end;
if (*p != '\0')
++p;
}
if (idx == nlines)
{
nlines += 2;
lines = (char **) xrealloc ((char *) lines,
nlines * sizeof (char *));
}
lines[idx++] = savestring (p, end - p);
p = end;
if (*p != '\0')
++p;
}
if (idx != nlines)
{
nlines = idx;
lines = (char **) xrealloc ((char *) lines,
nlines * sizeof (char *));
}
if (idx != nlines)
{
nlines = idx;
lines = (char **) xrealloc ((char *) lines,
nlines * sizeof (char *));
}
cmds->ncommand_lines = nlines;
cmds->command_lines = lines;
cmds->ncommand_lines = nlines;
cmds->command_lines = lines;
cmds->any_recurse = 0;
cmds->lines_flags = (char *) xmalloc (nlines);
for (idx = 0; idx < nlines; ++idx)
{
int flags = 0;
cmds->any_recurse = 0;
cmds->lines_flags = (char *) xmalloc (nlines);
for (idx = 0; idx < nlines; ++idx)
{
int flags = 0;
for (p = lines[idx];
isblank (*p) || *p == '-' || *p == '@' || *p == '+';
++p)
switch (*p)
{
case '+':
flags |= COMMANDS_RECURSE;
break;
case '@':
flags |= COMMANDS_SILENT;
break;
case '-':
flags |= COMMANDS_NOERROR;
break;
}
if (!(flags & COMMANDS_RECURSE))
{
unsigned int len = strlen (p);
if (sindex (p, len, "$(MAKE)", 7) != 0
|| sindex (p, len, "${MAKE}", 7) != 0)
flags |= COMMANDS_RECURSE;
}
for (p = lines[idx];
isblank (*p) || *p == '-' || *p == '@' || *p == '+';
++p)
switch (*p)
{
case '+':
flags |= COMMANDS_RECURSE;
break;
case '@':
flags |= COMMANDS_SILENT;
break;
case '-':
flags |= COMMANDS_NOERROR;
break;
}
if (!(flags & COMMANDS_RECURSE))
{
unsigned int len = strlen (p);
if (sindex (p, len, "$(MAKE)", 7) != 0
|| sindex (p, len, "${MAKE}", 7) != 0)
flags |= COMMANDS_RECURSE;
}
cmds->lines_flags[idx] = flags;
cmds->any_recurse |= flags & COMMANDS_RECURSE;
}
cmds->lines_flags[idx] = flags;
cmds->any_recurse |= flags & COMMANDS_RECURSE;
}
}
@@ -337,13 +341,11 @@ execute_file_commands (file)
the commands are nothing but whitespace. */
for (p = file->cmds->commands; *p != '\0'; ++p)
if (!isspace (*p) && *p != '-' && *p != '@')
if (!isspace ((unsigned char)*p) && *p != '-' && *p != '@')
break;
if (*p == '\0')
{
/* We are all out of commands.
If we have gotten this far, all the previous commands
have run successfully, so we have winning update status. */
/* If there are no commands, assume everything worked. */
set_command_state (file, cs_running);
file->update_status = 0;
notice_finished_file (file);
@@ -352,7 +354,7 @@ execute_file_commands (file)
/* First set the automatic variables according to this file. */
initialize_file_variables (file);
initialize_file_variables (file, 0);
set_file_variables (file);
@@ -546,10 +548,10 @@ print_commands (cmds)
{
char *end;
while (isspace (*s))
while (isspace ((unsigned char)*s))
++s;
end = index (s, '\n');
end = strchr (s, '\n');
if (end == 0)
end = s + strlen (s);

View File

@@ -1,4 +1,4 @@
/* config.h-vms. Generated by hand by Klaus Kämpf <kkaempf@progis.de> */
/* config.h-vms. Generated by hand by Klaus Kämpf <kkaempf@rmi.de> */
/* config.h. Generated automatically by configure. */
/* config.h.in. Generated automatically from configure.in by autoheader. */
@@ -11,6 +11,28 @@
/* Define if using alloca.c. */
/* #undef C_ALLOCA */
/* maybe this should be placed into make.h */
#if defined(__VAX) && defined(__DECC)
#define alloca(n) __ALLOCA(n)
#endif
/* Define to 1 if NLS is requested. */
/* #undef ENABLE_NLS */
/* Define as 1 if you have dcgettext. */
/* #undef HAVE_DCGETTEXT */
/* Define as 1 if you have gettext and don't want to use GNU gettext. */
/* #undef HAVE_GETTEXT */
/* Define if your locale.h file contains LC_MESSAGES. */
/* #undef HAVE_LC_MESSAGES */
/* Define to the installation directory for locales. */
#define LOCALEDIR ""
/* Define as 1 if you have the stpcpy function. */
/* #undef HAVE_STPCPY */
/* Define if the closedir function returns void instead of int. */
/* #undef CLOSEDIR_VOID */
@@ -117,18 +139,17 @@
/* #undef NO_MINUS_C_MINUS_O */
/* Define to `int' if <sys/types.h> doesn't define. */
/* #undef pid_t */
/* I assume types.h is available for all 5.0 cc/cxx compilers */
#if __DECC_VER < 50090000
#define pid_t int
#endif
/* Define if the system does not provide POSIX.1 features except
with this defined. */
/* #undef _POSIX_1_SOURCE */
#include <sys/types.h>
#include <ctype.h>
#include <signal.h>
/* Define if you need to in order for stat and other things to work. */
#define _POSIX_C_SOURCE 1
/* #undef _POSIX_SOURCE */
/* Define as the return type of signal handlers (int or void). */
#define RETSIGTYPE void
@@ -160,7 +181,9 @@
/* #undef SYS_SIGLIST_DECLARED */
/* Define to `int' if <sys/types.h> doesn't define. */
/* #undef uid_t */
#if __DECC_VER < 50090000
#define uid_t int
#endif
/* Define for Encore UMAX. */
/* #undef UMAX */
@@ -267,7 +290,7 @@
/* #undef HAVE_WAITPID */
/* Define if you have the <dirent.h> header file. */
/* #undef HAVE_DIRENT_H */
#define HAVE_DIRENT_H 1
/* Define if you have the <fcntl.h> header file. */
#ifdef __DECC
@@ -302,36 +325,64 @@
/* #undef HAVE_SYS_PARAM_H */
/* Define if you have the <sys/timeb.h> header file. */
#ifndef __GNUC__
#define HAVE_SYS_TIMEB_H 1
#endif
/* Define if you have the <sys/wait.h> header file. */
/* #undef HAVE_SYS_WAIT_H */
/* Define if you have the <unistd.h> header file. */
/* #undef HAVE_UNISTD_H */
/* Define if you have the dgc library (-ldgc). */
/* #undef HAVE_LIBDGC */
/* Define if you have the kstat library (-lkstat). */
/* #undef HAVE_LIBKSTAT */
/* #undef HAVE_LIBKSTAT *
/* Define if you have the sun library (-lsun). */
/* #undef HAVE_LIBSUN */
/* VMS specific */
/* Define for case insensitve filenames */
#define HAVE_CASE_INSENSITIVE_FS 1
#define HAVE_VMSDIR_H 1
/* VMS specific, define it if you want to use case sensitve targets */
/* #undef WANT_CASE_SENSITIVE_TARGETS */
/* VMS specific, V7.0 has opendir() and friends, so it's undefined */
/* If you want to use non-VMS code for opendir() etc. on V7.0 and greater
define the first or both macros AND change the compile command to get the
non-VMS versions linked: (prefix=(all,except=(opendir,... */
/* #undef HAVE_VMSDIR_H */
/* #undef _DIRENT_HAVE_D_NAMLEN */
/* On older systems without 7.0 backport of CRTL the first one is defined */
#ifdef __CRTL_VER
# if __CRTL_VER < 70000000
# define HAVE_VMSDIR_H 1
# endif
#else
# if __VMS_VER < 70000000
# define HAVE_VMSDIR_H 1
# endif
#endif
#if defined(HAVE_VMSDIR_H) && defined(HAVE_DIRENT_H)
#undef HAVE_DIRENT_H
#endif
#define HAVE_STDLIB_H 1
#define INCLUDEDIR "sys$sysroot:[syslib]"
#define LIBDIR "sys$sysroot:[syslib]"
/* Avoid broken RTL functions on OpenVMS */
#include <unixlib.h>
/* Don't use RTL functions of OpenVMS */
#ifdef __DECC
#include <stdio.h>
#include <unistd.h>
#define getopt gnu_getopt
#define optarg gnu_optarg
#define optopt gnu_optopt
#define optind gnu_optind
#define opterr gnu_opterr
#endif
#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
#undef PARAMS

View File

@@ -3,7 +3,7 @@ AC_REVISION([$Id$])
AC_PREREQ(2.13)dnl dnl Minimum Autoconf version required.
AC_INIT(vpath.c)dnl dnl A distinctive file to look for in srcdir.
AM_INIT_AUTOMAKE(make, 3.78)
AM_INIT_AUTOMAKE(make, 3.78.91)
AM_CONFIG_HEADER(config.h)
dnl Regular configure stuff
@@ -21,7 +21,6 @@ AC_MINIX
AC_CHECK_PROG(PERL, perl, perl, perl) dnl Needed for the test suite (only)
dnl This test must come as early as possible after the compiler configuration
dnl tests, because the choice of the file model can (in principle) affect
dnl whether functions and headers are available, whether they work, etc.
@@ -37,6 +36,7 @@ AC_CHECK_HEADERS(stdlib.h unistd.h limits.h sys/param.h fcntl.h string.h \
AC_PROG_CC_C_O
AM_PROG_CC_STDC
AC_C_CONST dnl getopt needs this.
AC_C_INLINE dnl gettext needs this.
AC_HEADER_STAT
AC_STRUCT_ST_MTIM_NSEC
@@ -60,7 +60,7 @@ AC_MSG_RESULT($ac_cv_check_symbol_$1)])dnl
# clock_gettime is in -lposix4 in Solaris 2.6.
AC_CHECK_LIB(posix4, clock_gettime)
AC_CHECK_FUNCS(memmove strdup psignal mktemp pstat_getdynamic \
AC_CHECK_FUNCS(memmove strchr memcpy strdup psignal mktemp pstat_getdynamic \
clock_gettime dup2 getcwd sigsetmask sigaction getgroups \
setlinebuf seteuid setegid setreuid setregid pipe \
strerror strsignal)
@@ -107,6 +107,11 @@ AC_MSG_RESULT($make_cv_union_wait)
AC_DECL_SYS_SIGLIST
dnl Handle internationalization
ALL_LINGUAS="de es fr ko nl pl ru"
fp_WITH_GETTEXT
# The presence of the following is not meant to imply
# that make necessarily works on those systems.
AC_CHECK_LIB(sun, getpwnam)
@@ -206,7 +211,8 @@ AC_CACHE_VAL(make_cv_sys_gnu_glob, [
case "$make_cv_sys_gnu_glob" in
yes) AC_MSG_RESULT(yes) ;;
no) AC_MSG_RESULT([no; using local copy])
CPPFLAGS="$CPPFLAGS -I$srcdir/glob"
AC_SUBST(GLOBDIR) GLOBDIR=glob
AC_SUBST(GLOBINC) GLOBINC='-I$(srcdir)/glob'
AC_SUBST(GLOBLIB) GLOBLIB=glob/libglob.a
;;
esac
@@ -221,7 +227,7 @@ if test -r "$srcdir/maintMakefile"; then
fi
AC_SUBST_FILE(MAINT_MAKEFILE)
AC_OUTPUT(build.sh Makefile glob/Makefile)
AC_OUTPUT(build.sh Makefile glob/Makefile i18n/Makefile)
dnl If we don't yet have build.sh.in, build.sh is a bogus 0-length file
dnl so remove it.

41
debug.h Normal file
View File

@@ -0,0 +1,41 @@
/* Debugging macros and interface.
Copyright (C) 1999 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Make is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Make; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#define DB_NONE (0x000)
#define DB_BASIC (0x001)
#define DB_VERBOSE (0x002)
#define DB_JOBS (0x004)
#define DB_IMPLICIT (0x008)
#define DB_MAKEFILES (0x100)
#define DB_ALL (0xfff)
extern int db_level;
#define ISDB(_l) ((_l)&db_level)
#define DBS(_l,_x) do{ if(ISDB(_l)) {print_spaces (depth); \
printf _x; fflush (stdout);} }while(0)
#define DBF(_l,_x) do{ if(ISDB(_l)) {print_spaces (depth); \
printf (_x, file->name); \
fflush (stdout);} }while(0)
#define DB(_l,_x) do{ if(ISDB(_l)) {printf _x; fflush (stdout);} }while(0)

View File

@@ -38,8 +38,8 @@ Boston, MA 02111-1307, USA. */
static char default_suffixes[]
#ifdef VMS
= ".exe .olb .ln .obj .c .cc .pas .p .for .f .r .y .l .mar \
.mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo \
= ".exe .olb .ln .obj .c .cxx .cc .pas .p .for .f .r .y .l .mar \
.s .ss .i .ii .mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo \
.w .ch .cweb .web .com .sh .elc .el";
#else
= ".out .a .ln .o .c .cc .C .cpp .p .f .F .r .y .l .s .S \
@@ -108,13 +108,21 @@ static char *default_suffix_rules[] =
{
#ifdef VMS
".obj.exe",
"$(LINK.obj) $^ $(LOADLIBES) $(LDLIBS) /exe=$@",
"$(LINK.obj) $^ $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@",
".mar.exe",
"$(LINK.mar) $^ $(LOADLIBES) $(LDLIBS) /exe=$@",
"$(COMPILE.mar) $^ \n $(LINK.obj) $(subst .mar,.obj,$^) $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@",
".s.exe",
"$(COMPILE.s) $^ \n $(LINK.obj) $(subst .s,.obj,$^) $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@",
".c.exe",
"$(COMPILE.c) $^ \n $(LINK.obj) $(subst .c,.obj,$^) $(LOADLIBES) $(LDLIBS) /exe=$@",
"$(COMPILE.c) $^ \n $(LINK.obj) $(subst .c,.obj,$^) $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@",
".cc.exe",
"$(COMPILE.cc) $^ \n $(LINK.obj) $(subst .cc,.obj,$^) $(LOADLIBES) $(LDLIBS) /exe=$@",
#ifdef GCC_IS_NATIVE
"$(COMPILE.cc) $^ \n $(LINK.obj) $(CXXSTARTUP),sys$$disk:[]$(subst .cc,.obj,$^) $(LOADLIBES) $(LXLIBS) $(LDLIBS) $(CXXRT0) /exe=$@",
#else
"$(COMPILE.cc) $^ \n $(CXXLINK.obj) $(subst .cc,.obj,$^) $(LOADLIBES) $(LXLIBS) $(LDLIBS) $(CXXRT0) /exe=$@",
".cxx.exe",
"$(COMPILE.cxx) $^ \n $(CXXLINK.obj) $(subst .cxx,.obj,$^) $(LOADLIBES) $(LXLIBS) $(LDLIBS) $(CXXRT0) /exe=$@",
#endif
".for.exe",
"$(COMPILE.for) $^ \n $(LINK.obj) $(subst .for,.obj,$^) $(LOADLIBES) $(LDLIBS) /exe=$@",
".pas.exe",
@@ -125,8 +133,24 @@ static char *default_suffix_rules[] =
".mar.obj",
"$(COMPILE.mar) /obj=$@ $<",
".s.obj",
"$(COMPILE.s) /obj=$@ $<",
".ss.obj",
"$(COMPILE.s) /obj=$@ $<",
".c.i",
"$(COMPILE.c)/prep /list=$@ $<",
".c.s",
"$(COMPILE.c)/noobj/machine /list=$@ $<",
".i.s",
"$(COMPILE.c)/noprep/noobj/machine /list=$@ $<",
".c.obj",
"$(COMPILE.c) /obj=$@ $<",
".cc.ii",
"$(COMPILE.cc)/prep /list=$@ $<",
".cc.ss",
"$(COMPILE.cc)/noobj/machine /list=$@ $<",
".ii.ss",
"$(COMPILE.cc)/noprep/noobj/machine /list=$@ $<",
".cc.obj",
"$(COMPILE.cc) /obj=$@ $<",
".for.obj",
@@ -276,12 +300,31 @@ static char *default_suffix_rules[] =
static char *default_variables[] =
{
#ifdef VMS
#ifdef __ALPHA
"ARCH", "ALPHA",
#else
"ARCH", "VAX",
#endif
"AR", "library/obj",
"ARFLAGS", "/replace",
"AS", "macro",
"MACRO", "macro",
#ifdef GCC_IS_NATIVE
"CC", "gcc",
#else
"CC", "cc",
#endif
"CD", "builtin_cd",
"MAKE", "make",
"ECHO", "write sys$$output \"",
#ifdef GCC_IS_NATIVE
"C++", "gcc/plus",
"CXX", "gcc/plus",
#else
"C++", "cxx",
"CXX", "cxx",
"CXXLD", "cxxlink",
#endif
"CO", "co",
"CPP", "$(CC) /preprocess_only",
"FC", "fortran",
@@ -292,21 +335,43 @@ static char *default_variables[] =
"LD", "link",
"LEX", "lex",
"PC", "pascal",
"YACC", "yacc", /* Or "bison -y" */
"YACC", "bison/yacc",
"YFLAGS", "/Define/Verbose",
"BISON", "bison",
"MAKEINFO", "makeinfo",
"TEX", "tex",
"TEXINDEX", "texindex",
"RM", "delete/nolog",
"CSTARTUP", "",
#ifdef GCC_IS_NATIVE
"CRT0", ",sys$$library:vaxcrtl.olb/lib,gnu_cc_library:crt0.obj",
"CXXSTARTUP", "gnu_cc_library:crtbegin.obj",
"CXXRT0", ",sys$$library:vaxcrtl.olb/lib,gnu_cc_library:crtend.obj,gnu_cc_library:gxx_main.obj",
"LXLIBS", ",gnu_cc_library:libstdcxx.olb/lib,gnu_cc_library:libgccplus.olb/lib",
"LDLIBS", ",gnu_cc_library:libgcc.olb/lib",
#else
"CRT0", "",
"CXXSTARTUP", "",
"CXXRT0", "",
"LXLIBS", "",
"LDLIBS", "",
#endif
"LINK.obj", "$(LD) $(LDFLAGS)",
#ifndef GCC_IS_NATIVE
"CXXLINK.obj", "$(CXXLD) $(LDFLAGS)",
"COMPILE.cxx", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
#endif
"COMPILE.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
"COMPILE.cc", "$(C++) $(C++FLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
"COMPILE.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
"YACC.y", "$(YACC) $(YFLAGS)",
"LEX.l", "$(LEX) $(LFLAGS)",
"COMPILE.for", "$(FC) $(FFLAGS) $(TARGET_ARCH)",
"COMPILE.pas", "$(PC) $(PFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
"COMPILE.mar", "$(AS) $(ASFLAGS) $(TARGET_MACH)",
"COMPILE.mar", "$(MACRO) $(MACROFLAGS)",
"COMPILE.s", "$(AS) $(ASFLAGS) $(TARGET_MACH)",
"LINT.c", "$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
"MV", "rename/new_version",
@@ -319,7 +384,11 @@ static char *default_variables[] =
"AS", "as",
#ifdef GCC_IS_NATIVE
"CC", "gcc",
# ifdef __MSDOS__
"CXX", "gpp", /* g++ is an invalid name on MSDOS */
# else
"CXX", "gcc",
# endif /* __MSDOS__ */
#else
"CC", "cc",
"CXX", "g++",
@@ -328,8 +397,7 @@ static char *default_variables[] =
/* This expands to $(CO) $(COFLAGS) $< $@ if $@ does not exist,
and to the empty string if $@ does exist. */
"CHECKOUT,v",
"+$(patsubst $@-noexist,$(CO) $(COFLAGS) $< $@,\
$(filter-out $@,$(firstword $(wildcard $@) $@-noexist)))",
"+$(if $(wildcard $@),,$(CO) $(COFLAGS) $< $@)",
"CO", "co",
"CPP", "$(CC) -E",

126
dir.c
View File

@@ -22,6 +22,9 @@ Boston, MA 02111-1307, USA. */
#ifdef HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
# ifdef VMS
extern char *vmsify PARAMS ((char *name, int type));
# endif
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
@@ -41,18 +44,18 @@ Boston, MA 02111-1307, USA. */
/* In GNU systems, <dirent.h> defines this macro for us. */
#ifdef _D_NAMLEN
#undef NAMLEN
#define NAMLEN(d) _D_NAMLEN(d)
# undef NAMLEN
# define NAMLEN(d) _D_NAMLEN(d)
#endif
#if (defined (POSIX) || defined (WINDOWS32)) && !defined (__GNU_LIBRARY__)
#if (defined (POSIX) || defined (VMS) || defined (WINDOWS32)) && !defined (__GNU_LIBRARY__)
/* Posix does not require that the d_ino field be present, and some
systems do not provide it. */
#define REAL_DIR_ENTRY(dp) 1
#define FAKE_DIR_ENTRY(dp)
# define REAL_DIR_ENTRY(dp) 1
# define FAKE_DIR_ENTRY(dp)
#else
#define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
#define FAKE_DIR_ENTRY(dp) (dp->d_ino = 1)
# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
# define FAKE_DIR_ENTRY(dp) (dp->d_ino = 1)
#endif /* POSIX */
#ifdef __MSDOS__
@@ -84,7 +87,7 @@ dosify (filename)
/* First, transform the name part. */
for (i = 0; *filename != '\0' && i < 8 && *filename != '.'; ++i)
*df++ = tolower (*filename++);
*df++ = tolower ((unsigned char)*filename++);
/* Now skip to the next dot. */
while (*filename != '\0' && *filename != '.')
@@ -93,7 +96,7 @@ dosify (filename)
{
*df++ = *filename++;
for (i = 0; *filename != '\0' && i < 3 && *filename != '.'; ++i)
*df++ = tolower (*filename++);
*df++ = tolower ((unsigned char)*filename++);
}
/* Look for more dots. */
@@ -135,7 +138,7 @@ downcase (filename)
/* First, transform the name part. */
for (i = 0; *filename != '\0'; ++i)
{
*df++ = tolower (*filename);
*df++ = tolower ((unsigned char)*filename);
++filename;
}
@@ -156,7 +159,8 @@ vms_hash (name)
while (*name)
{
h = (h << 4) + *name++;
h = (h << 4) + (isupper (*name) ? tolower (*name) : *name);
name++;
g = h & 0xf0000000;
if (g)
{
@@ -333,12 +337,12 @@ find_directory (name)
if (vmsstat_dir (name, &st) < 0)
#else
#ifdef WINDOWS32
# ifdef WINDOWS32
/* Remove any trailing '\'. Windows32 stat fails even on valid
directories if they end in '\'. */
if (p[-1] == '\\')
p[-1] = '\0';
#endif
# endif
if (stat (name, &st) < 0)
#endif
{
@@ -356,14 +360,14 @@ find_directory (name)
w32_path = w32ify(name, 1);
hash = ((unsigned int) st.st_dev << 16) | (unsigned int) st.st_ctime;
#else
#ifdef VMS
hash = ((unsigned int) st.st_dev << 16)
| ((unsigned int) st.st_ino[0]
+ (unsigned int) st.st_ino[1]
+ (unsigned int) st.st_ino[2]);
#else
# ifdef VMS
hash = (((unsigned int) st.st_dev << 16)
| ((unsigned int) st.st_ino[0]
+ (unsigned int) st.st_ino[1]
+ (unsigned int) st.st_ino[2]));
# else
hash = ((unsigned int) st.st_dev << 16) | (unsigned int) st.st_ino;
#endif
# endif
#endif
hash %= DIRECTORY_BUCKETS;
@@ -372,13 +376,14 @@ find_directory (name)
if (strieq(dc->path_key, w32_path))
#else
if (dc->dev == st.st_dev
#ifdef VMS
# ifdef VMS
&& 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)
#endif
&& dc->ino[2] == st.st_ino[2]
# else
&& dc->ino == st.st_ino
# endif
)
#endif /* WINDOWS32 */
break;
@@ -413,24 +418,22 @@ find_directory (name)
else
dc->fs_flags = FS_UNKNOWN;
#else
#ifdef VMS
# ifdef VMS
dc->ino[0] = st.st_ino[0];
dc->ino[1] = st.st_ino[1];
dc->ino[2] = st.st_ino[2];
#else
# else
dc->ino = st.st_ino;
#endif
# endif
#endif /* WINDOWS32 */
dc->next = directories_contents[hash];
directories_contents[hash] = dc;
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->files = 0;
}
/* Couldn't open the directory. Mark this by
setting the `files' member to a nil pointer. */
dc->files = 0;
else
{
/* Allocate an array of buckets for files and zero it. */
@@ -553,6 +556,14 @@ dir_contents_file_exists_p (dir, filename)
unsigned int len;
register unsigned int i;
#if defined(VMS) && defined(HAVE_DIRENT_H)
/* In VMS we get file versions too, which have to be stripped off */
{
char *p = strrchr (d->d_name, ';');
if (p)
*p = '\0';
}
#endif
if (!REAL_DIR_ENTRY (d))
continue;
@@ -635,16 +646,18 @@ file_exists_p (name)
#endif
#ifdef VMS
dirend = rindex (name, ']');
dirend = strrchr (name, ']');
if (dirend == 0)
dirend = strrchr (name, ':');
dirend++;
if (dirend == (char *)1)
return dir_file_exists_p ("[]", name);
#else /* !VMS */
dirend = rindex (name, '/');
dirend = strrchr (name, '/');
#if defined (WINDOWS32) || defined (__MSDOS__)
/* Forward and backslashes might be mixed. We need the rightmost one. */
{
char *bslash = rindex(name, '\\');
char *bslash = strrchr(name, '\\');
if (!dirend || bslash > dirend)
dirend = bslash;
/* The case of "d:file". */
@@ -693,16 +706,18 @@ file_impossible (filename)
register struct dirfile *new;
#ifdef VMS
dirend = rindex (p, ']');
dirend = strrchr (p, ']');
if (dirend == 0)
dirend = strrchr (p, ':');
dirend++;
if (dirend == (char *)1)
dir = find_directory ("[]");
#else
dirend = rindex (p, '/');
dirend = strrchr (p, '/');
#if defined (WINDOWS32) || defined (__MSDOS__)
/* Forward and backslashes might be mixed. We need the rightmost one. */
{
char *bslash = rindex(p, '\\');
char *bslash = strrchr(p, '\\');
if (!dirend || bslash > dirend)
dirend = bslash;
/* The case of "d:file". */
@@ -796,15 +811,15 @@ file_impossible_p (filename)
register struct dirfile *next;
#ifdef VMS
dirend = rindex (filename, ']');
dirend = strrchr (filename, ']');
if (dirend == 0)
dir = find_directory ("[]")->contents;
#else
dirend = rindex (filename, '/');
dirend = strrchr (filename, '/');
#if defined (WINDOWS32) || defined (__MSDOS__)
/* Forward and backslashes might be mixed. We need the rightmost one. */
{
char *bslash = rindex(filename, '\\');
char *bslash = strrchr(filename, '\\');
if (!dirend || bslash > dirend)
dirend = bslash;
/* The case of "d:file". */
@@ -1043,6 +1058,9 @@ read_dirstream (stream)
FAKE_DIR_ENTRY (d);
#ifdef _DIRENT_HAVE_D_NAMLEN
d->d_namlen = len - 1;
#endif
#ifdef _DIRENT_HAVE_D_TYPE
d->d_type = DT_UNKNOWN;
#endif
memcpy (d->d_name, df->name, len);
return d;
@@ -1064,19 +1082,33 @@ ansi_free(p)
free(p);
}
/* On 64 bit ReliantUNIX (5.44 and above) in LFS mode, stat() is actually a
* macro for stat64(). If stat is a macro, make a local wrapper function to
* invoke it.
*/
#ifndef stat
# ifndef VMS
extern int stat ();
# endif
# define local_stat stat
#else
static int local_stat (path, buf)
char *path;
struct stat *buf;
{
return stat (path, buf);
}
#endif
void
dir_setup_glob (gl)
glob_t *gl;
{
#ifndef VMS
extern int stat ();
#endif
/* Bogus sunos4 compiler complains (!) about & before functions. */
gl->gl_opendir = open_dirstream;
gl->gl_readdir = read_dirstream;
gl->gl_closedir = ansi_free;
gl->gl_stat = stat;
gl->gl_stat = local_stat;
/* We don't bother setting gl_lstat, since glob never calls it.
The slot is only there for compatibility with 4.4 BSD. */
}

112
expand.c
View File

@@ -17,6 +17,8 @@ along with GNU Make; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <assert.h>
#include "make.h"
#include "filedef.h"
#include "job.h"
@@ -89,9 +91,13 @@ initialize_variable_output ()
/* Recursively expand V. The returned string is malloc'd. */
static char *allocated_variable_append PARAMS ((struct variable *v,
struct variable_set_list *l));
char *
recursively_expand (v)
recursively_expand_setlist (v, list)
register struct variable *v;
struct variable_set_list *list;
{
char *value;
@@ -102,7 +108,10 @@ recursively_expand (v)
v->name);
v->expanding = 1;
value = allocated_variable_expand (v->value);
if (v->append)
value = allocated_variable_append (v, list);
else
value = allocated_variable_expand (v->value);
v->expanding = 0;
return value;
@@ -134,18 +143,24 @@ reference_variable (o, name, length)
char *name;
unsigned int length;
{
register struct variable *v = lookup_variable (name, length);
register struct variable *v;
struct variable_set_list *setlist;
char *value;
v = lookup_variable_setlist (name, length, &setlist);
if (v == 0)
warn_undefined (name, length);
if (v != 0 && *v->value != '\0')
{
char *value = (v->recursive ? recursively_expand (v) : v->value);
o = variable_buffer_output (o, value, strlen (value));
if (v->recursive)
free (value);
}
if (v == 0 || *v->value == '\0')
return o;
value = (v->recursive ? recursively_expand_setlist (v, setlist) : v->value);
o = variable_buffer_output (o, value, strlen (value));
if (v->recursive)
free (value);
return o;
}
@@ -189,7 +204,7 @@ variable_expand_string (line, string, length)
variable output buffer, and skip them. Uninteresting chars end
at the next $ or the end of the input. */
p1 = index (p, '$');
p1 = strchr (p, '$');
o = variable_buffer_output (o, p, p1 != 0 ? p1 - p : strlen (p) + 1);
@@ -229,7 +244,7 @@ variable_expand_string (line, string, length)
/* Is there a variable reference inside the parens or braces?
If so, expand it before expanding the entire reference. */
end = index (beg, closeparen);
end = strchr (beg, closeparen);
if (end == 0)
/* Unterminated variable reference. */
fatal (reading_file, _("unterminated variable reference"));
@@ -253,7 +268,7 @@ variable_expand_string (line, string, length)
{
beg = expand_argument (beg, p); /* Expand the name. */
free_beg = 1; /* Remember to free BEG when finished. */
end = index (beg, '\0');
end = strchr (beg, '\0');
}
}
else
@@ -273,7 +288,7 @@ variable_expand_string (line, string, length)
char *subst_beg, *subst_end, *replace_beg, *replace_end;
subst_beg = colon + 1;
subst_end = index (subst_beg, '=');
subst_end = strchr (subst_beg, '=');
if (subst_end == 0)
/* There is no = in sight. Punt on the substitution
reference and treat this as a variable name containing
@@ -414,7 +429,7 @@ expand_argument (str, end)
{
char *tmp;
if (*end == '\0')
if (!end || *end == '\0')
tmp = str;
else
{
@@ -435,7 +450,7 @@ variable_expand_for_file (line, file)
register struct file *file;
{
char *result;
struct variable_set_list *save, *fnext;
struct variable_set_list *save;
if (file == 0)
return variable_expand (line);
@@ -446,26 +461,65 @@ variable_expand_for_file (line, file)
reading_file = &file->cmds->fileinfo;
else
reading_file = 0;
fnext = file->variables->next;
/* See if there's a pattern-specific variable struct for this target. */
if (!file->pat_searched)
{
file->patvar = lookup_pattern_var(file->name);
file->pat_searched = 1;
}
if (file->patvar != 0)
{
file->patvar->vars->next = fnext;
file->variables->next = file->patvar->vars;
}
result = variable_expand (line);
current_variable_set_list = save;
reading_file = 0;
file->variables->next = fnext;
return result;
}
/* Like allocated_variable_expand, but we first expand this variable in the
context of the next variable set, then we append the expanded value. */
static char *
allocated_variable_append (v, list)
struct variable *v;
struct variable_set_list *list;
{
struct variable_set_list *save;
int len = strlen (v->name);
char *var = alloca (len + 4);
char *value;
char *obuf = variable_buffer;
unsigned int olen = variable_buffer_length;
variable_buffer = 0;
if (!list)
list = current_variable_set_list;
assert(list->next != 0);
save = current_variable_set_list;
current_variable_set_list = list->next;
var[0] = '$';
var[1] = '(';
strcpy (&var[2], v->name);
var[len+2] = ')';
var[len+3] = '\0';
value = variable_expand_for_file (var, 0);
current_variable_set_list = save;
value += strlen (value);
value = variable_buffer_output (value, " ", 1);
value = variable_expand_string (value, v->value, (long)-1);
value = variable_buffer;
#if 0
/* Waste a little memory and save time. */
value = xrealloc (value, strlen (value))
#endif
variable_buffer = obuf;
variable_buffer_length = olen;
return value;
}
/* Like variable_expand_for_file, but the returned string is malloc'd.
This function is called a lot. It wants to be efficient. */

35
file.c
View File

@@ -54,7 +54,7 @@ lookup_file (name)
register struct file *f;
register char *n;
register unsigned int hashval;
#ifdef VMS
#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)
register char *lname, *ln;
#endif
@@ -65,11 +65,13 @@ lookup_file (name)
for names read from makefiles. It is here for names passed
on the command line. */
#ifdef VMS
# ifndef WANT_CASE_SENSITIVE_TARGETS
lname = (char *)malloc(strlen(name) + 1);
for (n=name, ln=lname; *n != '\0'; ++n, ++ln)
*ln = isupper(*n) ? tolower(*n) : *n;
*ln = isupper((unsigned char)*n) ? tolower((unsigned char)*n) : *n;
*ln = '\0';
name = lname;
# endif
while (name[0] == '[' && name[1] == ']' && name[2] != '\0')
name += 2;
@@ -103,13 +105,13 @@ lookup_file (name)
{
if (strieq (f->hname, name))
{
#ifdef VMS
#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)
free (lname);
#endif
return f;
}
}
#ifdef VMS
#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)
free (lname);
#endif
return 0;
@@ -122,23 +124,25 @@ enter_file (name)
register struct file *f, *new;
register char *n;
register unsigned int hashval;
#ifdef VMS
#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)
char *lname, *ln;
#endif
if (*name == '\0')
abort ();
#ifdef VMS
#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)
lname = (char *)malloc (strlen (name) + 1);
for (n = name, ln = lname; *n != '\0'; ++n, ++ln)
{
if (isupper(*n))
*ln = tolower(*n);
if (isupper((unsigned char)*n))
*ln = tolower((unsigned char)*n);
else
*ln = *n;
}
*ln = 0;
/* Creates a possible leak, old value of name is unreachable, but I
currently don't know how to fix it. */
name = lname;
#endif
@@ -153,7 +157,7 @@ enter_file (name)
if (f != 0 && !f->double_colon)
{
#ifdef VMS
#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)
free(lname);
#endif
return f;
@@ -540,6 +544,10 @@ snap_deps ()
f = lookup_file (".POSIX");
if (f != 0 && f->is_target)
posix_pedantic = 1;
f = lookup_file (".NOTPARALLEL");
if (f != 0 && f->is_target)
not_parallel = 1;
}
/* Set the `command_state' member of FILE and all its `also_make's. */
@@ -627,8 +635,9 @@ print_file (f)
puts (_("# Command-line target."));
if (f->dontcare)
puts (_("# A default or MAKEFILES makefile."));
printf (_("# Implicit rule search has%s been done.\n"),
f->tried_implicit ? "" : _(" not"));
puts (f->tried_implicit
? _("# Implicit rule search has been done.")
: _("# Implicit rule search has not been done."));
if (f->stem != 0)
printf (_("# Implicit/static pattern stem: `%s'\n"), f->stem);
if (f->intermediate)
@@ -650,8 +659,8 @@ print_file (f)
file_timestamp_sprintf (buf, f->last_mtime);
printf (_("# Last modified %s\n"), buf);
}
printf (_("# File has%s been updated.\n"),
f->updated ? "" : _(" not"));
puts (f->updated
? _("# File has been updated.") : _("# File has not been updated."));
switch (f->command_state)
{
case cs_running:

View File

@@ -48,6 +48,10 @@ struct file
/* List of variable sets used for this file. */
struct variable_set_list *variables;
/* Pattern-specific variable reference for this target, or null if there
isn't one. Also see the pat_searched flag, below. */
struct variable_set_list *pat_variables;
/* Immediate dependent that caused this target to be remade,
or nil if there isn't one. */
struct file *parent;
@@ -56,10 +60,6 @@ struct file
the same file. Otherwise this is null. */
struct file *double_colon;
/* Pattern-specific variable reference for this target, or null if there
isn't one. Also see the pat_searched flag, below. */
struct pattern_var *patvar;
short int update_status; /* Status of the last attempt to update,
or -1 if none has been made. */
@@ -87,8 +87,6 @@ struct file
unsigned int secondary:1;
unsigned int dontcare:1; /* Nonzero if no complaint is to be made if
this target cannot be remade. */
unsigned int mfile_status:1;/* Nonzero if update_status was obtained
while remaking a makefile. */
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. */

View File

@@ -1,5 +1,5 @@
/* Builtin function expansion for GNU Make.
Copyright (C) 1988,89,91,92,93,94,95,96,97 Free Software Foundation, Inc.
Copyright (C) 1988,1989,1991-1997,1999 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify
@@ -23,6 +23,7 @@ Boston, MA 02111-1307, USA. */
#include "dep.h"
#include "job.h"
#include "commands.h"
#include "debug.h"
#ifdef _AMIGA
#include "amiga.h"
@@ -32,9 +33,10 @@ Boston, MA 02111-1307, USA. */
struct function_table_entry
{
const char *name;
int len;
int required_args;
int expand_args;
unsigned char len;
unsigned char minimum_args;
unsigned char maximum_args;
char expand_args;
char *(*func_ptr) PARAMS((char *output, char **argv, const char*funcname));
};
@@ -126,7 +128,7 @@ patsubst_expand (o, text, pattern, replace, pattern_percent, replace_percent)
unsigned int pattern_prepercent_len, pattern_postpercent_len;
unsigned int replace_prepercent_len, replace_postpercent_len = 0;
char *t;
unsigned int len;
int len;
int doneany = 0;
/* We call find_percent on REPLACE before checking PATTERN so that REPLACE
@@ -551,7 +553,7 @@ func_basename_dir(o, argv, funcname)
char *p3 = argv[0];
char *p2=0;
int doneany=0;
int len=0;
unsigned int len=0;
char *p=0;
int is_basename= streq(funcname, "basename");
int is_dir= !is_basename;
@@ -611,9 +613,9 @@ func_addsuffix_addprefix(o, argv, funcname)
int is_addprefix = streq (funcname, "addprefix");
int is_addsuffix = !is_addprefix;
int doneany =0;
char *p=0;
int len =0;
int doneany = 0;
char *p;
unsigned int len;
while ((p = find_next_token (&list_iterator, &len)) != 0)
{
@@ -652,8 +654,8 @@ func_firstword(o, argv, funcname)
char **argv;
const char *funcname;
{
int i=0;
char *words = argv[0];
unsigned int i;
char *words = argv[0]; /* Use a temp variable for find_next_token */
char *p = find_next_token (&words, &i);
if (p != 0)
@@ -688,9 +690,9 @@ strip_whitespace (begpp, endpp)
char **begpp;
char **endpp;
{
while (isspace (**begpp) && *begpp <= *endpp)
while (isspace ((unsigned char)**begpp) && *begpp <= *endpp)
(*begpp) ++;
while (isspace (**endpp) && *endpp >= *begpp)
while (isspace ((unsigned char)**endpp) && *endpp >= *begpp)
(*endpp) --;
return *begpp;
}
@@ -814,15 +816,15 @@ func_foreach (o, argv, funcname)
const char *funcname;
{
/* expand only the first two. */
char *varname = expand_argument (argv[0], argv[1] - 1);
char *list = expand_argument (argv[1], argv[2] -1);
char *body = savestring (argv[2], argv[3] - argv[2] - 1);
char *varname = expand_argument (argv[0], NULL);
char *list = expand_argument (argv[1], NULL);
char *body = argv[2];
int len =0;
int doneany = 0;
char *list_iterator = list;
char *p;
register struct variable *var=0;
int doneany =0;
unsigned int len;
register struct variable *var;
push_new_variable_scope ();
var = define_variable (varname, strlen (varname), "", o_automatic, 0);
@@ -856,7 +858,6 @@ func_foreach (o, argv, funcname)
pop_variable_scope ();
free (varname);
free (list);
free (body);
return o;
}
@@ -874,16 +875,15 @@ func_filter_filterout (o, argv, funcname)
char **argv;
const char *funcname;
{
struct a_word *wordhead =0;
struct a_word *wordtail =0;
struct a_word *wordhead = 0;
struct a_word *wordtail = 0;
int is_filter = streq (funcname, "filter");
char *patterns = argv[0];
char *word_iterator = argv[1];
char *p;
int len;
char *word_iterator = argv[1];
unsigned int len;
/* Chop ARGV[1] up into words and then run each pattern through. */
while ((p = find_next_token (&word_iterator, &len)) != 0)
@@ -904,13 +904,12 @@ func_filter_filterout (o, argv, funcname)
if (wordhead != 0)
{
struct a_word *wp =0;
char *pat_iterator = patterns;
int doneany = 0;
struct a_word *wp;
wordtail->next = 0;
/* Run each pattern through the words, killing words. */
while ((p = find_next_token (&pat_iterator, &len)) != 0)
{
@@ -958,10 +957,10 @@ func_strip(o, argv, funcname)
int i=0;
char *word_start=0;
while (isspace(*p))
while (isspace ((unsigned char)*p))
++p;
word_start = p;
for (i=0; *p != '\0' && !isspace(*p); ++p, ++i)
for (i=0; *p != '\0' && !isspace ((unsigned char)*p); ++p, ++i)
{}
if (!i)
break;
@@ -1031,15 +1030,15 @@ func_sort (o, argv, funcname)
/* Chop ARGV[0] into words and put them in WORDS. */
char *t = argv[0];
char *p=0;
int len;
char *p;
unsigned int len;
int i;
while ((p = find_next_token (&t, &len)) != 0)
{
if (wordi >= nwords - 1)
{
nwords = 2* nwords + 5;
nwords = (2 * nwords) + 5;
words = (char **) xrealloc ((char *) words,
nwords * sizeof (char *));
}
@@ -1091,7 +1090,7 @@ func_if (o, argv, funcname)
const char *funcname;
{
char *begp = argv[0];
char *endp = argv[1]-1;
char *endp = begp + strlen (argv[0]);
int result = 0;
/* Find the result of the condition: if we have a value, and it's not
@@ -1102,7 +1101,7 @@ func_if (o, argv, funcname)
if (begp < endp)
{
char *expansion = expand_argument (begp, endp);
char *expansion = expand_argument (begp, NULL);
result = strlen (expansion);
free (expansion);
@@ -1114,20 +1113,14 @@ func_if (o, argv, funcname)
argv += 1 + !result;
if (argv[0] != NULL && argv[1] != NULL)
if (argv[0])
{
char *expansion;
char **endp = argv+1;
/* If we're doing the else-clause, make sure we concatenate any
potential extra arguments into the last argument. */
if (!result)
while (*endp && **endp != '\0')
++endp;
expansion = expand_argument (*argv, *endp-1);
expansion = expand_argument (argv[0], NULL);
o = variable_buffer_output (o, expansion, strlen (expansion));
free (expansion);
}
@@ -1233,30 +1226,42 @@ windows32_openpipe (int *pipedes, int *pid_p, char **command_argv, char **envp)
if (!CreatePipe(&hChildOutRd, &hChildOutWr, &saAttr, 0))
fatal (NILF, _("CreatePipe() failed (e=%d)\n"), GetLastError());
hProcess = process_init_fd(hIn, hChildOutWr, hErr);
if (!hProcess)
fatal (NILF, _("windows32_openpipe (): process_init_fd() failed\n"));
else
process_register(hProcess);
/* make sure that CreateProcess() has Path it needs */
sync_Path_environment();
if (!process_begin(hProcess, command_argv, envp, command_argv[0], NULL))
if (!process_begin(hProcess, command_argv, envp, command_argv[0], NULL)) {
/* register process for wait */
process_register(hProcess);
/* set the pid for returning to caller */
*pid_p = (int) hProcess;
else
fatal (NILF, _("windows32_openpipe (): unable to launch process (e=%d)\n"),
process_last_err(hProcess));
/* set up to read data from child */
pipedes[0] = _open_osfhandle((long) hChildOutRd, O_RDONLY);
/* this will be closed almost right away */
pipedes[1] = _open_osfhandle((long) hChildOutWr, O_APPEND);
} else {
/* reap/cleanup the failed process */
process_cleanup(hProcess);
/* close handles which were duplicated, they weren't used */
CloseHandle(hIn);
CloseHandle(hErr);
/* close pipe handles, they won't be used */
CloseHandle(hChildOutRd);
CloseHandle(hChildOutWr);
/* set status for return */
pipedes[0] = pipedes[1] = -1;
*pid_p = -1;
}
}
#endif
@@ -1375,6 +1380,13 @@ func_shell (o, argv, funcname)
#ifdef WINDOWS32
windows32_openpipe (pipedes, &pid, command_argv, envp);
if (pipedes[0] < 0) {
/* open of the pipe failed, mark as failed execution */
shell_function_completed = -1;
return o;
} else
#else /* WINDOWS32 */
# ifdef __MSDOS__
@@ -1456,8 +1468,8 @@ func_shell (o, argv, funcname)
reap_children (1, 0);
if (batch_filename) {
if (debug_flag)
printf(_("Cleaning up temporary batch file %s\n"), batch_filename);
DB (DB_VERBOSE, (_("Cleaning up temporary batch file %s\n"),
batch_filename));
remove(batch_filename);
free(batch_filename);
}
@@ -1599,7 +1611,7 @@ func_not (char* o, char **argv, char *funcname)
{
char * s = argv[0];
int result = 0;
while (isspace (*s))
while (isspace ((unsigned char)*s))
s++;
result = ! (*s);
o = variable_buffer_output (o, result ? "1" : "", result);
@@ -1616,11 +1628,8 @@ func_not (char* o, char **argv, char *funcname)
some efficiency by moving most often used functions to the start of the
table.
If REQUIRED_ARGS is positive, the function takes exactly that many
arguments. All subsequent text is included with the last argument. So,
since $(sort a,b,c) takes only one argument, it will be the full string
"a,b,c". If the value is negative, it's the minimum number of arguments.
A function can have more, but if it has less an error is generated.
If MAXIMUM_ARGS is 0, that means there is no maximum and all
comma-separated values are treated as arguments.
EXPAND_ARGS means that all arguments should be expanded before invocation.
Functions that do namespace tricks (foreach) don't automatically expand. */
@@ -1630,36 +1639,36 @@ static char *func_call PARAMS((char *o, char **argv, const char *funcname));
static struct function_table_entry function_table[] =
{
/* Name/size */ /* ARG EXP? Function */
{ STRING_SIZE_TUPLE("addprefix"), 2, 1, func_addsuffix_addprefix},
{ STRING_SIZE_TUPLE("addsuffix"), 2, 1, func_addsuffix_addprefix},
{ STRING_SIZE_TUPLE("basename"), 1, 1, func_basename_dir},
{ STRING_SIZE_TUPLE("dir"), 1, 1, func_basename_dir},
{ STRING_SIZE_TUPLE("notdir"), 1, 1, func_notdir_suffix},
{ STRING_SIZE_TUPLE("subst"), 3, 1, func_subst},
{ STRING_SIZE_TUPLE("suffix"), 1, 1, func_notdir_suffix},
{ STRING_SIZE_TUPLE("filter"), 2, 1, func_filter_filterout},
{ STRING_SIZE_TUPLE("filter-out"), 2, 1, func_filter_filterout},
{ STRING_SIZE_TUPLE("findstring"), 2, 1, func_findstring},
{ STRING_SIZE_TUPLE("firstword"), 1, 1, func_firstword},
{ STRING_SIZE_TUPLE("join"), 2, 1, func_join},
{ STRING_SIZE_TUPLE("patsubst"), 3, 1, func_patsubst},
{ STRING_SIZE_TUPLE("shell"), 1, 1, func_shell},
{ STRING_SIZE_TUPLE("sort"), 1, 1, func_sort},
{ STRING_SIZE_TUPLE("strip"), 1, 1, func_strip},
{ STRING_SIZE_TUPLE("wildcard"), 1, 1, func_wildcard},
{ STRING_SIZE_TUPLE("word"), 2, 1, func_word},
{ STRING_SIZE_TUPLE("wordlist"), 3, 1, func_wordlist},
{ STRING_SIZE_TUPLE("words"), 1, 1, func_words},
{ STRING_SIZE_TUPLE("origin"), 1, 1, func_origin},
{ STRING_SIZE_TUPLE("foreach"), 3, 0, func_foreach},
{ STRING_SIZE_TUPLE("call"), -1, 1, func_call},
{ STRING_SIZE_TUPLE("error"), 1, 1, func_error},
{ STRING_SIZE_TUPLE("warning"), 1, 1, func_error},
{ STRING_SIZE_TUPLE("if"), -2, 0, func_if},
/* Name/size */ /* MIN MAX EXP? Function */
{ STRING_SIZE_TUPLE("addprefix"), 2, 2, 1, func_addsuffix_addprefix},
{ STRING_SIZE_TUPLE("addsuffix"), 2, 2, 1, func_addsuffix_addprefix},
{ STRING_SIZE_TUPLE("basename"), 1, 1, 1, func_basename_dir},
{ STRING_SIZE_TUPLE("dir"), 1, 1, 1, func_basename_dir},
{ STRING_SIZE_TUPLE("notdir"), 1, 1, 1, func_notdir_suffix},
{ STRING_SIZE_TUPLE("subst"), 3, 3, 1, func_subst},
{ STRING_SIZE_TUPLE("suffix"), 1, 1, 1, func_notdir_suffix},
{ STRING_SIZE_TUPLE("filter"), 2, 2, 1, func_filter_filterout},
{ STRING_SIZE_TUPLE("filter-out"), 2, 2, 1, func_filter_filterout},
{ STRING_SIZE_TUPLE("findstring"), 2, 2, 1, func_findstring},
{ STRING_SIZE_TUPLE("firstword"), 1, 1, 1, func_firstword},
{ STRING_SIZE_TUPLE("join"), 2, 2, 1, func_join},
{ STRING_SIZE_TUPLE("patsubst"), 3, 3, 1, func_patsubst},
{ STRING_SIZE_TUPLE("shell"), 1, 1, 1, func_shell},
{ STRING_SIZE_TUPLE("sort"), 1, 1, 1, func_sort},
{ STRING_SIZE_TUPLE("strip"), 1, 1, 1, func_strip},
{ STRING_SIZE_TUPLE("wildcard"), 1, 1, 1, func_wildcard},
{ STRING_SIZE_TUPLE("word"), 2, 2, 1, func_word},
{ STRING_SIZE_TUPLE("wordlist"), 3, 3, 1, func_wordlist},
{ STRING_SIZE_TUPLE("words"), 1, 1, 1, func_words},
{ STRING_SIZE_TUPLE("origin"), 1, 1, 1, func_origin},
{ STRING_SIZE_TUPLE("foreach"), 3, 3, 0, func_foreach},
{ STRING_SIZE_TUPLE("call"), 1, 0, 0, func_call},
{ STRING_SIZE_TUPLE("error"), 1, 1, 1, func_error},
{ STRING_SIZE_TUPLE("warning"), 1, 1, 1, func_error},
{ STRING_SIZE_TUPLE("if"), 2, 3, 0, func_if},
#ifdef EXPERIMENTAL
{ STRING_SIZE_TUPLE("eq"), 2, 1, func_eq},
{ STRING_SIZE_TUPLE("not"), 1, 1, func_not},
{ STRING_SIZE_TUPLE("eq"), 2, 2, 1, func_eq},
{ STRING_SIZE_TUPLE("not"), 1, 1, 1, func_not},
#endif
{ 0 }
};
@@ -1674,11 +1683,7 @@ expand_builtin_function (o, argc, argv, entry_p)
char **argv;
struct function_table_entry *entry_p;
{
int min = (entry_p->required_args > 0
? entry_p->required_args
: -entry_p->required_args);
if (argc < min)
if (argc < entry_p->minimum_args)
fatal (reading_file,
_("Insufficient number of arguments (%d) to function `%s'"),
argc, entry_p->name);
@@ -1703,39 +1708,36 @@ handle_function (op, stringp)
const struct function_table_entry *entry_p;
char openparen = (*stringp)[0];
char closeparen = openparen == '(' ? ')' : '}';
char *beg = *stringp + 1;
char *endref;
char *beg;
char *end;
int count = 0;
char *argbeg;
register char *p;
char **argv, **argvp;
int nargs;
beg = *stringp + 1;
entry_p = lookup_function (function_table, beg);
if (!entry_p)
return 0;
/* We have found a call to a builtin function. Find the end of the
arguments, and do the function. */
/* We found a builtin function. Find the beginning of its arguments (skip
whitespace after the name). */
endref = beg + entry_p->len;
/* Space after function name isn't part of the args. */
p = next_token (endref);
argbeg = p;
beg = next_token (beg + entry_p->len);
/* Find the end of the function invocation, counting nested use of
whichever kind of parens we use. Since we're looking, count commas
to get a rough estimate of how many arguments we might have. The
count might be high, but it'll never be low. */
for (nargs=1; *p != '\0'; ++p)
if (*p == ',')
for (nargs=1, end=beg; *end != '\0'; ++end)
if (*end == ',')
++nargs;
else if (*p == openparen)
else if (*end == openparen)
++count;
else if (*p == closeparen && --count < 0)
else if (*end == closeparen && --count < 0)
break;
if (count >= 0)
@@ -1743,47 +1745,63 @@ handle_function (op, stringp)
_("unterminated call to function `%s': missing `%c'"),
entry_p->name, closeparen);
*stringp = end;
/* Get some memory to store the arg pointers. */
argvp = argv = (char **) alloca (sizeof(char *) * (nargs + 2));
/* Chop the string into arguments, then store the end pointer and a nul.
If REQUIRED_ARGS is positive, as soon as we hit that many assume the
rest of the string is part of the last argument. */
*argvp = argbeg;
nargs = 1;
while (entry_p->required_args < 0 || nargs < entry_p->required_args)
/* Chop the string into arguments, then a nul. As soon as we hit
MAXIMUM_ARGS (if it's >0) assume the rest of the string is part of the
last argument.
If we're expanding, store pointers to the expansion of each one. If
not, make a duplicate of the string and point into that, nul-terminating
each argument. */
if (!entry_p->expand_args)
{
char *next = find_next_argument (openparen, closeparen, *argvp, p);
int len = end - beg;
if (!next)
break;
p = xmalloc (len+1);
memcpy (p, beg, len);
p[len] = '\0';
beg = p;
end = beg + len;
}
p = beg;
nargs = 0;
for (p=beg, nargs=0; p < end; ++argvp)
{
char *next;
*(++argvp) = next+1;
++nargs;
if (nargs == entry_p->maximum_args
|| (! (next = find_next_argument (openparen, closeparen, p, end))))
next = end;
if (entry_p->expand_args)
*argvp = expand_argument (p, next);
else
{
*argvp = p;
*next = '\0';
}
p = next + 1;
}
*(++argvp) = p+1;
*(++argvp) = 0;
/* If we should expand, do it. */
if (entry_p->expand_args)
{
for (argvp=argv; argvp[1] != 0; ++argvp)
*argvp = expand_argument (*argvp, argvp[1]-1);
/* end pointer doesn't make sense for expanded stuff. */
*argvp = 0;
}
*argvp = NULL;
/* Finally! Run the function... */
*op = expand_builtin_function (*op, nargs, argv, entry_p);
/* If we allocated memory for the expanded args, free it again. */
/* Free memory. */
if (entry_p->expand_args)
for (argvp=argv; *argvp != 0; ++argvp)
free (*argvp);
*stringp = p;
else
free (beg);
return 1;
}
@@ -1800,47 +1818,73 @@ func_call (o, argv, funcname)
const char *funcname;
{
char *fname;
char *cp;
int flen;
char *body;
int i;
const struct function_table_entry *entry_p;
/* Calling nothing is a no-op. */
if (*argv[0] == '\0')
return o;
fname = expand_argument (argv[0], NULL);
/* There is no way to define a variable with a space in the name, so strip
trailing whitespace as a favor to the user. */
leading and trailing whitespace as a favor to the user. */
cp = fname;
while (*cp != '\0' && isspace ((unsigned char)*cp))
++cp;
argv[0] = cp;
flen = strlen (argv[0]);
fname = argv[0] + flen - 1;
while (isspace (*fname))
--fname;
fname[1] = '\0';
cp += strlen(cp) - 1;
while (cp > argv[0] && isspace ((unsigned char)*cp))
--cp;
cp[1] = '\0';
flen = fname - argv[0] + 1;
fname = argv[0];
/* Calling nothing is a no-op */
if (*argv[0] == '\0')
{
free (fname);
return o;
}
/* Are we invoking a builtin function? */
entry_p = lookup_function (function_table, fname);
entry_p = lookup_function (function_table, argv[0]);
if (entry_p)
{
for (i=0; argv[i+1]; ++i)
;
char **av;
return expand_builtin_function (o, i, argv + 1, entry_p);
free (fname);
/* How many arguments do we have? */
for (i=0; argv[i+1]; ++i)
;
/* If we need to expand arguments, do it now. */
if (entry_p->expand_args)
for (av=argv+1; *av; ++av)
*av = expand_argument (*av, NULL);
o = expand_builtin_function (o, i, argv+1, entry_p);
/* What we expanded we must free... */
if (entry_p->expand_args)
for (av=argv+1; *av; ++av)
free (*av);
return o;
}
/* No, so the first argument is the name of a variable to be expanded and
interpreted as a function. Create the variable reference. */
/* Not a builtin, so the first argument is the name of a variable to be
expanded and interpreted as a function. Create the variable
reference. */
flen = strlen (argv[0]);
body = alloca (flen + 4);
body[0]='$';
body[1]='(';
strcpy (body + 2, fname);
body[flen+2]=')';
body[flen+3]= '\0';
body[0] = '$';
body[1] = '(';
memcpy (body + 2, fname, flen);
body[flen+2] = ')';
body[flen+3] = '\0';
/* Set up arguments $(1) .. $(N). $(0) is the function name. */
@@ -1851,7 +1895,7 @@ func_call (o, argv, funcname)
char num[11];
sprintf (num, "%d", i);
define_variable (num, strlen (num), *argv, o_automatic, 0);
define_variable (num, strlen (num), *argv, o_automatic, 1);
}
/* Expand the body in the context of the arguments, adding the result to
@@ -1861,5 +1905,6 @@ func_call (o, argv, funcname)
pop_variable_scope ();
free (fname);
return o + strlen(o);
}

View File

@@ -79,16 +79,11 @@
# endif
#endif
#ifndef _
/* This is for other GNU distributions with internationalized messages.
When compiling libc, the _ macro is predefined. */
# ifdef HAVE_LIBINTL_H
# include <libintl.h>
# define _(msgid) gettext (msgid)
# else
# define _(msgid) (msgid)
# endif
#endif
#include "gettext.h"
#define _(msgid) gettext (msgid)
/* This version of `getopt' appears to the caller like standard Unix `getopt'
but it behaves differently for the user, since it allows the user

2605
gettext.c Normal file

File diff suppressed because it is too large Load Diff

177
gettext.h Normal file
View File

@@ -0,0 +1,177 @@
/* Begin of libgettext.h */
/* Message catalogs for internationalization.
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Because on some systems (e.g. Solaris) we sometimes have to include
the systems libintl.h as well as this file we have more complex
include protection above. But the systems header might perhaps also
define _LIBINTL_H and therefore we have to protect the definition here. */
#if !defined _LIBINTL_H || !defined _LIBGETTEXT_H
#ifndef _LIBINTL_H
# define _LIBINTL_H 1
#endif
#define _LIBGETTEXT_H 1
/* We define an additional symbol to signal that we use the GNU
implementation of gettext. */
#define __USE_GNU_GETTEXT 1
#include <sys/types.h>
#if HAVE_LOCALE_H
# include <locale.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef PARAMS
# if __STDC__ || defined __cplusplus
# define PARAMS(args) args
# else
# define PARAMS(args) ()
# endif
#endif
#ifndef NULL
# if !defined __cplusplus || defined __GNUC__
# define NULL ((void *) 0)
# else
# define NULL (0)
# endif
#endif
#if !HAVE_LC_MESSAGES
/* This value determines the behaviour of the gettext() and dgettext()
function. But some system does not have this defined. Define it
to a default value. */
# define LC_MESSAGES (-1)
#endif
/* Declarations for gettext-using-catgets interface. Derived from
Jim Meyering's libintl.h. */
struct _msg_ent
{
const char *_msg;
int _msg_number;
};
#if HAVE_CATGETS
/* These two variables are defined in the automatically by po-to-tbl.sed
generated file `cat-id-tbl.c'. */
extern const struct _msg_ent _msg_tbl[];
extern int _msg_tbl_length;
#endif
/* For automatical extraction of messages sometimes no real
translation is needed. Instead the string itself is the result. */
#define gettext_noop(Str) (Str)
/* Look up MSGID in the current default message catalog for the current
LC_MESSAGES locale. If not found, returns MSGID itself (the default
text). */
extern char *gettext PARAMS ((const char *__msgid));
/* static char *gettext__ PARAMS ((const char *__msgid)); */
/* Look up MSGID in the DOMAINNAME message catalog for the current
LC_MESSAGES locale. */
extern char *dgettext PARAMS ((const char *__domainname, const char *__msgid));
/* static char *dgettext__ PARAMS ((const char *__domainname,
const char *__msgid)); */
/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY
locale. */
extern char *dcgettext PARAMS ((const char *__domainname, const char *__msgid,
int __category));
extern char *dcgettext__ PARAMS ((const char *__domainname,
const char *__msgid, int __category));
/* Set the current default message catalog to DOMAINNAME.
If DOMAINNAME is null, return the current default.
If DOMAINNAME is "", reset to the default of "messages". */
extern char *textdomain PARAMS ((const char *__domainname));
/* static char *textdomain__ PARAMS ((const char *__domainname)); */
/* Specify that the DOMAINNAME message catalog will be found
in DIRNAME rather than in the system locale data base. */
extern char *bindtextdomain PARAMS ((const char *__domainname,
const char *__dirname));
/* static char *bindtextdomain__ PARAMS ((const char *__domainname,
const char *__dirname)); */
#if ENABLE_NLS
/* Solaris 2.3 has the gettext function but dcgettext is missing.
So we omit this optimization for Solaris 2.3. BTW, Solaris 2.4
has dcgettext. */
# if !HAVE_CATGETS && (!HAVE_GETTEXT || HAVE_DCGETTEXT)
# define gettext(Msgid) \
dgettext (NULL, Msgid)
# define dgettext(Domainname, Msgid) \
dcgettext (Domainname, Msgid, LC_MESSAGES)
# if defined __GNUC__ && __GNUC__ == 2 && __GNUC_MINOR__ >= 7
/* This global variable is defined in loadmsgcat.c. We need a sign,
whether a new catalog was loaded, which can be associated with all
translations. */
extern int _nl_msg_cat_cntr;
# define dcgettext(Domainname, Msgid, Category) \
(__extension__ \
({ \
char *__result; \
if (__builtin_constant_p (Msgid)) \
{ \
static char *__translation__; \
static int __catalog_counter__; \
if (! __translation__ || __catalog_counter__ != _nl_msg_cat_cntr) \
{ \
__translation__ = \
dcgettext__ (Domainname, Msgid, Category); \
__catalog_counter__ = _nl_msg_cat_cntr; \
} \
__result = __translation__; \
} \
else \
__result = dcgettext__ (Domainname, Msgid, Category); \
__result; \
}))
# endif
# endif
#else
# define gettext(Msgid) (Msgid)
# define dgettext(Domainname, Msgid) (Msgid)
# define dcgettext(Domainname, Msgid, Category) (Msgid)
# define textdomain(Domainname) ((char *) Domainname)
# define bindtextdomain(Domainname, Dirname) ((char *) Dirname)
#endif
#ifdef __cplusplus
}
#endif
#endif
/* End of libgettext.h */

View File

@@ -299,6 +299,12 @@ static int glob_in_dir __P ((const char *pattern, const char *directory,
static int prefix_array __P ((const char *prefix, char **array, size_t n));
static int collated_compare __P ((const __ptr_t, const __ptr_t));
#ifdef VMS
/* these compilers like prototypes */
#if !defined _LIBC || !defined NO_GLOB_PATTERN_P
int __glob_pattern_p (const char *pattern, int quote);
#endif
#endif
/* Find the end of the sub-pattern in a brace expression. We define
this as an inline function if the compiler permits. */
@@ -609,7 +615,12 @@ glob (pattern, flags, errfunc, pglob)
if (dirname[1] == '\0' || dirname[1] == '/')
{
/* Look up home directory. */
const char *home_dir = getenv ("HOME");
#ifdef VMS
/* This isn't obvious, RTLs of DECC and VAXC know about "HOME" */
const char *home_dir = getenv ("SYS$LOGIN");
#else
const char *home_dir = getenv ("HOME");
#endif
# ifdef _AMIGA
if (home_dir == NULL || home_dir[0] == '\0')
home_dir = "SYS:";
@@ -618,6 +629,11 @@ glob (pattern, flags, errfunc, pglob)
if (home_dir == NULL || home_dir[0] == '\0')
home_dir = "c:/users/default"; /* poor default */
# else
# ifdef VMS
/* Again, this isn't obvious, if "HOME" isn't known "SYS$LOGIN" should be set */
if (home_dir == NULL || home_dir[0] == '\0')
home_dir = "SYS$DISK:[]";
# else
if (home_dir == NULL || home_dir[0] == '\0')
{
int success;
@@ -676,6 +692,7 @@ glob (pattern, flags, errfunc, pglob)
else
home_dir = "~"; /* No luck. */
}
# endif /* VMS */
# endif /* WINDOWS32 */
# endif
/* Now construct the full directory. */
@@ -696,7 +713,7 @@ glob (pattern, flags, errfunc, pglob)
dirname = newp;
}
}
# if !defined _AMIGA && !defined WINDOWS32
# if !defined _AMIGA && !defined WINDOWS32 && !defined VMS
else
{
char *end_name = strchr (dirname, '/');
@@ -776,7 +793,7 @@ glob (pattern, flags, errfunc, pglob)
home directory. */
return GLOB_NOMATCH;
}
# endif /* Not Amiga && not WINDOWS32. */
# endif /* Not Amiga && not WINDOWS32 && not VMS. */
}
#endif /* Not VMS. */
@@ -1213,6 +1230,10 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob)
int meta;
int save;
#ifdef VMS
if (*directory == 0)
directory = "[]";
#endif
meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE));
if (meta == 0)
{

View File

@@ -51,7 +51,15 @@ extern "C" {
typedef __SIZE_TYPE__ __size_t;
# else
/* This is a guess. */
/*hb
* Conflicts with DECCs aready defined type __size_t.
* Defining an own type with a name beginning with '__' is no good.
* Anyway if DECC is used and __SIZE_T is defined then __size_t is
* already defined (and I hope it's exactly the one we need here).
*/
#if !(defined __DECC && defined __SIZE_T)
typedef unsigned long int __size_t;
#endif
# endif
#else
/* The GNU CC stddef.h version defines __size_t as empty. We need a real
@@ -118,7 +126,11 @@ typedef struct
struct dirent *(*gl_readdir) __PMT ((void *));
__ptr_t (*gl_opendir) __PMT ((__const char *));
int (*gl_lstat) __PMT ((__const char *, struct stat *));
#if defined(VMS) && defined(__DECC) && !defined(_POSIX_C_SOURCE)
int (*gl_stat) __PMT ((__const char *, struct stat *, ...));
#else
int (*gl_stat) __PMT ((__const char *, struct stat *));
#endif
} glob_t;
#ifdef _LARGEFILE64_SOURCE

3
i18n/.cvsignore Normal file
View File

@@ -0,0 +1,3 @@
*.mo *.pot
Makefile.in Makefile

75
i18n/Makefile.am Normal file
View File

@@ -0,0 +1,75 @@
# Makefile for PO directories.
# François Pinard <pinard@iro.umontreal.ca>, 1998.
AUTOMAKE_OPTIONS = gnits
localedir = $(prefix)/share/locale
ALL_POFILES = @ALL_POFILES@
ALL_MOFILES = @ALL_MOFILES@
MOFILES = @MOFILES@
EXTRA_DIST = $(PACKAGE).pot $(ALL_POFILES) $(ALL_MOFILES)
MSGFMT = msgfmt
MSGMERGE = msgmerge
XGETTEXT = xgettext
SUFFIXES = .po .pox .mo
.po.pox:
$(MAKE) $(PACKAGE).pot
$(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox
.po.mo:
file=$(srcdir)/`echo $* | sed 's,.*/,,'`.mo \
&& rm -f $$file && $(MSGFMT) -o $$file $<
all: $(ALL_MOFILES)
install-data-local: $(MOFILES)
if USE_NLS
files='$(MOFILES)'; \
for file in $$files; do \
base=`basename $$file`; \
langdir=$(DESTDIR)$(localedir)/`echo $$base | sed 's/\.mo$$//'`/LC_MESSAGES; \
$(mkinstalldirs) $$langdir; \
echo " $(INSTALL_DATA) $(srcdir)/$$file $$langdir/$(PACKAGE).mo"; \
$(INSTALL_DATA) $(srcdir)/$$file $$langdir/$(PACKAGE).mo; \
done
endif
uninstall-local:
if USE_NLS
files='$(MOFILES)'; \
for file in $$files; do \
base=`basename $$file`; \
langdir=$(DESTDIR)$(localedir)/`echo $$base | sed 's/\.mo$$//'`/LC_MESSAGES; \
rm -f $$langdir/$(PACKAGE).mo; \
done
endif
MAINTAINER_CLEAN = $(PACKAGE).pot $(MOFILES)
$(srcdir)/$(PACKAGE).pot: $(top_srcdir)/stamp-pot
$(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \
--add-comments --keyword=_ --keyword=N_ `cat $(top_srcdir)/stamp-pot`
test ! -f $(PACKAGE).po || ( rm -f $@ && mv $(PACKAGE).po $@ )
update-po: Makefile
$(MAKE) $(PACKAGE).pot
files='$(ALL_MOFILES)'; \
for file in $$files; do \
base=`basename $$file`; \
lang=`echo $$base | sed 's/\.mo$$//'`; \
mv $(srcdir)/$$lang.po $(srcdir)/$$lang.old.po; \
echo "$$lang:"; \
cd $(srcdir) \
&& if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \
rm -f $$lang.old.po; \
else \
echo "msgmerge for $$file failed!"; \
rm -f $$lang.po; \
mv $$lang.old.po $$lang.po; \
fi; \
done

1772
i18n/de.po Normal file

File diff suppressed because it is too large Load Diff

1932
i18n/es.po Normal file

File diff suppressed because it is too large Load Diff

1445
i18n/fr.po Normal file

File diff suppressed because it is too large Load Diff

1445
i18n/ko.po Normal file

File diff suppressed because it is too large Load Diff

1441
i18n/nl.po Normal file

File diff suppressed because it is too large Load Diff

1467
i18n/pl.po Normal file

File diff suppressed because it is too large Load Diff

1424
i18n/ru.po Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA. */
#include "rule.h"
#include "dep.h"
#include "filedef.h"
#include "debug.h"
static int pattern_search PARAMS ((struct file *file, int archive, unsigned int depth,
unsigned int recursions));
@@ -36,7 +37,7 @@ try_implicit_rule (file, depth)
struct file *file;
unsigned int depth;
{
DEBUGPR (_("Looking for an implicit rule for `%s'.\n"));
DBF (DB_IMPLICIT, _("Looking for an implicit rule for `%s'.\n"));
/* The order of these searches was previously reversed. My logic now is
that since the non-archive search uses more information in the target
@@ -51,7 +52,8 @@ try_implicit_rule (file, depth)
archive member name to search for implicit rules. */
if (ar_name (file->name))
{
DEBUGPR (_("Looking for archive-member implicit rule for `%s'.\n"));
DBF (DB_IMPLICIT,
_("Looking for archive-member implicit rule for `%s'.\n"));
if (pattern_search (file, 1, depth, 0))
return 1;
}
@@ -60,11 +62,6 @@ try_implicit_rule (file, depth)
return 0;
}
#define DEBUGP2(msg, a1, a2) \
do { \
if (debug_flag) \
{ print_spaces (depth); printf (msg, a1, a2); fflush (stdout); } \
} while (0)
/* Search the pattern rules for a rule with an existing dependency to make
FILE. If a rule is found, the appropriate commands and deps are put in FILE
@@ -88,7 +85,7 @@ pattern_search (file, archive, depth, recursions)
unsigned int recursions;
{
/* Filename we are searching for a rule for. */
char *filename = archive ? index (file->name, '(') : file->name;
char *filename = archive ? strchr (file->name, '(') : file->name;
/* Length of FILENAME. */
unsigned int namelen = strlen (filename);
@@ -165,14 +162,16 @@ pattern_search (file, archive, depth, recursions)
but not counting any slash at the end. (foo/bar/ counts as
bar/ in directory foo/, not empty in directory foo/bar/.) */
#ifdef VMS
lastslash = rindex (filename, ']');
lastslash = strrchr (filename, ']');
if (lastslash == 0)
lastslash = strrchr (filename, ':');
#else
lastslash = rindex (filename, '/');
lastslash = strrchr (filename, '/');
#if defined(__MSDOS__) || defined(WINDOWS32)
/* Handle backslashes (possibly mixed with forward slashes)
and the case of "d:file". */
{
char *bslash = rindex (filename, '\\');
char *bslash = strrchr (filename, '\\');
if (lastslash == 0 || bslash > lastslash)
lastslash = bslash;
if (lastslash == 0 && filename[0] && filename[1] == ':')
@@ -199,7 +198,7 @@ pattern_search (file, archive, depth, recursions)
don't use it here. */
if (rule->in_use)
{
DEBUGP2 (_("Avoiding implicit rule recursion.%s%s\n"), "", "");
DBS (DB_IMPLICIT, (_("Avoiding implicit rule recursion.\n")));
continue;
}
@@ -228,9 +227,11 @@ pattern_search (file, archive, depth, recursions)
prefix and the target pattern does not contain a slash. */
#ifdef VMS
check_lastslash = lastslash != 0 && index (target, ']') == 0;
check_lastslash = lastslash != 0
&& ((strchr (target, ']') == 0)
&& (strchr (target, ':') == 0));
#else
check_lastslash = lastslash != 0 && index (target, '/') == 0;
check_lastslash = lastslash != 0 && strchr (target, '/') == 0;
#endif
if (check_lastslash)
{
@@ -335,18 +336,16 @@ pattern_search (file, archive, depth, recursions)
stemlen -= (lastslash - filename) + 1;
}
DEBUGP2 (_("Trying pattern rule with stem `%.*s'.\n"),
(int) stemlen, stem);
DBS (DB_IMPLICIT, (_("Trying pattern rule with stem `%.*s'.\n"),
(int) stemlen, stem));
/* Try each dependency; see if it "exists". */
deps_found = 0;
for (dep = rule->deps; dep != 0; dep = dep->next)
{
struct file *fp;
/* If the dependency name has a %, substitute the stem. */
p = index (dep_name (dep), '%');
p = strchr (dep_name (dep), '%');
if (p != 0)
{
register unsigned int i;
@@ -376,16 +375,21 @@ pattern_search (file, archive, depth, recursions)
"impossible", then the rule fails and don't
bother trying it on the second pass either
since we know that will fail too. */
DEBUGP2 (_("Rejecting impossible %s prerequisite `%s'.\n"),
p == depname ? _("implicit") : _("rule"), p);
DBS (DB_IMPLICIT,
(p == depname
? _("Rejecting impossible implicit prerequisite `%s'.\n")
: _("Rejecting impossible rule prerequisite `%s'.\n"),
p));
tryrules[i] = 0;
break;
}
intermediate_files[deps_found] = 0;
DEBUGP2 (_("Trying %s prerequisite `%s'.\n"),
p == depname ? _("implicit") : _("rule"), p);
DBS (DB_IMPLICIT,
(p == depname
? _("Trying implicit prerequisite `%s'.\n")
: _("Trying rule prerequisite `%s'.\n"), p));
/* The DEP->changed flag says that this dependency resides in a
nonexistent directory. So we normally can skip looking for
@@ -393,12 +397,9 @@ pattern_search (file, archive, depth, recursions)
dependency file we are actually looking for is in a different
directory (the one gotten by prepending FILENAME's directory),
so it might actually exist. */
/* If we find a file but the intermediate flag is set, then it
was put here by a .INTERMEDIATE: rule so ignore it. */
if ((!dep->changed || check_lastslash)
&& (((fp = lookup_file (p)) != 0 && !fp->intermediate)
|| file_exists_p (p)))
&& (lookup_file (p) != 0 || file_exists_p (p)))
{
found_files[deps_found++] = xstrdup (p);
continue;
@@ -408,8 +409,8 @@ pattern_search (file, archive, depth, recursions)
vp = p;
if (vpath_search (&vp, (FILE_TIMESTAMP *) 0))
{
DEBUGP2 (_("Found prerequisite `%s' as VPATH `%s'\n"),
p, vp);
DBS (DB_IMPLICIT,
(_("Found prerequisite `%s' as VPATH `%s'\n"), p, vp));
strcpy (vp, p);
found_files[deps_found++] = vp;
continue;
@@ -425,8 +426,9 @@ pattern_search (file, archive, depth, recursions)
intermediate_file
= (struct file *) alloca (sizeof (struct file));
DEBUGP2 (_("Looking for a rule with %s file `%s'.\n"),
_("intermediate"), p);
DBS (DB_IMPLICIT,
(_("Looking for a rule with intermediate file `%s'.\n"),
p));
bzero ((char *) intermediate_file, sizeof (struct file));
intermediate_file->name = p;

693
job.c
View File

@@ -17,12 +17,17 @@ along with GNU Make; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <assert.h>
#include "make.h"
#include "job.h"
#include "debug.h"
#include "filedef.h"
#include "commands.h"
#include "variable.h"
#include <assert.h>
#include "debug.h"
#include <string.h>
/* Default shell to use. */
#ifdef WINDOWS32
@@ -41,7 +46,12 @@ extern int MyExecute (char **);
directories we could trust). */
char *default_shell = "command.com";
# else /* __MSDOS__ */
# ifdef VMS
# include <descrip.h>
char default_shell[] = "";
# else
char default_shell[] = "/bin/sh";
# endif /* VMS */
# endif /* __MSDOS__ */
int batch_mode_shell = 0;
# endif /* _AMIGA */
@@ -65,7 +75,9 @@ static int amiga_batch_file;
#ifdef VMS
# include <time.h>
# include <processes.h>
# ifndef __GNUC__
# include <processes.h>
# endif
# include <starlet.h>
# include <lib$routines.h>
#endif
@@ -181,6 +193,7 @@ extern int start_remote_job_p PARAMS ((int));
extern int remote_status PARAMS ((int *exit_code_ptr, int *signal_ptr,
int *coredump_ptr, int block));
RETSIGTYPE child_handler PARAMS ((int));
static void free_child PARAMS ((struct child *));
static void start_job_command PARAMS ((struct child *child));
static int load_too_high PARAMS ((void));
@@ -210,8 +223,6 @@ static struct child *waiting_jobs = 0;
int unixy_shell = 1;
/* #define debug_flag 1 */
#ifdef WINDOWS32
/*
@@ -223,7 +234,6 @@ int w32_kill(int pid, int sig)
}
#endif /* WINDOWS32 */
/* Write an error message describing the exit status given in
EXIT_CODE, EXIT_SIG, and COREDUMP, for the target TARGET_NAME.
Append "(ignored)" if IGNORED is nonzero. */
@@ -239,7 +249,10 @@ child_error (target_name, exit_code, exit_sig, coredump, ignored)
#ifdef VMS
if (!(exit_code & 1))
error (NILF, _("*** [%s] Error 0x%x%s"), target_name, exit_code, ((ignored)? _(" (ignored)") : ""));
error (NILF,
(ignored ? _("*** [%s] Error 0x%x (ignored)")
: _("*** [%s] Error 0x%x")),
target_name, exit_code);
#else
if (exit_sig == 0)
error (NILF, ignored ? _("[%s] Error %d (ignored)") :
@@ -269,6 +282,98 @@ vmsWaitForChildren(int *status)
}
return;
}
/* Set up IO redirection. */
char *
vms_redirect (desc, fname, ibuf)
struct dsc$descriptor_s *desc;
char *fname;
char *ibuf;
{
char *fptr;
extern char *vmsify ();
ibuf++;
while (isspace (*ibuf))
ibuf++;
fptr = ibuf;
while (*ibuf && !isspace (*ibuf))
ibuf++;
*ibuf = 0;
if (strcmp (fptr, "/dev/null") != 0)
{
strcpy (fname, vmsify (fptr, 0));
if (strchr (fname, '.') == 0)
strcat (fname, ".");
}
desc->dsc$w_length = strlen(fname);
desc->dsc$a_pointer = fname;
desc->dsc$b_dtype = DSC$K_DTYPE_T;
desc->dsc$b_class = DSC$K_CLASS_S;
if (*fname == 0)
printf (_("Warning: Empty redirection\n"));
return ibuf;
}
/*
found apostrophe at (p-1)
inc p until after closing apostrophe. */
static char *
handle_apos (char *p)
{
int alast;
int inside;
#define SEPCHARS ",/()= "
inside = 0;
while (*p != 0)
{
if (*p == '"')
{
if (inside)
{
while ((alast > 0)
&& (*p == '"'))
{
p++;
alast--;
}
if (alast == 0)
inside = 0;
else
{
fprintf (stderr, _("Syntax error, still inside '\"'\n"));
exit (3);
}
}
else
{
p++;
if (strchr (SEPCHARS, *p))
break;
inside = 1;
alast = 1;
while (*p == '"')
{
alast++;
p++;
}
}
}
else
p++;
}
return p;
}
#endif
@@ -296,8 +401,7 @@ child_handler (sig)
job_rfd = -1;
}
if (debug_flag)
printf (_("Got a SIGCHLD; %u unreaped children.\n"), dead_children);
DB (DB_JOBS, (_("Got a SIGCHLD; %u unreaped children.\n"), dead_children));
}
@@ -375,10 +479,9 @@ reap_children (block, err)
{
any_remote |= c->remote;
any_local |= ! c->remote;
if (debug_flag)
printf (_("Live child 0x%08lx (%s) PID %ld %s\n"),
(unsigned long int) c, c->file->name,
(long) c->pid, c->remote ? _(" (remote)") : "");
DB (DB_JOBS, (_("Live child 0x%08lx (%s) PID %ld %s\n"),
(unsigned long int) c, c->file->name,
(long) c->pid, c->remote ? _(" (remote)") : ""));
#ifdef VMS
break;
#endif
@@ -534,15 +637,15 @@ reap_children (block, err)
Ignore it; it was inherited from our invoker. */
continue;
if (debug_flag)
printf (_("Reaping %s child 0x%08lx PID %ld %s\n"),
child_failed ? _("losing") : _("winning"),
(unsigned long int) c, (long) c->pid,
c->remote ? _(" (remote)") : "");
DB (DB_JOBS, (child_failed
? _("Reaping losing child 0x%08lx PID %ld %s\n")
: _("Reaping winning child 0x%08lx PID %ld %s\n"),
(unsigned long int) c, (long) c->pid,
c->remote ? _(" (remote)") : ""));
if (c->sh_batch_file) {
if (debug_flag)
printf (_("Cleaning up temp batch file %s\n"), c->sh_batch_file);
DB (DB_JOBS, (_("Cleaning up temp batch file %s\n"),
c->sh_batch_file));
/* just try and remove, don't care if this fails */
remove (c->sh_batch_file);
@@ -634,10 +737,9 @@ reap_children (block, err)
update_status to its also_make files. */
notice_finished_file (c->file);
if (debug_flag)
printf (_("Removing child 0x%08lx PID %ld %s from chain.\n"),
(unsigned long int) c, (long) c->pid,
c->remote ? _(" (remote)") : "");
DB (DB_JOBS, (_("Removing child 0x%08lx PID %ld %s from chain.\n"),
(unsigned long int) c, (long) c->pid,
c->remote ? _(" (remote)") : ""));
/* Block fatal signals while frobnicating the list, so that
children and job_slots_used are always consistent. Otherwise
@@ -694,9 +796,8 @@ free_child (child)
if (!EINTR_SET)
pfatal_with_name (_("write jobserver"));
if (debug_flag)
printf (_("Released token for child 0x%08lx (%s).\n"),
(unsigned long int) child, child->file->name);
DB (DB_JOBS, (_("Released token for child 0x%08lx (%s).\n"),
(unsigned long int) child, child->file->name));
}
if (handling_fatal_signal) /* Don't bother free'ing if about to die. */
@@ -794,6 +895,9 @@ start_job_command (child)
++p;
}
/* Update the file's command flags with any new ones we found. */
child->file->cmds->lines_flags[child->command_line - 1] |= flags;
/* If -q was given, just say that updating `failed'. The exit status of
1 tells the user that -q is saying `something to do'; the exit status
for a random error is 2. */
@@ -1186,10 +1290,9 @@ start_waiting_job (c)
{
case cs_running:
c->next = children;
if (debug_flag)
printf (_("Putting child 0x%08lx (%s) PID %ld%s on the chain.\n"),
(unsigned long int) c, c->file->name,
(long) c->pid, c->remote ? _(" (remote)") : "");
DB (DB_JOBS, (_("Putting child 0x%08lx (%s) PID %ld%s on the chain.\n"),
(unsigned long int) c, c->file->name,
(long) c->pid, c->remote ? _(" (remote)") : ""));
children = c;
/* One more job slot is in use. */
++job_slots_used;
@@ -1254,7 +1357,7 @@ new_job (file)
IN gets ahead of OUT. */
in = out = cmds->command_lines[i];
while ((ref = index (in, '$')) != 0)
while ((ref = strchr (in, '$')) != 0)
{
++ref; /* Move past the $. */
@@ -1340,11 +1443,9 @@ new_job (file)
`struct child', and add that to the chain. */
c = (struct child *) xmalloc (sizeof (struct child));
bzero ((char *)c, sizeof (struct child));
c->file = file;
c->command_lines = lines;
c->command_line = 0;
c->command_ptr = 0;
c->environment = 0;
c->sh_batch_file = NULL;
/* Fetch the first command line to be run. */
@@ -1386,9 +1487,8 @@ new_job (file)
if (read (job_rfd, &token, 1) == 1)
{
if (debug_flag)
printf (_("Obtained token for child 0x%08lx (%s).\n"),
(unsigned long int) c, c->file->name);
DB (DB_JOBS, (_("Obtained token for child 0x%08lx (%s).\n"),
(unsigned long int) c, c->file->name));
break;
}
@@ -1410,7 +1510,7 @@ new_job (file)
(This will notice if there are in fact no commands.) */
(void) start_waiting_job (c);
if (job_slots == 1)
if (job_slots == 1 || not_parallel)
/* Since there is only one job slot, make things run linearly.
Wait for the child to die, setting the state to `cs_finished'. */
while (file->command_state == cs_running)
@@ -1462,7 +1562,8 @@ load_too_high ()
{
if (errno == 0)
/* An errno value of zero means getloadavg is just unsupported. */
error (NILF, _("cannot enforce load limits on this operating system"));
error (NILF,
_("cannot enforce load limits on this operating system"));
else
perror_with_name (_("cannot enforce load limit: "), "getloadavg");
}
@@ -1567,7 +1668,8 @@ int vmsHandleChildTerm(struct child *child)
break;
default:
error (NILF, _("internal error: `%s' command_state"), c->file->name);
error (NILF, _("internal error: `%s' command_state"),
c->file->name);
abort ();
break;
}
@@ -1605,6 +1707,76 @@ int vmsHandleChildTerm(struct child *child)
#define MAXCMDLEN 200
/* local helpers to make ctrl+c and ctrl+y working, see below */
#include <iodef.h>
#include <libclidef.h>
#include <ssdef.h>
static int ctrlMask= LIB$M_CLI_CTRLY;
static int oldCtrlMask;
static int setupYAstTried= 0;
static int pidToAbort= 0;
static int chan= 0;
static void reEnableAst(void) {
lib$enable_ctrl (&oldCtrlMask,0);
}
static astHandler (void) {
if (pidToAbort) {
sys$forcex (&pidToAbort, 0, SS$_ABORT);
pidToAbort= 0;
}
kill (getpid(),SIGQUIT);
}
static void tryToSetupYAst(void) {
$DESCRIPTOR(inputDsc,"SYS$COMMAND");
int status;
struct {
short int status, count;
int dvi;
} iosb;
setupYAstTried++;
if (!chan) {
status= sys$assign(&inputDsc,&chan,0,0);
if (!(status&SS$_NORMAL)) {
lib$signal(status);
return;
}
}
status= sys$qiow (0, chan, IO$_SETMODE|IO$M_CTRLYAST,&iosb,0,0,
astHandler,0,0,0,0,0);
if (status==SS$_ILLIOFUNC) {
sys$dassgn(chan);
#ifdef CTRLY_ENABLED_ANYWAY
fprintf (stderr,
_("-warning, CTRL-Y will leave sub-process(es) around.\n"));
#else
return;
#endif
}
if (status==SS$_NORMAL)
status= iosb.status;
if (!(status&SS$_NORMAL)) {
lib$signal(status);
return;
}
/* called from AST handler ? */
if (setupYAstTried>1)
return;
if (atexit(reEnableAst))
fprintf (stderr,
_("-warning, you may have to re-enable CTRL-Y handling from DCL.\n"));
status= lib$disable_ctrl (&ctrlMask, &oldCtrlMask);
if (!(status&SS$_NORMAL)) {
lib$signal(status);
return;
}
}
int
child_execute_job (argv, child)
char *argv;
@@ -1612,32 +1784,183 @@ child_execute_job (argv, child)
{
int i;
static struct dsc$descriptor_s cmddsc;
#ifndef DONTWAITFORCHILD
int spflags = 0;
#else
static struct dsc$descriptor_s pnamedsc;
static struct dsc$descriptor_s ifiledsc;
static struct dsc$descriptor_s ofiledsc;
static struct dsc$descriptor_s efiledsc;
int have_redirection = 0;
int have_newline = 0;
int spflags = CLI$M_NOWAIT;
#endif
int status;
char cmd[4096],*p,*c;
char *cmd = alloca (strlen (argv) + 512), *p, *q;
char ifile[256], ofile[256], efile[256];
char comname[50];
char procname[100];
/* Remove backslashes */
for (p = argv, c = cmd; *p; p++,c++)
/* Parse IO redirection. */
ifile[0] = 0;
ofile[0] = 0;
efile[0] = 0;
DB (DB_JOBS, ("child_execute_job (%s)\n", argv));
while (isspace (*argv))
argv++;
if (*argv == 0)
return 0;
sprintf (procname, "GMAKE_%05x", getpid () & 0xfffff);
pnamedsc.dsc$w_length = strlen(procname);
pnamedsc.dsc$a_pointer = procname;
pnamedsc.dsc$b_dtype = DSC$K_DTYPE_T;
pnamedsc.dsc$b_class = DSC$K_CLASS_S;
/* Handle comments and redirection. */
for (p = argv, q = cmd; *p; p++, q++)
{
if (*p == '\\') p++;
*c = *p;
switch (*p)
{
case '#':
*p-- = 0;
*q-- = 0;
break;
case '\\':
p++;
if (*p == '\n')
p++;
if (isspace (*p))
{
do { p++; } while (isspace (*p));
p--;
}
*q = *p;
break;
case '<':
p = vms_redirect (&ifiledsc, ifile, p);
*q = ' ';
have_redirection = 1;
break;
case '>':
have_redirection = 1;
if (*(p-1) == '2')
{
q--;
if (strncmp (p, ">&1", 3) == 0)
{
p += 3;
strcpy (efile, "sys$output");
efiledsc.dsc$w_length = strlen(efile);
efiledsc.dsc$a_pointer = efile;
efiledsc.dsc$b_dtype = DSC$K_DTYPE_T;
efiledsc.dsc$b_class = DSC$K_CLASS_S;
}
else
{
p = vms_redirect (&efiledsc, efile, p);
}
}
else
{
p = vms_redirect (&ofiledsc, ofile, p);
}
*q = ' ';
break;
case '\n':
have_newline = 1;
default:
*q = *p;
break;
}
}
*c = *p;
*q = *p;
/* Check for maximum DCL length and create *.com file if neccesary.
Also create a .com file if the command is more than one line long. */
if (strncmp (cmd, "builtin_", 8) == 0)
{
child->pid = 270163;
child->efn = 0;
child->cstatus = 1;
DB (DB_JOBS, (_("BUILTIN [%s][%s]\n"), cmd, cmd+8));
p = cmd + 8;
if ((*(p) == 'c')
&& (*(p+1) == 'd')
&& ((*(p+2) == ' ') || (*(p+2) == '\t')))
{
p += 3;
while ((*p == ' ') || (*p == '\t'))
p++;
DB (DB_JOBS, (_("BUILTIN CD %s\n"), p));
if (chdir (p))
return 0;
else
return 1;
}
else if ((*(p) == 'r')
&& (*(p+1) == 'm')
&& ((*(p+2) == ' ') || (*(p+2) == '\t')))
{
int in_arg;
/* rm */
p += 3;
while ((*p == ' ') || (*p == '\t'))
p++;
in_arg = 1;
DB (DB_JOBS, (_("BUILTIN RM %s\n"), p));
while (*p)
{
switch (*p)
{
case ' ':
case '\t':
if (in_arg)
{
*p++ = ';';
in_arg = 0;
}
break;
default:
break;
}
p++;
}
}
else
{
printf(_("Unknown builtin command '%s'\n"), cmd);
fflush(stdout);
return 0;
}
}
/* Create a *.com file if either the command is too long for
lib$spawn, or the command contains a newline, or if redirection
is desired. Forcing commands with newlines into DCLs allows to
store search lists on user mode logicals. */
comname[0] = '\0';
if (strlen (cmd) > MAXCMDLEN || strchr (cmd, '\n'))
if (strlen (cmd) > MAXCMDLEN
|| (have_redirection != 0)
|| (have_newline != 0))
{
FILE *outfile;
char tmp;
char c;
char *sep;
int alevel = 0; /* apostrophe level */
if (strlen (cmd) == 0)
{
printf (_("Error, empty command\n"));
fflush (stdout);
return 0;
}
strcpy (comname, "sys$scratch:CMDXXXXXX.COM");
(void) mktemp (comname);
@@ -1646,34 +1969,87 @@ child_execute_job (argv, child)
if (outfile == 0)
pfatal_with_name (comname);
fprintf (outfile, "$ ");
c = cmd;
while (c)
if (ifile[0])
{
p = strchr (c, ',');
if ((p == NULL) || (p-c > MAXCMDLEN))
p = strchr (c, ' ');
if (p != NULL)
{
p++;
tmp = *p;
*p = '\0';
}
else
tmp = '\0';
fprintf (outfile, "%s%s\n", c, (tmp == '\0')?"":" -");
if (p != NULL)
*p = tmp;
c = p;
fprintf (outfile, "$ assign/user %s sys$input\n", ifile);
DB (DB_JOBS, (_("Redirected input from %s\n"), ifile));
ifiledsc.dsc$w_length = 0;
}
if (efile[0])
{
fprintf (outfile, "$ define sys$error %s\n", efile);
DB (DB_JOBS, (_("Redirected error to %s\n"), efile));
efiledsc.dsc$w_length = 0;
}
if (ofile[0])
{
fprintf (outfile, "$ define sys$output %s\n", ofile);
DB (DB_JOBS, (_("Redirected output to %s\n"), ofile));
ofiledsc.dsc$w_length = 0;
}
p = sep = q = cmd;
for (c = '\n'; c; c = *q++)
{
switch (c)
{
case '\n':
/* At a newline, skip any whitespace around a leading $
from the command and issue exactly one $ into the DCL. */
while (isspace (*p))
p++;
if (*p == '$')
p++;
while (isspace (*p))
p++;
fwrite (p, 1, q - p, outfile);
fputc ('$', outfile);
fputc (' ', outfile);
/* Reset variables. */
p = sep = q;
break;
/* Nice places for line breaks are after strings, after
comma or space and before slash. */
case '"':
q = handle_apos (q + 1);
sep = q;
break;
case ',':
case ' ':
sep = q;
break;
case '/':
case '\0':
sep = q - 1;
break;
default:
break;
}
if (sep - p > 78)
{
/* Enough stuff for a line. */
fwrite (p, 1, sep - p, outfile);
p = sep;
if (*sep)
{
/* The command continues. */
fputc ('-', outfile);
}
fputc ('\n', outfile);
}
}
fwrite (p, 1, q - p, outfile);
fputc ('\n', outfile);
fclose (outfile);
sprintf (cmd, "$ @%s", comname);
if (debug_flag)
printf (_("Executing %s instead\n"), cmd);
DB (DB_JOBS, (_("Executing %s instead\n"), cmd));
}
cmddsc.dsc$w_length = strlen(cmd);
@@ -1684,31 +2060,98 @@ child_execute_job (argv, child)
child->efn = 0;
while (child->efn < 32 || child->efn > 63)
{
status = lib$get_ef(&child->efn);
status = lib$get_ef ((unsigned long *)&child->efn);
if (!(status & 1))
return 0;
}
sys$clref(child->efn);
sys$clref (child->efn);
vms_jobsefnmask |= (1 << (child->efn - 32));
/*
LIB$SPAWN [command-string]
[,input-file]
[,output-file]
[,flags]
[,process-name]
[,process-id] [,completion-status-address] [,byte-integer-event-flag-num]
[,AST-address] [,varying-AST-argument]
[,prompt-string] [,cli] [,table]
*/
#ifndef DONTWAITFORCHILD
status = lib$spawn(&cmddsc,0,0,&spflags,0,&child->pid,&child->cstatus,
&child->efn,0,0);
/*
* Code to make ctrl+c and ctrl+y working.
* The problem starts with the synchronous case where after lib$spawn is
* called any input will go to the child. But with input re-directed,
* both control characters won't make it to any of the programs, neither
* the spawning nor to the spawned one. Hence the caller needs to spawn
* with CLI$M_NOWAIT to NOT give up the input focus. A sys$waitfr
* has to follow to simulate the wanted synchronous behaviour.
* The next problem is ctrl+y which isn't caught by the crtl and
* therefore isn't converted to SIGQUIT (for a signal handler which is
* already established). The only way to catch ctrl+y, is an AST
* assigned to the input channel. But ctrl+y handling of DCL needs to be
* disabled, otherwise it will handle it. Not to mention the previous
* ctrl+y handling of DCL needs to be re-established before make exits.
* One more: At the time of LIB$SPAWN signals are blocked. SIGQUIT will
* make it to the signal handler after the child "normally" terminates.
* This isn't enough. It seems reasonable for simple command lines like
* a 'cc foobar.c' spawned in a subprocess but it is unacceptable for
* spawning make. Therefore we need to abort the process in the AST.
*
* Prior to the spawn it is checked if an AST is already set up for
* ctrl+y, if not one is set up for a channel to SYS$COMMAND. In general
* this will work except if make is run in a batch environment, but there
* nobody can press ctrl+y. During the setup the DCL handling of ctrl+y
* is disabled and an exit handler is established to re-enable it.
* If the user interrupts with ctrl+y, the assigned AST will fire, force
* an abort to the subprocess and signal SIGQUIT, which will be caught by
* the already established handler and will bring us back to common code.
* After the spawn (now /nowait) a sys$waitfr simulates the /wait and
* enables the ctrl+y be delivered to this code. And the ctrl+c too,
* which the crtl converts to SIGINT and which is caught by the common
* signal handler. Because signals were blocked before entering this code
* sys$waitfr will always complete and the SIGQUIT will be processed after
* it (after termination of the current block, somewhere in common code).
* And SIGINT too will be delayed. That is ctrl+c can only abort when the
* current command completes. Anyway it's better than nothing :-)
*/
if (!setupYAstTried)
tryToSetupYAst();
status = lib$spawn (&cmddsc, /* cmd-string */
(ifiledsc.dsc$w_length == 0)?0:&ifiledsc, /* input-file */
(ofiledsc.dsc$w_length == 0)?0:&ofiledsc, /* output-file */
&spflags, /* flags */
&pnamedsc, /* proc name */
&child->pid, &child->cstatus, &child->efn,
0, 0,
0, 0, 0);
pidToAbort= child->pid;
status= sys$waitfr (child->efn);
pidToAbort= 0;
vmsHandleChildTerm(child);
#else
status = lib$spawn(&cmddsc,0,0,&spflags,0,&child->pid,&child->cstatus,
&child->efn,vmsHandleChildTerm,child);
status = lib$spawn (&cmddsc,
(ifiledsc.dsc$w_length == 0)?0:&ifiledsc,
(ofiledsc.dsc$w_length == 0)?0:&ofiledsc,
&spflags,
&pnamedsc,
&child->pid, &child->cstatus, &child->efn,
vmsHandleChildTerm, child,
0, 0, 0);
#endif
if (!(status & 1))
{
printf(_("Error spawning, %d\n"),status);
fflush(stdout);
printf (_("Error spawning, %d\n") ,status);
fflush (stdout);
}
unlink (comname);
if (comname[0] && !ISDB (DB_JOBS))
unlink (comname);
return (status & 1);
}
@@ -1751,6 +2194,10 @@ exec_command (argv, envp)
char **argv, **envp;
{
#ifdef VMS
/* to work around a problem with signals and execve: ignore them */
#ifdef SIGCHLD
signal (SIGCHLD,SIG_IGN);
#endif
/* Run the program. */
execve (argv[0], argv, envp);
perror_with_name ("execve: ", argv[0]);
@@ -1951,7 +2398,7 @@ construct_command_argv_internal (line, restp, shell, ifs, batch_filename_ptr)
0 };
#else
#ifdef WINDOWS32
static char sh_chars_dos[] = "\"|<>";
static char sh_chars_dos[] = "\"|&<>";
static char *sh_cmds_dos[] = { "break", "call", "cd", "chcp", "chdir", "cls",
"copy", "ctty", "date", "del", "dir", "echo",
"erase", "exit", "for", "goto", "if", "if", "md",
@@ -2096,12 +2543,12 @@ construct_command_argv_internal (line, restp, shell, ifs, batch_filename_ptr)
If we see any of those, punt.
But on MSDOS, if we use COMMAND.COM, double and single
quotes have the same effect. */
else if (instring == '"' && index ("\\$`", *p) != 0 && unixy_shell)
else if (instring == '"' && strchr ("\\$`", *p) != 0 && unixy_shell)
goto slow;
else
*ap++ = *p;
}
else if (index (sh_chars, *p) != 0)
else if (strchr (sh_chars, *p) != 0)
/* Not inside a string, but it's a special char. */
goto slow;
#ifdef __MSDOS__
@@ -2178,8 +2625,9 @@ construct_command_argv_internal (line, restp, shell, ifs, batch_filename_ptr)
}
else
#endif
if (p[1] != '\\' && p[1] != '\'' && !isspace (p[1])
&& (index (sh_chars_sh, p[1]) == 0))
if (p[1] != '\\' && p[1] != '\''
&& !isspace ((unsigned char)p[1])
&& (strchr (sh_chars_sh, p[1]) == 0))
/* back up one notch, to copy the backslash */
--p;
@@ -2327,7 +2775,7 @@ construct_command_argv_internal (line, restp, shell, ifs, batch_filename_ptr)
*/
/* Make sure not to bother processing an empty line. */
while (isspace (*line))
while (isspace ((unsigned char)*line))
++line;
if (*line == '\0')
return 0;
@@ -2339,19 +2787,23 @@ construct_command_argv_internal (line, restp, shell, ifs, batch_filename_ptr)
argument list. */
unsigned int shell_len = strlen (shell);
#ifndef VMS
static char minus_c[] = " -c ";
#else
static char minus_c[] = "";
#endif
unsigned int line_len = strlen (line);
char *new_line = (char *) alloca (shell_len + (sizeof (minus_c) - 1)
+ (line_len * 2) + 1);
char* command_ptr = NULL; /* used for batch_mode_shell mode */
char *command_ptr = NULL; /* used for batch_mode_shell mode */
ap = new_line;
bcopy (shell, ap, shell_len);
ap += shell_len;
bcopy (minus_c, ap, sizeof (minus_c) - 1);
ap += sizeof (minus_c) - 1;
command_ptr = ap;
command_ptr = ap;
for (p = line; *p != '\0'; ++p)
{
if (restp != NULL && *p == '\n')
@@ -2384,8 +2836,8 @@ construct_command_argv_internal (line, restp, shell, ifs, batch_filename_ptr)
/* DOS shells don't know about backslash-escaping. */
if (unixy_shell && !batch_mode_shell &&
(*p == '\\' || *p == '\'' || *p == '"'
|| isspace (*p)
|| index (sh_chars, *p) != 0))
|| isspace ((unsigned char)*p)
|| strchr (sh_chars, *p) != 0))
*ap++ = '\\';
#ifdef __MSDOS__
else if (unixy_shell && strneq (p, "...", 3))
@@ -2432,8 +2884,8 @@ construct_command_argv_internal (line, restp, shell, ifs, batch_filename_ptr)
strcat(*batch_filename_ptr, ".sh");
}
if (debug_flag)
printf(_("Creating temporary batch file %s\n"), *batch_filename_ptr);
DB (DB_JOBS, (_("Creating temporary batch file %s\n"),
*batch_filename_ptr));
/* create batch file to execute command */
batch = fopen (*batch_filename_ptr, "w");
@@ -2444,7 +2896,7 @@ construct_command_argv_internal (line, restp, shell, ifs, batch_filename_ptr)
fclose (batch);
/* create argv */
new_argv = (char **) xmalloc(3 * sizeof(char *));
new_argv = (char **) xmalloc(3 * sizeof (char *));
if (unixy_shell) {
new_argv[0] = xstrdup (shell);
new_argv[1] = *batch_filename_ptr; /* only argv[0] gets freed later */
@@ -2458,7 +2910,7 @@ construct_command_argv_internal (line, restp, shell, ifs, batch_filename_ptr)
if (unixy_shell)
new_argv = construct_command_argv_internal (new_line, (char **) NULL,
(char *) 0, (char *) 0,
(char *) 0);
(char **) 0);
#ifdef __MSDOS__
else
{
@@ -2482,6 +2934,7 @@ construct_command_argv_internal (line, restp, shell, ifs, batch_filename_ptr)
return new_argv;
}
#endif /* !VMS */
/* Figure out the argument list necessary to run LINE as a command. Try to
avoid using a shell. This routine handles only ' quoting, and " quoting
@@ -2505,6 +2958,47 @@ construct_command_argv (line, restp, file, batch_filename_ptr)
char *shell, *ifs;
char **argv;
#ifdef VMS
char *cptr;
int argc;
argc = 0;
cptr = line;
for (;;)
{
while ((*cptr != 0)
&& (isspace (*cptr)))
cptr++;
if (*cptr == 0)
break;
while ((*cptr != 0)
&& (!isspace(*cptr)))
cptr++;
argc++;
}
argv = (char **)malloc (argc * sizeof (char *));
if (argv == 0)
abort ();
cptr = line;
argc = 0;
for (;;)
{
while ((*cptr != 0)
&& (isspace (*cptr)))
cptr++;
if (*cptr == 0)
break;
DB (DB_JOBS, ("argv[%d] = [%s]\n", argc, cptr));
argv[argc++] = cptr;
while ((*cptr != 0)
&& (!isspace(*cptr)))
cptr++;
if (*cptr != 0)
*cptr++ = 0;
}
#else
{
/* Turn off --warn-undefined-variables while we expand SHELL and IFS. */
int save = warn_undefined_variables_flag;
@@ -2530,10 +3024,9 @@ construct_command_argv (line, restp, file, batch_filename_ptr)
free (shell);
free (ifs);
#endif /* !VMS */
return argv;
}
#endif /* !VMS */
#if !defined(HAVE_DUP2) && !defined(_AMIGA)
int

290
main.c
View File

@@ -24,7 +24,9 @@ MA 02111-1307, USA. */
#include "job.h"
#include "commands.h"
#include "rule.h"
#include "debug.h"
#include "getopt.h"
#include <assert.h>
#ifdef _AMIGA
# include <dos/dos.h>
@@ -73,7 +75,7 @@ static void print_version PARAMS ((void));
static void decode_switches PARAMS ((int argc, char **argv, int env));
static void decode_env_switches PARAMS ((char *envar, unsigned int len));
static void define_makeflags PARAMS ((int all, int makefile));
static char *quote_as_word PARAMS ((char *out, char *in, int double_dollars));
static char *quote_for_env PARAMS ((char *out, char *in));
/* The structure that describes an accepted command switch. */
@@ -137,9 +139,12 @@ int touch_flag;
int just_print_flag;
/* Print debugging trace info (-d). */
/* Print debugging info (--debug). */
int debug_flag = 0;
static struct stringlist *db_flags;
static int debug_flag = 0;
int db_level = 0;
#ifdef WINDOWS32
/* Suspend make in main for a short time to allow debugger to attach */
@@ -252,102 +257,106 @@ static const struct command_switch switches[] =
{
{ 'b', ignore, 0, 0, 0, 0, 0, 0,
0, 0,
_("Ignored for compatibility") },
N_("Ignored for compatibility") },
{ 'C', string, (char *) &directories, 0, 0, 0, 0, 0,
"directory", _("DIRECTORY"),
_("Change to DIRECTORY before doing anything") },
"directory", N_("DIRECTORY"),
N_("Change to DIRECTORY before doing anything") },
{ 'd', flag, (char *) &debug_flag, 1, 1, 0, 0, 0,
"debug", 0,
_("Print lots of debugging information") },
0, 0,
N_("Print lots of debugging information") },
{ CHAR_MAX+1, string, (char *) &db_flags, 1, 1, 0,
"basic", 0,
"debug", N_("FLAGS"),
N_("Print various types of debugging information") },
#ifdef WINDOWS32
{ 'D', flag, (char *) &suspend_flag, 1, 1, 0, 0, 0,
"suspend-for-debug", 0,
_("Suspend process to allow a debugger to attach") },
N_("Suspend process to allow a debugger to attach") },
#endif
{ 'e', flag, (char *) &env_overrides, 1, 1, 0, 0, 0,
"environment-overrides", 0,
_("Environment variables override makefiles") },
N_("Environment variables override makefiles") },
{ 'f', string, (char *) &makefiles, 0, 0, 0, 0, 0,
"file", _("FILE"),
_("Read FILE as a makefile") },
"file", N_("FILE"),
N_("Read FILE as a makefile") },
{ 'h', flag, (char *) &print_usage_flag, 0, 0, 0, 0, 0,
"help", 0,
_("Print this message and exit") },
N_("Print this message and exit") },
{ 'i', flag, (char *) &ignore_errors_flag, 1, 1, 0, 0, 0,
"ignore-errors", 0,
_("Ignore errors from commands") },
N_("Ignore errors from commands") },
{ 'I', string, (char *) &include_directories, 1, 1, 0, 0, 0,
"include-dir", _("DIRECTORY"),
_("Search DIRECTORY for included makefiles") },
"include-dir", N_("DIRECTORY"),
N_("Search DIRECTORY for included makefiles") },
{ 'j',
positive_int, (char *) &job_slots, 1, 1, 0,
(char *) &inf_jobs, (char *) &default_job_slots,
"jobs", "N",
_("Allow N jobs at once; infinite jobs with no arg") },
{ CHAR_MAX+1, string, (char *) &jobserver_fds, 1, 1, 0, 0, 0,
N_("Allow N jobs at once; infinite jobs with no arg") },
{ CHAR_MAX+2, string, (char *) &jobserver_fds, 1, 1, 0, 0, 0,
"jobserver-fds", 0,
0 },
{ 'k', flag, (char *) &keep_going_flag, 1, 1, 0,
0, (char *) &default_keep_going_flag,
"keep-going", 0,
_("Keep going when some targets can't be made") },
N_("Keep going when some targets can't be made") },
#ifndef NO_FLOAT
{ 'l', floating, (char *) &max_load_average, 1, 1, 0,
(char *) &default_load_average, (char *) &default_load_average,
"load-average", "N",
_("Don't start multiple jobs unless load is below N") },
N_("Don't start multiple jobs unless load is below N") },
#else
{ 'l', positive_int, (char *) &max_load_average, 1, 1, 0,
(char *) &default_load_average, (char *) &default_load_average,
"load-average", "N",
_("Don't start multiple jobs unless load is below N") },
N_("Don't start multiple jobs unless load is below N") },
#endif
{ 'm', ignore, 0, 0, 0, 0, 0, 0,
0, 0,
"-b" },
{ 'n', flag, (char *) &just_print_flag, 1, 1, 1, 0, 0,
"just-print", 0,
_("Don't actually run any commands; just print them") },
N_("Don't actually run any commands; just print them") },
{ 'o', string, (char *) &old_files, 0, 0, 0, 0, 0,
"old-file", _("FILE"),
_("Consider FILE to be very old and don't remake it") },
"old-file", N_("FILE"),
N_("Consider FILE to be very old and don't remake it") },
{ 'p', flag, (char *) &print_data_base_flag, 1, 1, 0, 0, 0,
"print-data-base", 0,
_("Print make's internal database") },
N_("Print make's internal database") },
{ 'q', flag, (char *) &question_flag, 1, 1, 1, 0, 0,
"question", 0,
_("Run no commands; exit status says if up to date") },
N_("Run no commands; exit status says if up to date") },
{ 'r', flag, (char *) &no_builtin_rules_flag, 1, 1, 0, 0, 0,
"no-builtin-rules", 0,
_("Disable the built-in implicit rules") },
N_("Disable the built-in implicit rules") },
{ 'R', flag, (char *) &no_builtin_variables_flag, 1, 1, 0, 0, 0,
"no-builtin-variables", 0,
_("Disable the built-in variable settings") },
N_("Disable the built-in variable settings") },
{ 's', flag, (char *) &silent_flag, 1, 1, 0, 0, 0,
"silent", 0,
_("Don't echo commands") },
N_("Don't echo commands") },
{ 'S', flag_off, (char *) &keep_going_flag, 1, 1, 0,
0, (char *) &default_keep_going_flag,
"no-keep-going", 0,
_("Turns off -k") },
N_("Turns off -k") },
{ 't', flag, (char *) &touch_flag, 1, 1, 1, 0, 0,
"touch", 0,
_("Touch targets instead of remaking them") },
N_("Touch targets instead of remaking them") },
{ 'v', flag, (char *) &print_version_flag, 1, 1, 0, 0, 0,
"version", 0,
_("Print the version number of make and exit") },
N_("Print the version number of make and exit") },
{ 'w', flag, (char *) &print_directory_flag, 1, 1, 0, 0, 0,
"print-directory", 0,
_("Print the current directory") },
{ CHAR_MAX+2, flag, (char *) &inhibit_print_directory_flag, 1, 1, 0, 0, 0,
N_("Print the current directory") },
{ CHAR_MAX+3, flag, (char *) &inhibit_print_directory_flag, 1, 1, 0, 0, 0,
"no-print-directory", 0,
_("Turn off -w, even if it was turned on implicitly") },
N_("Turn off -w, even if it was turned on implicitly") },
{ 'W', string, (char *) &new_files, 0, 0, 0, 0, 0,
"what-if", _("FILE"),
_("Consider FILE to be infinitely new") },
{ CHAR_MAX+3, flag, (char *) &warn_undefined_variables_flag, 1, 1, 0, 0, 0,
"what-if", N_("FILE"),
N_("Consider FILE to be infinitely new") },
{ CHAR_MAX+4, flag, (char *) &warn_undefined_variables_flag, 1, 1, 0, 0, 0,
"warn-undefined-variables", 0,
_("Warn when an undefined variable is referenced") },
N_("Warn when an undefined variable is referenced") },
{ '\0', }
};
@@ -419,6 +428,11 @@ struct file *default_file;
int posix_pedantic;
/* Nonzero if we have seen the `.NOTPARALLEL' target.
This turns off parallel builds for this invocation of make. */
int not_parallel;
/* Nonzero if some rule detected clock skew; we keep track so (a) we only
print one warning about it during the run, and (b) we can print a final
warning at the end of the run. */
@@ -479,7 +493,60 @@ static RETSIGTYPE
debug_signal_handler (sig)
int sig;
{
debug_flag = ! debug_flag;
db_level = db_level ? DB_NONE : DB_BASIC;
}
static void
decode_debug_flags ()
{
char **pp;
if (debug_flag)
db_level = DB_ALL;
if (!db_flags)
return;
for (pp=db_flags->list; *pp; ++pp)
{
const char *p = *pp;
while (1)
{
switch (tolower (p[0]))
{
case 'a':
db_level |= DB_ALL;
break;
case 'b':
db_level |= DB_BASIC;
break;
case 'i':
db_level |= DB_BASIC | DB_IMPLICIT;
break;
case 'j':
db_level |= DB_JOBS;
break;
case 'm':
db_level |= DB_BASIC | DB_MAKEFILES;
break;
case 'v':
db_level |= DB_BASIC | DB_VERBOSE;
break;
default:
fatal (NILF, _("unknown debug level specification `%s'"), p);
}
while (*(++p) != '\0')
if (*p == ',' || *p == ' ')
break;
if (*p == '\0')
break;
++p;
}
}
}
#ifdef WINDOWS32
@@ -487,8 +554,8 @@ debug_signal_handler (sig)
* HANDLE runtime exceptions by avoiding a requestor on the GUI. Capture
* exception and print it to stderr instead.
*
* If debug_flag not set, just print a simple message and exit.
* If debug_flag set, print a more verbose message.
* If ! DB_VERBOSE, just print a simple message and exit.
* If DB_VERBOSE, print a more verbose message.
* If compiled for DEBUG, let exception pass through to GUI so that
* debuggers can attach.
*/
@@ -504,30 +571,26 @@ handle_runtime_exceptions( struct _EXCEPTION_POINTERS *exinfo )
LPTSTR lpszStrings[1];
#endif
if (!debug_flag)
if (! ISDB (DB_VERBOSE))
{
sprintf(errmsg, _("%s: Interrupt/Exception caught "), prg);
sprintf(&errmsg[strlen(errmsg)],
"(code = 0x%x, addr = 0x%x)\r\n",
exrec->ExceptionCode, exrec->ExceptionAddress);
sprintf(errmsg,
_("%s: Interrupt/Exception caught (code = 0x%x, addr = 0x%x)\n"),
prg, exrec->ExceptionCode, exrec->ExceptionAddress);
fprintf(stderr, errmsg);
exit(255);
}
sprintf(errmsg,
_("\r\nUnhandled exception filter called from program %s\r\n"), prg);
sprintf(&errmsg[strlen(errmsg)], "ExceptionCode = %x\r\n",
exrec->ExceptionCode);
sprintf(&errmsg[strlen(errmsg)], "ExceptionFlags = %x\r\n",
exrec->ExceptionFlags);
sprintf(&errmsg[strlen(errmsg)], "ExceptionAddress = %x\r\n",
_("\nUnhandled exception filter called from program %s\nExceptionCode = %x\nExceptionFlags = %x\nExceptionAddress = %x\n"),
prg, exrec->ExceptionCode, exrec->ExceptionFlags,
exrec->ExceptionAddress);
if (exrec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION
&& exrec->NumberParameters >= 2)
sprintf(&errmsg[strlen(errmsg)],
_("Access violation: %s operation at address %x\r\n"),
exrec->ExceptionInformation[0] ? _("write"): _("read"),
(exrec->ExceptionInformation[0]
? _("Access violation: write operation at address %x\n")
: _("Access violation: read operation at address %x\n")),
exrec->ExceptionInformation[1]);
/* turn this on if we want to put stuff in the event log too */
@@ -591,8 +654,8 @@ find_and_set_default_shell(char *token)
/* search token path was found */
sprintf(sh_path, "%s", search_token);
default_shell = xstrdup(w32ify(sh_path,0));
if (debug_flag)
printf(_("find_and_set_shell setting default_shell = %s\n"), default_shell);
DB (DB_VERBOSE,
(_("find_and_set_shell setting default_shell = %s\n"), default_shell));
sh_found = 1;
} else {
char *p;
@@ -633,8 +696,10 @@ find_and_set_default_shell(char *token)
sh_found = 1;
}
if (debug_flag && sh_found)
printf(_("find_and_set_shell path search set default_shell = %s\n"), default_shell);
if (sh_found)
DB (DB_VERBOSE,
(_("find_and_set_shell path search set default_shell = %s\n"),
default_shell));
}
}
@@ -705,8 +770,16 @@ int main (int argc, char ** argv)
#endif
/* Set up gettext/internationalization support. */
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
#if !defined (HAVE_STRSIGNAL) && !defined (HAVE_SYS_SIGLIST)
signame_init ();
{
extern void signame_init ();
signame_init ();
}
#endif
#ifdef POSIX
@@ -784,18 +857,18 @@ int main (int argc, char ** argv)
else
{
#ifdef VMS
program = rindex (argv[0], ']');
program = strrchr (argv[0], ']');
#else
program = rindex (argv[0], '/');
program = strrchr (argv[0], '/');
#endif
#ifdef __MSDOS__
if (program == 0)
program = rindex (argv[0], '\\');
program = strrchr (argv[0], '\\');
else
{
/* Some weird environments might pass us argv[0] with
both kinds of slashes; we must find the rightmost. */
char *p = rindex (argv[0], '\\');
char *p = strrchr (argv[0], '\\');
if (p && p > program)
program = p;
}
@@ -937,9 +1010,11 @@ int main (int argc, char ** argv)
}
#endif
decode_debug_flags ();
/* Print version information. */
if (print_version_flag || print_data_base_flag || debug_flag)
if (print_version_flag || print_data_base_flag || db_level)
print_version ();
/* `make --version' is supposed to just print the version and exit. */
@@ -983,7 +1058,7 @@ int main (int argc, char ** argv)
argv[0] = concat (current_directory, "/", argv[0]);
#else /* !__MSDOS__ */
if (current_directory[0] != '\0'
&& argv[0] != 0 && argv[0][0] != '/' && index (argv[0], '/') != 0)
&& argv[0] != 0 && argv[0][0] != '/' && strchr (argv[0], '/') != 0)
argv[0] = concat (current_directory, "/", argv[0]);
#endif /* !__MSDOS__ */
#endif /* WINDOWS32 */
@@ -1010,7 +1085,8 @@ int main (int argc, char ** argv)
if (! v->recursive)
++len;
++len;
len += 3 * strlen (v->value);
len += 2 * strlen (v->value);
++len;
}
/* Now allocate a buffer big enough and fill it. */
@@ -1018,11 +1094,11 @@ int main (int argc, char ** argv)
for (cv = command_variables; cv != 0; cv = cv->next)
{
v = cv->variable;
p = quote_as_word (p, v->name, 0);
p = quote_for_env (p, v->name);
if (! v->recursive)
*p++ = ':';
*p++ = '=';
p = quote_as_word (p, v->value, 0);
p = quote_for_env (p, v->value);
*p++ = ' ';
}
p[-1] = '\0'; /* Kill the final space and terminate. */
@@ -1467,9 +1543,12 @@ int main (int argc, char ** argv)
unsigned int mm_idx = 0;
char **nargv = argv;
int nargc = argc;
int orig_db_level = db_level;
if (debug_flag)
puts (_("Updating makefiles...."));
if (! ISDB (DB_MAKEFILES))
db_level = DB_NONE;
DB (DB_BASIC, (_("Updating makefiles....\n")));
/* Remove any makefiles we don't want to try to update.
Also record the current modtimes so we can compare them later. */
@@ -1493,9 +1572,9 @@ int main (int argc, char ** argv)
stupidly; but if you work for Athena, that's how
you write your makefiles.) */
if (debug_flag)
printf (_("Makefile `%s' might loop; not remaking it.\n"),
f->name);
DB (DB_VERBOSE,
(_("Makefile `%s' might loop; not remaking it.\n"),
f->name));
if (last == 0)
read_makefiles = d->next;
@@ -1688,24 +1767,19 @@ int main (int argc, char ** argv)
}
#endif
if (debug_flag)
if (ISDB (DB_BASIC))
{
char **p;
fputs (_("Re-executing:"), stdout);
for (p = nargv; *p != 0; ++p)
printf (" %s", *p);
puts ("");
putchar ('\n');
}
fflush (stdout);
fflush (stderr);
/* Close the jobserver pipes if we opened any. */
if (job_fds[0] >= 0)
{
close (job_fds[0]);
close (job_fds[1]);
}
/* Close the dup'd jobserver pipe if we opened one. */
if (job_rfd >= 0)
close (job_rfd);
@@ -1717,6 +1791,8 @@ int main (int argc, char ** argv)
#endif
/* NOTREACHED */
}
db_level = orig_db_level;
}
/* Set up `MAKEFLAGS' again for the normal targets. */
@@ -1754,8 +1830,7 @@ int main (int argc, char ** argv)
/* Update the goals. */
if (debug_flag)
puts (_("Updating goal targets...."));
DB (DB_BASIC, (_("Updating goal targets....\n")));
switch (update_goal_chain (goals, 0))
{
@@ -1780,7 +1855,8 @@ int main (int argc, char ** argv)
/* If we detected some clock skew, generate one last warning */
if (clock_skew_detected)
error (NILF, _("*** Warning: Clock skew detected. Your build may be incomplete."));
error (NILF,
_("warning: Clock skew detected. Your build may be incomplete."));
/* Exit. */
die (status);
@@ -1864,7 +1940,7 @@ handle_non_switch_argument (arg, env)
if (arg[0] == '-' && arg[1] == '\0')
/* Ignore plain `-' for compatibility. */
return;
v = try_variable_definition (0, arg, o_command);
v = try_variable_definition (0, arg, o_command, 0);
if (v != 0)
{
/* It is indeed a variable definition. Record a pointer to
@@ -1951,12 +2027,12 @@ print_usage (bad)
shortarg[0] = longarg[0] = '\0';
break;
case required_argument:
sprintf (longarg, "=%s", cs->argdesc);
sprintf (shortarg, " %s", cs->argdesc);
sprintf (longarg, "=%s", gettext (cs->argdesc));
sprintf (shortarg, " %s", gettext (cs->argdesc));
break;
case optional_argument:
sprintf (longarg, "[=%s]", cs->argdesc);
sprintf (shortarg, " [%s]", cs->argdesc);
sprintf (longarg, "[=%s]", gettext (cs->argdesc));
sprintf (shortarg, " [%s]", gettext (cs->argdesc));
break;
}
@@ -2015,8 +2091,10 @@ print_usage (bad)
fprintf (usageto, "%*s%s.\n",
- DESCRIPTION_COLUMN,
buf, cs->description);
buf, gettext (cs->description));
}
fprintf (usageto, _("\nReport bugs to <bug-make@gnu.org>.\n"));
}
/* Decode switches from ARGC and ARGV.
@@ -2113,7 +2191,7 @@ decode_switches (argc, argv, env)
case positive_int:
if (optarg == 0 && argc > optind
&& ISDIGIT (argv[optind][0]))
&& ISDIGIT (argv[optind][0]))
optarg = argv[optind++];
if (!doit)
@@ -2216,7 +2294,7 @@ decode_env_switches (envar, len)
argv[argc] = p;
while (*value != '\0')
{
if (*value == '\\')
if (*value == '\\' && value[1] != '\0')
++value; /* Skip the backslash. */
else if (isblank (*value))
{
@@ -2233,7 +2311,7 @@ decode_env_switches (envar, len)
*p = '\0';
argv[++argc] = 0;
if (argv[1][0] != '-' && index (argv[1], '=') == 0)
if (argv[1][0] != '-' && strchr (argv[1], '=') == 0)
/* The first word doesn't start with a dash and isn't a variable
definition. Add a dash and pass it along to decode_switches. We
need permanent storage for this in case decode_switches saves
@@ -2245,27 +2323,21 @@ decode_env_switches (envar, len)
}
/* Quote the string IN so that it will be interpreted as a single word with
no magic by the shell; if DOUBLE_DOLLARS is nonzero, also double dollar
signs to avoid variable expansion in make itself. Write the result into
OUT, returning the address of the next character to be written.
Allocating space for OUT twice the length of IN (thrice if
DOUBLE_DOLLARS is nonzero) is always sufficient. */
no magic by decode_env_switches; also double dollar signs to avoid
variable expansion in make itself. Write the result into OUT, returning
the address of the next character to be written.
Allocating space for OUT twice the length of IN is always sufficient. */
static char *
quote_as_word (out, in, double_dollars)
quote_for_env (out, in)
char *out, *in;
int double_dollars;
{
while (*in != '\0')
{
#ifdef VMS
if (index ("^;'\"*?$<>(){}|&~`\\ \t\r\n\f\v", *in) != 0)
#else
if (index ("^;'\"*?[]$<>(){}|&~`\\ \t\r\n\f\v", *in) != 0)
#endif
*out++ = '\\';
if (double_dollars && *in == '$')
if (*in == '$')
*out++ = '$';
else if (isblank (*in) || *in == '\\')
*out++ = '\\';
*out++ = *in++;
}
@@ -2434,7 +2506,7 @@ define_makeflags (all, makefile)
{
/* Add its argument too. */
*p++ = !short_option (flags->cs->c) ? '=' : ' ';
p = quote_as_word (p, flags->arg, 1);
p = quote_for_env (p, flags->arg);
}
++words;
/* Write a following space and dash, for the next flag. */

84
make.h
View File

@@ -40,11 +40,13 @@ Boston, MA 02111-1307, USA. */
#endif /* C++ or ANSI C. */
/* For now, set gettext macro to a no-op. */
#undef _
#undef N_
#define _(s) s
#define N_(s) s
#include "gettext.h"
#define _(Text) gettext (Text)
#define N_(Text) gettext_noop (Text)
#if !HAVE_SETLOCALE
# define setlocale(Category, Locale) /* empty */
#endif
#ifdef CRAY
@@ -107,23 +109,6 @@ extern int errno;
# define POSIX 1
#endif
#if defined (HAVE_SYS_SIGLIST) && !defined (SYS_SIGLIST_DECLARED)
extern char *sys_siglist[];
#endif
#if !defined (HAVE_SYS_SIGLIST) || !defined (HAVE_STRSIGNAL)
# include "signame.h"
#endif
/* Some systems do not define NSIG in <signal.h>. */
#ifndef NSIG
# ifdef _NSIG
# define NSIG _NSIG
# else
# define NSIG 32
# endif
#endif
#ifndef RETSIGTYPE
# define RETSIGTYPE void
#endif
@@ -192,11 +177,9 @@ extern unsigned int get_path_max PARAMS ((void));
#endif
#ifdef VMS
# include <stdio.h>
# include <types.h>
# include <unixlib.h>
# include <unixio.h>
# include <errno.h>
# include <perror.h>
#endif
@@ -240,24 +223,8 @@ extern void exit PARAMS ((int)) __attribute__ ((noreturn));
#endif /* Standard headers. */
#if ST_MTIM_NSEC
# if HAVE_INTTYPES_H
# include <inttypes.h>
# endif
# define FILE_TIMESTAMP uintmax_t
#else
# define FILE_TIMESTAMP time_t
#endif
#ifdef ANSI_STRING
# ifndef index
# define index(s, c) strchr((s), (c))
# endif
# ifndef rindex
# define rindex(s, c) strrchr((s), (c))
# endif
# ifndef bcmp
# define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
# endif
@@ -270,6 +237,11 @@ extern void exit PARAMS ((int)) __attribute__ ((noreturn));
#else /* Not ANSI_STRING. */
# ifndef HAVE_STRCHR
# define strchr(s, c) index((s), (c))
# define strrchr(s, c) rindex((s), (c))
# endif
# ifndef bcmp
extern int bcmp PARAMS ((const char *, const char *, int));
# endif
@@ -303,6 +275,15 @@ extern char *alloca ();
# endif /* HAVE_ALLOCA_H. */
#endif /* GCC. */
#if ST_MTIM_NSEC
# if HAVE_INTTYPES_H
# include <inttypes.h>
# endif
# define FILE_TIMESTAMP uintmax_t
#else
# define FILE_TIMESTAMP time_t
#endif
/* ISDIGIT offers the following features:
- Its arg may be any int or unsigned int; it need not be an unsigned char.
- It's guaranteed to evaluate its argument exactly once.
@@ -321,8 +302,9 @@ extern char *alloca ();
# ifdef HAVE_CASE_INSENSITIVE_FS
/* This is only used on Windows/DOS platforms, so we assume strcmpi(). */
# define strieq(a, b) \
((a) == (b) || \
(tolower(*(a)) == tolower(*(b)) && (*(a) == '\0' || !strcmpi ((a) + 1, (b) + 1))))
((a) == (b) \
|| (tolower((unsigned char)*(a)) == tolower((unsigned char)*(b)) \
&& (*(a) == '\0' || !strcmpi ((a) + 1, (b) + 1))))
# else
# define strieq(a, b) streq(a, b)
# endif
@@ -332,13 +314,16 @@ extern char *alloca ();
# define strieq(a, b) (strcmp ((a), (b)) == 0)
#endif
#define strneq(a, b, l) (strncmp ((a), (b), (l)) == 0)
#ifdef VMS
extern int strcmpi (const char *,const char *);
#endif
/* Add to VAR the hashing value of C, one character in a name. */
#define HASH(var, c) \
((var += (c)), (var = ((var) << 7) + ((var) >> 20)))
#ifdef HAVE_CASE_INSENSITIVE_FS /* Fold filenames */
# define HASHI(var, c) \
((var += tolower((c))), (var = ((var) << 7) + ((var) >> 20)))
((var += tolower((unsigned char)(c))), (var = ((var) << 7) + ((var) >> 20)))
#else
# define HASHI(var, c) HASH(var,c)
#endif
@@ -469,10 +454,9 @@ extern long int lseek ();
#endif /* Not GNU C library or POSIX. */
#ifdef HAVE_GETCWD
# if !defined(VMS) && !defined(__DECC)
extern char *getcwd ();
# ifdef VMS
extern char *getwd PARAMS ((char *));
# endif
#endif
#else
extern char *getwd ();
# define getcwd(buf, len) getwd (buf)
@@ -483,10 +467,10 @@ extern const struct floc *reading_file;
extern char **environ;
extern int just_print_flag, silent_flag, ignore_errors_flag, keep_going_flag;
extern int debug_flag, print_data_base_flag, question_flag, touch_flag;
extern int print_data_base_flag, question_flag, touch_flag;
extern int env_overrides, no_builtin_rules_flag, no_builtin_variables_flag;
extern int print_version_flag, print_directory_flag;
extern int warn_undefined_variables_flag, posix_pedantic;
extern int warn_undefined_variables_flag, posix_pedantic, not_parallel;
extern int clock_skew_detected;
/* can we run commands via 'sh -c xxx' or must we use batch files? */
@@ -518,10 +502,6 @@ extern int handling_fatal_signal;
#define MAX(_a,_b) ((_a)>(_b)?(_a):(_b))
#endif
#define DEBUGPR(msg) \
do if (debug_flag) { print_spaces (depth); printf (msg, file->name); \
fflush (stdout); } while (0)
#ifdef VMS
# ifndef EXIT_FAILURE
# define EXIT_FAILURE 3

View File

@@ -8,10 +8,10 @@
@c FSF publishers: format makebook.texi instead of using this file directly.
@set RCSID $Id$
@set EDITION 0.53
@set VERSION 3.78
@set UPDATED 14 April 1999
@set UPDATE-MONTH April 1999
@set EDITION 0.54
@set VERSION 3.78.1
@set UPDATED 09 September 1999
@set UPDATE-MONTH September 1999
@comment The ISBN number might need to change on next publication.
@set ISBN 1-882114-80-9 @c CHANGE THIS BEFORE PRINTING AGAIN! --psmith 16jul98
@@ -2471,6 +2471,16 @@ Simply by being mentioned as a target, this tells @code{make} to
export all variables to child processes by default.
@xref{Variables/Recursion, ,Communicating Variables to a
Sub-@code{make}}.
@findex .NOTPARALLEL
@item .NOTPARALLEL
@cindex parallel execution, overriding
If @code{.NOTPARALLEL} is mentioned as a target, then this invocation of
@code{make} will be run serially, even if the @samp{-j} option is
given. Any recursively invoked @code{make} command will still be run in
parallel if its makefile doesn't contain this target. Any prerequisites
on this target are ignored.
@end table
Any defined implicit rule suffix also counts as a special target if it

View File

@@ -7,6 +7,13 @@ $! P2 = DEBUG will build an image with debug information
$!
$! In case of problems with the install you might contact me at
$! zinser@decus.decus.de (preferred) or martin_zinser@exchange.de
$
$! hb
$! But don't ask Martin Zinser about the lines, I added/changed.
$! In case of an error do some cleanup
$ on error then $ goto cleanup
$! in case somebody set up her/his own symbol for cc
$ set symbol/scope=(nolocal,noglobal)
$!
$! Look for the compiler used
$!
@@ -57,9 +64,16 @@ $ linkit:
$ close optf
$ if p1 .nes. "" then goto link_using_library
$ link/exe=make make.opt/opt'lopt
$ exit
$ goto cleanup
$
$ link_using_library:
$ link/exe=make make.opt/opt,sys$library:vaxcrtl/lib'lopt
$
$ cleanup:
$ if f$trnlnm("SYS").nes."" then $ deassign sys
$ if f$trnlnm("OPTF").nes."" then $ close optf
$ if f$search("make.opt").nes."" then $ del make.opt;*
$ exit
$!
$ compileit : subroutine
$ ploc = f$locate("]",p1)

View File

@@ -2,7 +2,8 @@
# This file is part of GNU Make.
#
# VMS extensions from GNU Make 3.60 imported by
# Klaus Kämpf (kkaempf@progis.de) of proGIS Software, Aachen, Germany
# Klaus Kämpf (kkaempf@rmi.de)
# Modified for version 3.78.1 by Hartmut.Becker@compaq.com.
#
# GNU Make is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -19,7 +20,7 @@
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
CC = cc/warn
CC = cc
CP = copy
%.obj: %.c
@@ -28,11 +29,23 @@ CP = copy
# Makefile for GNU Make
#
CFLAGS = $(defines) /debug/noopt/include=([],[.glob])
ifeq ($(CC),cc)
CFLAGS = $(defines) /include=([],[.glob])/prefix=all/standard=relaxed
else
CFLAGS = $(defines) /include=([],[.glob])
endif
#LDFLAGS = /deb
LDFLAGS =
ifeq ($(CC),cc)
defines = /define=("unlink=remove","HAVE_CONFIG_H","VMS","allocated_variable_expand_for_file=alloc_var_expand_for_file")
else
ifeq ($(ARCH),VAX)
defines = /define=("HAVE_CONFIG_H","GCC_IS_NATIVE","VAX")
else
defines = /define=("HAVE_CONFIG_H","GCC_IS_NATIVE")
endif
endif
LOAD_AVG = /define="NO_LDAV"
@@ -44,12 +57,17 @@ ARCHIVES_SRC = ar.c arscan.c
# System V probably need -lPW for alloca.
# if on vax, uncomment the following line
#LOADLIBES = ,c.opt/opt
LOADLIBES =,sys$$library:vaxcrtl.olb/lib
ifeq ($(CC),cc)
#LOADLIBES =,sys$$library:vaxcrtl.olb/lib
CRT0 =
else
LOADLIBES =,gnu_cc_library:libgcc.olb/lib
endif
# If your system doesn't have alloca, or the one provided is bad,
# get it from the Emacs distribution and define these.
ALLOCA = ,alloca.obj
ALLOCASRC = alloca.c
#ALLOCA = ,alloca.obj
#ALLOCASRC = alloca.c
# If there are remote execution facilities defined,
# enable them with switches here (see remote-*.c).
@@ -86,11 +104,14 @@ doc: make.info make.dvi
make.exe: $(objs)
$(LD)$(LDFLAGS)/exe=$@ $^$(LOADLIBES)
$(LD)$(LDFLAGS)/exe=$@ $^$(LOADLIBES)$(CRT0)
.PHONY: clean realclean
clean:
-$(RM) make.exe;,*.obj;*
$$ purge [...]
-$(RM) make.exe;,*.obj;
-$(RM) *.opt;
-$(RM) [.glob]*.obj;
# Automatically generated dependencies.
commands.obj: commands.c make.h dep.h commands.h filedef.h variable.h job.h
@@ -108,7 +129,7 @@ variable.obj: variable.c make.h commands.h variable.h dep.h filedef.h
expand.obj: expand.c make.h commands.h filedef.h variable.h
function.obj: function.c make.h variable.h dep.h commands.h job.h
vpath.obj: vpath.c make.h filedef.h variable.h
version.obj: version.c
version.obj: version.c config.h
arscan.obj: arscan.c
ar.obj: ar.c make.h filedef.h
signame.obj: signame.c
@@ -117,6 +138,8 @@ remote-stub.obj: remote-stub.c
[.glob]fnmatch.obj: [.glob]fnmatch.c
getopt.obj: getopt.c
getopt1.obj: getopt1.c
vmsfunctions.obj: vmsfunctions.c make.h vmsdir.h
vmsify.obj: vmsify.c make.h
config.h: config.h-vms
$(CP) $< $@

8
misc.c
View File

@@ -19,7 +19,7 @@ Boston, MA 02111-1307, USA. */
#include "make.h"
#include "dep.h"
#include "debug.h"
/* Variadic functions. We go through contortions to allow proper function
prototypes for both ANSI and pre-ANSI C compilers, and also for those
@@ -81,7 +81,7 @@ collapse_continuations (line)
register int backslash;
register unsigned int bs_write;
in = index (line, '\n');
in = strchr (line, '\n');
if (in == 0)
return;
@@ -168,7 +168,7 @@ remove_comments (line)
*comment = '\0';
}
/* Print N spaces (used by DEBUGPR for target-depth). */
/* Print N spaces (used in debug for target-depth). */
void
print_spaces (n)
@@ -643,7 +643,7 @@ static void
log_access (flavor)
char *flavor;
{
if (! debug_flag)
if (! ISDB (DB_JOBS))
return;
/* All the other debugging messages go to stdout,

88
read.c
View File

@@ -29,6 +29,7 @@ Boston, MA 02111-1307, USA. */
#include "commands.h"
#include "variable.h"
#include "rule.h"
#include "debug.h"
#ifndef WINDOWS32
@@ -149,8 +150,7 @@ read_all_makefiles (makefiles)
{
unsigned int num_makefiles = 0;
if (debug_flag)
puts (_("Reading makefiles..."));
DB (DB_BASIC, (_("Reading makefiles...\n")));
/* If there's a non-null variable MAKEFILES, its value is a list of
files to read first thing. But don't let it prevent reading the
@@ -177,9 +177,9 @@ read_all_makefiles (makefiles)
while ((name = find_next_token (&p, &length)) != 0)
{
name = xstrdup (name);
if (*p != '\0')
*p++ = '\0';
name = xstrdup (name);
if (read_makefile (name,
RM_NO_DEFAULT_GOAL|RM_INCLUDED|RM_DONTCARE) < 2)
free (name);
@@ -329,7 +329,7 @@ read_makefile (filename, flags)
pattern_percent = 0;
cmds_started = fileinfo.lineno;
if (debug_flag)
if (ISDB (DB_VERBOSE))
{
printf (_("Reading makefile `%s'"), fileinfo.filenm);
if (flags & RM_NO_DEFAULT_GOAL)
@@ -478,7 +478,7 @@ read_makefile (filename, flags)
/* Compare a word, both length and contents. */
#define word1eq(s, l) (len == l && strneq (s, p, l))
p = collapsed;
while (isspace (*p))
while (isspace ((unsigned char)*p))
++p;
if (*p == '\0')
/* This line is completely empty. */
@@ -488,7 +488,7 @@ read_makefile (filename, flags)
* ":" here since we compare tokens by length (so "export" will never
* be equal to "export:").
*/
for (p2 = p+1; *p2 != '\0' && !isspace(*p2); ++p2)
for (p2 = p+1; *p2 != '\0' && !isspace ((unsigned char)*p2); ++p2)
{}
len = p2 - p;
@@ -496,7 +496,7 @@ read_makefile (filename, flags)
since it can't be a preprocessor token--this allows targets named
`ifdef', `export', etc. */
reading_target = 0;
while (isspace (*p2))
while (isspace ((unsigned char)*p2))
++p2;
if (*p2 == '\0')
p2 = NULL;
@@ -546,7 +546,7 @@ read_makefile (filename, flags)
with trailing blanks stripped (comments have already been
removed), so it could be a complex variable/function
reference that might contain blanks. */
p = index (p2, '\0');
p = strchr (p2, '\0');
while (isblank (p[-1]))
--p;
do_define (p2, p - p2, o_file, infile, &fileinfo);
@@ -573,14 +573,14 @@ read_makefile (filename, flags)
with trailing blanks stripped (comments have already been
removed), so it could be a complex variable/function
reference that might contain blanks. */
p = index (p2, '\0');
p = strchr (p2, '\0');
while (isblank (p[-1]))
--p;
do_define (p2, p - p2, o_override, infile, &fileinfo);
}
}
else if (!ignoring
&& !try_variable_definition (&fileinfo, p2, o_override))
&& !try_variable_definition (&fileinfo, p2, o_override, 0))
error (&fileinfo, _("invalid `override' directive"));
continue;
@@ -598,7 +598,7 @@ read_makefile (filename, flags)
p2 = next_token (p + 6);
if (*p2 == '\0')
export_all_variables = 1;
v = try_variable_definition (&fileinfo, p2, o_file);
v = try_variable_definition (&fileinfo, p2, o_file, 0);
if (v != 0)
v->export = v_export;
else
@@ -609,7 +609,7 @@ read_makefile (filename, flags)
{
v = lookup_variable (p, len);
if (v == 0)
v = define_variable (p, len, "", o_file, 0);
v = define_variable_loc (p, len, "", o_file, 0, &fileinfo);
v->export = v_export;
}
}
@@ -626,7 +626,7 @@ read_makefile (filename, flags)
{
v = lookup_variable (p, len);
if (v == 0)
v = define_variable (p, len, "", o_file, 0);
v = define_variable_loc (p, len, "", o_file, 0, &fileinfo);
v->export = v_noexport;
}
}
@@ -717,7 +717,7 @@ read_makefile (filename, flags)
reading_file = &fileinfo;
}
#undef word1eq
else if (try_variable_definition (&fileinfo, p, o_file))
else if (try_variable_definition (&fileinfo, p, o_file, 0))
/* This line has been dealt with. */
;
else if (lb.buffer[0] == '\t')
@@ -837,8 +837,8 @@ read_makefile (filename, flags)
are whitespace and a left paren. If others are possible,
they should be added to the string in the call to index. */
while (colonp && (colonp[1] == '/' || colonp[1] == '\\') &&
colonp > p2 && isalpha(colonp[-1]) &&
(colonp == p2 + 1 || index(" \t(", colonp[-2]) != 0))
colonp > p2 && isalpha ((unsigned char)colonp[-1]) &&
(colonp == p2 + 1 || strchr (" \t(", colonp[-2]) != 0))
colonp = find_char_unquote(colonp + 1, ":", 0);
#endif
if (colonp != 0)
@@ -957,7 +957,7 @@ read_makefile (filename, flags)
}
/* Is this a static pattern rule: `target: %targ: %dep; ...'? */
p = index (p2, ':');
p = strchr (p2, ':');
while (p != 0 && p[-1] == '\\')
{
register char *q = &p[-1];
@@ -965,7 +965,7 @@ read_makefile (filename, flags)
while (*q-- == '\\')
backslash = !backslash;
if (backslash)
p = index (p + 1, ':');
p = strchr (p + 1, ':');
else
break;
}
@@ -982,7 +982,8 @@ read_makefile (filename, flags)
The rule is that it's only a target, if there are TWO :'s
OR a space around the :.
*/
if (p && !(isspace(p[1]) || !p[1] || isspace(p[-1])))
if (p && !(isspace ((unsigned char)p[1]) || !p[1]
|| isspace ((unsigned char)p[-1])))
p = 0;
#endif
#if defined (WINDOWS32) || defined (__MSDOS__)
@@ -990,9 +991,9 @@ read_makefile (filename, flags)
check_again = 0;
/* For MSDOS and WINDOWS32, skip a "C:\..." or a "C:/..." */
if (p != 0 && (p[1] == '\\' || p[1] == '/') &&
isalpha(p[-1]) &&
(p == p2 + 1 || index(" \t:(", p[-2]) != 0)) {
p = index(p + 1, ':');
isalpha ((unsigned char)p[-1]) &&
(p == p2 + 1 || strchr (" \t:(", p[-2]) != 0)) {
p = strchr (p + 1, ':');
check_again = 1;
}
} while (check_again);
@@ -1115,7 +1116,8 @@ do_define (name, namelen, origin, infile, flocp)
definition[0] = '\0';
else
definition[idx - 1] = '\0';
(void) define_variable (var, strlen (var), definition, origin, 1);
(void) define_variable_loc (var, strlen (var), definition, origin,
1, flocp);
free (definition);
freebuffer (&lb);
return;
@@ -1421,6 +1423,9 @@ record_target_var (filenames, defn, two_colon, origin, flocp)
global = current_variable_set_list;
/* If the variable is an append version, store that but treat it as a
normal recursive variable. */
for (; filenames != 0; filenames = nextf)
{
struct variable *v;
@@ -1450,14 +1455,14 @@ record_target_var (filenames, defn, two_colon, origin, flocp)
/* Get a file reference for this file, and initialize it. */
f = enter_file (name);
initialize_file_variables (f);
initialize_file_variables (f, 1);
vlist = f->variables;
fname = f->name;
}
/* Make the new variable context current and define the variable. */
current_variable_set_list = vlist;
v = try_variable_definition (flocp, defn, origin);
v = try_variable_definition (flocp, defn, origin, 1);
if (!v)
error (flocp, _("Malformed per-target variable definition"));
v->per_target = 1;
@@ -1473,7 +1478,7 @@ record_target_var (filenames, defn, two_colon, origin, flocp)
gv = lookup_variable (v->name, len);
if (gv && (gv->origin == o_env_override || gv->origin == o_command))
define_variable_in_set (v->name, len, gv->value, gv->origin,
gv->recursive, vlist->set);
gv->recursive, vlist->set, flocp);
}
/* Free name if not needed further. */
@@ -1741,9 +1746,9 @@ record_files (filenames, pattern, pattern_percent, deps, cmds_started,
/* See if this is first target seen whose name does
not start with a `.', unless it contains a slash. */
if (default_goal_file == 0 && set_default
&& (*name != '.' || index (name, '/') != 0
&& (*name != '.' || strchr (name, '/') != 0
#if defined(__MSDOS__) || defined(WINDOWS32)
|| index (name, '\\') != 0
|| strchr (name, '\\') != 0
#endif
))
{
@@ -1806,7 +1811,7 @@ find_char_unquote (string, stopchars, blank)
while (1)
{
while (*p != '\0' && index (stopchars, *p) == 0
while (*p != '\0' && strchr (stopchars, *p) == 0
&& (!blank || !isblank (*p)))
++p;
if (*p == '\0')
@@ -1905,8 +1910,9 @@ parse_file_seq (stringp, stopchar, size, strip)
*p =' ';
#endif
#ifdef _AMIGA
if (stopchar == ':' && p && *p == ':' &&
!(isspace(p[1]) || !p[1] || isspace(p[-1])))
if (stopchar == ':' && p && *p == ':'
&& !(isspace ((unsigned char)p[1]) || !p[1]
|| isspace ((unsigned char)p[-1])))
{
p = find_char_unquote (p+1, stopchars, 1);
}
@@ -1917,8 +1923,8 @@ parse_file_seq (stringp, stopchar, size, strip)
Note that tokens separated by spaces should be treated as separate
tokens since make doesn't allow path names with spaces */
if (stopchar == ':')
while (p != 0 && !isspace(*p) &&
(p[1] == '\\' || p[1] == '/') && isalpha (p[-1]))
while (p != 0 && !isspace ((unsigned char)*p) &&
(p[1] == '\\' || p[1] == '/') && isalpha ((unsigned char)p[-1]))
p = find_char_unquote (p + 1, stopchars, 1);
#endif
if (p == 0)
@@ -2000,14 +2006,14 @@ parse_file_seq (stringp, stopchar, size, strip)
while (new1 != 0)
if (new1->name[0] != '(' /* Don't catch "(%)" and suchlike. */
&& new1->name[strlen (new1->name) - 1] == ')'
&& index (new1->name, '(') == 0)
&& strchr (new1->name, '(') == 0)
{
/* NEW1 ends with a `)' but does not contain a `('.
Look back for an elt with an opening `(' but no closing `)'. */
struct nameseq *n = new1->next, *lastn = new1;
char *paren = 0;
while (n != 0 && (paren = index (n->name, '(')) == 0)
while (n != 0 && (paren = strchr (n->name, '(')) == 0)
{
lastn = n;
n = n->next;
@@ -2288,7 +2294,7 @@ get_next_mword (buffer, delim, startp, length)
}
default:
if (delim && index(delim, c))
if (delim && strchr (delim, c))
wtype = w_static;
break;
}
@@ -2325,9 +2331,9 @@ get_next_mword (buffer, delim, startp, length)
/* A word CAN include a colon in its drive spec. The drive
spec is allowed either at the beginning of a word, or as part
of the archive member name, like in "libfoo.a(d:/foo/bar.o)". */
if (!(p - beg >= 2 &&
(*p == '/' || *p == '\\') && isalpha (p[-2]) &&
(p - beg == 2 || p[-3] == '(')))
if (!(p - beg >= 2
&& (*p == '/' || *p == '\\') && isalpha ((unsigned char)p[-2])
&& (p - beg == 2 || p[-3] == '(')))
#endif
goto done_word;
@@ -2379,7 +2385,7 @@ get_next_mword (buffer, delim, startp, length)
break;
default:
if (delim && index(delim, c))
if (delim && strchr (delim, c))
goto done_word;
break;
}
@@ -2550,7 +2556,7 @@ tilde_expand (name)
else
{
struct passwd *pwent;
char *userend = index (name + 1, '/');
char *userend = strchr (name + 1, '/');
if (userend != 0)
*userend = '\0';
pwent = getpwnam (name + 1);

View File

@@ -1,9 +1,126 @@
This is the VMS port of GNU Make done by Hartmut.Becker@compaq.com.
It is based on the specific version 3.77k and on 3.78.1. 3.77k was done
by Klaus Kämpf <kkaempf@rmi.de>, the code was based on the VMS port of
GNU Make 3.60 by Mike Moretti.
It was ported on OpenVMS/Alpha V7.1, DECC V5.7-006. It was re-build and
tested on OpenVMS/Alpha V7.2, OpenVMS/VAX 7.1 and 5.5-2. Different
versions of DECC were used. VAXC was tried: it fails; but it doesn't
seem worth to get it working. There are still some PTRMISMATCH warnings
during the compile. Although perl is working on VMS the test scripts
don't work. The function $shell is still missing.
There is a known bug in some of the VMS CRTLs. It is in the shipped
versions of VMS V7.2 and V7.2-1 and in the currently (October 1999)
available ECOs for VMS V7.1 and newer versions. It is fixed in versions
shipped with newer VMS versions and all ECO kits after October 1999. It
only shows up during the daylight saving time period (DST): stat()
returns a modification time 1 hour ahead. This results in GNU make
warning messages. For a just created source you will see:
$ gmake x.exe
gmake.exe;1: *** Warning: File `x.c' has modification time in the future (940582863 > 940579269)
cc /obj=x.obj x.c
link x.obj /exe=x.exe
gmake.exe;1: *** Warning: Clock skew detected. Your build may be incomplete.
New in 3.78.1:
Fix a problem with automatically remaking makefiles. GNU make uses an
execve to restart itself after a successful remake of the makefile. On
UNIX systems execve replaces the running program with a new one and
resets all signal handling to the default. On VMS execve creates a child
process, signal and exit handlers of the parent are still active, and,
unfortunately, corrupt the exit code from the child. Fix in job.c:
ignore SIGCHLD.
Added some switches to reflect latest features of DECC. Modifications in
makefile.vms.
Set some definitions to reflect latest features of DECC. Modifications in
config.h-vms (which is copied to config.h).
Added extern strcmpi declaration to avoid 'implicitly declared' messages.
Modification in make.h.
Default rule for C++, conditionals for gcc (GCC_IS_NATIVE) or DEC/Digital/
Compaq c/c++ compilers. Modifications in default.c.
Usage of opendir() and friends, suppress file version. Modifications in dir.c.
Added VMS specific code to handle ctrl+c and ctrl+y to abort make.
Modifications in job.c.
Added support to have case sensitive targets and dependencies but to
still use case blind file names. This is especially useful for Java
makefiles on VMS:
.SUFFIXES :
.SUFFIXES : .class .java
.java.class :
javac "$<
HelloWorld.class : HelloWorld.java
A new macro WANT_CASE_SENSITIVE_TARGETS in config.h-vms was introduced.
It needs to be enabled to get this feature; default is disabled. The
macro HAVE_CASE_INSENSITIVE_FS must not be touched: it is still enabled.
Modifications in file.c and config.h-vms.
Bootstrap make to start building make is still makefile.com, but make
needs to be re-made with a make to make a correct version: ignore all
possible warnings, delete all objects, rename make.exe to a different
name and run it.
Made some minor modifications to the bootstrap build makefile.com.
This is the VMS port of GNU Make.
It is based on the VMS port of GNU Make 3.60 by Mike Moretti.
This port was done by Klaus Kämpf <kkaempf@progis.de> of
proGIS Software, Aachen, Germany.
This port was done by Klaus Kämpf <kkaempf@rmi.de>
There is first-level support available from proGIS Software, Germany.
Visit their web-site at http://www.progis.de to get information
about other vms software and forthcoming updates to gnu make.
New for 3.77:
/bin/sh style I/O redirection is supported. You can now write lines like
mcr sys$disk:[]program.exe < input.txt > output.txt &> error.txt
Makefile variables are looked up in the current environment. You can set
symbols or logicals in DCL and evaluate them in the Makefile via
$(<name-of-symbol-or-logical>). Variables defined in the Makefile
override VMS symbols/logicals !
Functions for file names are working now. See the GNU Make manual for
$(dir ...) and $(wildcard ...). Unix-style and VMS-style names are
supported as arguments.
The default rules are set up for GNU C. Building an executable from a
single source file is as easy as 'make file.exe'.
The variable $(ARCH) is predefined as ALPHA or VAX resp. Makefiles for
different VMS systems can now be written by checking $(ARCH) as in
ifeq ($(ARCH),ALPHA)
$(ECHO) "On the Alpha"
else
$(ECHO) "On the VAX"
endif
Command lines of excessive length are correctly broken and written to a
batch file in sys$scratch for later execution. There's no limit to the
lengths of commands (and no need for .opt files :-) any more.
Empty commands are handled correctly and don't end in a new DCL process.
New for 3.76:
John W. Eaton has updated the VMS port to support libraries and VPATH.
To build Make, simply type @makefile. This should compile all the
necessary files and link Make. There is also a file called
@@ -12,6 +129,16 @@ Make with this makefile to rebuild.
Here are some notes about GNU Make for VMS:
The cd command is supported if it's called as $(CD). This invokes
the 'builtin_cd' command which changes the directory.
Calling 'set def' doesn't do the trick, since a sub-shell is
spawned for this command, the directory is changed *in this sub-shell*
and the sub-shell ends.
Libraries are not supported. They were in GNU Make 3.60 but somehow I
didn't care porting the code. If there is enough interest, I'll do it at
some later time.
The variable $^ separates files with commas instead of spaces (It's the
natural thing to do for VMS).
@@ -26,8 +153,8 @@ The default include directory for including other makefiles is
SYS$SYSROOT:[SYSLIB] (I don't remember why I didn't just use
SYS$LIBRARY: instead; maybe it wouldn't work that way).
The default makefiles make looks for are: makefile.vms, gnumakefile, makefile.,
and gnumakefile. .
The default makefiles make looks for are: makefile.vms, gnumakefile,
makefile., and gnumakefile. .
The stat() function and handling of time stamps in VMS is broken, so I
replaced it with a hack in vmsfunctions.c. I will provide a full rewrite
@@ -37,9 +164,9 @@ less than what vms provides. This might be a problem on the faster Alphas.
You can use a : in a filename only if you preceed it with a backslash ('\').
E.g.- hobbes\:[bogas.files]
Make ignores success, informational, or warning errors (-S-, -I-, or -W-).
But it will stop on -E- and -F- errors. (unless you do something to override
this in your makefile, or whatever).
Make ignores success, informational, or warning errors (-S-, -I-, or
-W-). But it will stop on -E- and -F- errors. (unless you do something
to override this in your makefile, or whatever).
Remote stuff isn't implemented yet.
@@ -47,18 +174,10 @@ Multiple line DCL commands, such as "if" statements, must be put inside
command files. You can run a command file by using \@.
Change history:
VMS changes made for 3.74.3
3.76.x
======
Added VMS help version (make.hlp) of the Unix man page. To integrate
that with an existing Help library use a command like the following
$lib/ins/help sys$help:helplib.hlb make.hlp
3.74.3
======
Lots of default settings are adapted for VMS. See default.c.
Long command lines are now converted to command files.
Comma (',') as a separator is now allowed. See makefile.vms for an example.

255
remake.c
View File

@@ -23,6 +23,7 @@ Boston, MA 02111-1307, USA. */
#include "commands.h"
#include "dep.h"
#include "variable.h"
#include "debug.h"
#include <assert.h>
@@ -93,15 +94,6 @@ update_goal_chain (goals, makefiles)
g->changed = 0;
}
#if 0
/* Only run one job at a time when building makefiles.
No one seems to know why this was done, and no one can think of a good
reason to do it. Hopefully an obvious one won't appear as soon as we
release the next version :-/. */
if (makefiles)
job_slots = 1;
#endif
/* All files start with the considered bit 0, so the global value is 1. */
considered = 1;
@@ -266,39 +258,6 @@ update_goal_chain (goals, makefiles)
return status;
}
/* Generate an error/fatal message if no rules are available for the target.
*/
static void
no_rule_error(file)
struct file *file;
{
static const char msg_noparent[]
= _("%sNo rule to make target `%s'%s");
static const char msg_parent[]
= _("%sNo rule to make target `%s', needed by `%s'%s");
if (keep_going_flag || file->dontcare)
{
/* If the previous attempt was made while we were creating
makefiles, but we aren't anymore, print an error now. */
if (!file->dontcare
|| (file->mfile_status && !updating_makefiles))
{
if (file->parent == 0)
error (NILF, msg_noparent, "*** ", file->name, ".");
else
error (NILF, msg_parent, "*** ",
file->name, file->parent->name, ".");
}
file->update_status = 2;
file->mfile_status = updating_makefiles;
}
else if (file->parent == 0)
fatal (NILF, msg_noparent, "", file->name, "");
else
fatal (NILF, msg_parent, "", file->name, file->parent->name, "");
}
/* If FILE is not up to date, execute the commands for it.
Return 0 if successful, 1 if unsuccessful;
but with some flag settings, just call `exit' if unsuccessful.
@@ -319,41 +278,50 @@ update_file (file, depth)
register int status = 0;
register struct file *f;
for (f = file->double_colon ? file->double_colon : file; f != 0; f = f->prev)
f = file->double_colon ? file->double_colon : file;
/* Prune the dependency graph: if we've already been here on _this_
pass through the dependency graph, we don't have to go any further.
We won't reap_children until we start the next pass, so no state
change is possible below here until then. */
if (f->considered == considered)
{
DBF (DB_VERBOSE, _("Pruning file `%s'.\n"));
return 0;
}
/* This loop runs until we start commands for a double colon rule, or until
the chain is exhausted. */
for (; f != 0; f = f->prev)
{
/* Prune the dependency graph: if we've already been here on _this_
pass through the dependency graph, we don't have to go any further.
We won't reap_children until we start the next pass, so no state
change is possible below here until then. */
if (f->considered == considered)
{
DEBUGPR (_("Pruning file `%s'.\n"));
continue;
}
f->considered = considered;
status |= update_file_1 (f, depth);
check_renamed (f);
if (status != 0 && !keep_going_flag)
return status;
break;
switch (f->command_state)
{
case cs_finished:
/* The file is done being remade. */
break;
case cs_running:
case cs_deps_running:
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. */
return 0;
status = 0;
break;
}
}
default:
assert (f->command_state == cs_running);
break;
}
/* Process the remaining rules in the double colon chain so they're marked
considered. Start their prerequisites, too. */
for (; f != 0 ; f = f->prev)
{
struct dep *d;
f->considered = considered;
for (d = f->deps; d != 0; d = d->next)
status |= update_file (d->file, depth + 1);
}
return status;
@@ -372,18 +340,18 @@ update_file_1 (file, depth)
register struct dep *d, *lastd;
int running = 0;
DEBUGPR (_("Considering target file `%s'.\n"));
DBF (DB_VERBOSE, _("Considering target file `%s'.\n"));
if (file->updated)
{
if (file->update_status > 0)
{
DEBUGPR (_("Recently tried and failed to update file `%s'.\n"));
no_rule_error(file);
DBF (DB_VERBOSE,
_("Recently tried and failed to update file `%s'.\n"));
return file->update_status;
}
DEBUGPR (_("File `%s' was considered already.\n"));
DBF (DB_VERBOSE, _("File `%s' was considered already.\n"));
return 0;
}
@@ -393,10 +361,10 @@ update_file_1 (file, depth)
case cs_deps_running:
break;
case cs_running:
DEBUGPR (_("Still updating file `%s'.\n"));
DBF (DB_VERBOSE, _("Still updating file `%s'.\n"));
return 0;
case cs_finished:
DEBUGPR (_("Finished updating file `%s'.\n"));
DBF (DB_VERBOSE, _("Finished updating file `%s'.\n"));
return file->update_status;
default:
abort ();
@@ -417,7 +385,7 @@ update_file_1 (file, depth)
check_renamed (file);
noexist = this_mtime == (FILE_TIMESTAMP) -1;
if (noexist)
DEBUGPR (_("File `%s' does not exist.\n"));
DBF (DB_BASIC, _("File `%s' does not exist.\n"));
must_make = noexist;
@@ -427,15 +395,15 @@ update_file_1 (file, depth)
if (!file->phony && file->cmds == 0 && !file->tried_implicit)
{
if (try_implicit_rule (file, depth))
DEBUGPR (_("Found an implicit rule for `%s'.\n"));
DBF (DB_IMPLICIT, _("Found an implicit rule for `%s'.\n"));
else
DEBUGPR (_("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
&& default_file != 0 && default_file->cmds != 0)
{
DEBUGPR (_("Using default commands for `%s'.\n"));
DBF (DB_IMPLICIT, _("Using default commands for `%s'.\n"));
file->cmds = default_file->cmds;
}
@@ -533,13 +501,13 @@ update_file_1 (file, depth)
file->updating = 0;
DEBUGPR (_("Finished prerequisites of target file `%s'.\n"));
DBF (DB_VERBOSE, _("Finished prerequisites of target file `%s'.\n"));
if (running)
{
set_command_state (file, cs_deps_running);
--depth;
DEBUGPR (_("The prerequisites of `%s' are being made.\n"));
DBF (DB_VERBOSE, _("The prerequisites of `%s' are being made.\n"));
return 0;
}
@@ -552,7 +520,7 @@ update_file_1 (file, depth)
depth--;
DEBUGPR (_("Giving up on target file `%s'.\n"));
DBF (DB_VERBOSE, _("Giving up on target file `%s'.\n"));
if (depth == 0 && keep_going_flag
&& !just_print_flag && !question_flag)
@@ -598,15 +566,29 @@ update_file_1 (file, depth)
or its dependent, FILE, is older or does not exist. */
d->changed |= noexist || d_mtime > this_mtime;
if (debug_flag && !noexist)
if (!noexist && ISDB (DB_BASIC|DB_VERBOSE))
{
print_spaces (depth);
const char *fmt = 0;
if (d_mtime == (FILE_TIMESTAMP) -1)
printf (_("Prerequisite `%s' does not exist.\n"), dep_name (d));
else
printf (_("Prerequisite `%s' is %s than target `%s'.\n"),
dep_name (d), d->changed ? _("newer") : _("older"), file->name);
fflush (stdout);
{
if (ISDB (DB_BASIC))
fmt = _("Prerequisite `%s' of target `%s' does not exist.\n");
}
else if (d->changed)
{
if (ISDB (DB_BASIC))
fmt = _("Prerequisite `%s' is newer than target `%s'.\n");
}
else if (ISDB (DB_VERBOSE))
fmt = _("Prerequisite `%s' is older than target `%s'.\n");
if (fmt)
{
print_spaces (depth);
printf (fmt, dep_name (d), file->name);
fflush (stdout);
}
}
}
@@ -616,24 +598,26 @@ update_file_1 (file, depth)
if (file->double_colon && file->deps == 0)
{
must_make = 1;
DEBUGPR (_("Target `%s' is double-colon and has no prerequisites.\n"));
DBF (DB_BASIC,
_("Target `%s' is double-colon and has no prerequisites.\n"));
}
else if (!noexist && file->is_target && !deps_changed && file->cmds == 0)
{
must_make = 0;
DEBUGPR (_("No commands for `%s' and no prerequisites actually changed.\n"));
DBF (DB_VERBOSE,
_("No commands for `%s' and no prerequisites actually changed.\n"));
}
if (!must_make)
{
if (debug_flag)
if (ISDB (DB_VERBOSE))
{
print_spaces(depth);
printf(_("No need to remake target `%s'"), file->name);
if (!streq(file->name, file->hname))
printf(_("; using VPATH name `%s'"), file->hname);
printf(".\n");
fflush(stdout);
print_spaces (depth);
printf (_("No need to remake target `%s'"), file->name);
if (!streq (file->name, file->hname))
printf (_("; using VPATH name `%s'"), file->hname);
puts (".");
fflush (stdout);
}
notice_finished_file (file);
@@ -651,18 +635,13 @@ update_file_1 (file, depth)
return 0;
}
DEBUGPR (_("Must remake target `%s'.\n"));
DBF (DB_BASIC, _("Must remake target `%s'.\n"));
/* It needs to be remade. If it's VPATH and not reset via GPATH, toss the
VPATH. */
if (!streq(file->name, file->hname))
{
if (debug_flag)
{
print_spaces (depth);
printf(_(" Ignoring VPATH name `%s'.\n"), file->hname);
fflush(stdout);
}
DB (DB_BASIC, (_(" Ignoring VPATH name `%s'.\n"), file->hname));
file->ignore_vpath = 1;
}
@@ -671,20 +650,20 @@ update_file_1 (file, depth)
if (file->command_state != cs_finished)
{
DEBUGPR (_("Commands of `%s' are being run.\n"));
DBF (DB_VERBOSE, _("Commands of `%s' are being run.\n"));
return 0;
}
switch (file->update_status)
{
case 2:
DEBUGPR (_("Failed to remake target file `%s'.\n"));
DBF (DB_BASIC, _("Failed to remake target file `%s'.\n"));
break;
case 0:
DEBUGPR (_("Successfully remade target file `%s'.\n"));
DBF (DB_BASIC, _("Successfully remade target file `%s'.\n"));
break;
case 1:
DEBUGPR (_("Target file `%s' needs remade under -q.\n"));
DBF (DB_BASIC, _("Target file `%s' needs remade under -q.\n"));
break;
default:
assert (file->update_status >= 0 && file->update_status <= 2);
@@ -746,12 +725,25 @@ notice_finished_file (file)
if (ran && !file->phony)
{
struct file *f;
int i = 0;
if (just_print_flag || question_flag
|| (file->is_target && file->cmds == 0))
file->last_mtime = NEW_MTIME;
else
file->last_mtime = 0;
/* If -n or -q and all the commands are recursive, we ran them so
really check the target's mtime again. Otherwise, assume the target
would have been updated. */
if (question_flag || just_print_flag)
{
for (i = file->cmds->ncommand_lines; i > 0; --i)
if (! (file->cmds->lines_flags[i-1] & COMMANDS_RECURSE))
break;
}
/* If there were no commands at all, it's always new. */
else if (file->is_target && file->cmds == 0)
i = 1;
file->last_mtime = i == 0 ? 0 : NEW_MTIME;
/* Propagate the change of modification time to all the double-colon
entries for this file. */
@@ -823,15 +815,15 @@ check_dep (file, depth, this_mtime, must_make_ptr)
if (!file->phony && file->cmds == 0 && !file->tried_implicit)
{
if (try_implicit_rule (file, depth))
DEBUGPR (_("Found an implicit rule for `%s'.\n"));
DBF (DB_IMPLICIT, _("Found an implicit rule for `%s'.\n"));
else
DEBUGPR (_("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
&& default_file != 0 && default_file->cmds != 0)
{
DEBUGPR (_("Using default commands for `%s'.\n"));
DBF (DB_IMPLICIT, _("Using default commands for `%s'.\n"));
file->cmds = default_file->cmds;
}
@@ -970,20 +962,45 @@ remake_file (file)
Pretend it was successfully remade. */
file->update_status = 0;
else
no_rule_error(file);
{
const char *msg_noparent
= _("%sNo rule to make target `%s'%s");
const char *msg_parent
= _("%sNo rule to make target `%s', needed by `%s'%s");
/* This is a dependency file we cannot remake. Fail. */
if (!keep_going_flag && !file->dontcare)
{
if (file->parent == 0)
fatal (NILF, msg_noparent, "", file->name, "");
fatal (NILF, msg_parent, "", file->name, file->parent->name, "");
}
if (!file->dontcare)
{
if (file->parent == 0)
error (NILF, msg_noparent, "*** ", file->name, ".");
else
error (NILF, msg_parent, "*** ",
file->name, file->parent->name, ".");
}
file->update_status = 2;
}
}
else
{
chop_commands (file->cmds);
/* The normal case: start some commands. */
if (!touch_flag || file->cmds->any_recurse)
{
execute_file_commands (file);
return;
}
else
/* This tells notice_finished_file it is ok to touch the file. */
file->update_status = 0;
/* This tells notice_finished_file it is ok to touch the file. */
file->update_status = 0;
}
/* This does the touching under -t. */
@@ -1229,7 +1246,7 @@ library_search (lib, mtime_ptr)
/* Loop variables for the libpatterns value. */
char *p, *p2;
int len;
unsigned int len;
char *file, **dp;

View File

@@ -26,6 +26,8 @@ Boston, MA 02111-1307, USA. */
#include "filedef.h"
#include "commands.h"
#include "job.h"
#include "debug.h"
#include <sys/time.h>
#include <netdb.h>
@@ -81,7 +83,7 @@ start_remote_job_p (first_p)
Customs requires a privileged source port be used. */
make_access ();
if (debug_flag)
if (ISDB (DB_EXTRA))
Rpc_Debug(1);
/* Ping the daemon once to see if it is there. */
@@ -122,8 +124,8 @@ start_remote_job_p (first_p)
status = Customs_Host (EXPORT_SAME, &permit);
if (status != RPC_SUCCESS)
{
if (debug_flag)
printf ("Customs won't export: %s\n", Rpc_ErrorMessage (status));
DB (DB_EXTRA, (_("Customs won't export: %s\n"),
Rpc_ErrorMessage (status)));
return 0;
}

16
rule.c
View File

@@ -108,11 +108,15 @@ count_implicit_rule_limits ()
unsigned int len = strlen (dep->name);
#ifdef VMS
char *p = rindex (dep->name, ']');
char *p = strrchr (dep->name, ']');
char *p2;
if (p == 0)
p = strrchr (dep->name, ':');
p2 = p != 0 ? strchr (dep->name, '%') : 0;
#else
char *p = rindex (dep->name, '/');
char *p = strrchr (dep->name, '/');
char *p2 = p != 0 ? strchr (dep->name, '%') : 0;
#endif
char *p2 = p != 0 ? index (dep->name, '%') : 0;
ndeps++;
if (len > max_pattern_dep_length)
@@ -140,7 +144,7 @@ count_implicit_rule_limits ()
dep->changed = !dir_file_exists_p (name, "");
#ifdef VMS
if (dep->changed && *name == ']')
if (dep->changed && strchr (name, ':') != 0)
#else
if (dep->changed && *name == '/')
#endif
@@ -603,12 +607,12 @@ lookup_pattern_var (target)
continue;
/* Compare the text in the pattern after the stem, if any.
We could test simply use streq, but this way we compare the
We could test simply using streq, but this way we compare the
first two characters immediately. This saves time in the very
common case where the first character matches because it is a
period. */
if (*p->suffix == stem[stemlen]
&& (*p->suffix == '\0'|| streq (&p->suffix[1], &stem[stemlen+1])))
&& (*p->suffix == '\0' || streq (&p->suffix[1], &stem[stemlen+1])))
break;
}

View File

@@ -1,5 +1,5 @@
/* Convert between signal names and numbers.
Copyright (C) 1990, 1992, 1993, 1995, 1996 Free Software Foundation, Inc.
Copyright (C) 1990,92,93,95,96,99 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,23 +17,10 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* In the GNU make version, all the headers we need are provided by make.h. */
#include "make.h"
#include <stdio.h>
#include <sys/types.h> /* Some systems need this for <signal.h>. */
#include <signal.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
/* Some systems declare `sys_siglist in <unistd.h>; if
configure defined SYS_SIGLIST_DECLARED, it may expect
to find the declaration there. */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
/* Some systems do not define NSIG in <signal.h>. */
#ifndef NSIG

View File

@@ -1,3 +1,84 @@
2000-02-04 Paul D. Smith <psmith@gnu.org>
* scripts/features/patspecific_vars: Add a test for PR/1407.
2000-02-02 Paul D. Smith <psmith@gnu.org>
* run_make_tests.pl (set_more_defaults): Hard-code the LANG to C
to make sure porting order, etc. is predictable.
Reported by Andreas Jaeger <aj@suse.de>.
* run_make_tests.pl (set_more_defaults): Set the $wtime variable
depending on the OS. Eli Zaretskii <eliz@is.elta.co.il> reports
this seems to need to be *4* on DOS/Windows, not just 2. Keep it
1 for other systems.
* scripts/features/vpathplus (touchfiles): Use the $wtime value
instead of hardcoding 2.
* scripts/targets/SECONDARY: Ditto.
* scripts/targets/INTERMEDIATE: Ditto.
2000-01-23 Paul D. Smith <psmith@gnu.org>
* scripts/features/include: Remove a check; the fix caused more
problems than the error, so I removed it and removed the test for
it.
2000-01-11 Paul D. Smith <psmith@gnu.org>
* scripts/functions/call: Add a test for PR/1517 and PR/1527: make
sure $(call ...) doesn't eval its arguments and that you can
invoke foreach from it without infinitely looping.
1999-12-15 Paul D. Smith <psmith@gnu.org>
* scripts/targets/INTERMEDIATE: Add a test for PR/1423: make sure
.INTERMEDIATE settings on files don't disable them as implicit
intermediate possibilities.
1999-12-01 Paul D. Smith <psmith@gnu.org>
* scripts/features/double_colon: Add a test for PR/1476: Try
double-colon rules as non-goal targets and during parallel builds
to make sure they're handled serially.
1999-11-17 Paul D. Smith <psmith@gnu.org>
* scripts/functions/if: Add a test for PR/1429: put some text
after an if-statement to make sure it works.
* scripts/features/targetvars: Add a test for PR/1380: handling +=
in target-specific variable definitions correctly.
1999-10-15 Paul D. Smith <psmith@gnu.org>
* scripts/variables/MAKEFILES: This was really broken: it didn't
test anything at all, really. Rewrote it, plus added a test for
PR/1394.
1999-10-13 Paul D. Smith <psmith@gnu.org>
* scripts/options/dash-n: Add a test for PR/1379: "-n doesn't
behave properly when used with recursive targets".
1999-10-08 Paul D. Smith <psmith@gnu.org>
* scripts/features/targetvars: Add a check for PR/1378:
"Target-specific vars don't inherit correctly"
1999-09-29 Paul D. Smith <psmith@gnu.org>
* test_driver.pl (get_osname): Change $fancy_file_names to
$short_filenames and reverse the logic.
(run_each_test): Change test of non-existent $port_host to use
$short_filenames--problem reported by Eli Zaretskii.
1999-09-23 Paul D. Smith <psmith@gnu.org>
* scripts/features/parallelism: Add a check to ensure that the
jobserver works when we re-invoke. Also cleaned up the tests a
little, reducing the number of rules we use so the test won't need
as many "sleep" commands.
1999-09-16 Paul D. Smith <psmith@gnu.org>
* scripts/features/reinvoke: Remove invocations of "touch" in

View File

@@ -129,6 +129,11 @@ sub set_more_defaults
local($string);
local($index);
# Make sure we're in the C locale for those systems that support it,
# so sorting, etc. is predictable.
#
$ENV{LANG} = 'C';
# find the type of the port. We do this up front to have a single
# point of change if it needs to be tweaked.
#
@@ -152,6 +157,12 @@ sub set_more_defaults
$port_type = 'UNIX';
}
# On DOS/Windows system the filesystem apparently can't track
# timestamps with second granularity (!!). Change the sleep time
# needed to force a file to be considered "old".
#
$wtime = $port_type eq 'UNIX' ? 1 : 4;
# Find the full pathname of Make. For DOS systems this is more
# complicated, so we ask make itself.

View File

@@ -1,48 +1,108 @@
$description = "The following test creates a makefile to test Double-Colon\n"
."Rules. They are rules which are written with '::' instead\n"
."of ':' after the target names. This tells make that each \n"
."of these rules are independent of the others and each rule's\n"
."commands are executed if the target is older than any \n"
."dependencies of that rule.";
# -*-perl-*-
$description = "Test handling of double-colon rules.";
$details = "The makefile created by this test contains two double-colon \n"
."rules for foo; each with their own commands. When make is run,\n"
."each command should be executed in the sequence that they are \n"
."found. The command is a simple echo statement.";
$details = "\
We test these features:
open(MAKEFILE,"> $makefile");
- Multiple commands for the same (double-colon) target
- Different prerequisites for targets: only out-of-date
ones are rebuilt.
- Double-colon targets that aren't the goal target.
Then we do the same thing for parallel builds: double-colon
targets should always be built serially.";
# The Contents of the MAKEFILE ...
print MAKEFILE "foo:: bar.h \n"
."\t\@echo Executing rule foo FIRST\n"
."foo2: bar.h \n"
."foo:: bar2.h \n"
."\t\@echo Executing rule foo SECOND\n";
open(MAKEFILE,"> $makefile");
# END of Contents of MAKEFILE
print MAKEFILE <<'EOF';
all: baz
foo:: f1.h ; @echo foo FIRST
foo:: f2.h ; @echo foo SECOND
bar:: ; @echo aaa; sleep 1; echo aaa done
bar:: ; @echo bbb
baz:: ; @echo aaa
baz:: ; @echo bbb
biz:: ; @echo aaa
biz:: two ; @echo bbb
two: ; @echo two
f1.h f2.h: ; @echo $@
EOF
close(MAKEFILE);
&touch("bar.h","bar2.h");
# TEST 0: A simple double-colon rule that isn't the goal target.
&run_make_with_options($makefile,
"",
&get_logfile,
0);
&run_make_with_options($makefile, "all", &get_logfile, 0);
$answer = "aaa\nbbb\n";
&compare_output($answer, &get_logfile(1));
# TEST 1: As above, in parallel
$answer = "Executing rule foo FIRST\n"
."Executing rule foo SECOND\n";
&run_make_with_options($makefile, "-j10 all", &get_logfile, 0);
$answer = "aaa\nbbb\n";
&compare_output($answer, &get_logfile(1));
&compare_output($answer,&get_logfile(1));
# TEST 2: A simple double-colon rule that is the goal target
unlink("bar.h","bar2.h");
&run_make_with_options($makefile, "bar", &get_logfile, 0);
$answer = "aaa\naaa done\nbbb\n";
&compare_output($answer, &get_logfile(1));
# TEST 3: As above, in parallel
&run_make_with_options($makefile, "-j10 bar", &get_logfile, 0);
$answer = "aaa\naaa done\nbbb\n";
&compare_output($answer, &get_logfile(1));
# TEST 4: Each double-colon rule is supposed to be run individually
&touch('f2.h');
&touch('foo');
&run_make_with_options($makefile, "foo", &get_logfile, 0);
$answer = "f1.h\nfoo FIRST\n";
&compare_output($answer, &get_logfile(1));
# TEST 5: Again, in parallel.
&run_make_with_options($makefile, "-j10 foo", &get_logfile, 0);
$answer = "f1.h\nfoo FIRST\n";
&compare_output($answer, &get_logfile(1));
# TEST 6: Each double-colon rule is supposed to be run individually
&touch('f1.h');
unlink('f2.h');
&touch('foo');
&run_make_with_options($makefile, "foo", &get_logfile, 0);
$answer = "f2.h\nfoo SECOND\n";
&compare_output($answer, &get_logfile(1));
# TEST 7: Again, in parallel.
&run_make_with_options($makefile, "-j10 foo", &get_logfile, 0);
$answer = "f2.h\nfoo SECOND\n";
&compare_output($answer, &get_logfile(1));
# TEST 8: I don't grok why this is different than the above, but it is...
#
# Hmm... further testing indicates this might be timing-dependent?
#
#&run_make_with_options($makefile, "-j10 biz", &get_logfile, 0);
#$answer = "aaa\ntwo\nbbb\n";
#&compare_output($answer, &get_logfile(1));
unlink('foo','f1.h','f2.h');
1;

View File

@@ -51,8 +51,11 @@ $answer = "This is another included makefile\n";
# the -include suppressed it during the makefile read phase, we should
# see one during the makefile run phase).
&run_make_with_options($makefile, "error", &get_logfile, 512);
$answer = "$make_name: *** No rule to make target `makeit.mk', needed by `error'.\n";
&compare_output($answer, &get_logfile(1));
# The fix to this caused more problems than the error, so I removed it.
# pds -- 22 Jan 2000
#&run_make_with_options($makefile, "error", &get_logfile, 512);
#$answer = "$make_name: *** No rule to make target `makeit.mk', needed by `error'.\n";
#&compare_output($answer, &get_logfile(1));
1;

View File

@@ -3,7 +3,7 @@
$description = "Test parallelism (-j) option.";
$details = "This test creates a makefile with three double-colon default
$details = "This test creates a makefile with two double-colon default
rules. The first rule has a series of sleep and echo commands
intended to run in series. The second and third have just an
echo statement. When make is called in this test, it is given
@@ -29,48 +29,72 @@ else {
open(MAKEFILE,"> $makefile");
print MAKEFILE <<"EOF";
all : def_1 def_5 def_6
def_1 :
\t\@$sleep_command 3 ; echo ONE
\t\@echo TWO
\t\@$sleep_command 1 ; echo THREE
\t\@echo FOUR
def_5 :
\t\@echo FIVE
def_6 :
\t\@$sleep_command 1 ; echo SIX
all : def_1 def_2 def_3
def_1 : ; \@echo ONE; $sleep_command 3 ; echo TWO
def_2 : ; \@$sleep_command 2 ; echo THREE
def_3 : ; \@$sleep_command 1 ; echo FOUR
EOF
close(MAKEFILE);
&run_make_with_options($makefile, "-j 4", &get_logfile);
$answer = "FIVE\nSIX\nONE\nTWO\nTHREE\nFOUR\n";
$answer = "ONE\nFOUR\nTHREE\nTWO\n";
&compare_output($answer, &get_logfile(1));
# Test parallelism with included files
# Test parallelism with included files. Here we sleep/echo while
# building the included files, to test that they are being built in
# parallel.
$makefile2 = &get_tmpfile;
open(MAKEFILE,"> $makefile2");
print MAKEFILE <<'EOF';
all: 1 2 3; @echo success
print MAKEFILE <<"EOF";
all: 1 2; \@echo success
-include 1.inc 2.inc 3.inc
-include 1.inc 2.inc
1.inc: ; @sleep 1; echo 1; echo "1: ; @sleep 2; echo $@ has been included" > $@
2.inc: ; @sleep 2; echo 2; echo "2: ; @echo $@ has been included" > $@
3.inc: ; @echo 3; echo "3: ; @sleep 1; echo $@ has been included" > $@
1.inc: ; \@echo ONE.inc; $sleep_command 2; echo TWO.inc; echo "1: ; \@echo ONE; $sleep_command 2; echo TWO" > \$\@
2.inc: ; \@$sleep_command 1; echo THREE.inc; echo "2: ; \@$sleep_command 1; echo THREE" > \$\@
EOF
close(MAKEFILE);
&run_make_with_options("$makefile2", "-j 4", &get_logfile);
$answer = "3\n1\n2\n2.inc has been included\n3.inc has been included\n1.inc has been included\nsuccess\n";
$answer = "ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n";
&compare_output($answer, &get_logfile(1));
unlink('1.inc', '2.inc', '3.inc');
unlink('1.inc', '2.inc');
# Test parallelism with included files--this time recurse first and make
# sure the jobserver works.
$makefile3 = &get_tmpfile;
open(MAKEFILE,"> $makefile3");
print MAKEFILE <<"EOF";
recurse: ; \@\$(MAKE) --no-print-directory -f $makefile3 INC=yes all
all: 1 2; \@echo success
INC = no
ifeq (\$(INC),yes)
-include 1.inc 2.inc
endif
1.inc: ; \@echo ONE.inc; $sleep_command 2; echo TWO.inc; echo "1: ; \@echo ONE; $sleep_command 2; echo TWO" > \$\@
2.inc: ; \@$sleep_command 1; echo THREE.inc; echo "2: ; \@$sleep_command 1; echo THREE" > \$\@
EOF
close(MAKEFILE);
&run_make_with_options("$makefile3", "-j 4", &get_logfile);
$answer = "ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n";
&compare_output($answer, &get_logfile(1));
unlink('1.inc', '2.inc');
1;

View File

@@ -19,6 +19,8 @@ t%.x: BAR = four
%.x: override BAZ = three
one.x: override FOO = one
one.x two.x three.x: ; @echo $(FOO) $(BAR) $(BAZ)
four.x: baz ; @echo $(FOO) $(BAR) $(BAZ)
baz: ; @echo $(FOO) $(BAR) $(BAZ)
EOF
close(MAKEFILE);
@@ -37,4 +39,11 @@ $answer = "one two three\nfoo four baz\nfoo bar three\n";
$answer = "one two three\nfoo four five\nfoo bar three\n";
&compare_output($answer,&get_logfile(1));
# TEST #3 -- make sure patterns are inherited properly
&run_make_with_options($makefile, "four.x", &get_logfile);
$answer = "foo two three\nfoo two three\n";
&compare_output($answer,&get_logfile(1));
1;

View File

@@ -105,4 +105,50 @@ $answer = "qvar = qvar\nqvar =\n";
&compare_output($answer,&get_logfile(1));
# TEST #8
# For PR/1378: Target-specific vars don't inherit correctly
$makefile2 = &get_tmpfile;
open(MAKEFILE,"> $makefile2");
print MAKEFILE <<'EOF';
foo: FOO = foo
bar: BAR = bar
foo: bar
bar: baz
baz: ; @echo $(FOO) $(BAR)
EOF
close(MAKEFILE);
&run_make_with_options("$makefile2", "", &get_logfile);
$answer = "foo bar\n";
&compare_output($answer, &get_logfile(1));
# TEST #9
# For PR/1380: Using += assignment in target-specific variables sometimes fails
$makefile3 = &get_tmpfile;
open(MAKEFILE,"> $makefile3");
print MAKEFILE <<'EOF';
.PHONY: all one
all: FOO += baz
all: one; @echo $(FOO)
FOO = bar
one: FOO += biz
one: ; @echo $(FOO)
EOF
close(MAKEFILE);
&run_make_with_options("$makefile3", "", &get_logfile);
$answer = "bar baz biz\nbar baz\n";
&compare_output($answer, &get_logfile(1));
&run_make_with_options("$makefile3", "one", &get_logfile);
$answer = "bar biz\n";
&compare_output($answer, &get_logfile(1));
1;

View File

@@ -57,12 +57,10 @@ close(MAKEFILE);
sub touchfiles {
foreach (@_) {
sleep($wtime);
($f = $_) =~ s,VP/,$VP,g;
&touch($f);
push(@touchedfiles, $f);
# Sleep 2 seconds for DOS/Windows FAT volumes which have 2-second
# granularity of file times.
sleep(2);
}
}

View File

@@ -9,7 +9,7 @@ open(MAKEFILE, "> $makefile");
# The Contents of the MAKEFILE ...
print MAKEFILE <<'EOMAKE';
# Simple, just reverse something
# Simple, just reverse two things
#
reverse = $2 $1
@@ -21,9 +21,19 @@ map = $(foreach a,$2,$(call $1,$a))
#
my-notdir = $(call notdir,$(1))
# Test using non-expanded builtins
#
my-foreach = $(foreach $(1),$(2),$(3))
my-if = $(if $(1),$(2),$(3))
all: ; @echo '$(call reverse,bar,foo)'; \
echo '$(call map,origin,MAKE reverse map)'; \
echo '$(call my-notdir,a/b c/d e/f)'
echo '$(call my-notdir,a/b c/d e/f)'; \
echo '$(call my-foreach)'; \
echo '$(call my-foreach,a,,,)'; \
echo '$(call my-foreach,a,x y z,$(a)$(a))'; \
echo '$(call my-if,a,b,c)'; \
echo '$(call my-if,,$(warning don't print this),ok)'
EOMAKE
@@ -32,7 +42,7 @@ EOMAKE
close(MAKEFILE);
&run_make_with_options($makefile, "", &get_logfile);
$answer = "foo bar\ndefault file file\nb d f\n";
$answer = "foo bar\ndefault file file\nb d f\n\n\nxx yy zz\nb\nok\n";
&compare_output($answer, &get_logfile(1));
1;

View File

@@ -18,14 +18,14 @@ all:
\t\@echo \$(if ,\$(shell echo hi),false)
\t\@echo \$(if \$(call NEQ,a,b),true,false)
\t\@echo \$(if \$(call NEQ,a,a),true,false)
\t\@echo \$(if z,true,fal,se)
\t\@echo \$(if ,true,fal,se)
\t\@echo \$(if z,true,fal,se) hi
\t\@echo \$(if ,true,fal,se)there
EOMAKE
close(MAKEFILE);
&run_make_with_options($makefile, "", &get_logfile);
$answer = "false\n\n\ntrue\ntrue\nfalse\ntrue\nfalse\ntrue\nfal,se\n";
$answer = "false\n\n\ntrue\ntrue\nfalse\ntrue\nfalse\ntrue hi\nfal,sethere\n";
&compare_output($answer, &get_logfile(1));
1;

View File

@@ -28,4 +28,36 @@ $answer = "echo >> intermediate\necho >> final\n";
unlink('orig', 'intermediate', 'final');
# TEST2
# We consider the actual updated timestamp of targets with all
# recursive commands, even with -n.
$makefile2 = &get_tmpfile;
open(MAKEFILE, "> $makefile2");
print MAKEFILE <<'EOF';
.SUFFIXES:
BAR = # nothing
FOO = +$(BAR)
a: b; echo > $@
b: c; $(FOO)
EOF
close(MAKEFILE);
&touch('a', 'b');
sleep(1);
&touch('c');
&run_make_with_options($makefile2, "", &get_logfile);
$answer = "$make_name: `a' is up to date.\n";
&compare_output($answer, &get_logfile(1));
&run_make_with_options($makefile2, "-n", &get_logfile);
$answer = "$make_name: `a' is up to date.\n";
&compare_output($answer, &get_logfile(1));
unlink('a', 'b', 'c');
1;

View File

@@ -35,6 +35,7 @@ close(MAKEFILE);
&touch('foo.f');
&touch('bar.f');
sleep($wtime);
&run_make_with_options($makefile,'foo.d',&get_logfile);
$answer = "cp foo.f foo.e\ncp foo.e foo.d\nrm foo.e\n";
@@ -48,9 +49,7 @@ $answer = "$make_name: `foo.d' is up to date.\n";
# TEST #2
# Sleep 2 seconds for DOS/Windows FAT volumes which have 2-second
# granularity of file times.
sleep(2);
sleep($wtime);
&touch('foo.f');
&run_make_with_options($makefile,'foo.d',&get_logfile);
@@ -71,9 +70,7 @@ $answer = "$make_name: `foo.c' is up to date.\n";
# TEST #5
# Sleep 2 seconds for DOS/Windows FAT volumes which have 2-second
# granularity of file times.
sleep(2);
sleep($wtime);
&touch('foo.f');
&run_make_with_options($makefile,'foo.c',&get_logfile);
@@ -82,5 +79,26 @@ $answer = "cp foo.f foo.e\ncp bar.f bar.e\ncat foo.e bar.e > foo.c\nrm foo.e bar
unlink('foo.f', 'foo.e', 'foo.d', 'foo.c', 'bar.f', 'bar.e', 'bar.d', 'bar.c');
# TEST #6 -- added for PR/1423
$makefile2 = &get_tmpfile;
open(MAKEFILE, "> $makefile2");
print MAKEFILE <<'EOF';
all: foo
foo.a: ; touch $@
%: %.a ; touch $@
.INTERMEDIATE: foo.a
EOF
close(MAKEFILE);
&run_make_with_options($makefile2, "-R", &get_logfile);
$answer = "touch foo.a\ntouch foo\nrm foo.a\n";
&compare_output($answer, &get_logfile(1));
unlink('foo');
# This tells the test driver that the perl test script executed properly.
1;

View File

@@ -49,9 +49,7 @@ $answer = "$make_name: `foo.d' is up to date.\n";
# TEST #3
# Sleep 2 seconds for DOS/Windows FAT volumes which have 2-second
# granularity of file times.
sleep(2);
sleep($wtime);
&touch('foo.f');
&run_make_with_options($makefile,'foo.d',&get_logfile);
@@ -74,9 +72,7 @@ $answer = "$make_name: `foo.c' is up to date.\n";
# TEST #6
# Sleep 2 seconds for DOS/Windows FAT volumes which have 2-second
# granularity of file times.
sleep(2);
sleep($wtime);
&touch('foo.f');
&run_make_with_options($makefile,'foo.c',&get_logfile);

View File

@@ -1,3 +1,5 @@
# -*-perl-*-
$description = "This tests the CURDIR varaible.";
$details = "Echo CURDIR both with and without -C. Also ensure overrides work.";

View File

@@ -1,37 +1,34 @@
$description = "The following test creates a makefile to test ";
# -*-perl-*-
$description = "Test the MAKEFILES variable.";
$makefile2 = &get_tmpfile;
$makefile3 = &get_tmpfile;
open(MAKEFILE,"> $makefile");
# The Contents of the MAKEFILE ...
print MAKEFILE "MAKEFILES = work/MAKEFILES_variable.mk.2\n\n";
print MAKEFILE "all:\n";
print MAKEFILE "\t\@echo THIS IS THE DEFAULT RULE\n";
# END of Contents of MAKEFILE
print MAKEFILE 'all: ; @echo DEFAULT RULE: M2=$(M2) M3=$(M3)', "\n";
close(MAKEFILE);
open(MAKEFILE,"> $makefile2");
print MAKEFILE "NDEF:\n";
print MAKEFILE "\t\@echo THIS IS THE RULE FROM MAKEFILE 2\n";
print MAKEFILE <<EOF;
M2 = m2
NDEF: ; \@echo RULE FROM MAKEFILE 2
EOF
close(MAKEFILE);
&run_make_with_options($makefile,"",&get_logfile);
open(MAKEFILE,"> $makefile3");
print MAKEFILE <<EOF;
M3 = m3
NDEF3: ; \@echo RULE FROM MAKEFILE 3
EOF
close(MAKEFILE);
# Create the answer to what should be produced by this Makefile
$answer = "THIS IS THE DEFAULT RULE\n";
# COMPARE RESULTS
# In this call to compare output, you should use the call &get_logfile(1)
# to send the name of the last logfile created.
&run_make_with_options($makefile, "MAKEFILES='$makefile2 $makefile3'",
&get_logfile);
$answer = "DEFAULT RULE: M2=m2 M3=m3\n";
&compare_output($answer,&get_logfile(1));
# If you wish to stop if the compare fails, then add
# a "|| &error ("abort")" to the
# end of the previous line.
# This tells the test driver that the perl test script executed properly.
1;

View File

@@ -62,7 +62,7 @@ sub toplevel
$cwd = "."; # don't we wish we knew
$cwdslash = ""; # $cwd . $pathsep, but "" rather than "./"
&get_osname; # sets $osname, $vos, $pathsep, and $fancy_file_names
&get_osname; # sets $osname, $vos, $pathsep, and $short_filenames
&set_defaults; # suite-defined
@@ -173,12 +173,12 @@ sub get_osname
# See if the filesystem supports long file names with multiple
# dots. DOS doesn't.
$fancy_file_names = 1;
$short_filenames = 0;
(open (TOUCHFD, "> fancy.file.name") && close (TOUCHFD))
|| ($fancy_file_names = 0);
unlink ("fancy.file.name") || ($fancy_file_names = 0);
|| ($short_filenames = 1);
unlink ("fancy.file.name") || ($short_filenames = 1);
if ($fancy_file_names) {
if (! $short_filenames) {
# Thanks go to meyering@cs.utexas.edu (Jim Meyering) for suggesting a
# better way of doing this. (We used to test for existence of a /mnt
# dir, but that apparently fails on an SGI Indigo (whatever that is).)
@@ -190,7 +190,7 @@ sub get_osname
chdir (".ostest") || &error ("Couldn't chdir to .ostest: $!\n", 1);
}
if ($fancy_file_names && -f "ick")
if (! $short_filenames && -f "ick")
{
$osname = "vos";
$vos = 1;
@@ -219,7 +219,7 @@ sub get_osname
$pathsep = "/";
}
if ($fancy_file_names) {
if (! $short_filenames) {
chdir ("..") || &error ("Couldn't chdir to ..: $!\n", 1);
unlink (".ostest>ick");
rmdir (".ostest") || &error ("Couldn't rmdir .ostest: $!\n", 1);
@@ -363,7 +363,7 @@ sub run_each_test
$testpath = "$workpath$pathsep$testname";
# Leave enough space in the extensions to append a number, even
# though it needs to fit into 8+3 limits.
if ($port_host eq 'DOS') {
if ($short_filenames) {
$logext = 'l';
$diffext = 'd';
$baseext = 'b';

View File

@@ -23,6 +23,7 @@ Boston, MA 02111-1307, USA. */
#include "job.h"
#include "commands.h"
#include "variable.h"
#include "rule.h"
#ifdef WINDOWS32
#include "pathstuff.h"
#endif
@@ -58,13 +59,14 @@ static struct variable *lookup_variable_in_set PARAMS ((char *name,
that it should be recursively re-expanded. */
struct variable *
define_variable_in_set (name, length, value, origin, recursive, set)
define_variable_in_set (name, length, value, origin, recursive, set, flocp)
char *name;
unsigned int length;
char *value;
enum variable_origin origin;
int recursive;
struct variable_set *set;
const struct floc *flocp;
{
register unsigned int i;
register unsigned int hashval;
@@ -99,6 +101,10 @@ define_variable_in_set (name, length, value, origin, recursive, set)
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;
}
@@ -110,54 +116,35 @@ define_variable_in_set (name, length, value, origin, recursive, set)
v = (struct variable *) xmalloc (sizeof (struct variable));
v->name = savestring (name, length);
v->value = xstrdup (value);
if (flocp != 0)
v->fileinfo = *flocp;
else
v->fileinfo.filenm = 0;
v->origin = origin;
v->recursive = recursive;
v->expanding = 0;
v->per_target = 0;
v->append = 0;
v->export = v_default;
v->next = set->table[hashval];
set->table[hashval] = v;
return v;
}
/* Define a variable in the current variable set. */
struct variable *
define_variable (name, length, value, origin, recursive)
char *name;
unsigned int length;
char *value;
enum variable_origin origin;
int recursive;
{
return define_variable_in_set (name, length, value, origin, recursive,
current_variable_set_list->set);
}
/* Define a variable in FILE's variable set. */
struct variable *
define_variable_for_file (name, length, value, origin, recursive, file)
char *name;
unsigned int length;
char *value;
enum variable_origin origin;
int recursive;
struct file *file;
{
return define_variable_in_set (name, length, value, origin, recursive,
file->variables->set);
}
/* Lookup a variable whose name is a string starting at NAME
and with LENGTH chars. NAME need not be null-terminated.
Returns address of the `struct variable' containing all info
on the variable, or nil if no such variable is defined. */
on the variable, or nil if no such variable is defined.
If LISTP is not nil, return a pointer to the setlist where
the variable was found. If the variable wasn't found, the
value of LISTP is unchanged. */
struct variable *
lookup_variable (name, length)
lookup_variable_setlist (name, length, listp)
char *name;
unsigned int length;
struct variable_set_list **listp;
{
register struct variable_set_list *setlist;
@@ -178,9 +165,73 @@ lookup_variable (name, length)
if (*v->name == *name
&& strneq (v->name + 1, name + 1, length - 1)
&& v->name[length] == 0)
return v;
{
if (listp)
*listp = setlist;
return v;
}
}
#ifdef VMS
/* since we don't read envp[] on startup, try to get the
variable via getenv() here. */
{
char *vname = alloca (length + 1);
char *value;
strncpy (vname, name, length);
vname[length] = 0;
value = getenv (vname);
if (value != 0)
{
char *sptr;
int scnt;
sptr = value;
scnt = 0;
if (listp)
*listp = current_variable_set_list;
while ((sptr = strchr (sptr, '$')))
{
scnt++;
sptr++;
}
if (scnt > 0)
{
char *nvalue;
char *nptr;
nvalue = alloca (length + scnt + 1);
sptr = value;
nptr = nvalue;
while (*sptr)
{
if (*sptr == '$')
{
*nptr++ = '$';
*nptr++ = '$';
}
else
{
*nptr++ = *sptr;
}
sptr++;
}
return define_variable (vname, length, nvalue, o_env, 1);
}
return define_variable (vname, length, value, o_env, 1);
}
}
#endif /* VMS */
return 0;
}
@@ -214,13 +265,17 @@ lookup_variable_in_set (name, length, set)
/* Initialize FILE's variable set list. If FILE already has a variable set
list, the topmost variable set is left intact, but the the rest of the
chain is replaced with FILE->parent's setlist. */
chain is replaced with FILE->parent's setlist. If we're READing a
makefile, don't do the pattern variable search now, since the pattern
variable might not have been defined yet. */
void
initialize_file_variables (file)
initialize_file_variables (file, reading)
struct file *file;
int reading;
{
register struct variable_set_list *l = file->variables;
if (l == 0)
{
l = (struct variable_set_list *)
@@ -238,10 +293,35 @@ initialize_file_variables (file)
l->next = &global_setlist;
else
{
if (file->parent->variables == 0)
initialize_file_variables (file->parent);
initialize_file_variables (file->parent, reading);
l->next = file->parent->variables;
}
/* If we're not reading makefiles and we haven't looked yet, see if
we can find a pattern variable. */
if (!reading && !file->pat_searched)
{
struct pattern_var *p = lookup_pattern_var (file->name);
file->pat_searched = 1;
if (p != 0)
{
/* If we found one, insert it between the current target's
variables and the next set, whatever it is. */
file->pat_variables = (struct variable_set_list *)
xmalloc (sizeof (struct variable_set_list));
file->pat_variables->set = p->vars->set;
}
}
/* If we have a pattern variable match, set it up. */
if (file->pat_variables != 0)
{
file->pat_variables->next = l->next;
l->next = file->pat_variables;
}
}
/* Pop the top set off the current variable set list,
@@ -457,6 +537,15 @@ define_automatic_variables ()
/* Define the magic D and F variables in terms of
the automatic variables they are variations of. */
#ifdef VMS
define_variable ("@D", 2, "$(dir $@)", o_automatic, 1);
define_variable ("%D", 2, "$(dir $%)", o_automatic, 1);
define_variable ("*D", 2, "$(dir $*)", o_automatic, 1);
define_variable ("<D", 2, "$(dir $<)", o_automatic, 1);
define_variable ("?D", 2, "$(dir $?)", o_automatic, 1);
define_variable ("^D", 2, "$(dir $^)", o_automatic, 1);
define_variable ("+D", 2, "$(dir $+)", o_automatic, 1);
#else
define_variable ("@D", 2, "$(patsubst %/,%,$(dir $@))", o_automatic, 1);
define_variable ("%D", 2, "$(patsubst %/,%,$(dir $%))", o_automatic, 1);
define_variable ("*D", 2, "$(patsubst %/,%,$(dir $*))", o_automatic, 1);
@@ -464,6 +553,7 @@ define_automatic_variables ()
define_variable ("?D", 2, "$(patsubst %/,%,$(dir $?))", o_automatic, 1);
define_variable ("^D", 2, "$(patsubst %/,%,$(dir $^))", o_automatic, 1);
define_variable ("+D", 2, "$(patsubst %/,%,$(dir $+))", o_automatic, 1);
#endif
define_variable ("@F", 2, "$(notdir $@)", o_automatic, 1);
define_variable ("%F", 2, "$(notdir $%)", o_automatic, 1);
define_variable ("*F", 2, "$(notdir $*)", o_automatic, 1);
@@ -679,10 +769,11 @@ target_environment (file)
returned. */
struct variable *
try_variable_definition (flocp, line, origin)
try_variable_definition (flocp, line, origin, target_var)
const struct floc *flocp;
char *line;
enum variable_origin origin;
int target_var;
{
register int c;
register char *p = line;
@@ -692,6 +783,7 @@ try_variable_definition (flocp, line, origin)
f_simple, f_recursive, f_append, f_conditional } flavor = f_bogus;
char *name, *expanded_name, *value, *alloc_value=NULL;
struct variable *v;
int append = 0;
while (1)
{
@@ -801,6 +893,16 @@ try_variable_definition (flocp, line, origin)
value = p;
break;
case f_append:
/* If we have += but we're in a target variable context, defer the
append until the context expansion. */
if (target_var)
{
append = 1;
flavor = f_recursive;
value = p;
break;
}
/* An appending variable definition "var += value".
Extract the old value and append the new one. */
v = lookup_variable (expanded_name, strlen (expanded_name));
@@ -868,8 +970,9 @@ try_variable_definition (flocp, line, origin)
if (*p == '\\')
*p = '/';
}
v = define_variable (expanded_name, strlen (expanded_name),
shellpath, origin, flavor == f_recursive);
v = define_variable_loc (expanded_name, strlen (expanded_name),
shellpath, origin, flavor == f_recursive,
flocp);
}
else
{
@@ -879,8 +982,8 @@ try_variable_definition (flocp, line, origin)
char *fake_env[2];
size_t pathlen = 0;
shellbase = rindex (value, '/');
bslash = rindex (value, '\\');
shellbase = strrchr (value, '/');
bslash = strrchr (value, '\\');
if (!shellbase || bslash > shellbase)
shellbase = bslash;
if (!shellbase && value[1] == ':')
@@ -908,8 +1011,9 @@ try_variable_definition (flocp, line, origin)
if (*p == '\\')
*p = '/';
}
v = define_variable (expanded_name, strlen (expanded_name),
shellpath, origin, flavor == f_recursive);
v = define_variable_loc (expanded_name, strlen (expanded_name),
shellpath, origin,
flavor == f_recursive, flocp);
}
else
v = lookup_variable (expanded_name, strlen (expanded_name));
@@ -930,15 +1034,18 @@ try_variable_definition (flocp, line, origin)
* set new value for SHELL variable.
*/
if (find_and_set_default_shell(value)) {
v = define_variable (expanded_name, strlen (expanded_name),
default_shell, origin, flavor == f_recursive);
v = define_variable_loc (expanded_name, strlen (expanded_name),
default_shell, origin, flavor == f_recursive,
flocp);
no_default_sh_exe = 0;
}
} else
#endif
v = define_variable (expanded_name, strlen (expanded_name),
value, origin, flavor == f_recursive);
v = define_variable_loc (expanded_name, strlen (expanded_name), value,
origin, flavor == f_recursive, flocp);
v->append = append;
if (alloc_value)
free (alloc_value);
@@ -959,42 +1066,45 @@ print_variable (v, prefix)
switch (v->origin)
{
case o_default:
origin = "default";
origin = _("default");
break;
case o_env:
origin = "environment";
origin = _("environment");
break;
case o_file:
origin = "makefile";
origin = _("makefile");
break;
case o_env_override:
origin = "environment under -e";
origin = _("environment under -e");
break;
case o_command:
origin = "command line";
origin = _("command line");
break;
case o_override:
origin = "`override' directive";
origin = _("`override' directive");
break;
case o_automatic:
origin = "automatic";
origin = _("automatic");
break;
case o_invalid:
default:
abort ();
}
printf ("# %s\n", origin);
fputs ("# ", stdout);
fputs (origin, stdout);
if (v->fileinfo.filenm)
printf (" (from `%s', line %lu)", v->fileinfo.filenm, v->fileinfo.lineno);
putchar ('\n');
fputs (prefix, stdout);
/* Is this a `define'? */
if (v->recursive && index (v->value, '\n') != 0)
if (v->recursive && strchr (v->value, '\n') != 0)
printf ("define %s\n%s\nendef\n", v->name, v->value);
else
{
register char *p;
printf ("%s %s= ", v->name, v->recursive ? "" : ":");
printf ("%s %s= ", v->name, v->recursive ? v->append ? "+" : "" : ":");
/* Check if the value is just whitespace. */
p = next_token (v->value);

View File

@@ -40,11 +40,14 @@ struct variable
struct variable *next; /* Link in the chain. */
char *name; /* Variable name. */
char *value; /* Variable value. */
struct floc fileinfo; /* Where the variable was defined. */
enum variable_origin
origin ENUM_BITFIELD (3); /* Variable origin. */
unsigned int recursive:1; /* Gets recursively re-evaluated. */
unsigned int expanding:1; /* Nonzero if currently being expanded. */
unsigned int per_target:1; /* Nonzero if a target-specific variable. */
unsigned int append:1; /* Nonzero if an appending target-specific
variable. */
enum variable_export
{
v_export, /* Export this variable. */
@@ -92,26 +95,51 @@ extern char *patsubst_expand PARAMS ((char *o, char *text, char *pattern, char *
char *pattern_percent, char *replace_percent));
/* expand.c */
extern char *recursively_expand PARAMS ((struct variable *v));
extern char *recursively_expand_setlist PARAMS ((struct variable *v,
struct variable_set_list *l));
#define recursively_expand(v) recursively_expand_setlist((v),(struct variable_set_list *)0)
/* variable.c */
extern struct variable_set_list *create_new_variable_set PARAMS ((void));
extern struct variable_set_list *push_new_variable_scope PARAMS ((void));
extern void pop_variable_scope PARAMS ((void));
extern void define_automatic_variables PARAMS ((void));
extern void initialize_file_variables PARAMS ((struct file *file));
extern void initialize_file_variables PARAMS ((struct file *file, int read));
extern void print_file_variables PARAMS ((struct file *file));
extern void print_variable_set PARAMS ((struct variable_set *set, char *prefix));
extern void merge_variable_set_lists PARAMS ((struct variable_set_list **setlist0, struct variable_set_list *setlist1));
extern struct variable *try_variable_definition PARAMS ((const struct floc *flocp, char *line, enum variable_origin origin));
extern struct variable *try_variable_definition PARAMS ((const struct floc *flocp, char *line, enum variable_origin origin, int target_var));
extern struct variable *lookup_variable_setlist
PARAMS ((char *name, unsigned int length,
struct variable_set_list **lisp));
#define lookup_variable(n,l) lookup_variable_setlist((n),(l),\
(struct variable_set_list **)0)
extern struct variable *define_variable_in_set
PARAMS ((char *name, unsigned int length, char *value,
enum variable_origin origin, int recursive,
struct variable_set *set, const struct floc *flocp));
/* Define a variable in the current variable set. */
#define define_variable(n,l,v,o,r) \
define_variable_in_set((n),(l),(v),(o),(r),\
current_variable_set_list->set,NILF)
/* Define a variable with a location in the current variable set. */
#define define_variable_loc(n,l,v,o,r,f) \
define_variable_in_set((n),(l),(v),(o),(r),\
current_variable_set_list->set,(f))
/* Define a variable in FILE's variable set. */
#define define_variable_for_file(n,l,v,o,r,f) \
define_variable_in_set((n),(l),(v),(o),(r),(f)->variables->set,NILF)
extern struct variable *lookup_variable PARAMS ((char *name, unsigned int length));
extern struct variable *define_variable PARAMS ((char *name, unsigned int length, char *value,
enum variable_origin origin, int recursive));
extern struct variable *define_variable_in_set PARAMS ((char *name, unsigned int length,
char *value, enum variable_origin origin, int recursive, struct variable_set *set));
extern struct variable *define_variable_for_file PARAMS ((char *name, unsigned int length,
char *value, enum variable_origin origin, int recursive, struct file *file));
extern char **target_environment PARAMS ((struct file *file));
extern int export_all_variables;

View File

@@ -1,15 +1,21 @@
/* dirent.h for vms */
#ifndef VMSDIR_H
#define VMSDIR_H
#include <rms.h>
#define MAXNAMLEN 255
#ifndef __DECC
#if !defined (__GNUC__) && !defined (__ALPHA)
typedef unsigned long u_long;
typedef unsigned short u_short;
#endif
#endif
struct direct {
struct direct
{
off_t d_off;
u_long d_fileno;
u_short d_reclen;
@@ -18,8 +24,11 @@ struct direct {
};
#undef DIRSIZ
#define DIRSIZ(dp) \
(((sizeof (struct direct) - (MAXNAMLEN+1) + ((dp)->d_namlen+1)) + 3) & ~3)
#define DIRSIZ(dp) \
(((sizeof (struct direct) \
- (MAXNAMLEN+1) \
+ ((dp)->d_namlen+1)) \
+ 3) & ~3)
#define d_ino d_fileno /* compatability */
@@ -28,15 +37,25 @@ struct direct {
* Definitions for library routines operating on directories.
*/
typedef struct FAB DIR;
typedef struct DIR
{
struct direct dir;
char d_result[MAXNAMLEN + 1];
#if defined (__ALPHA) || defined (__DECC)
struct FAB fab;
#else
struct fabdef fab;
#endif
} DIR;
#ifndef NULL
#define NULL 0
#endif
extern DIR *opendir PARAMS (());
extern struct direct *readdir PARAMS ((DIR *dfd));
#define rewinddir(dirp) seekdir((dirp), (long)0)
extern int closedir PARAMS ((DIR *dfd));
extern char *vmsify PARAMS ((char *name, int type));
/* EOF */
#endif /* VMSDIR_H */

View File

@@ -1,10 +1,8 @@
/* vmsfunctions.c */
#define KDEBUG 0
#include <stdio.h>
#include <ctype.h>
#include "make.h"
#include "debug.h"
#ifdef __DECC
#include <starlet.h>
#endif
@@ -15,43 +13,23 @@
#include <fibdef.h>
#include "vmsdir.h"
#if __VMS_VER < 70000000
#ifdef HAVE_VMSDIR_H
DIR *
opendir (dspec)
char *dspec;
{
static struct FAB *dfab;
struct NAM *dnam;
char *searchspec;
struct DIR *dir = (struct DIR *)xmalloc (sizeof (struct DIR));
struct NAM *dnam = (struct NAM *)xmalloc (sizeof (struct NAM));
struct FAB *dfab = &dir->fab;
char *searchspec = (char *)xmalloc (MAXNAMLEN + 1);
dfab = (struct FAB *) xmalloc (sizeof (struct FAB));
if (! dfab)
{
printf ("Error mallocing for FAB\n");
return (NULL);
}
dnam = (struct NAM *) xmalloc (sizeof (struct NAM));
if (! dnam)
{
printf ("Error mallocing for NAM\n");
free (dfab);
return (NULL);
}
searchspec = (char *) xmalloc (MAXNAMLEN + 1);
if (! searchspec)
{
printf ("Error mallocing for searchspec\n");
free (dfab);
free (dnam);
return (NULL);
}
sprintf (searchspec, "%s*.*;", dspec);
memset (dir, 0, sizeof *dir);
*dfab = cc$rms_fab;
*dnam = cc$rms_nam;
sprintf (searchspec, "%s*.*;", dspec);
dfab->fab$l_fna = searchspec;
dfab->fab$b_fns = strlen (searchspec);
dfab->fab$l_nam = dnam;
@@ -62,13 +40,13 @@ opendir (dspec)
if (! (sys$parse (dfab) & 1))
{
free (dfab);
free (dir);
free (dnam);
free (searchspec);
return (NULL);
}
return (dfab);
return dir;
}
#define uppercasify(str) \
@@ -76,73 +54,63 @@ opendir (dspec)
{ \
char *tmp; \
for (tmp = (str); *tmp != '\0'; tmp++) \
if (islower (*tmp)) \
*tmp = toupper (*tmp); \
if (islower ((unsigned char)*tmp)) \
*tmp = toupper ((unsigned char)*tmp); \
} \
while (0)
struct direct *
readdir (dfd)
DIR * dfd;
readdir (dir)
DIR * dir;
{
static struct direct *dentry;
static char resultspec[MAXNAMLEN + 1];
struct FAB *dfab = &dir->fab;
struct NAM *dnam = (struct NAM *)(dfab->fab$l_nam);
struct direct *dentry = &dir->dir;
int i;
dentry = (struct direct *) xmalloc (sizeof (struct direct));
if (! dentry)
memset (dentry, 0, sizeof *dentry);
dnam->nam$l_rsa = dir->d_result;
dnam->nam$b_rss = MAXNAMLEN;
DB (DB_VERBOSE, ("."));
if (!((i = sys$search (dfab)) & 1))
{
printf ("Error mallocing for direct\n");
return (NULL);
}
dfd->fab$l_nam->nam$l_rsa = resultspec;
dfd->fab$l_nam->nam$b_rss = MAXNAMLEN;
if (debug_flag)
printf (".");
if (!((i = sys$search (dfd)) & 1))
{
if (debug_flag)
printf ("sys$search failed with %d\n", i);
free (dentry);
DB (DB_VERBOSE, (_("sys$search failed with %d\n"), i));
return (NULL);
}
dentry->d_off = 0;
if (dfd->fab$l_nam->nam$w_fid == 0)
if (dnam->nam$w_fid == 0)
dentry->d_fileno = 1;
else
dentry->d_fileno = dfd->fab$l_nam->nam$w_fid[0]
+ dfd->fab$l_nam->nam$w_fid[1] << 16;
dentry->d_fileno = dnam->nam$w_fid[0] + (dnam->nam$w_fid[1] << 16);
dentry->d_reclen = sizeof (struct direct);
#if 0
if (!strcmp(dfd->fab$l_nam->nam$l_type, ".DIR"))
dentry->d_namlen = dfd->fab$l_nam->nam$b_name;
else
#endif
dentry->d_namlen = dfd->fab$l_nam->nam$b_name + dfd->fab$l_nam->nam$b_type;
strncpy (dentry->d_name, dfd->fab$l_nam->nam$l_name, dentry->d_namlen);
dentry->d_namlen = dnam->nam$b_name + dnam->nam$b_type;
strncpy (dentry->d_name, dnam->nam$l_name, dentry->d_namlen);
dentry->d_name[dentry->d_namlen] = '\0';
uppercasify (dentry->d_name);
#if 0
uvUnFixRCSSeparator(dentry->d_name);
#endif
return (dentry);
}
closedir (dfd)
DIR *dfd;
int
closedir (dir)
DIR *dir;
{
if (dfd)
if (dir != NULL)
{
if (dfd->fab$l_nam)
free (dfd->fab$l_nam->nam$l_esa);
free (dfd->fab$l_nam);
free (dfd);
struct FAB *dfab = &dir->fab;
struct NAM *dnam = (struct NAM *)(dfab->fab$l_nam);
if (dnam != NULL)
free (dnam->nam$l_esa);
free (dnam);
free (dir);
}
return 0;
}
#endif /* compiled for OpenVMS prior to V7.x */
@@ -229,7 +197,7 @@ vms_stat (name, buf)
/* Initialize the FIB */
for (i = 0; i < 3; i++)
{
#if __DECC
#ifndef __VAXC
Fib.fib$w_fid[i] = Nam.nam$w_fid[i];
Fib.fib$w_did[i] = Nam.nam$w_did[i];
#else
@@ -277,3 +245,17 @@ cvt_time (tval)
return (str);
}
int
strcmpi (s1, s2)
const char *s1;
const char *s2;
{
while (*s1 != '\0' && toupper(*s1) == toupper(*s2))
{
s1++;
s2++;
}
return toupper(*(unsigned char *) s1) - toupper(*(unsigned char *) s2);
}

221
vmsify.c
View File

@@ -8,6 +8,7 @@
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
@@ -78,8 +79,8 @@ copyto (char **to, char **from, char upto, int as_dir)
}
else
{
if (islower (**from))
**to = toupper (**from);
if (isupper ((unsigned char)**from))
**to = tolower ((unsigned char)**from);
else
**to = **from;
}
@@ -127,6 +128,27 @@ trnlog (char *name)
return s;
}
static char *
showall (char *s)
{
static char t[512];
char *pt;
pt = t;
if (strchr (s, '\\') == 0)
return s;
while (*s)
{
if (*s == '\\')
{
*pt++ = *s;
}
*pt++ = *s++;
}
return pt;
}
enum namestate { N_START, N_DEVICE, N_OPEN, N_DOT, N_CLOSED, N_DONE };
/*
@@ -205,16 +227,39 @@ vmsify (name, type)
s = strpbrk (name, "$:");
if (s != 0)
{
char *s1;
char *s2;
if (type == 1)
{
s1 = strchr (s+1, '[');
s2 = strchr (s+1, ']');
}
if (*s == '$')
{
if (strchr (name, '/') == 0)
{
return name;
if ((type == 1) && (s1 != 0) && (s2 == 0))
{
strcpy (vmsname, name);
strcat (vmsname, "]");
return vmsname;
}
else
return name;
}
}
else
{
return name;
if ((type == 1) && (s1 != 0) && (s2 == 0))
{
strcpy (vmsname, name);
strcat (vmsname, "]");
return vmsname;
}
else
return name;
}
}
@@ -227,7 +272,15 @@ vmsify (name, type)
s1 = strchr (s+1, '[');
if (s1 == 0)
{
return name; /* single [, keep unchanged */
if ((type == 1)
&& (strchr (s+1, ']') == 0))
{
strcpy (vmsname, name);
strcat (vmsname, "]");
return vmsname;
}
else
return name; /* single [, keep unchanged */
}
s1--;
if (*s1 != ']')
@@ -403,7 +456,7 @@ vmsify (name, type)
{
if (*(s2-1) == '.') /* ends in '.]' */
{
if (!strneq (fptr, "000000", 6))
if (strncmp (fptr, "000000", 6) != 0)
rooted = 0;
}
else
@@ -727,21 +780,48 @@ vmsify (name, type)
while (*fptr == '/');
}
{ /* got '..' or '../' */
nstate = N_OPEN;
*vptr++ = '[';
while (count--)
*vptr++ = '-';
char cwdbuf[MAXPATHLEN+1];
if (*fptr == 0) /* had '..' or '../' */
s1 = getcwd(cwdbuf, MAXPATHLEN);
if (s1 == 0)
{
*vptr++ = ']';
state = -1;
return ""; /* FIXME, err getcwd */
}
else /* had '../xxx' */
strcpy (vptr, s1);
s = strchr (vptr, ']');
if (s != 0)
{
state = 9;
nstate = N_OPEN;
while (s > vptr)
{
s--;
if (*s == '[')
{
s++;
strcpy (s, "000000]");
state = -1;
break;
}
else if (*s == '.')
{
if (--count == 0)
{
if (*fptr == 0) /* had '..' or '../' */
{
*s++ = ']';
state = -1;
}
else /* had '../xxx' */
{
state = 9;
}
*s = 0;
break;
}
}
}
}
*vptr = 0;
vptr += strlen (vptr);
}
break;
@@ -752,89 +832,38 @@ vmsify (name, type)
{
return name;
}
fptr++;
while (*fptr == '/')
fptr++;
}
if (*fptr)
{
state = 9;
{
char cwdbuf[MAXPATHLEN+1];
switch (type)
{
case 0:
nstate = N_CLOSED;
*vptr++ = '[';
*vptr++ = ']';
break;
case 1:
nstate = N_OPEN;
*vptr++ = '[';
break;
case 2:
nstate = N_CLOSED;
break;
}
}
else
{
if (type == 1)
{
*vptr++ = '[';
*vptr++ = ']';
state = -1;
}
else
{
char cwdbuf[MAXPATHLEN+1];
s1 = getcwd(cwdbuf, MAXPATHLEN);
if (s1 == 0)
{
return "foo"; /*FIXME, err getcwd */
}
strcpy (vptr, s1);
vptr += strlen (vptr);
if (type == 2)
{
s = vptr;
while (s > vmsname)
{
if (*s == '.')
{
*s = ']';
vptr--;
break;
}
if (*s == '[')
{
int i;
char *t = vptr - 2;
while (t > s)
{
*(t+7) = *t;
t--;
}
s++;
for (i = 0; i < 6; i++)
*s++ = '0';
*s = ']';
vptr += 6;
break;
}
s--;
}
strcpy (vptr, ".dir");
vptr += 4;
}
state = -1;
}
}
s1 = getcwd(cwdbuf, MAXPATHLEN);
if (s1 == 0)
{
return ""; /*FIXME, err getcwd */
}
strcpy (vptr, s1);
if (*fptr == 0)
{
state = -1;
break;
}
else
{
s = strchr (vptr, ']');
if (s == 0)
{
state = -1;
break;
}
*s = 0;
nstate = N_OPEN;
vptr += strlen (vptr);
state = 9;
}
}
break;
}

View File

@@ -402,11 +402,11 @@ selective_vpath_search (path, file, mtime_ptr)
NAME_DPLEN gets the length of the prefix; FILENAME gets the
pointer to the name-within-directory and FLEN is its length. */
n = rindex (*file, '/');
n = strrchr (*file, '/');
#if defined (WINDOWS32) || defined (__MSDOS__)
/* We need the rightmost slash or backslash. */
{
char *bslash = rindex(*file, '\\');
char *bslash = strrchr(*file, '\\');
if (!n || bslash > n)
n = bslash;
}

View File

@@ -59,5 +59,7 @@ arr2envblk(char **arr, char **envblk_out)
ptr += strlen(tmp[arrcnt]) + 1;
arrcnt++;
}
free(tmp);
return TRUE;
}