Compare commits

...

1030 Commits

Author SHA1 Message Date
Roland McGrath
3c767901f6 (make-$(version).tar): Rename install.sh to install-sh. 1994-11-28 20:54:38 +00:00
Roland McGrath
c6dfff5f1b (prefix, exec_prefix): Set.
(CPPFLAGS): Filter out @...@.
($(ARCH)/glob/libglob.a): Don't pass down variables.
1994-11-28 20:51:40 +00:00
Roland McGrath
74540a1e91 Abbreviate copyright years. 1994-11-28 20:50:45 +00:00
Roland McGrath
5159db0aa4 (AC_OUTPUT): Don't write glob/Makefile. 1994-11-28 20:48:43 +00:00
Roland McGrath
e495d2380d (AC_CHECK_SYMBOL): Use AC_DEFINE_UNQUOTED. 1994-11-28 20:28:26 +00:00
Roland McGrath
1ed34a0118 Don't check for ranlib. 1994-11-28 20:20:43 +00:00
Roland McGrath
e8f64b2c88 (notice_finished_file): Only mark also_make's as updated if really ran
cmds.
1994-11-23 03:42:34 +00:00
Roland McGrath
4867409da2 Put dnls before random whitespace. 1994-11-15 11:32:39 +00:00
Roland McGrath
f801fc3521 (CPPFLAGS): New variable, set from @CPPFLAGS@.
(RANLIB): Variable removed.
(prefix, exec_prefix): Set these from @...@.
(.c.o): Use $(CPPFLAGS).
(glob/libglob.a): Don't pass down variables to sub-make.
glob/Makefile should be configured properly by configure.
(distclean): Remove config.log and config.cache (autoconf stuff).
1994-11-13 10:02:19 +00:00
David J. MacKenzie
b2c0446e71 Explain reason for new filesystem layout. 1994-11-11 04:33:24 +00:00
Roland McGrath
8f98ceb724 Add #undef HAVE_UNION_WAIT. 1994-11-08 02:09:49 +00:00
Roland McGrath
dea9990bc8 Converted to Autoconf v2. 1994-11-08 02:08:24 +00:00
Roland McGrath
e4c43aab3e Test HAVE_DIRENT_H, HAVE_SYS_DIR_H, HAVE_NDIR_H instead of DIRENT, SYSDIR,
NDIR.
1994-11-08 00:14:50 +00:00
Roland McGrath
e55ed78080 (prefix, exec_prefix): Set these from @...@.
(CPPFLAGS): New variable, set from @CPPFLAGS@.
(compiling loop): Pass $CPPFLAGS before $CFLAGS.
1994-11-07 23:42:58 +00:00
Roland McGrath
ca54a0b991 Initial revision 1994-11-07 23:40:44 +00:00
Roland McGrath
e25e2fb7f5 (define_makeflags): When no flags, set WORDS to zero. 1994-11-07 18:57:56 +00:00
Roland McGrath
1a886b6359 (define_makeflags): Terminate properly when FLAGSTRING is empty. 1994-11-06 23:33:55 +00:00
Roland McGrath
b511712f25 (rcs-mark-{alpha,beta}): Let make do the globbing instead of sh. 1994-11-04 21:08:52 +00:00
Roland McGrath
30fcca501f Remove `DRAFT' from edition. 1994-11-04 20:23:23 +00:00
Roland McGrath
806dc4f7c4 (Variables/Recursion): Fix typo. 1994-11-01 08:40:19 +00:00
Roland McGrath
c0163410d2 (start_job_command): When ARGV is nil, only set update_state and call
notice_finished_file if job_next_command returns zero.
1994-11-01 08:34:10 +00:00
Roland McGrath
eac1e9ee66 Doc .DELETE_ON_ERROR.
Doc new MAKEFLAGS/MAKEOVERRIDES.
Doc .IGNORE/.SILENT with deps.
1994-11-01 08:29:31 +00:00
Roland McGrath
8ad5af7c28 (start_job_command): Call notice_finished_file for empty command line. 1994-11-01 06:18:07 +00:00
Roland McGrath
857d7ad256 (snap_deps): Set COMMANDS_SILENT for .SILENT, not COMMANDS_NOERROR. 1994-10-27 06:02:43 +00:00
Roland McGrath
612a29e0dd [alliant && i860] (FSCALE): Move defn before #ifndef FSCALE. 1994-10-27 00:34:56 +00:00
Roland McGrath
462304918c (snap_deps): Set command_flags bits in all :: entries. 1994-10-26 02:49:21 +00:00
Roland McGrath
9d36c92adb (snap_deps): Fix last change. 1994-10-24 23:44:16 +00:00
Roland McGrath
640c4ecd99 (posix_pedantic): Declare it. 1994-10-24 23:11:57 +00:00
Roland McGrath
07f09cfd88 (main): Move checks .IGNORE, .SILENT, .POSIX to snap_deps. 1994-10-24 22:57:07 +00:00
Roland McGrath
d37c9ba18a (snap_deps): Check .IGNORE, .SILENT, .POSIX here instead of in main.
If .IGNORE has deps, OR COMMANDS_NOERROR into their command_flags and
don't set -i.  Likewise .SILENT.
1994-10-24 22:56:27 +00:00
Roland McGrath
cc8d6cf343 (start_job_command): In FLAGS initialization, OR in
CHILD->file->command_flags.
1994-10-24 22:50:01 +00:00
Roland McGrath
4b17f0982b (struct file): New member `command_flags'. 1994-10-24 22:47:43 +00:00
Roland McGrath
dc576b2051 (Automatic Dependencies): Improve recommended sed command.
Mention -MM flag to gcc.
1994-10-24 05:05:43 +00:00
Roland McGrath
a543a2ae9f (Commands): Add warning about "blank" line starting with a tab. 1994-10-17 00:02:27 +00:00
Roland McGrath
0e352e4bf7 (switches): Bump flag values for --no-print-directory and
--warn-undefined-variables, so neither is 1 (which indicates a nonoption
argument).
1994-10-16 05:01:46 +00:00
Roland McGrath
3f8bde0f25 (main): Add missing code in .IGNORE test. 1994-10-16 03:39:35 +00:00
Roland McGrath
4308542cb1 Document $+ and $(+D), $(+F). 1994-10-10 08:10:13 +00:00
Roland McGrath
e622fcf22e (define_automatic_variables): Define +D and +F. 1994-10-10 08:08:58 +00:00
Roland McGrath
1766b7fa59 (main): Define hidden automatic variable with command vars, and
MAKEOVERRIDES to a reference to that.
(define_makeflags): If posix_pedantic, write a reference to that instead.
1994-10-01 08:07:35 +00:00
Roland McGrath
fa999783d7 (posix_pedantic): New variable.
(main): Set posix_pedantic if .POSIX is a target.
Fix .IGNORE and .SILENT hecks to require is_target.
1994-09-30 01:04:54 +00:00
Roland McGrath
e97d6632b5 Comment fix. 1994-09-29 19:52:49 +00:00
Roland McGrath
e3d013a79a (set_file_variables): Define new automatic variable $+, like $^ but before
calling uniquize_deps.
1994-09-29 08:23:25 +00:00
Roland McGrath
9807a2869f (reap_children): Call delete_child_targets for non-signal error if
.DELETE_ON_ERROR is a target.
1994-09-29 04:14:20 +00:00
Roland McGrath
e9521d3447 [alliant && i860] (LOAD_AVE_TYPE, FSCALE, NLIST_STRUCT): Define. 1994-09-28 21:00:06 +00:00
Roland McGrath
c62ca42327 (reap_children): Don't change C->file->command_state when dying.
Test it only after calling start_job_command for a new command line.
When no more cmds, just set C->file->update_status.
(start_job_command): When the last line is empty or under -n, set
C->file->update_status.
(start_waiting_job): Grok cs_not_started after start_job_command as success.
(new_job): Set C->file->update_status when there are no cmds.
(job_next_command): When out of lines, don't set CHILD->file->update_status or
CHILD->file->command_state.
1994-09-26 23:02:40 +00:00
Roland McGrath
2feb36f620 (quote_as_word): Actually test DOUBLE_DOLLARS, instead of always doubling. 1994-09-26 22:45:08 +00:00
Roland McGrath
f40918e005 (quote_as_word): Renamed from shell_quote.
Take new arg; if nonzero, also double $s.
(main): Define MAKEOVERRIDES from command_variables here.
(define_makeflags): Don't use command_variables here; instead write a
reference $(MAKEOVERRIDES) in MAKEFLAGS.  Make vars recursive.
1994-09-26 22:37:10 +00:00
Roland McGrath
b13a443fa7 [__MSDOS__]: Fixed typo. 1994-09-26 22:20:56 +00:00
Roland McGrath
e938a511be (selective_vpath_search): Reset EXISTS when stat fails. 1994-09-26 22:16:51 +00:00
David J. MacKenzie
a96d572aa6 remove CONFIG_BROKETS 1994-09-26 21:57:54 +00:00
David J. MacKenzie
990c39d973 REMOVE CONFIG_BROKETS 1994-09-26 21:56:21 +00:00
David J. MacKenzie
24d37fb493 remove CONFIG_BROKETS 1994-09-26 21:52:40 +00:00
Richard M. Stallman
c1e20276cb (getloadavg): Add OSF_ALPHA support. 1994-09-17 00:16:57 +00:00
Roland McGrath
9f71eaf6b5 Include <assert.h> and use assert instead of printfs and abort. 1994-09-10 15:04:57 +00:00
Roland McGrath
03cd08cca2 (decode_switches): Loop until optind hits ARGC, not just until getopt_long
returns EOF.  Initialize C to zero before loop; in loop if C is EOF, set
optarg from ARGV[optind++], else call getopt_long.
(decode_env_switches): Use variable_expand instead of
allocated_variable_expand.  Allocate a fresh buffer to copy split words
into; scan characters by hand to break words and debackslashify.
(shell_quote): New function.
(define_makeflags): Allocate doubled space for switch args, and command
variable names and values; use shell_quote to quote those things.
1994-09-10 07:01:10 +00:00
Roland McGrath
dc44a79020 Add HAVE_SYS_SIGLIST and HAVE__SYS_SIGLIST. 1994-09-09 07:16:54 +00:00
Roland McGrath
8ed6e13cfe (Archive Suffix Rules): Remove Next pointer. 1994-09-09 06:59:08 +00:00
Roland McGrath
b321e0f535 (decode_switches): The non-option return from getopt is 1, not 0.
(command_variables): New type and variable.
(decode_switches, decode_env_switches): After making a variable definition,
record the struct variable pointer in the command_variables chain.
(define_makeflags): If ALL, write variable definitions for
command_variables.
1994-09-09 06:45:51 +00:00
Roland McGrath
c1433e9495 (other_args): Variable removed.
(goals, lastgoal): New static variables (moved from auto in main).
(main): Don't process OTHER_ARGS at all.
Don't set variable MAKEOVERRIDES at all; define MAKE to just $(MAKE_COMMAND).
(init_switches): Prepend a - (return in order) instead of a + (require order).
(decode_switches): Don't set OTHER_ARGS at all.
Grok '\0' return from getopt_long as non-option argument; try variable
definition and (if !ENV) enter goal targets here.
(decode_env_switches): Use allocated_variable_expand to store value.
Use find_next_token to simplify word-splitting loop.
Don't prepend a dash to uninterpreted value.
Instead, if split into only one word, try variable definition and failing
that prepend a dash to the word and pass it to decode_switches as a single arg.
1994-09-09 05:37:40 +00:00
Roland McGrath
e4a94e0210 (notice_finished_file): Only recheck modtimes if FILE->command_state was
cs_running on entry (meaning the commands actually just ran).
(update_file_1): Whenever we set FILE->update_status, call
notice_finished_file instead of just set_command_state.
1994-09-07 07:06:46 +00:00
Roland McGrath
9e97330bcb (start_job_command): Whenever we set CHILD->file->update_status, call
notice_finished_file instead of just set_command_state.
1994-09-07 07:02:23 +00:00
Roland McGrath
4969b416b8 (set_command_state): Actually set FILE->command_state. 1994-09-07 00:31:13 +00:00
Roland McGrath
0bd0301ae3 (set_command_state): Fix typo. 1994-09-07 00:24:10 +00:00
Roland McGrath
ff6efbadf5 (set_command_state): Declare D. 1994-09-07 00:17:57 +00:00
Roland McGrath
0b3317d2e1 Add missing ". 1994-09-07 00:15:23 +00:00
Roland McGrath
ca5a872280 Changed all assignments of command_state members to calls to
set_command_state.
1994-09-07 00:04:49 +00:00
Roland McGrath
4244f182f2 (set_command_state): New function. 1994-09-07 00:02:25 +00:00
Roland McGrath
be6e6d74bb Declare set_command_state. 1994-09-06 23:48:36 +00:00
Roland McGrath
4c0fef3dd7 (init_switches): Put a + first in options. 1994-09-06 23:13:43 +00:00
Richard M. Stallman
d3b65c3cb7 entered into RCS 1994-08-21 17:29:57 +00:00
gnu
bc48185f8e Formerly make-stds.texi.~29~ 1994-08-10 05:41:00 +00:00
Roland McGrath
6fcf219fa7 Initial revision 1994-07-25 23:47:05 +00:00
Roland McGrath
d2e23eefd2 Added trailing CRs. 1994-07-25 23:46:16 +00:00
Roland McGrath
55162a6730 Changed all uses of ':' to PATH_SEPARATOR_CHAR. 1994-07-25 23:34:32 +00:00
Roland McGrath
021ea7e61c (directory_before_chdir): New variable, moved out of main (was local).
(main) [__MSDOS__]: Look for \ or : to delimit last component of PROGRAM.
Don't frob ARGV[0] before setting MAKE_COMMAND variable.
(die): Change back to `directory_before_chdir' before dying.

Part of MSDOS/GO32 port from DJ Delorie <dj@ctron.com>.
1994-07-25 23:33:26 +00:00
Roland McGrath
f663464925 (PATH_SEPARATOR_CHAR): Macro removed (now in make.h). 1994-07-25 23:28:08 +00:00
Roland McGrath
5d435e0859 (PATH_SEPARATOR_CHAR): New macro; differing defns for [__MSDOS__] and not. 1994-07-25 23:27:48 +00:00
Roland McGrath
a2ab31ba62 [__MSDOS__]: Include <process.h>.
(PATH_SEPARATOR_CHAR): New macro; differing defns for [__MSDOS__] and not.
[__MSDOS__] (dos_pid, dos_status, dos_bname, dos_bename, dos_batch_file):
New variables.
(reap_children) [__MSDOS__]: Don't call wait; just examine those vars.
(unblock_sigs) [__MSDOS__]: Do nothing.
(start_job_command) [__MSDOS__]: Use spawnvpe instead of vfork and exec.
(load_too_high) [__MSDOS__]: Always return true.
(search_path) [__MSDOS__]: Check for : or / in FILE to punt.
Use PATH_SEPARATOR_CHAR instead of ':'.
(construct_command_argv_internal) [__MSDOS__]: Wholly different values for
sh_chars and sh_cmds.  Wholly new code to handle shell scripts.

Part of MSDOS/GO32 port from DJ Delorie <dj@ctron.com>.
1994-07-25 23:23:03 +00:00
Roland McGrath
da2ea1ea7f (expand_function: `shell') [__MSDOS__]: Wholly new implementation. 1994-07-25 23:06:00 +00:00
Roland McGrath
21a1b3b255 [__MSDOS__] (dosify): New function.
(dir_contents_file_exists_p) [__MSDOS__]: Call it on FILENAME and process
the result instead of FILENAME itself.
(file_impossible_p) [__MSDOS__]: Likewise.
Part of MSDOS/GO32 port from DJ Delorie <dj@ctron.com>.
1994-07-25 23:01:19 +00:00
Roland McGrath
c8e76a708e [__MSDOS__]: Define GCC_IS_NATIVE.
(default_suffix_rules) [__MSDOS__]: Use `y_tab.c' instead of `y.tab.c'.
(default_variables) [GCC_IS_NATIVE]: Set CC and CXX to `gcc', YACC to
`bison -y', and LEX to `flex'.
Part of MSDOS/GO32 port from DJ Delorie <dj@ctron.com>.
1994-07-25 22:54:09 +00:00
Roland McGrath
461cffc4e9 Initial revision 1994-07-25 22:48:06 +00:00
Roland McGrath
cdd25d1fb3 (fatal_error_signal) [__MSDOS__]: Just remove intermediates and exit.
Part of MSDOS/GO32 port from DJ Delorie <dj@ctron.com>.
1994-07-25 22:47:14 +00:00
Roland McGrath
9a3666d550 (set_file_variables): Add parens in length computation in .SUFFIXES dep
loop to quiet compiler warning.  From Jim Meyering.
1994-07-25 22:09:25 +00:00
Roland McGrath
90dffad2cc (read_makefile): Free FILENAME if we allocated it. From Jim Meyering. 1994-07-25 22:07:41 +00:00
Roland McGrath
c1f2ef6d09 Update ISBN number to 1-882114-50-7 for edition 0.46.
Use new macro ISBN set at top of file.
1994-07-20 12:30:52 +00:00
Roland McGrath
51250a676d Split a shell command line in @example to avoid overfull hbox. 1994-07-08 18:33:15 +00:00
Roland McGrath
d2461a2409 (Goals): Say that only first target in first rule is default goal.
(Archive Pitfalls): New node.
1994-07-05 21:27:09 +00:00
Roland McGrath
fdea69c5fa (selective_vpath_search): Use safe_stat in place of stat. 1994-07-04 21:56:24 +00:00
Roland McGrath
7c7552336d (construct_include_path): Use safe_stat in place of stat. 1994-07-04 21:55:13 +00:00
Roland McGrath
535dcf6a22 (search_path): Use safe_stat in place of stat. 1994-07-04 21:54:18 +00:00
Roland McGrath
84091971f9 (find_directory): Use safe_stat in place of stat. 1994-07-04 21:53:25 +00:00
Roland McGrath
61da194af9 (delete_target): Use safe_stat in place of stat. 1994-07-04 21:52:28 +00:00
Roland McGrath
30c1465265 (ar_member_touch) [EINTR]: Do EINTR looping around fstat. 1994-07-04 21:51:49 +00:00
Roland McGrath
b574b8ea5a (name_mtime): Use safe_stat in place of stat.
(touch_file) [EINTR]: Do EINTR looping around fstat.
1994-07-04 21:50:03 +00:00
Roland McGrath
710e8e6f6f (safe_stat): New function, EINTR-safe wrapper around stat. 1994-07-04 21:46:58 +00:00
Roland McGrath
4a8a7637f3 (read_makefile): Check for a shell command first, and then strip leading
tabs before further checking if it's not a shell command line.
1994-06-24 10:34:03 +00:00
Roland McGrath
6348923799 Fix typo in last change. 1994-06-24 10:22:37 +00:00
Roland McGrath
660a23d649 [__arm]: Undefine POSIX.
[!__GNU_LIBRARY__ && !POSIX && !_POSIX_VERSION]: Don't declare system
functions that return int.
1994-06-24 09:45:35 +00:00
Roland McGrath
5bd9836fba (construct_command_argv_internal): After swallowing a backslash-newline
combination, if INSTRING is set goto string_char (new label) for normal
INSTRING handling code.
1994-06-24 09:40:13 +00:00
Roland McGrath
0cb47363e1 Put #include of errno.h and decl of errno before #ifndef HAVE_GETLOADAVG. 1994-06-04 05:24:48 +00:00
Roland McGrath
fff5a9ece0 Don't check for sys_siglist and _sys_siglist with AC_HAVE_FUNCS.
Instead use two AC_COMPILE_CHECKs.
1994-06-04 05:11:12 +00:00
Richard M. Stallman
e3a24fc596 [emacs]: Block input around the garbage reclamation.
Include blockinput.h.
1994-06-02 17:45:40 +00:00
Roland McGrath
bb38b0c253 [!__GNU_LIBRARY__ && !POSIX]: Also test #ifndef _POSIX_VERSION for these
declarations.
1994-05-23 22:25:30 +00:00
Roland McGrath
d2ed03e72a [GETLOADAVG_PRIVILEGED] [POSIX]: Remove bogus #ifndefs around #undefs of
HAVE_SETREUID and HAVE_SETREGID.
1994-05-23 22:20:30 +00:00
Roland McGrath
e72213687f [GETLOADAVG_PRIVILEGED] [POSIX]: Don't test [HAVE_SETUID] and [HAVE_SETGID].
Every system has those, and configure doesn't check for them.
1994-05-21 20:28:10 +00:00
Roland McGrath
491d66a916 [_POSIX_VERSION]: Don't #define POSIX #ifdef ultrix. 1994-05-21 20:27:18 +00:00
Roland McGrath
f4fb1be3d8 (loadavg): Depend on and use loadavg.c instead of getloadavg.c.
(loadavg.c): Link or copy it from getloadavg.c.
(distclean): Remove loadavg.c.
1994-05-21 20:26:33 +00:00
Roland McGrath
10abeb4a08 (AC_MACRODIR): Don't define it.
[AC_MACRODIR]: Protect deps using it with ifdef.
1994-05-19 00:35:53 +00:00
Roland McGrath
a369402d11 Correct update date updated in last change. 1994-05-17 03:50:09 +00:00
Roland McGrath
fe3962cf54 Update update date for last change. 1994-05-17 03:46:27 +00:00
Roland McGrath
cf76b42f2b [GETLOADAVG_PRIVILEGED] [! POSIX]: Undefine HAVE_SETEUID and HAVE_SETEGID. 1994-05-17 03:09:02 +00:00
Roland McGrath
fb088e4526 (SCCS_GET_MINUS_G check): Put -G flag before file name. 1994-05-17 02:59:57 +00:00
Roland McGrath
f2804372bd (default_terminal_rules): In SCCS rules, put $(SCCS_OUTPUT_OPTION) before
$<.  On some systems -G is grokked only before the file name.
1994-05-17 02:58:49 +00:00
Roland McGrath
c25db14264 (Overriding Makefiles): Don't suggest using .DEFAULT; that loses if the
target file exists.  Instead recommend the combination of a match-anything
rule and a force target.
1994-05-11 01:42:43 +00:00
Roland McGrath
e83c7d40cd (construct_command_argv_internal): Swallow backslash-newline combinations
inside '' strings too.
1994-05-10 20:27:17 +00:00
Roland McGrath
65d0cd98a9 (do_define): Call collapse_continuations on each line before all else. 1994-05-05 08:15:00 +00:00
Roland McGrath
ec505152e0 (AC_MACRODIR): Change default back. 1994-05-02 23:45:18 +00:00
Roland McGrath
0d2488a804 Note that dirs in VPATH, vpath can be separated by blanks as well as
colons.
1994-05-02 23:00:39 +00:00
Roland McGrath
bc5f054132 (config.h.in): Use $(AC_MACRODIR) in dep. 1994-05-02 22:32:54 +00:00
Roland McGrath
e812d40f9f (AC_MACRODIR): Define if undefined.
(ACFLAGS, configure, config.h.in): Use that value.
1994-05-02 22:29:56 +00:00
Roland McGrath
b12c639bb2 (ARCH==hp300): Disabled customs. 1994-04-25 23:37:12 +00:00
Roland McGrath
dd841ded6f (construct_command_argv_internal): Notice newline inside '' string when
RESTP is non-null.
1994-04-25 23:31:55 +00:00
Roland McGrath
3c9e8b266a (update_goal_chain): Reset FILE to G->file after the double-colon loop so
it is never null for following code.
1994-04-22 21:58:26 +00:00
Roland McGrath
e6bce5ef88 (read_makefile): Fix `override define' parsing to skip whitespace after
`define' properly.
1994-04-22 21:57:47 +00:00
Roland McGrath
bdff21b09a (srcdir): Define as @srcdir@; don't reference $(VPATH).
(glob/Makefile): New target.
1994-04-22 21:33:25 +00:00
Roland McGrath
408e868fd2 (Using Variables): Fixed @xref node to `Automatic'. 1994-04-21 22:39:51 +00:00
Roland McGrath
cf63c0c966 (dist): Depend on rcs-mark first.
(rcs-mark): New target.
(rcs-mark-alpha, rcs-mark-beta): Use $(version-); append : to name for -N.
(version-): New variable, removes dots (RCS doesn't like) from $(version).
1994-04-21 22:35:15 +00:00
Roland McGrath
d2e496cc01 (Using Variables): Fix menu item to `Automatic'. 1994-04-21 22:23:37 +00:00
Roland McGrath
ac336f7a9c Undo last change; reverted to revision 1.22. 1994-04-21 22:14:01 +00:00
Roland McGrath
8f581d3bc0 (parse_file_seq): Fix typo in last change. Remove unused variable. 1994-04-21 21:28:59 +00:00
Roland McGrath
b2522ec319 (chop_commands): Fix braino in last change (failed to initialize IDX for
loop).
1994-04-21 21:28:02 +00:00
Roland McGrath
117d4e0f36 (remove_comments): Use find_char_unquote. 1994-04-21 21:18:04 +00:00
Roland McGrath
9b0a99a051 (find_char_unquote): Declare it. 1994-04-21 20:37:39 +00:00
Roland McGrath
5c807f5457 (find_char_unquote): New function, generalized from find_percent.
(find_percent, find_semicolon, parse_file_seq): Use that.
1994-04-21 20:36:47 +00:00
Roland McGrath
7eeab2fbe1 (chop_commands): Use find_char_unquote to find newlines. 1994-04-21 20:16:42 +00:00
Roland McGrath
f6716d5e74 (pattern_search): Always allocate new storage for FILE->stem.
It is not safe to store STEM's address because it might be auto storage.
1994-04-21 03:48:00 +00:00
Roland McGrath
be451f6d29 Check for seteuid and setegid. 1994-04-21 02:41:56 +00:00
Roland McGrath
eb0dbf1993 [HAVE_SETEUID]: Declare seteuid.
[HAVE_SETEGID]: Declare setegid.
(make_access, user_access) [HAVE_SETEUID]: Use seteuid.
[HAVE_SETEGID]: Use setegid.
1994-04-21 02:41:36 +00:00
Roland McGrath
5ebd380d7a Clarify -q exit status.
(Running): Enumerate possible exit status values (0, 1, 2).
1994-04-21 02:33:10 +00:00
Roland McGrath
cbfe6d75f6 (update_goal_chain): Set STATUS to FILE->update_status, to preserve whether
it's 2 for error or 1 for -q trigger.  When STATUS gets nonzero and -q is
set, always stop immediately.
1994-04-21 02:15:37 +00:00
Roland McGrath
716e804b5b (main, decode_switches): Die with 2 for errors.
(main): Accept 2 return from update_goal_chain and die with that.
1994-04-21 02:08:28 +00:00
Roland McGrath
4848c19870 (fatal, makefile_fatal): Die with 2; 1 is reserved for -q answer. 1994-04-21 02:01:24 +00:00
Roland McGrath
bca4e882ba (reap_children): Die with 2 for error.
(start_job_command): Set update_status to 2 for error.  Set it to 1 when we
would run a command and question_flag is set.
1994-04-21 02:00:20 +00:00
Roland McGrath
eb08818828 (read_makefile): Don't mark makefiles as precious. Just like other
targets, they can be left inconsistent and in need of remaking by aborted
commands.
1994-04-21 01:39:36 +00:00
Roland McGrath
b86e35d2a6 (Automatic Dependencies): Mention here that deps preclude intermediate files. 1994-04-21 01:35:11 +00:00
Roland McGrath
f5b14eee67 (Wildcard Pitfall): Fixed typo. 1994-04-21 01:21:39 +00:00
Roland McGrath
118439508b (Bugs): Take my bloody e-mail address out of the manual and tell them to
send misc. questions to the bug address.
1994-04-21 00:59:00 +00:00
Roland McGrath
f875c95115 (Archive Members): Don't say archive file must exist. Instead, in ar cmds
example, use `c' flag and mention it is needed if archive doesn't exist.
(Archive Update): Fix typo: foo.o -> file.o.
1994-04-21 00:55:18 +00:00
Roland McGrath
f2c10dedf0 (read_makefile): Write no error msg for -include file. 1994-04-20 22:42:32 +00:00
Roland McGrath
37c95f6d39 (dist-flavor): New variable, default to alpha.
(dist): Depend on rcs-mark-$(dist-flavor).
(rcs-mark-beta): New target.
1994-04-20 22:25:09 +00:00
Roland McGrath
22846c7022 (Using Variables): Add paragraph that xrefs to Automatic Variables.
Add Automatic Variables item to the menu.
1994-04-20 22:21:51 +00:00
Roland McGrath
fd025b9089 (fatal_error_signal): Don't unblock signals. 1994-04-06 01:17:43 +00:00
Roland McGrath
6dc8e442f2 (update_goal_chain): Do inner loop on double-colon entries.
(update_file): Use FILE->double_colon pointer to find all entries.
(f_mtime): Likewise.
(notice_finished_file): Propagate mtime change to all entries.
1994-04-05 10:37:12 +00:00
Roland McGrath
4e4b1ed670 (main): When disqualifying makefiles for updating, use double_colon pointer
to find all entries for a file.
1994-04-05 10:20:03 +00:00
Roland McGrath
3580cdedd8 (enter_file): If there is already a double-colon entry for the file, set
NEW->double_colon to that pointer.
(file_hash_enter): Use FILE->double_colon to find all entries to set name.
1994-04-05 10:17:01 +00:00
Roland McGrath
108cca9aa5 (record_files): Set double_colon pointer instead of flag. 1994-04-05 10:14:49 +00:00
Roland McGrath
98104e4d2e (try_variable_definition): Return after abort. 1994-04-05 10:09:28 +00:00
Roland McGrath
dc8983dc8b (struct file): Change member double_colon' from flag to struct file *'. 1994-04-05 09:22:13 +00:00
Roland McGrath
0513e29593 (read_makefile): Remove unused variable.
(parse_file_seq): When removing an elt that is just `)', properly fix up
the previous elt's next pointer.
1994-04-01 23:44:10 +00:00
Roland McGrath
087ef58502 Put $Id$ inside [] in AC_REVISION, since expansion contains a comma. 1994-03-29 00:23:41 +00:00
Roland McGrath
298a8363ff (rcs-mark-alpha): New target.
(dist): Depend on that.
1994-03-29 00:18:03 +00:00
Roland McGrath
ebe1ed2e49 (Makefile.in): Edit MAKE assignment into @SET_MAKE@. 1994-03-29 00:13:58 +00:00
Roland McGrath
6a7b0d623b Do AC_SET_MAKE. 1994-03-28 23:31:37 +00:00
Roland McGrath
f0c1a986db Added rcsid. 1994-03-28 22:58:08 +00:00
Roland McGrath
e7defc873b entered into RCS 1994-03-23 14:53:21 +00:00
Roland McGrath
4b4d5bcd0a Added rcs id. 1994-03-23 14:43:56 +00:00
Roland McGrath
d3fbc4f345 entered into RCS 1994-03-23 14:12:55 +00:00
Roland McGrath
227cffec2b entered into RCS 1994-03-04 05:36:26 +00:00
Roland McGrath
5d3189c952 Formerly read.c.~75~ 1994-03-04 05:10:22 +00:00
Roland McGrath
c71c43c0b5 Formerly misc.c.~31~ 1994-03-04 05:10:20 +00:00
Roland McGrath
1944def8db entered into RCS 1994-02-16 23:58:49 +00:00
Roland McGrath
4b7d940657 Formerly read.c.~74~ 1994-02-16 22:55:31 +00:00
Roland McGrath
d68bb0895b entered into RCS 1994-02-16 21:32:01 +00:00
Roland McGrath
29b051dc0c Formerly misc.c.~30~ 1994-02-16 21:25:32 +00:00
Roland McGrath
8e1432e250 Formerly main.c.~105~ 1994-02-16 21:13:16 +00:00
Roland McGrath
015d472119 entered into RCS 1994-02-16 21:09:47 +00:00
Roland McGrath
7aca4a343d entered into RCS 1994-02-12 00:16:20 +00:00
Roland McGrath
92c245ab98 entered into RCS 1994-02-11 02:45:27 +00:00
Roland McGrath
3bb79f5823 Formerly make.h.~82~ 1994-02-04 21:28:53 +00:00
Roland McGrath
554f67bc64 Formerly misc.c.~29~ 1994-02-03 07:21:18 +00:00
Roland McGrath
5ee9dc7472 Formerly variable.c.~27~ 1994-02-01 00:11:47 +00:00
Roland McGrath
bb55335906 Formerly read.c.~73~ 1994-02-01 00:07:17 +00:00
Roland McGrath
b5665419ba Formerly variable.c.~26~ 1994-01-26 00:48:30 +00:00
Roland McGrath
7f534ea595 Formerly make.texinfo.~127~ 1994-01-26 00:47:07 +00:00
Roland McGrath
23e64a0b13 Formerly commands.c.~20~ 1994-01-25 21:51:25 +00:00
Roland McGrath
1c0df127f8 Formerly make.texinfo.~126~ 1994-01-19 23:04:36 +00:00
Roland McGrath
68a5f2a17a Formerly make.texinfo.~125~ 1994-01-17 22:06:11 +00:00
Roland McGrath
50bb35c3e3 Formerly default.c.~32~ 1994-01-17 22:05:22 +00:00
Roland McGrath
fc99c2260b Formerly GNUmakefile.~116~ 1994-01-12 00:30:18 +00:00
Roland McGrath
f178779347 Formerly GNUmakefile.~115~ 1994-01-07 21:28:25 +00:00
Roland McGrath
90829c3577 entered into RCS 1994-01-07 21:27:29 +00:00
Roland McGrath
7c1f91ced2 Formerly main.c.~104~ 1994-01-06 23:12:09 +00:00
Roland McGrath
b4ccaac8da Formerly compatMakefile.~87~ 1994-01-06 23:11:22 +00:00
Roland McGrath
2932fb1bca Formerly read.c.~72~ 1993-12-23 22:56:05 +00:00
Roland McGrath
db98fe95a4 Formerly GNUmakefile.~113~ 1993-12-23 20:41:21 +00:00
Roland McGrath
66784463c0 Formerly configure.in.~32~ 1993-12-23 19:46:50 +00:00
Roland McGrath
fe450df425 Formerly vpath.c.~15~ 1993-12-23 04:42:29 +00:00
Roland McGrath
c9f149173f Formerly GNUmakefile.~112~ 1993-12-22 22:18:14 +00:00
Roland McGrath
9ee5e4d17d Formerly configure.in.~31~ 1993-12-22 22:00:41 +00:00
Roland McGrath
96d67bce90 Formerly configure.in.~30~ 1993-12-17 20:31:32 +00:00
Roland McGrath
a0ab37fcd6 Formerly arscan.c.~32~ 1993-12-16 23:24:39 +00:00
Roland McGrath
65b8056203 Formerly main.c.~103~ 1993-12-16 20:10:36 +00:00
Roland McGrath
4f752036ac Formerly main.c.~102~ 1993-12-15 22:49:45 +00:00
Roland McGrath
b8c55666a7 Formerly make.texinfo.~124~ 1993-12-15 00:33:30 +00:00
Roland McGrath
08e7a4fcdd Formerly configure.in.~29~ 1993-12-14 23:06:56 +00:00
Roland McGrath
386d0a7ffc Formerly make.texinfo.~123~ 1993-12-14 22:16:38 +00:00
Roland McGrath
c33908dea5 Formerly default.c.~31~ 1993-12-14 21:59:57 +00:00
Roland McGrath
1bc63e8cc7 Formerly configure.in.~28~ 1993-12-14 21:56:50 +00:00
Roland McGrath
ad87633b72 entered into RCS 1993-12-14 21:50:51 +00:00
Roland McGrath
21eecea26d Formerly ar.c.~6~ 1993-12-14 21:06:33 +00:00
Roland McGrath
d519e2c19b Formerly read.c.~71~ 1993-12-14 20:09:51 +00:00
Roland McGrath
cf9bc4ae2f Formerly file.c.~27~ 1993-12-14 19:36:43 +00:00
Roland McGrath
2a19159394 Formerly vpath.c.~14~ 1993-12-14 19:28:59 +00:00
Roland McGrath
8e73c0981b Formerly configure.in.~27~ 1993-12-03 21:40:28 +00:00
Roland McGrath
f935610ca9 Formerly read.c.~70~ 1993-12-02 20:44:03 +00:00
Roland McGrath
12113c5925 Formerly misc.c.~28~ 1993-12-02 20:37:46 +00:00
Roland McGrath
63160928cd Formerly GNUmakefile.~111~ 1993-11-11 16:51:19 +00:00
Roland McGrath
48fe766053 Formerly default.c.~30~ 1993-11-11 16:47:27 +00:00
Roland McGrath
acd7330a5f Formerly read.c.~69~ 1993-11-10 11:06:04 +00:00
Roland McGrath
78454538f9 entered into RCS 1993-11-03 13:06:04 +00:00
Roland McGrath
a7bafcee76 Formerly make.texinfo.~122~ 1993-11-03 12:21:47 +00:00
Roland McGrath
4394c7a32d entered into RCS 1993-11-03 11:56:26 +00:00
Roland McGrath
38abf5e6c4 Formerly function.c.~31~ 1993-10-29 21:50:48 +00:00
Roland McGrath
58c146fa50 Formerly compatMakefile.~86~ 1993-10-29 20:47:10 +00:00
Roland McGrath
e612cccef3 Formerly make.h.~81~ 1993-10-28 00:09:14 +00:00
Roland McGrath
960650331a Formerly file.h.~6~ 1993-10-27 22:23:18 +00:00
Roland McGrath
462e175970 Formerly main.c.~101~ 1993-10-27 22:14:41 +00:00
Roland McGrath
a1749c85c8 Formerly remake.c.~52~ 1993-10-27 22:14:26 +00:00
Roland McGrath
c727af1bcc Formerly main.c.~100~ 1993-10-26 23:55:04 +00:00
Roland McGrath
8cb881fa9e Formerly remake.c.~51~ 1993-10-26 23:45:32 +00:00
Roland McGrath
3aeb946943 Formerly read.c.~68~ 1993-10-25 19:25:17 +00:00
Roland McGrath
9012e6a254 Formerly GNUmakefile.~110~ 1993-10-25 19:11:46 +00:00
Roland McGrath
251b0fc75f Formerly main.c.~99~ 1993-10-25 18:52:25 +00:00
Roland McGrath
f7a6c58f5b Formerly configure.in.~26~ 1993-10-22 06:56:46 +00:00
Roland McGrath
0ddf761563 entered into RCS 1993-10-21 20:48:08 +00:00
Roland McGrath
58d81fe699 Formerly make.texinfo.~121~ 1993-10-21 20:02:11 +00:00
Roland McGrath
4daf275edd Formerly make.texinfo.~120~ 1993-10-20 05:46:21 +00:00
Roland McGrath
d27b2c3de5 Formerly configure.in.~25~ 1993-10-18 11:15:08 +00:00
Roland McGrath
7c456a7368 Formerly rule.c.~16~ 1993-10-18 11:04:04 +00:00
Roland McGrath
a8c24526e3 Formerly file.c.~26~ 1993-10-18 11:01:37 +00:00
Roland McGrath
9e7e303ac8 Formerly make.h.~80~ 1993-10-14 22:29:26 +00:00
Roland McGrath
a3d7dfa85c Formerly default.c.~29~ 1993-10-14 22:25:17 +00:00
Roland McGrath
88054f8ad3 Formerly main.c.~98~ 1993-10-14 22:23:39 +00:00
Roland McGrath
f5e7fb8ea0 Formerly job.h.~6~ 1993-10-14 21:27:29 +00:00
Roland McGrath
7cb595fc60 Formerly compatMakefile.~85~ 1993-10-14 21:04:51 +00:00
Roland McGrath
4cbe738cfb Formerly make.h.~79~ 1993-10-14 19:08:38 +00:00
Roland McGrath
0f83ab90e3 entered into RCS 1993-10-14 19:08:36 +00:00
Roland McGrath
0e15559bbf Formerly GNUmakefile.~109~ 1993-10-11 23:47:29 +00:00
Jim Meyering
eaba9405d7 entered into RCS 1993-10-08 00:11:55 +00:00
Roland McGrath
492f92b9ec *** empty log message *** 1993-10-03 19:33:04 +00:00
Roland McGrath
cc5be7c0cd Formerly default.c.~28~ 1993-10-03 19:15:29 +00:00
Roland McGrath
f8300f1e1c Formerly main.c.~97~ 1993-09-28 18:20:17 +00:00
Roland McGrath
7f71af7974 Formerly job.c.~110~ 1993-09-28 18:18:15 +00:00
Roland McGrath
065ac461c5 Formerly job.c.~109~ 1993-09-20 22:33:18 +00:00
Roland McGrath
f8c3e52b0f Formerly main.c.~96~ 1993-09-20 22:05:19 +00:00
Richard M. Stallman
1775c102ad entered into RCS 1993-09-20 20:03:30 +00:00
Roland McGrath
2a53aecb26 entered into RCS 1993-09-20 20:03:20 +00:00
Roland McGrath
3087dcdb2e *** empty log message *** 1993-09-20 20:02:01 +00:00
Roland McGrath
5174a5e5a1 Formerly make.texinfo.~119~ 1993-09-17 07:33:03 +00:00
Roland McGrath
b018db955c Formerly remake.c.~50~ 1993-09-17 04:51:21 +00:00
Roland McGrath
0da218acc1 Formerly make.h.~78~ 1993-09-17 04:49:17 +00:00
Roland McGrath
9fc36f7358 Formerly commands.c.~19~ 1993-09-17 04:46:36 +00:00
Roland McGrath
ec2751c045 Formerly job.c.~108~ 1993-09-17 04:37:54 +00:00
Roland McGrath
7b91e889b6 *** empty log message *** 1993-09-10 04:22:01 +00:00
Roland McGrath
16667d15e0 Formerly main.c.~95~ 1993-09-09 00:14:18 +00:00
Roland McGrath
b9337d3143 Formerly make.texinfo.~118~ 1993-09-06 23:34:51 +00:00
Roland McGrath
2bf7e9bcda Formerly make.texinfo.~117~ 1993-08-30 16:36:35 +00:00
Roland McGrath
b24a026b02 entered into RCS 1993-08-30 16:31:47 +00:00
Roland McGrath
0ef3708713 *** empty log message *** 1993-08-25 21:46:19 +00:00
Roland McGrath
2012e2877c Formerly make.texinfo.~116~ 1993-08-19 21:03:38 +00:00
Roland McGrath
ba45b6e5fa Formerly make.h.~77~ 1993-08-19 20:36:09 +00:00
Roland McGrath
308e6149e6 Formerly main.c.~94~ 1993-08-19 20:36:08 +00:00
Roland McGrath
cbbf3ee5ef Formerly variable.c.~25~ 1993-08-19 20:36:05 +00:00
Roland McGrath
8171a9ba6e Formerly read.c.~67~ 1993-08-18 19:01:46 +00:00
Roland McGrath
8788690192 Formerly GNUmakefile.~108~ 1993-08-16 21:40:16 +00:00
Roland McGrath
769061023a Formerly compatMakefile.~84~ 1993-08-16 21:39:37 +00:00
Roland McGrath
ba2c317cb7 Formerly configure.in.~24~ 1993-08-16 21:34:26 +00:00
Roland McGrath
aea1502a78 *** empty log message *** 1993-08-16 19:10:25 +00:00
Roland McGrath
9dcfb711c1 *** empty log message *** 1993-08-12 22:17:13 +00:00
Roland McGrath
4d8fff0ec0 Formerly make.h.~76~ 1993-08-12 21:19:12 +00:00
Roland McGrath
3c954a048b Formerly job.c.~107~ 1993-08-11 20:16:45 +00:00
Roland McGrath
2f8d1abe7c Formerly main.c.~93~ 1993-08-11 20:04:39 +00:00
Roland McGrath
d2654362c5 Formerly variable.c.~24~ 1993-08-11 20:04:34 +00:00
Roland McGrath
1bafe5ed81 Formerly job.c.~106~ 1993-08-11 19:32:02 +00:00
Roland McGrath
869ec1b877 *** empty log message *** 1993-08-11 07:27:10 +00:00
Roland McGrath
3cc0c7306a Formerly main.c.~92~ 1993-08-11 06:59:04 +00:00
Roland McGrath
c52575a837 Formerly main.c.~91~ 1993-08-11 06:54:23 +00:00
Roland McGrath
6d00f337e5 Formerly function.c.~30~ 1993-08-11 06:35:19 +00:00
Richard M. Stallman
b6e638af6d *** empty log message *** 1993-08-10 21:27:23 +00:00
Roland McGrath
5fc2539281 Formerly job.c.~105~ 1993-08-09 22:25:00 +00:00
Roland McGrath
0bab40c121 Formerly remote-stub.c.~3~ 1993-08-09 22:21:56 +00:00
Roland McGrath
8980e49036 Formerly function.c.~29~ 1993-08-09 22:11:17 +00:00
Roland McGrath
84b4d9cce4 Formerly compatMakefile.~83~ 1993-08-03 23:18:21 +00:00
Roland McGrath
92a67d1895 Formerly dep.h.~6~ 1993-08-03 04:18:56 +00:00
Roland McGrath
22cd0cd4e3 Formerly compatMakefile.~82~ 1993-08-02 20:49:11 +00:00
Roland McGrath
e75d998e50 *** empty log message *** 1993-08-02 20:48:12 +00:00
Roland McGrath
ae087fbb2f *** empty log message *** 1993-08-01 23:03:26 +00:00
Roland McGrath
714aeaf857 Formerly make.texinfo.~115~ 1993-08-01 22:32:20 +00:00
Roland McGrath
cbeeeafde9 *** empty log message *** 1993-08-01 20:39:38 +00:00
Roland McGrath
572856fa8f entered into RCS 1993-08-01 20:28:14 +00:00
Roland McGrath
1d9b68aef5 Formerly compatMakefile.~81~ 1993-08-01 20:17:31 +00:00
Roland McGrath
e813da324d Formerly misc.c.~27~ 1993-08-01 20:03:45 +00:00
Roland McGrath
b018243a45 Formerly compatMakefile.~80~ 1993-07-30 20:55:50 +00:00
Roland McGrath
9326e8fec5 Formerly compatMakefile.~79~ 1993-07-30 05:29:32 +00:00
Roland McGrath
5cf5f261d9 Formerly configure.in.~23~ 1993-07-30 03:37:40 +00:00
Roland McGrath
e22a936ca5 *** empty log message *** 1993-07-30 03:20:49 +00:00
Roland McGrath
9f33e6cdcb *** empty log message *** 1993-07-27 00:37:13 +00:00
Roland McGrath
16777bbe0f entered into RCS 1993-07-26 20:20:46 +00:00
Roland McGrath
e851ef2303 Initial revision 1993-07-26 20:20:42 +00:00
Roland McGrath
1681a1f29a Formerly make.texinfo.~114~ 1993-07-26 19:10:51 +00:00
melissa
acb8140655 Formerly make.texinfo.~113~ 1993-07-26 18:27:27 +00:00
Roland McGrath
245d0b3772 *** empty log message *** 1993-07-26 17:37:11 +00:00
Roland McGrath
96fb58e401 Formerly compatMakefile.~78~ 1993-07-26 02:23:47 +00:00
Roland McGrath
02d19fe9c1 Formerly GNUmakefile.~107~ 1993-07-26 02:12:47 +00:00
Roland McGrath
32b80e7367 Formerly make.texinfo.~112~ 1993-07-25 21:08:39 +00:00
Roland McGrath
7c30adcd57 Formerly make.texinfo.~111~ 1993-07-23 22:07:42 +00:00
Roland McGrath
8153755c17 Formerly make.h.~75~ 1993-07-23 20:04:37 +00:00
Roland McGrath
2a983b8ead Formerly configure.in.~22~ 1993-07-23 20:04:35 +00:00
Roland McGrath
bd395b5c02 Formerly make.texinfo.~110~ 1993-07-22 21:35:45 +00:00
Roland McGrath
d24f1f2330 Formerly make.texinfo.~109~ 1993-07-16 22:14:09 +00:00
Roland McGrath
cace096aba Formerly make.texinfo.~108~ 1993-07-15 02:31:03 +00:00
Roland McGrath
f0929a13c3 Formerly read.c.~66~ 1993-07-15 02:25:00 +00:00
Roland McGrath
7a031cd4b2 Formerly variable.c.~23~ 1993-07-15 01:59:03 +00:00
Roland McGrath
fc8fa16253 Formerly variable.c.~22~ 1993-07-15 00:22:56 +00:00
Roland McGrath
ca3b88c66a Formerly function.c.~28~ 1993-07-15 00:22:55 +00:00
Roland McGrath
f7f63b75b5 Formerly make.texinfo.~107~ 1993-07-14 23:54:44 +00:00
Roland McGrath
250e638f44 Formerly read.c.~65~ 1993-07-14 23:04:39 +00:00
Roland McGrath
0a0130dcf2 Formerly dep.h.~5~ 1993-07-14 22:56:42 +00:00
Roland McGrath
aef2a1ccd0 Formerly main.c.~90~ 1993-07-14 22:56:38 +00:00
Jim Meyering
2ef2fbe7a4 *** empty log message *** 1993-07-13 16:37:01 +00:00
Roland McGrath
c3b30f576d Formerly make.h.~74~ 1993-07-13 02:42:59 +00:00
David J. MacKenzie
c2cc8e33fb *** empty log message *** 1993-07-12 22:13:12 +00:00
Roland McGrath
af7ef68647 Formerly make.texinfo.~106~ 1993-07-09 18:02:38 +00:00
Roland McGrath
9a6b8d1015 Formerly vpath.c.~13~ 1993-07-09 01:30:13 +00:00
Roland McGrath
3296fa1dff Formerly rule.c.~15~ 1993-07-09 01:22:33 +00:00
Roland McGrath
5a4a5d3160 Formerly make.h.~73~ 1993-07-08 23:51:22 +00:00
David J. MacKenzie
3a511f5874 *** empty log message *** 1993-07-06 23:07:30 +00:00
Roland McGrath
2b8f817cfb Formerly GNUmakefile.~106~ 1993-07-01 03:36:40 +00:00
Roland McGrath
7789ea8a3c Formerly implicit.c.~14~ 1993-06-30 23:04:21 +00:00
Roland McGrath
5003c9b26b Formerly rule.h.~5~ 1993-06-30 22:42:37 +00:00
Roland McGrath
d92b741fce Formerly rule.c.~14~ 1993-06-30 22:40:50 +00:00
Roland McGrath
aa68ee5ce2 Formerly file.c.~25~ 1993-06-30 22:11:36 +00:00
Roland McGrath
26c6ec1893 Formerly make.texinfo.~103~ 1993-06-30 20:07:02 +00:00
Roland McGrath
86d4d7425b Formerly job.c.~104~ 1993-06-25 20:03:56 +00:00
Roland McGrath
f84518396b Formerly read.c.~64~ 1993-06-25 20:03:54 +00:00
Roland McGrath
2e0e3d22ec Formerly vpath.c.~12~ 1993-06-25 20:03:51 +00:00
Roland McGrath
d3fc910b29 Formerly make.texinfo.~102~ 1993-06-25 19:47:50 +00:00
Roland McGrath
9c32a4c3cd Formerly main.c.~89~ 1993-06-25 19:47:20 +00:00
Roland McGrath
54462c9590 Formerly make.h.~72~ 1993-06-25 19:20:49 +00:00
Roland McGrath
ae112a5cb5 Formerly expand.c.~9~ 1993-06-25 19:20:36 +00:00
Roland McGrath
4ac6d66244 Formerly default.c.~27~ 1993-06-25 18:59:05 +00:00
melissa
08c71a7dbf Formerly make.texinfo.~101~ 1993-06-24 21:21:03 +00:00
Roland McGrath
5b5415bf87 Formerly make.texinfo.~100~ 1993-06-22 06:02:26 +00:00
Roland McGrath
f64cd37b29 Formerly default.c.~26~ 1993-06-21 21:56:36 +00:00
Roland McGrath
8bd226777e Formerly compatMakefile.~77~ 1993-06-11 18:42:04 +00:00
Roland McGrath
e176cf73a5 Formerly read.c.~63~ 1993-06-10 22:20:53 +00:00
Roland McGrath
d66f4e3407 Formerly ar.c.~5~ 1993-06-10 22:13:54 +00:00
Roland McGrath
4abb5e433f Formerly make.texinfo.~99~ 1993-06-10 21:56:37 +00:00
Roland McGrath
46a5b5adcc Formerly make.texinfo.~98~ 1993-06-10 01:52:27 +00:00
Roland McGrath
4694e31659 Formerly ar.c.~4~ 1993-06-10 01:43:06 +00:00
Roland McGrath
3d6b586776 Formerly read.c.~62~ 1993-06-10 01:31:02 +00:00
Roland McGrath
c4cc2ec376 Formerly dep.h.~4~ 1993-06-10 00:18:21 +00:00
Roland McGrath
4a94240844 Formerly rule.c.~13~ 1993-06-09 23:16:30 +00:00
Roland McGrath
6fc0ab541e Formerly default.c.~25~ 1993-06-09 23:16:28 +00:00
Roland McGrath
5b4a918d26 Formerly function.c.~27~ 1993-06-09 23:16:25 +00:00
Roland McGrath
bd3309f09b Formerly GNUmakefile.~105~ 1993-06-09 22:06:20 +00:00
Roland McGrath
122c9699fa *** empty log message *** 1993-06-09 20:28:35 +00:00
Roland McGrath
e2f08f5dbf Formerly make.texinfo.~97~ 1993-06-09 17:45:57 +00:00
Jim Blandy
7089c07d4e *** empty log message *** 1993-06-09 09:23:12 +00:00
Roland McGrath
f363e41c27 Formerly read.c.~61~ 1993-06-08 00:36:13 +00:00
Roland McGrath
24cd5ede9e Formerly compatMakefile.~76~ 1993-06-08 00:24:19 +00:00
Roland McGrath
f4fac65746 Formerly main.c.~88~ 1993-06-08 00:08:45 +00:00
Roland McGrath
f6b549870a Formerly dep.h.~3~ 1993-06-07 23:28:51 +00:00
Roland McGrath
074d147ef7 Formerly main.c.~87~ 1993-06-04 19:53:32 +00:00
Roland McGrath
55f5d979ae Formerly main.c.~86~ 1993-06-04 00:27:28 +00:00
Roland McGrath
00dc97cb8a Formerly implicit.c.~13~ 1993-06-04 00:15:12 +00:00
Roland McGrath
9766fe1775 Formerly main.c.~85~ 1993-06-03 20:56:33 +00:00
Roland McGrath
b5fb6b260e Formerly GNUmakefile.~104~ 1993-06-03 20:47:55 +00:00
Roland McGrath
6382676838 Formerly read.c.~60~ 1993-06-02 21:42:39 +00:00
Roland McGrath
14f2b39dff Formerly GNUmakefile.~103~ 1993-06-02 21:09:00 +00:00
Roland McGrath
9697738544 entered into RCS 1993-06-02 20:56:37 +00:00
Roland McGrath
4a9fdcd65f Formerly file.c.~24~ 1993-06-02 20:51:35 +00:00
Roland McGrath
80091295df Formerly main.c.~84~ 1993-06-02 20:51:28 +00:00
Roland McGrath
3c11aba3cd Formerly compatMakefile.~75~ 1993-05-31 22:48:16 +00:00
Roland McGrath
54fb272967 Formerly implicit.c.~12~ 1993-05-27 21:34:50 +00:00
Roland McGrath
e12d722d99 Formerly make.texinfo.~96~ 1993-05-26 21:21:42 +00:00
Roland McGrath
8a5a2b9b8d Formerly make.texinfo.~95~ 1993-05-26 18:41:58 +00:00
Roland McGrath
0246a6dc63 Formerly main.c.~83~ 1993-05-26 18:33:12 +00:00
Richard M. Stallman
60c868c193 *** empty log message *** 1993-05-25 00:43:37 +00:00
Roland McGrath
1e71bdd085 Formerly make.texinfo.~94~ 1993-05-25 00:00:35 +00:00
Roland McGrath
b0a9db44b6 Formerly rule.c.~12~ 1993-05-24 23:02:13 +00:00
Roland McGrath
f846c07d43 *** empty log message *** 1993-05-24 21:41:18 +00:00
Roland McGrath
dfc8da6e0e Formerly compatMakefile.~74~ 1993-05-24 20:17:29 +00:00
Jim Blandy
8960f971ca *** empty log message *** 1993-05-24 15:57:15 +00:00
Roland McGrath
ff71fe9277 Formerly file.c.~23~ 1993-05-22 20:24:37 +00:00
Roland McGrath
fe92d8e656 Formerly main.c.~82~ 1993-05-22 20:20:16 +00:00
Jim Blandy
f0080188b7 *** empty log message *** 1993-05-21 23:39:17 +00:00
Roland McGrath
5a55f43ddc Formerly compatMakefile.~73~ 1993-05-21 22:15:48 +00:00
Roland McGrath
63b6de85b5 Formerly GNUmakefile.~102~ 1993-05-21 17:36:32 +00:00
Roland McGrath
29acbbea8d Initial revision 1993-05-20 20:22:34 +00:00
Roland McGrath
e66d29867e Formerly compatMakefile.~72~ 1993-05-20 01:30:41 +00:00
Roland McGrath
0bcabeb134 Formerly read.c.~59~ 1993-05-19 21:15:51 +00:00
Roland McGrath
e90a315ebe entered into RCS 1993-05-19 17:56:38 +00:00
Roland McGrath
b06b92566c Formerly make.texinfo.~93~ 1993-05-17 00:24:00 +00:00
Roland McGrath
8aa529e55e Formerly vpath.c.~11~ 1993-05-14 23:09:34 +00:00
Roland McGrath
03acd42408 Formerly dir.c.~12~ 1993-05-14 22:41:07 +00:00
Roland McGrath
bc0276c3cb Formerly read.c.~58~ 1993-05-14 22:25:11 +00:00
Roland McGrath
3d952e5879 Formerly main.c.~81~ 1993-05-14 21:50:11 +00:00
Roland McGrath
3f15ef960a Formerly make.texinfo.~92~ 1993-05-14 21:50:07 +00:00
Roland McGrath
fa67064dc6 Formerly make.h.~71~ 1993-05-14 20:40:38 +00:00
Roland McGrath
5340230f6b Formerly README.template.~5~ 1993-05-12 21:22:14 +00:00
Roland McGrath
7162378126 Formerly arscan.c.~31~ 1993-05-12 21:05:03 +00:00
Roland McGrath
534926ac7a Formerly function.c.~26~ 1993-05-12 19:44:41 +00:00
Roland McGrath
5580266222 Formerly configure.in.~21~ 1993-05-12 19:24:14 +00:00
Roland McGrath
6c6f210456 Formerly job.c.~103~ 1993-05-12 19:20:45 +00:00
Jim Meyering
c5c92b71ce Initial revision 1993-05-11 23:23:34 +00:00
Roland McGrath
369bb2a609 Formerly function.c.~25~ 1993-05-07 22:34:49 +00:00
Roland McGrath
5c82e72caa Formerly commands.c.~18~ 1993-05-06 21:30:42 +00:00
Roland McGrath
ca5b7c487d Formerly make.h.~70~ 1993-05-06 21:30:40 +00:00
Roland McGrath
9596950898 Formerly job.c.~102~ 1993-05-06 21:30:10 +00:00
Roland McGrath
29de1a7e5a Formerly expand.c.~8~ 1993-05-06 21:14:33 +00:00
Roland McGrath
f1daf67200 Formerly read.c.~57~ 1993-05-03 21:14:22 +00:00
Roland McGrath
e8c11d4e32 Formerly arscan.c.~30~ 1993-05-03 21:03:37 +00:00
Roland McGrath
481e0e7d22 Formerly arscan.c.~29~ 1993-04-30 01:08:30 +00:00
Roland McGrath
2b81718876 Formerly ar.c.~3~ 1993-04-29 23:57:58 +00:00
Roland McGrath
6ee7823efe Formerly job.c.~101~ 1993-04-29 01:20:37 +00:00
Roland McGrath
683e4a5de9 Formerly arscan.c.~28~ 1993-04-26 20:43:32 +00:00
Roland McGrath
548b4c9bf1 Formerly make.h.~69~ 1993-04-26 20:07:49 +00:00
Roland McGrath
fba3960a6a Formerly main.c.~80~ 1993-04-26 20:05:02 +00:00
Roland McGrath
0986bb2c43 Formerly GNUmakefile.~100~ 1993-04-22 22:42:00 +00:00
Roland McGrath
5532d1d11d Formerly make.texinfo.~91~ 1993-04-19 19:42:09 +00:00
Roland McGrath
dab0d4214e Formerly compatMakefile.~71~ 1993-04-16 20:11:42 +00:00
Roland McGrath
088a491f10 Formerly GNUmakefile.~99~ 1993-04-16 18:41:16 +00:00
Roland McGrath
681f7a3067 Formerly make.texinfo.~90~ 1993-04-16 18:26:18 +00:00
Roland McGrath
ada4528484 Formerly configure.in.~20~ 1993-04-16 00:54:50 +00:00
Roland McGrath
1386d961a9 Formerly default.c.~24~ 1993-04-16 00:54:40 +00:00
Roland McGrath
828b45420a Initial revision 1993-04-16 00:51:27 +00:00
Roland McGrath
e9f008dc04 Formerly misc.c.~26~ 1993-04-15 22:42:20 +00:00
Roland McGrath
44ecfc2f36 Formerly read.c.~56~ 1993-04-15 22:30:01 +00:00
Roland McGrath
e28495225d Formerly rule.c.~11~ 1993-04-15 22:29:57 +00:00
Roland McGrath
c190a98796 Formerly function.c.~24~ 1993-04-15 22:29:47 +00:00
Roland McGrath
a03f503fb7 Formerly misc.c.~25~ 1993-04-14 20:43:53 +00:00
Roland McGrath
04789f11cd Formerly make.texinfo.~89~ 1993-04-14 19:44:21 +00:00
Roland McGrath
f02ced5786 Formerly main.c.~79~ 1993-04-14 18:20:33 +00:00
Roland McGrath
2fae4442e2 Formerly make.h.~68~ 1993-04-14 17:34:15 +00:00
Roland McGrath
f138f0eeff Formerly job.c.~100~ 1993-04-14 17:22:35 +00:00
Roland McGrath
ea1e49e5a8 Formerly default.c.~23~ 1993-04-14 15:32:26 +00:00
Roland McGrath
9bd8004ded Formerly make.texinfo.~88~ 1993-04-12 21:11:48 +00:00
Roland McGrath
596d50cb1c Formerly arscan.c.~27~ 1993-04-12 20:52:46 +00:00
Roland McGrath
48f4ce2825 Formerly remake.c.~49~ 1993-04-12 20:52:45 +00:00
Roland McGrath
d8b7640a81 Formerly dir.c.~11~ 1993-04-12 20:51:44 +00:00
Roland McGrath
8c01d0459a Formerly main.c.~78~ 1993-04-12 20:51:42 +00:00
Roland McGrath
e4dce6fa11 Formerly configure.in.~19~ 1993-04-12 20:51:39 +00:00
Roland McGrath
7831181410 Formerly make.h.~67~ 1993-04-12 20:51:32 +00:00
Roland McGrath
2cc84f7c97 Formerly variable.c.~21~ 1993-04-12 20:02:24 +00:00
Roland McGrath
5136f317d2 Formerly default.c.~22~ 1993-04-12 19:58:26 +00:00
Roland McGrath
ae7b53245a Formerly make.texinfo.~87~ 1993-04-11 22:26:07 +00:00
Roland McGrath
542a0f8112 Formerly main.c.~77~ 1993-04-08 22:14:23 +00:00
Roland McGrath
2ed0333f3c Formerly job.c.~99~ 1993-04-08 22:08:11 +00:00
Roland McGrath
791928d60b Formerly job.c.~98~ 1993-04-07 21:10:12 +00:00
Roland McGrath
de21395cad Formerly make.texinfo.~86~ 1993-04-07 20:44:43 +00:00
Roland McGrath
5973c4e97a Formerly main.c.~76~ 1993-04-07 20:40:35 +00:00
Roland McGrath
6dbdf2caa8 Formerly compatMakefile.~70~ 1993-04-07 19:31:50 +00:00
Roland McGrath
6ed99f4d40 Formerly configure.in.~18~ 1993-04-06 00:58:10 +00:00
Roland McGrath
3f0a207eaf Formerly job.c.~97~ 1993-04-06 00:21:23 +00:00
Roland McGrath
07c6b685b7 Formerly main.c.~75~ 1993-04-02 22:16:47 +00:00
Roland McGrath
0c1c2ff3d0 Formerly GNUmakefile.~98~ 1993-03-29 19:30:33 +00:00
Roland McGrath
d1a988ce9f Formerly GNUmakefile.~97~ 1993-03-28 22:36:05 +00:00
Roland McGrath
ae1278315f Formerly compatMakefile.~69~ 1993-03-28 22:06:13 +00:00
Roland McGrath
164dcdad22 Formerly vpath.c.~10~ 1993-03-24 20:13:56 +00:00
Roland McGrath
f3bd744187 Formerly make.texinfo.~85~ 1993-03-24 19:29:31 +00:00
Roland McGrath
722018bdbe Formerly variable.c.~20~ 1993-03-24 19:27:11 +00:00
Roland McGrath
bfe005e8a0 Formerly GNUmakefile.~96~ 1993-03-18 01:34:17 +00:00
Roland McGrath
f9b50f6436 Formerly main.c.~74~ 1993-03-18 01:02:20 +00:00
Roland McGrath
28c125b725 Formerly compatMakefile.~68~ 1993-03-12 20:54:25 +00:00
Roland McGrath
ab9034ef4e Formerly compatMakefile.~67~ 1993-03-11 19:25:31 +00:00
Roland McGrath
19c3ead040 Formerly configure.in.~17~ 1993-03-11 19:25:28 +00:00
Roland McGrath
63b17f1d63 Formerly GNUmakefile.~95~ 1993-03-11 19:25:25 +00:00
Roland McGrath
3e9cf581d1 entered into RCS 1993-03-11 19:25:21 +00:00
Roland McGrath
e7b737dc5e Formerly GNUmakefile.~94~ 1993-03-10 22:56:43 +00:00
Roland McGrath
1a56335cbf Formerly implicit.c.~11~ 1993-03-10 20:41:03 +00:00
Roland McGrath
4b30933904 Formerly file.c.~22~ 1993-03-10 20:24:57 +00:00
Roland McGrath
094f89cee5 Formerly make.texinfo.~84~ 1993-03-08 21:54:29 +00:00
Roland McGrath
36a66b6bec Formerly remake.c.~48~ 1993-03-08 20:04:20 +00:00
Roland McGrath
69105addb4 Formerly compatMakefile.~66~ 1993-03-08 19:50:11 +00:00
Roland McGrath
e4c66e2f88 Formerly read.c.~55~ 1993-03-08 18:50:09 +00:00
Roland McGrath
d5ef06dee5 Formerly main.c.~73~ 1993-03-08 18:49:51 +00:00
Roland McGrath
7c675f86e6 Formerly make.man.~4~ 1993-03-08 18:38:35 +00:00
Roland McGrath
60a76e0d39 Formerly compatMakefile.~65~ 1993-02-22 19:19:33 +00:00
Roland McGrath
c88072ca74 Formerly implicit.c.~10~ 1993-02-21 22:03:38 +00:00
Roland McGrath
a609f1f9c2 Formerly rule.c.~10~ 1993-02-21 21:58:43 +00:00
Roland McGrath
2413679845 Formerly rule.h.~4~ 1993-02-21 21:56:09 +00:00
Roland McGrath
b50f2fc0a6 Formerly commands.c.~17~ 1993-02-21 20:05:54 +00:00
Roland McGrath
4034f2bdfb Formerly compatMakefile.~64~ 1993-02-21 19:49:42 +00:00
Roland McGrath
b2361b3591 Formerly misc.c.~24~ 1993-02-21 19:48:46 +00:00
Roland McGrath
ed70d6422c Formerly main.c.~72~ 1993-02-21 19:28:33 +00:00
Roland McGrath
17bc902648 Formerly variable.c.~19~ 1993-02-21 19:28:30 +00:00
Roland McGrath
db6a102206 Formerly read.c.~54~ 1993-02-21 19:28:27 +00:00
Roland McGrath
ded09420ad Formerly remake.c.~47~ 1993-02-08 22:56:09 +00:00
Roland McGrath
078cc29e60 Formerly implicit.c.~9~ 1993-02-08 22:50:02 +00:00
Roland McGrath
bede66b709 Formerly vpath.c.~9~ 1993-02-08 22:50:00 +00:00
Roland McGrath
cc1433e808 Formerly compatMakefile.~63~ 1993-02-08 22:12:47 +00:00
Roland McGrath
4f1320fba2 Formerly compatMakefile.~62~ 1993-02-05 22:48:57 +00:00
Roland McGrath
b8a4e2bb0e Formerly commands.c.~16~ 1993-02-05 22:34:51 +00:00
Roland McGrath
720b21097c Formerly commands.h.~2~ 1993-02-05 22:31:57 +00:00
Roland McGrath
162269418e Formerly remake.c.~46~ 1993-02-05 22:31:31 +00:00
Roland McGrath
580e2a7391 Formerly job.c.~96~ 1993-02-05 22:31:29 +00:00
Roland McGrath
d870f4df8c Formerly configure.in.~16~ 1993-02-05 20:24:00 +00:00
Roland McGrath
309a65a790 Formerly remote-cstms.c.~8~ 1993-02-04 18:31:53 +00:00
Roland McGrath
963f33c909 Formerly make.h.~66~ 1993-02-04 18:23:27 +00:00
Roland McGrath
af73694245 Formerly main.c.~71~ 1993-02-04 18:23:19 +00:00
Roland McGrath
a4f557cb63 Formerly make.texinfo.~83~ 1993-02-04 18:06:47 +00:00
Roland McGrath
d47d6051a3 Formerly compatMakefile.~61~ 1993-02-04 18:01:50 +00:00
Roland McGrath
87bb5a6259 Formerly make.texinfo.~82~ 1993-02-04 01:45:16 +00:00
Roland McGrath
708c7c90a3 Formerly compatMakefile.~60~ 1993-02-04 01:16:36 +00:00
Roland McGrath
573ddaf6da Formerly job.c.~95~ 1993-02-04 00:58:10 +00:00
Roland McGrath
db545dffcc Formerly read.c.~53~ 1993-02-04 00:01:08 +00:00
Roland McGrath
f7ee7d26a5 Formerly GNUmakefile.~93~ 1993-02-03 23:12:43 +00:00
Roland McGrath
15d4ec2322 Formerly expand.c.~7~ 1993-02-03 20:59:22 +00:00
Roland McGrath
88ae51cb2e Formerly compatMakefile.~59~ 1993-02-02 01:49:11 +00:00
Roland McGrath
657338f0c9 Formerly remote-cstms.c.~7~ 1993-02-01 23:58:39 +00:00
Roland McGrath
fe356384aa Formerly GNUmakefile.~92~ 1993-02-01 23:22:42 +00:00
Roland McGrath
69e442ec90 Formerly job.h.~5~ 1993-02-01 21:03:32 +00:00
Roland McGrath
8b738924b0 Formerly job.c.~94~ 1993-02-01 21:02:40 +00:00
Roland McGrath
afa97833cc Formerly read.c.~52~ 1993-02-01 00:24:58 +00:00
Roland McGrath
3c516ccd35 Formerly compatMakefile.~58~ 1993-02-01 00:11:27 +00:00
Roland McGrath
dfaa02a8d5 Formerly job.c.~93~ 1993-01-31 22:54:06 +00:00
mycroft
50d1798203 Formerly make.texinfo.~81~ 1993-01-29 02:57:54 +00:00
Roland McGrath
85da8b0b54 Formerly commands.c.~15~ 1993-01-28 23:01:09 +00:00
Roland McGrath
ddd3143498 Formerly variable.c.~18~ 1993-01-28 23:01:01 +00:00
Roland McGrath
cd493b3d8f Formerly configure.in.~15~ 1993-01-28 21:41:44 +00:00
Roland McGrath
6a44c4b672 Formerly make.texinfo.~78~ 1993-01-28 19:47:54 +00:00
Roland McGrath
2603a60526 Formerly configure.in.~14~ 1993-01-26 02:24:51 +00:00
Roland McGrath
9a1a8d0dc6 Formerly vpath.c.~8~ 1993-01-26 01:51:23 +00:00
Roland McGrath
7444af63fc Formerly compatMakefile.~57~ 1993-01-26 01:16:01 +00:00
Roland McGrath
ae0045f50e Formerly remake.c.~45~ 1993-01-26 00:41:38 +00:00
Roland McGrath
2c132055ef Formerly remake.c.~44~ 1993-01-25 23:30:19 +00:00
Roland McGrath
09e4a320e6 Formerly make.h.~65~ 1993-01-25 23:30:16 +00:00
Roland McGrath
c1e3141433 Formerly file.h.~5~ 1993-01-25 22:45:49 +00:00
Roland McGrath
c316ab7609 Formerly main.c.~70~ 1993-01-25 22:16:33 +00:00
Roland McGrath
cf197b7550 Formerly variable.c.~17~ 1993-01-25 21:42:31 +00:00
Roland McGrath
c653200459 Formerly variable.c.~16~ 1993-01-23 01:54:04 +00:00
Roland McGrath
0b396e2587 Formerly GNUmakefile.~91~ 1993-01-23 00:35:32 +00:00
Roland McGrath
6090eb3125 Formerly job.c.~92~ 1993-01-22 22:31:27 +00:00
Roland McGrath
21c1a55665 Formerly configure.in.~13~ 1993-01-22 22:16:40 +00:00
Roland McGrath
c50958dd46 Formerly remake.c.~43~ 1993-01-22 22:02:48 +00:00
Roland McGrath
d56535498b Formerly misc.c.~23~ 1993-01-22 21:32:00 +00:00
Roland McGrath
81e8efbcdf Formerly dir.c.~10~ 1993-01-22 19:46:10 +00:00
Roland McGrath
c308b3a5f3 Formerly configure.in.~12~ 1993-01-21 23:50:44 +00:00
Roland McGrath
f48fcf5f45 Formerly compatMakefile.~56~ 1993-01-21 23:50:44 +00:00
Roland McGrath
4d36cfe6a3 Formerly build.template.~4~ 1993-01-21 23:50:43 +00:00
Roland McGrath
2370f79846 Formerly job.c.~91~ 1993-01-21 23:27:00 +00:00
Roland McGrath
b758dc3f8b Formerly GNUmakefile.~90~ 1993-01-21 23:24:19 +00:00
Roland McGrath
e8a9cedc6a Formerly remake.c.~42~ 1993-01-21 22:24:55 +00:00
Roland McGrath
44078a3441 Formerly job.c.~90~ 1993-01-19 00:32:39 +00:00
Roland McGrath
ce25808caa Formerly configure.in.~11~ 1993-01-19 00:19:54 +00:00
Roland McGrath
c2b69b5d9d Formerly read.c.~51~ 1993-01-19 00:14:29 +00:00
Roland McGrath
6925f7153a Formerly compatMakefile.~55~ 1993-01-18 19:54:17 +00:00
Roland McGrath
5460cd5a00 Formerly make.texinfo.~77~ 1993-01-15 19:56:31 +00:00
Roland McGrath
2861ad6208 Formerly main.c.~69~ 1993-01-15 18:18:29 +00:00
Roland McGrath
37d9554e31 Formerly remake.c.~41~ 1993-01-15 18:06:22 +00:00
Roland McGrath
633efa004c Formerly make.h.~64~ 1993-01-15 18:05:49 +00:00
melissa
800a9e957d Formerly make.texinfo.~76~ 1993-01-15 02:46:25 +00:00
Robert J. Chassell
8ea8c0372a Formerly make.texinfo.~75~ 1993-01-14 22:55:03 +00:00
Roland McGrath
4dd2ed0ad1 entered into RCS 1993-01-14 22:25:02 +00:00
Roland McGrath
bbf2720b4d Formerly make.texinfo.~74~ 1993-01-14 20:23:10 +00:00
Roland McGrath
5893545370 Formerly read.c.~50~ 1993-01-14 19:26:47 +00:00
Roland McGrath
6ef5854e47 Formerly compatMakefile.~54~ 1993-01-14 18:53:17 +00:00
Roland McGrath
5c44db1b5f Formerly misc.c.~22~ 1993-01-13 21:23:01 +00:00
Roland McGrath
f0c68224d6 Formerly arscan.c.~26~ 1993-01-13 21:18:56 +00:00
Roland McGrath
bb90ac7aef Formerly variable.c.~15~ 1993-01-13 21:09:20 +00:00
Roland McGrath
4694e3fe2e Formerly GNUmakefile.~89~ 1993-01-13 21:05:06 +00:00
Roland McGrath
fae8065d7f Formerly build.template.~3~ 1993-01-13 21:05:03 +00:00
Roland McGrath
099b4d5643 Formerly build.template.~2~ 1993-01-12 23:00:41 +00:00
Roland McGrath
5e83d8b10a Formerly GNUmakefile.~88~ 1993-01-12 22:51:00 +00:00
Roland McGrath
4c84e13064 Formerly configure.in.~10~ 1993-01-12 21:11:23 +00:00
Roland McGrath
ef028aa4c6 Formerly README.template.~4~ 1993-01-12 21:02:13 +00:00
Roland McGrath
2bff7aa420 Formerly main.c.~68~ 1993-01-12 19:42:13 +00:00
Roland McGrath
e07db8077c Formerly make.h.~63~ 1993-01-12 19:36:16 +00:00
Roland McGrath
35ffa6973a Initial revision 1993-01-12 19:30:31 +00:00
Roland McGrath
402b400e52 Formerly compatMakefile.~53~ 1993-01-12 17:31:40 +00:00
Roland McGrath
6b6a4f1de2 Formerly GNUmakefile.~87~ 1993-01-11 23:02:32 +00:00
Roland McGrath
ab6a618dac Formerly make.texinfo.~73~ 1993-01-11 22:51:16 +00:00
Roland McGrath
45572fa600 Formerly vpath.c.~7~ 1993-01-11 22:46:31 +00:00
Richard M. Stallman
36a6a9eb7d Formerly make-stds.texi.~2~ 1993-01-11 22:29:30 +00:00
Roland McGrath
7c91702697 Formerly misc.c.~21~ 1993-01-11 19:45:54 +00:00
Roland McGrath
71fceb51e3 Formerly compatMakefile.~52~ 1993-01-11 19:45:52 +00:00
Richard M. Stallman
9705781777 Initial revision 1993-01-11 17:41:09 +00:00
Roland McGrath
76ae16dee3 Formerly job.c.~89~ 1993-01-08 22:40:24 +00:00
Roland McGrath
035157a2fd Formerly vpath.c.~6~ 1993-01-08 22:07:33 +00:00
Roland McGrath
50a643208f Formerly GNUmakefile.~86~ 1993-01-08 21:49:21 +00:00
Roland McGrath
92cd154b95 Formerly main.c.~67~ 1993-01-08 21:48:11 +00:00
Roland McGrath
d07b95da6f Formerly misc.c.~20~ 1993-01-08 20:32:36 +00:00
Roland McGrath
2f22bfeaaa Formerly make.texinfo.~72~ 1993-01-08 20:01:42 +00:00
Roland McGrath
fcedb448bb Formerly make.texinfo.~71~ 1993-01-07 22:47:51 +00:00
Roland McGrath
5a4ab813f0 Formerly job.c.~88~ 1993-01-07 01:46:47 +00:00
Robert J. Chassell
99369403b7 Formerly make.texinfo.~70~ 1993-01-07 01:40:19 +00:00
Roland McGrath
adde98d27b Formerly main.c.~66~ 1993-01-07 00:34:28 +00:00
Roland McGrath
e2622b0fea Formerly make.h.~62~ 1993-01-06 23:28:54 +00:00
Roland McGrath
99afb91aca Formerly function.c.~23~ 1993-01-06 22:57:35 +00:00
Roland McGrath
1632e7feb3 Formerly implicit.c.~8~ 1993-01-06 22:57:30 +00:00
Roland McGrath
9403ef9942 Formerly commands.c.~14~ 1993-01-06 22:57:24 +00:00
Roland McGrath
c8d4d2305d Formerly read.c.~49~ 1993-01-06 22:57:21 +00:00
Roland McGrath
f341a61976 Formerly job.h.~4~ 1993-01-06 22:57:14 +00:00
Roland McGrath
5778d6cdb9 Formerly compatMakefile.~51~ 1993-01-06 22:39:31 +00:00
Roland McGrath
f2bc0a0c93 Formerly dir.c.~9~ 1993-01-06 20:07:35 +00:00
Roland McGrath
d8817e2c39 Formerly GNUmakefile.~85~ 1993-01-06 00:30:46 +00:00
Roland McGrath
5b45a568c0 Formerly job.c.~87~ 1993-01-05 23:41:29 +00:00
Roland McGrath
d19c2ef049 Formerly misc.c.~19~ 1993-01-05 23:02:42 +00:00
Roland McGrath
c0c67164d5 Formerly configure.in.~9~ 1993-01-05 22:40:32 +00:00
Roland McGrath
93385de9ff Formerly compatMakefile.~50~ 1993-01-05 19:54:03 +00:00
Roland McGrath
9edb745a71 Formerly GNUmakefile.~84~ 1993-01-05 19:53:58 +00:00
Roland McGrath
d315acf15e Formerly main.c.~65~ 1993-01-04 21:59:56 +00:00
Roland McGrath
aa8a3b306d Formerly make.texinfo.~69~ 1993-01-04 20:42:16 +00:00
melissa
89b66be8b3 Formerly make.texinfo.~68~ 1992-12-31 20:56:47 +00:00
Roland McGrath
b313929074 Formerly make.h.~61~ 1992-12-31 17:26:10 +00:00
Robert J. Chassell
8c6ef34e56 Formerly make.texinfo.~67~ 1992-12-30 23:57:35 +00:00
Roland McGrath
f4f6b2b97e Formerly compatMakefile.~49~ 1992-12-29 18:59:17 +00:00
Roland McGrath
c2dbc39224 Formerly GNUmakefile.~83~ 1992-12-29 02:36:27 +00:00
Roland McGrath
2d89aa53df Formerly read.c.~48~ 1992-12-29 00:20:25 +00:00
Roland McGrath
52930ae3a9 Formerly compatMakefile.~48~ 1992-12-28 23:25:58 +00:00
Roland McGrath
ede645439a Formerly read.c.~47~ 1992-12-23 21:14:20 +00:00
Roland McGrath
95614c2e7c Formerly compatMakefile.~47~ 1992-12-23 18:18:27 +00:00
Roland McGrath
37fb62e217 Formerly variable.h.~9~ 1992-12-22 23:44:09 +00:00
Roland McGrath
555a705aaa Formerly expand.c.~6~ 1992-12-22 23:44:03 +00:00
Roland McGrath
123f70c521 Formerly compatMakefile.~46~ 1992-12-22 23:31:46 +00:00
Roland McGrath
02caa22338 Formerly default.c.~21~ 1992-12-22 22:31:16 +00:00
Roland McGrath
38f78c7be1 Formerly file.c.~21~ 1992-12-22 22:31:13 +00:00
Roland McGrath
fd5c585cab Formerly implicit.c.~7~ 1992-12-22 22:31:10 +00:00
Roland McGrath
0aa6e8609e Formerly read.c.~46~ 1992-12-22 22:31:08 +00:00
Roland McGrath
40463f4410 Formerly commands.c.~13~ 1992-12-22 22:31:07 +00:00
Roland McGrath
01e07f8ae2 Formerly variable.c.~14~ 1992-12-22 22:16:14 +00:00
Robert J. Chassell
f75288402e Formerly make.texinfo.~66~ 1992-12-22 21:42:45 +00:00
Roland McGrath
63fec5f467 Formerly remake.c.~40~ 1992-12-22 21:22:05 +00:00
Roland McGrath
b0a8c63bf2 Formerly make.texinfo.~65~ 1992-12-22 20:14:36 +00:00
Roland McGrath
2d038ae579 Formerly GNUmakefile.~82~ 1992-12-21 21:53:24 +00:00
Roland McGrath
50f2c1fbd9 Formerly configure.in.~7~ 1992-12-20 23:08:11 +00:00
Roland McGrath
40507f313a Formerly GNUmakefile.~81~ 1992-12-20 22:59:52 +00:00
Roland McGrath
11404035d1 Formerly compatMakefile.~45~ 1992-12-20 22:58:53 +00:00
Roland McGrath
3cc78a1a0f Formerly make.h.~60~ 1992-12-20 22:57:06 +00:00
Roland McGrath
501241725a Formerly compatMakefile.~44~ 1992-12-17 21:16:40 +00:00
Roland McGrath
501732ca84 Formerly configure.in.~6~ 1992-12-16 21:25:21 +00:00
Roland McGrath
17d92fd05b Formerly make.texinfo.~64~ 1992-12-16 00:08:34 +00:00
Roland McGrath
d0d141ea5b Formerly make.texinfo.~63~ 1992-12-15 19:35:51 +00:00
Roland McGrath
97f458f27e Formerly make.texinfo.~62~ 1992-12-11 01:10:17 +00:00
Roland McGrath
da96d5b5bb Formerly make.texinfo.~61~ 1992-12-10 20:04:37 +00:00
Roland McGrath
68aec7ab65 Formerly make.texinfo.~60~ 1992-12-10 18:48:19 +00:00
Noah Friedman
c1d26a2bde Formerly make.texinfo.~59~ 1992-12-09 23:32:39 +00:00
Roland McGrath
dfdedfe97a Formerly make.texinfo.~58~ 1992-12-09 23:28:14 +00:00
Roland McGrath
8c4eb82fb8 Formerly main.c.~64~ 1992-12-09 22:10:14 +00:00
Roland McGrath
2b42e280e8 Formerly default.c.~20~ 1992-12-09 22:09:42 +00:00
Roland McGrath
289417e089 Formerly read.c.~45~ 1992-12-09 21:02:53 +00:00
Roland McGrath
1faf31158c Formerly remake.c.~39~ 1992-12-09 20:34:36 +00:00
Roland McGrath
0a7da8a929 Formerly make.texinfo.~57~ 1992-12-09 19:35:34 +00:00
Roland McGrath
a3254ad7b3 Formerly variable.c.~13~ 1992-11-23 20:53:24 +00:00
Roland McGrath
b8b8ba69d4 Formerly default.c.~19~ 1992-11-23 20:48:49 +00:00
Roland McGrath
081275c58e Formerly make.h.~59~ 1992-11-23 20:41:02 +00:00
Roland McGrath
968e9fce6c Formerly job.c.~86~ 1992-11-23 20:04:25 +00:00
Roland McGrath
b81f248c35 Formerly main.c.~63~ 1992-11-23 20:04:19 +00:00
Roland McGrath
fa0cf27f72 Formerly read.c.~44~ 1992-11-18 19:54:01 +00:00
Roland McGrath
4cbb8e0d70 Formerly make.texinfo.~56~ 1992-11-17 23:43:09 +00:00
Roland McGrath
4a970dc04e Formerly make.texinfo.~55~ 1992-11-17 01:08:21 +00:00
Roland McGrath
4125f8f08e Formerly main.c.~62~ 1992-11-16 23:59:17 +00:00
Roland McGrath
45649948db Formerly vpath.c.~5~ 1992-11-16 22:49:14 +00:00
Roland McGrath
7d8fafa4b7 Formerly make.texinfo.~54~ 1992-11-13 23:19:57 +00:00
Roland McGrath
9e258d2369 Formerly rule.c.~9~ 1992-11-13 23:14:36 +00:00
Roland McGrath
1ab478ef48 Formerly make.texinfo.~53~ 1992-11-13 22:19:43 +00:00
Roland McGrath
ecc3b33299 Formerly job.c.~85~ 1992-11-12 20:45:29 +00:00
Roland McGrath
424bcccf98 Formerly read.c.~43~ 1992-11-10 21:41:55 +00:00
Roland McGrath
d13ecbbb67 Formerly dir.c.~8~ 1992-11-10 20:43:35 +00:00
Roland McGrath
09fe55be99 Formerly rule.c.~8~ 1992-11-10 20:36:44 +00:00
Roland McGrath
1efb91cda6 Formerly default.c.~18~ 1992-11-10 20:36:42 +00:00
Roland McGrath
3d72bcb583 Formerly function.c.~22~ 1992-11-10 20:36:39 +00:00
Roland McGrath
2fbb3407dd Formerly vpath.c.~4~ 1992-11-10 20:29:48 +00:00
Roland McGrath
9d58debbcc Formerly remake.c.~38~ 1992-11-09 22:52:52 +00:00
Roland McGrath
07a309961b Formerly make.h.~58~ 1992-11-09 22:52:50 +00:00
Roland McGrath
eae9bb14a2 Formerly job.c.~84~ 1992-11-09 22:52:13 +00:00
Roland McGrath
a401a5e46a Formerly read.c.~42~ 1992-11-05 23:33:11 +00:00
Roland McGrath
019a25fa84 Formerly vpath.c.~3~ 1992-11-05 23:33:08 +00:00
Roland McGrath
a8993377f7 Formerly compatMakefile.~43~ 1992-11-04 02:00:19 +00:00
Roland McGrath
8c9b95d07e Formerly file.c.~20~ 1992-11-04 01:44:30 +00:00
Roland McGrath
db8c8b2ad8 Formerly read.c.~41~ 1992-10-29 21:49:15 +00:00
Roland McGrath
55b9f37c35 Formerly make.texinfo.~52~ 1992-10-29 20:32:03 +00:00
Roland McGrath
815ee70d7d Formerly remake.c.~37~ 1992-10-25 06:16:09 +00:00
Roland McGrath
04b7426dfa Formerly commands.c.~12~ 1992-10-25 06:13:10 +00:00
Roland McGrath
0e4062c177 Formerly remake.c.~36~ 1992-10-25 05:49:07 +00:00
Roland McGrath
cff0af8d6d Formerly read.c.~40~ 1992-10-25 03:24:24 +00:00
Roland McGrath
8b591a8b90 Formerly expand.c.~5~ 1992-10-25 03:01:07 +00:00
Roland McGrath
deefc22d2f Formerly GNUmakefile.~80~ 1992-10-25 02:43:22 +00:00
Roland McGrath
a485ade084 Formerly variable.c.~12~ 1992-10-23 19:57:55 +00:00
Roland McGrath
b45d1ae3c2 Formerly default.c.~17~ 1992-10-15 23:11:06 +00:00
Roland McGrath
7db4dd0dbd Formerly dir.c.~7~ 1992-10-15 23:11:04 +00:00
Roland McGrath
348caf1627 Formerly compatMakefile.~42~ 1992-10-15 23:11:02 +00:00
Roland McGrath
6683a1c8db Formerly make.h.~57~ 1992-10-15 23:01:36 +00:00
Roland McGrath
d3543bc097 Formerly misc.c.~18~ 1992-10-15 23:01:34 +00:00
Roland McGrath
6247727678 Formerly job.c.~83~ 1992-10-12 21:58:54 +00:00
Roland McGrath
67516d5331 Formerly make.h.~56~ 1992-10-12 21:58:52 +00:00
Roland McGrath
e7f3e4a031 Formerly compatMakefile.~41~ 1992-10-12 20:32:29 +00:00
Roland McGrath
b0a49baf2f Formerly GNUmakefile.~79~ 1992-10-12 18:16:07 +00:00
Roland McGrath
d9ffca6d79 Formerly dir.c.~6~ 1992-10-12 18:05:41 +00:00
Roland McGrath
dba6ec5d0c Formerly file.c.~19~ 1992-10-12 18:04:07 +00:00
Roland McGrath
953f1c7df0 Formerly compatMakefile.~40~ 1992-10-12 17:46:23 +00:00
Roland McGrath
81acf8675a Formerly read.c.~39~ 1992-10-12 17:35:43 +00:00
Roland McGrath
f31ff1c1c4 Formerly main.c.~61~ 1992-10-11 21:26:57 +00:00
Roland McGrath
8140043344 Formerly dir.c.~5~ 1992-10-11 21:25:04 +00:00
Roland McGrath
29002aca14 Formerly compatMakefile.~39~ 1992-10-11 21:01:06 +00:00
Roland McGrath
a39f01fb1d Formerly configure.in.~4~ 1992-10-11 21:01:04 +00:00
Roland McGrath
b13de88757 Formerly read.c.~38~ 1992-10-09 18:00:37 +00:00
Roland McGrath
b3747a6bdb Formerly commands.c.~11~ 1992-10-09 17:50:59 +00:00
Roland McGrath
112dd3508d Formerly variable.c.~11~ 1992-10-09 17:50:55 +00:00
Roland McGrath
46ccc784fe Formerly dir.c.~4~ 1992-10-09 17:35:07 +00:00
Roland McGrath
9603279fb8 Formerly vpath.c.~2~ 1992-10-09 17:35:03 +00:00
Roland McGrath
e567c8d914 Formerly configure.in.~3~ 1992-10-09 16:12:29 +00:00
Roland McGrath
21d566bf51 Formerly make.h.~55~ 1992-10-02 23:42:13 +00:00
Roland McGrath
313e5ec45d Formerly main.c.~60~ 1992-09-30 23:21:22 +00:00
Roland McGrath
b0cafff1bf Formerly main.c.~59~ 1992-09-30 01:26:59 +00:00
Roland McGrath
f683e78f53 Formerly make.texinfo.~51~ 1992-09-30 00:47:33 +00:00
Roland McGrath
be0d85ba3e Formerly make.texinfo.~50~ 1992-09-25 19:37:40 +00:00
Robert J. Chassell
6a0cfeb0f2 Formerly make.texinfo.~49~ 1992-09-25 18:05:31 +00:00
Roland McGrath
1f534482de Formerly read.c.~37~ 1992-09-16 20:15:19 +00:00
Roland McGrath
144b6ecba5 Formerly main.c.~58~ 1992-09-15 20:10:46 +00:00
Roland McGrath
53f7c27956 Formerly read.c.~36~ 1992-09-15 19:14:03 +00:00
Roland McGrath
44251cbc0c Formerly remake.c.~35~ 1992-09-09 20:46:57 +00:00
Roland McGrath
a1849dfc5f Formerly job.c.~82~ 1992-09-09 20:32:56 +00:00
Roland McGrath
e7930bea3a Formerly commands.c.~10~ 1992-09-09 20:20:37 +00:00
Roland McGrath
d8f06cf21f Formerly default.c.~16~ 1992-09-09 19:50:38 +00:00
Roland McGrath
44653ac71b Formerly compatMakefile.~38~ 1992-09-02 22:03:40 +00:00
Roland McGrath
7f0fe7f44d Formerly make.h.~54~ 1992-09-02 21:53:59 +00:00
Roland McGrath
47839c882d Formerly make.texinfo.~48~ 1992-08-29 00:51:40 +00:00
Robert J. Chassell
e547c81b9a Formerly make.texinfo.~47~ 1992-08-28 18:27:35 +00:00
Roland McGrath
b52b376cf1 Formerly read.c.~35~ 1992-08-28 00:14:48 +00:00
Roland McGrath
e80a2e9424 Formerly compatMakefile.~37~ 1992-08-28 00:14:44 +00:00
Roland McGrath
e30c4023e1 Formerly read.c.~34~ 1992-08-27 23:53:17 +00:00
Roland McGrath
5aa595c99b Formerly remake.c.~34~ 1992-08-27 23:29:25 +00:00
Roland McGrath
a301f9327a Formerly GNUmakefile.~78~ 1992-08-27 23:25:59 +00:00
Roland McGrath
602d1e18af Formerly file.c.~18~ 1992-08-27 22:06:44 +00:00
Roland McGrath
178a758738 Formerly compatMakefile.~36~ 1992-08-27 21:51:23 +00:00
Roland McGrath
381a6bbfb4 Formerly configure.in.~2~ 1992-08-27 19:30:57 +00:00
Roland McGrath
f4a089447d Formerly make.texinfo.~46~ 1992-08-26 22:33:53 +00:00
Roland McGrath
d080dd0182 Formerly main.c.~57~ 1992-08-26 21:47:38 +00:00
Roland McGrath
37bfd879df Formerly remake.c.~33~ 1992-08-26 21:18:03 +00:00
Roland McGrath
4d345bdee3 Formerly GNUmakefile.~77~ 1992-08-26 21:00:12 +00:00
Roland McGrath
e222f10616 Formerly make.texinfo.~45~ 1992-08-20 23:27:46 +00:00
Robert J. Chassell
9869db36e9 Formerly make.texinfo.~44~ 1992-08-20 21:29:58 +00:00
Roland McGrath
2ebdf6de85 Formerly job.c.~81~ 1992-08-20 18:20:20 +00:00
Roland McGrath
db7633eac4 Formerly remake.c.~32~ 1992-08-20 18:10:20 +00:00
Roland McGrath
8fbb772041 Formerly make.texinfo.~43~ 1992-08-19 22:16:47 +00:00
Roland McGrath
3c660b4d55 Formerly function.c.~21~ 1992-08-19 22:16:15 +00:00
Roland McGrath
0fad0bd5c5 Formerly compatMakefile.~35~ 1992-08-19 20:24:03 +00:00
Roland McGrath
1fa7491d02 Initial revision 1992-08-18 21:25:14 +00:00
Roland McGrath
1292aa1e4b Formerly make.texinfo.~42~ 1992-08-18 18:59:26 +00:00
Roland McGrath
0c61dffcb5 Formerly make.texinfo.~41~ 1992-08-14 18:47:05 +00:00
Robert J. Chassell
30016eef42 Formerly make.texinfo.~40~ 1992-08-14 18:39:14 +00:00
Roland McGrath
781ce7f4a8 Formerly arscan.c.~25~ 1992-08-14 16:37:50 +00:00
Roland McGrath
c76d6785de Formerly GNUmakefile.~76~ 1992-08-13 22:09:36 +00:00
Roland McGrath
81731a29d1 Formerly main.c.~56~ 1992-08-13 21:50:48 +00:00
Roland McGrath
ad93a01fa6 Formerly make.texinfo.~39~ 1992-08-11 21:03:44 +00:00
Roland McGrath
423783c913 Formerly implicit.c.~6~ 1992-08-10 22:08:41 +00:00
Roland McGrath
ccff1cc0d2 Formerly function.c.~20~ 1992-08-10 22:03:03 +00:00
Roland McGrath
47707f76cb Formerly compatMakefile.~34~ 1992-08-10 21:05:08 +00:00
Roland McGrath
3241a91312 Formerly file.c.~17~ 1992-08-02 11:28:04 +00:00
Roland McGrath
b732b99c0b Formerly variable.c.~10~ 1992-08-02 11:28:03 +00:00
Roland McGrath
b001b6a55a Formerly file.h.~4~ 1992-08-02 11:28:01 +00:00
Roland McGrath
24c9aabe16 Formerly make.h.~53~ 1992-08-02 11:28:00 +00:00
Roland McGrath
92df7dd504 Formerly variable.h.~8~ 1992-08-02 11:27:59 +00:00
Roland McGrath
fba924717c Formerly GNUmakefile.~75~ 1992-08-02 10:36:52 +00:00
Roland McGrath
e07d203a2f Formerly file.c.~16~ 1992-08-02 10:16:54 +00:00
Roland McGrath
92546f9ff9 Formerly rule.h.~3~ 1992-08-02 10:11:29 +00:00
Roland McGrath
849b2101e6 Formerly rule.c.~7~ 1992-08-02 10:11:25 +00:00
Roland McGrath
09a534168f Formerly file.h.~3~ 1992-08-02 09:51:40 +00:00
Roland McGrath
a98a648754 Formerly make.h.~52~ 1992-08-02 09:10:08 +00:00
Roland McGrath
f4c3f77b96 Formerly variable.h.~7~ 1992-08-02 09:10:05 +00:00
Roland McGrath
b95e47d401 Formerly variable.c.~9~ 1992-08-02 09:10:03 +00:00
Roland McGrath
8aff0091fc Formerly dep.h.~2~ 1992-08-02 05:42:58 +00:00
Roland McGrath
bc8c4949b7 Formerly GNUmakefile.~74~ 1992-07-30 20:32:16 +00:00
Roland McGrath
f44c1d9366 Formerly main.c.~55~ 1992-07-30 20:31:50 +00:00
Roland McGrath
5329b592b7 Formerly default.c.~15~ 1992-07-30 19:53:39 +00:00
Roland McGrath
39e2dbb7b3 Formerly make.h.~51~ 1992-07-30 19:41:18 +00:00
Roland McGrath
47db5afe4f Formerly make.h.~50~ 1992-07-26 22:30:45 +00:00
Roland McGrath
19142fcfd4 Formerly job.c.~80~ 1992-07-26 20:57:13 +00:00
Roland McGrath
2283b32986 Formerly variable.c.~8~ 1992-07-24 06:16:47 +00:00
Roland McGrath
2e5f56539d Formerly main.c.~54~ 1992-07-24 06:02:26 +00:00
Roland McGrath
a63f4e1f9c Formerly make.texinfo.~38~ 1992-07-24 02:23:53 +00:00
Roland McGrath
1d2e7e6142 Formerly make.texinfo.~37~ 1992-07-24 02:03:20 +00:00
Robert J. Chassell
099b302768 Formerly make.texinfo.~36~ 1992-07-24 00:25:51 +00:00
Robert J. Chassell
c29174d96b Formerly make.texinfo.~35~ 1992-07-17 17:05:55 +00:00
Robert J. Chassell
cda455684c Formerly make.texinfo.~34~ 1992-07-16 22:42:17 +00:00
Roland McGrath
0858bbcfb5 Formerly GNUmakefile.~73~ 1992-07-16 19:17:12 +00:00
Roland McGrath
f23e838c15 Formerly README.template.~3~ 1992-07-16 18:35:19 +00:00
Roland McGrath
5814d65428 Formerly GNUmakefile.~72~ 1992-07-16 18:34:43 +00:00
Roland McGrath
f8197823a4 Formerly main.c.~53~ 1992-07-16 18:31:50 +00:00
Roland McGrath
b408ee65f6 Formerly remake.c.~31~ 1992-07-15 02:15:54 +00:00
Roland McGrath
0f045633a7 Formerly main.c.~52~ 1992-07-15 02:15:53 +00:00
Roland McGrath
62e8630bdc Formerly rule.c.~6~ 1992-07-14 23:08:36 +00:00
Roland McGrath
eb7484abc4 Formerly GNUmakefile.~71~ 1992-07-13 22:17:50 +00:00
Roland McGrath
8ef3af8bed Formerly commands.c.~9~ 1992-07-13 21:51:47 +00:00
Roland McGrath
4eb52d9a45 Formerly make.texinfo.~33~ 1992-07-10 05:18:22 +00:00
Roland McGrath
7817332cc1 Formerly variable.h.~6~ 1992-07-10 04:06:24 +00:00
Roland McGrath
e3fbb5828f Formerly variable.c.~7~ 1992-07-10 04:06:22 +00:00
Roland McGrath
45cf6ce658 Formerly compatMakefile.~33~ 1992-07-10 01:40:44 +00:00
Roland McGrath
69222204e6 Formerly compatMakefile.~32~ 1992-07-07 23:55:43 +00:00
Roland McGrath
dc2a270b71 Formerly job.c.~79~ 1992-07-07 23:12:46 +00:00
Roland McGrath
9c7598db10 Formerly make.texinfo.~32~ 1992-07-07 01:04:06 +00:00
Roland McGrath
00fb56c2b9 Formerly GNUmakefile.~70~ 1992-07-05 01:55:13 +00:00
Roland McGrath
e37b0392be Formerly commands.c.~8~ 1992-07-05 00:52:52 +00:00
Roland McGrath
7dba11957a Formerly job.c.~78~ 1992-07-05 00:52:50 +00:00
Roland McGrath
517a17b6d9 Formerly main.c.~51~ 1992-07-05 00:52:48 +00:00
Roland McGrath
9d3d0c6b79 Formerly make.h.~49~ 1992-07-05 00:52:46 +00:00
Roland McGrath
bc1770c035 Formerly remote-cstms.c.~6~ 1992-07-05 00:52:45 +00:00
Roland McGrath
50cd0d5a12 Formerly main.c.~50~ 1992-07-02 22:48:17 +00:00
Roland McGrath
8d6f98b83d Formerly GNUmakefile.~69~ 1992-07-01 22:37:12 +00:00
Roland McGrath
8809c8ec38 Formerly job.c.~77~ 1992-07-01 00:52:45 +00:00
Roland McGrath
6feabe12a7 Formerly file.c.~15~ 1992-07-01 00:52:43 +00:00
Roland McGrath
41d94fb0e3 Formerly function.c.~19~ 1992-07-01 00:52:41 +00:00
Roland McGrath
d425bd20a2 Formerly make.h.~48~ 1992-07-01 00:52:39 +00:00
Roland McGrath
e7e9d84a54 Formerly arscan.c.~24~ 1992-07-01 00:52:37 +00:00
Roland McGrath
c84a275871 Formerly make.texinfo.~31~ 1992-06-26 00:58:23 +00:00
Roland McGrath
8d1f6733a9 Formerly GNUmakefile.~68~ 1992-06-26 00:54:04 +00:00
Roland McGrath
c355295fe0 Formerly README.template.~2~ 1992-06-26 00:52:43 +00:00
Roland McGrath
9ef264a343 Formerly remake.c.~30~ 1992-06-26 00:46:53 +00:00
Roland McGrath
fec3694512 Formerly job.c.~76~ 1992-06-26 00:33:00 +00:00
Roland McGrath
eaa2a12a44 Formerly main.c.~49~ 1992-06-25 21:45:52 +00:00
Roland McGrath
1b3fc99e0f Formerly compatMakefile.~31~ 1992-06-25 21:10:49 +00:00
Roland McGrath
e293b96610 Formerly dir.c.~3~ 1992-06-25 01:05:20 +00:00
Roland McGrath
f2c51355ed Formerly make.h.~47~ 1992-06-25 00:28:36 +00:00
Roland McGrath
7ab1580762 Formerly job.c.~75~ 1992-06-25 00:13:20 +00:00
Roland McGrath
a819615113 Formerly make.texinfo.~30~ 1992-06-24 23:40:28 +00:00
Roland McGrath
f519275024 Formerly file.c.~14~ 1992-06-23 22:42:43 +00:00
Roland McGrath
7a9130401f Formerly compatMakefile.~30~ 1992-06-22 20:34:09 +00:00
Roland McGrath
bfb4dddc2e Formerly GNUmakefile.~67~ 1992-06-22 20:34:05 +00:00
Roland McGrath
6f322b59da Formerly arscan.c.~23~ 1992-06-19 20:21:54 +00:00
Roland McGrath
320a119913 Formerly make.texinfo.~29~ 1992-06-18 23:25:43 +00:00
Robert J. Chassell
fcd3964082 Formerly make.texinfo.~28~ 1992-06-18 23:17:48 +00:00
Roland McGrath
eeb9b7065d Formerly default.c.~14~ 1992-06-17 21:59:54 +00:00
Roland McGrath
2aed822bd7 Formerly compatMakefile.~29~ 1992-06-17 02:07:35 +00:00
Roland McGrath
add4780bf7 Formerly commands.c.~7~ 1992-06-16 23:43:37 +00:00
Roland McGrath
df884f9d9a Formerly file.c.~13~ 1992-06-16 23:43:35 +00:00
Roland McGrath
498f1b50f7 Formerly make.h.~46~ 1992-06-16 23:43:31 +00:00
Roland McGrath
29380252a8 Formerly expand.c.~4~ 1992-06-16 23:43:29 +00:00
Roland McGrath
ade465512f Formerly arscan.c.~22~ 1992-06-16 23:43:25 +00:00
Roland McGrath
37fbe2a271 Formerly compatMakefile.~28~ 1992-06-16 01:30:57 +00:00
Roland McGrath
15614defd8 Formerly GNUmakefile.~66~ 1992-06-16 01:25:32 +00:00
Roland McGrath
b5ee5f8539 Formerly variable.c.~6~ 1992-06-15 22:41:38 +00:00
Roland McGrath
febf5d0944 Formerly make.h.~45~ 1992-06-15 22:41:21 +00:00
Roland McGrath
9e37e514d2 Formerly arscan.c.~21~ 1992-06-15 22:38:32 +00:00
Roland McGrath
5c2f4a7d88 Formerly job.c.~74~ 1992-06-15 22:10:36 +00:00
Roland McGrath
db8eb71a9c Formerly compatMakefile.~27~ 1992-06-15 21:53:41 +00:00
Roland McGrath
5780852aee Formerly job.c.~73~ 1992-06-15 21:47:25 +00:00
Roland McGrath
6619d7d8ac Formerly remake.c.~29~ 1992-06-15 21:47:19 +00:00
Roland McGrath
82f7d51bde Formerly file.c.~12~ 1992-06-15 16:39:11 +00:00
Roland McGrath
8407664cf6 Formerly job.c.~72~ 1992-06-12 23:41:40 +00:00
Roland McGrath
b5b32c8f9a Formerly file.h.~2~ 1992-06-12 23:17:24 +00:00
Roland McGrath
3dbe309fce Formerly make.texinfo.~27~ 1992-06-12 23:12:20 +00:00
Robert J. Chassell
87c5a97b91 Formerly make.texinfo.~26~ 1992-06-12 22:52:31 +00:00
Robert J. Chassell
83bb8c72a7 Formerly make.texinfo.~25~ 1992-06-12 20:59:52 +00:00
Robert J. Chassell
2172dfa41f Formerly make.texinfo.~24~ 1992-06-12 03:51:46 +00:00
Roland McGrath
ef46822708 Formerly variable.h.~5~ 1992-06-12 00:29:24 +00:00
Roland McGrath
78e7551083 Formerly expand.c.~3~ 1992-06-12 00:29:21 +00:00
Roland McGrath
d298fecfda Formerly GNUmakefile.~65~ 1992-06-12 00:29:17 +00:00
Roland McGrath
d3ea420650 Formerly job.c.~71~ 1992-06-12 00:21:48 +00:00
Roland McGrath
067777e77d Formerly arscan.c.~20~ 1992-06-11 22:30:17 +00:00
Roland McGrath
5ccd482b90 Formerly compatMakefile.~26~ 1992-06-11 20:08:55 +00:00
Roland McGrath
3893d9217c Formerly main.c.~48~ 1992-06-11 20:05:40 +00:00
Roland McGrath
efc335d4a1 Formerly GNUmakefile.~64~ 1992-06-11 05:33:52 +00:00
Roland McGrath
b9f64130af Formerly make.h.~44~ 1992-06-11 05:30:34 +00:00
Roland McGrath
0a4502e116 Formerly compatMakefile.~25~ 1992-06-11 05:30:32 +00:00
Roland McGrath
b6364d9ae4 Formerly job.c.~70~ 1992-06-11 05:25:28 +00:00
Roland McGrath
59caea5674 Formerly read.c.~33~ 1992-06-11 05:16:34 +00:00
Roland McGrath
2f5b18ba2f Formerly commands.c.~6~ 1992-06-11 05:12:44 +00:00
Roland McGrath
5631243fdd Formerly remake.c.~28~ 1992-06-11 05:05:49 +00:00
Roland McGrath
a61fc8acd1 Formerly dir.c.~2~ 1992-06-11 04:58:32 +00:00
Roland McGrath
b87ff76b7e Formerly remote-cstms.c.~5~ 1992-06-11 04:58:23 +00:00
Roland McGrath
1c9e851fe0 Formerly main.c.~47~ 1992-06-11 04:58:20 +00:00
Roland McGrath
5382f6d197 Formerly misc.c.~17~ 1992-06-11 04:58:15 +00:00
Roland McGrath
8ca2f785e2 Formerly arscan.c.~19~ 1992-06-11 04:58:10 +00:00
Roland McGrath
459c8137c0 Formerly ar.c.~2~ 1992-06-11 04:58:08 +00:00
Roland McGrath
9165d8e5d1 Formerly variable.h.~4~ 1992-06-11 02:28:31 +00:00
Roland McGrath
fcc5c80298 Formerly variable.c.~5~ 1992-06-11 02:27:16 +00:00
Roland McGrath
e309bb2f76 Formerly expand.c.~2~ 1992-06-11 02:27:09 +00:00
Roland McGrath
92dc493189 Formerly read.c.~32~ 1992-06-11 02:07:33 +00:00
Roland McGrath
39f1bf9ce8 Formerly job.c.~69~ 1992-06-05 01:04:26 +00:00
Roland McGrath
fe8bcf44ef Formerly main.c.~46~ 1992-06-05 01:04:07 +00:00
Roland McGrath
56ccbcff9a Formerly file.c.~11~ 1992-06-04 03:52:53 +00:00
Roland McGrath
72b7cf376b Formerly GNUmakefile.~63~ 1992-06-03 03:24:11 +00:00
Roland McGrath
374e8d510a Formerly commands.c.~5~ 1992-06-03 01:45:11 +00:00
Roland McGrath
343ac48a2d Formerly commands.c.~4~ 1992-06-03 01:17:16 +00:00
Roland McGrath
85bab9477b Formerly default.c.~13~ 1992-06-03 01:13:51 +00:00
Roland McGrath
835c266436 Formerly make.h.~43~ 1992-06-03 01:13:30 +00:00
Roland McGrath
6b0a5fd941 Formerly arscan.c.~18~ 1992-06-03 01:07:39 +00:00
Roland McGrath
1e9a5d4b8e Formerly GNUmakefile.~62~ 1992-05-28 05:03:09 +00:00
Roland McGrath
b238874895 Formerly GNUmakefile.~61~ 1992-05-26 10:26:59 +00:00
Roland McGrath
fc1ec6ab56 Formerly rule.c.~5~ 1992-05-26 05:26:26 +00:00
Roland McGrath
b4f6efcf69 Formerly main.c.~45~ 1992-05-25 23:02:13 +00:00
Roland McGrath
b3cc9ddd66 Formerly make.texinfo.~23~ 1992-05-21 20:34:22 +00:00
Roland McGrath
3a34103bb6 Formerly compatMakefile.~24~ 1992-05-20 00:51:39 +00:00
Roland McGrath
6268af4ceb Formerly main.c.~44~ 1992-05-20 00:49:58 +00:00
Roland McGrath
ecfe56b932 Formerly job.c.~68~ 1992-05-14 20:42:25 +00:00
Roland McGrath
16d81de018 Formerly GNUmakefile.~60~ 1992-05-14 20:05:17 +00:00
Roland McGrath
a5a036c101 Formerly job.c.~67~ 1992-05-13 22:28:01 +00:00
Roland McGrath
792819609a Formerly job.c.~66~ 1992-05-12 21:32:24 +00:00
Roland McGrath
3b69c7a484 Formerly main.c.~43~ 1992-05-12 17:29:57 +00:00
Roland McGrath
8ed1c7446e Formerly make.texinfo.~22~ 1992-05-12 04:43:56 +00:00
Roland McGrath
8486a30c74 Formerly variable.c.~4~ 1992-05-12 04:42:11 +00:00
Roland McGrath
8696be1950 Formerly GNUmakefile.~59~ 1992-05-11 19:21:28 +00:00
Roland McGrath
b43df925f8 Formerly compatMakefile.~23~ 1992-05-11 19:20:28 +00:00
Roland McGrath
cfe0c54e8c Formerly main.c.~42~ 1992-05-11 18:11:40 +00:00
Roland McGrath
81db471695 Formerly make.texinfo.~21~ 1992-05-11 05:31:18 +00:00
Roland McGrath
eb5d80d39a Formerly main.c.~41~ 1992-05-11 05:28:52 +00:00
Roland McGrath
ea3d4b3712 Formerly main.c.~40~ 1992-05-09 04:28:28 +00:00
Roland McGrath
cf561391a1 Formerly GNUmakefile.~58~ 1992-05-09 04:06:58 +00:00
Roland McGrath
276016fba7 Formerly compatMakefile.~22~ 1992-05-09 04:02:30 +00:00
Roland McGrath
d9dedc8f27 Formerly job.c.~65~ 1992-05-09 02:26:35 +00:00
Roland McGrath
569cdeac4e Formerly read.c.~31~ 1992-05-07 02:02:33 +00:00
Roland McGrath
48cabc8f9f Formerly job.c.~64~ 1992-05-05 22:04:08 +00:00
Roland McGrath
69e9db54be Formerly GNUmakefile.~57~ 1992-05-04 22:54:21 +00:00
Roland McGrath
1be71be2a2 Formerly make.texinfo.~20~ 1992-05-04 22:47:45 +00:00
Roland McGrath
2ebaa9f881 Formerly variable.c.~3~ 1992-05-04 22:37:22 +00:00
Roland McGrath
207db3747f Formerly read.c.~30~ 1992-05-04 22:37:19 +00:00
Roland McGrath
a3bd6fa73f Formerly variable.h.~3~ 1992-05-04 22:33:57 +00:00
Roland McGrath
883239f29a Formerly GNUmakefile.~56~ 1992-05-03 22:24:16 +00:00
Roland McGrath
e74b5d4fbf Formerly make.texinfo.~19~ 1992-05-03 22:21:18 +00:00
Roland McGrath
7a7b9644aa Formerly variable.h.~2~ 1992-05-03 22:09:16 +00:00
Roland McGrath
a2032ba51f Formerly read.c.~29~ 1992-05-03 22:03:26 +00:00
Roland McGrath
b8d48ad379 Formerly variable.c.~2~ 1992-05-03 22:02:26 +00:00
Roland McGrath
fec655d5e9 Formerly main.c.~39~ 1992-05-01 15:39:36 +00:00
Roland McGrath
9edeb3ad8e Formerly main.c.~38~ 1992-04-30 22:17:12 +00:00
Roland McGrath
56f17eb659 Formerly job.c.~63~ 1992-04-30 21:50:23 +00:00
Roland McGrath
d052fb99ee Formerly misc.c.~16~ 1992-04-29 21:23:10 +00:00
Roland McGrath
be3ab15f71 Formerly remake.c.~27~ 1992-04-29 21:22:58 +00:00
Roland McGrath
6a325039e2 Formerly main.c.~37~ 1992-04-29 21:15:52 +00:00
Roland McGrath
08ab2b7f94 Formerly job.c.~62~ 1992-04-29 21:11:44 +00:00
Roland McGrath
d724ba1739 Formerly job.c.~61~ 1992-04-29 01:10:14 +00:00
Roland McGrath
687844b2fe Formerly rule.c.~4~ 1992-04-29 00:44:29 +00:00
Roland McGrath
8b8764b427 Formerly rule.c.~3~ 1992-04-26 19:19:06 +00:00
Roland McGrath
f959c6b5b5 Formerly job.c.~60~ 1992-04-22 01:52:14 +00:00
Roland McGrath
7d375209b9 Formerly GNUmakefile.~55~ 1992-04-21 08:01:27 +00:00
Roland McGrath
75448c19f4 Formerly job.c.~59~ 1992-04-21 07:59:32 +00:00
Roland McGrath
a80e32c0fe Formerly main.c.~36~ 1992-04-21 07:56:07 +00:00
Roland McGrath
02b78d7ed0 Formerly commands.c.~3~ 1992-04-21 07:50:13 +00:00
Roland McGrath
3fcefefce5 Formerly function.c.~17~ 1992-04-21 07:50:09 +00:00
Roland McGrath
00da07ebd1 Formerly job.h.~3~ 1992-04-21 07:50:08 +00:00
Roland McGrath
79a2237ed2 Formerly remake.c.~26~ 1992-04-21 07:44:18 +00:00
Roland McGrath
fb37865802 Formerly job.h.~2~ 1992-04-21 07:16:26 +00:00
Roland McGrath
4ee750d034 Formerly job.c.~58~ 1992-04-15 06:02:36 +00:00
Roland McGrath
a31b168049 Formerly GNUmakefile.~54~ 1992-04-14 23:35:25 +00:00
Roland McGrath
22fda945cc Formerly implicit.c.~5~ 1992-04-14 22:39:01 +00:00
Roland McGrath
c5f7787f37 Formerly make.h.~42~ 1992-04-14 22:37:04 +00:00
Roland McGrath
7c92d87313 Formerly read.c.~28~ 1992-04-14 22:31:19 +00:00
Roland McGrath
491a9d9cb4 Formerly GNUmakefile.~53~ 1992-04-14 02:30:18 +00:00
Roland McGrath
71956239ac Formerly remake.c.~25~ 1992-04-14 02:12:51 +00:00
Roland McGrath
123c2494c3 Formerly remake.c.~24~ 1992-04-01 10:06:27 +00:00
Roland McGrath
d8742e9b3e Formerly file.c.~10~ 1992-04-01 09:58:26 +00:00
Roland McGrath
a7ec3f0576 Formerly read.c.~27~ 1992-04-01 09:42:11 +00:00
Roland McGrath
008dab1b25 Formerly commands.c.~2~ 1992-03-31 00:24:58 +00:00
Roland McGrath
d922934cf8 Formerly rule.c.~2~ 1992-03-24 09:50:46 +00:00
Roland McGrath
39d4bb0c7a Formerly remake.c.~23~ 1992-03-11 19:59:26 +00:00
Roland McGrath
feb8a001e1 Formerly make.texinfo.~18~ 1992-03-11 19:56:18 +00:00
melissa
9573cef0a8 Formerly make.texinfo.~17~ 1992-03-11 03:20:05 +00:00
melissa
bc8dd5d3f0 Formerly make.texinfo.~15~ 1992-03-10 23:51:10 +00:00
Roland McGrath
a4bfdb8264 Formerly remote-stub.c.~2~ 1992-03-10 22:15:46 +00:00
Roland McGrath
ee200385e4 Formerly remote-cstms.c.~4~ 1992-03-10 22:15:39 +00:00
Roland McGrath
c7ba588030 Formerly compatMakefile.~21~ 1992-03-10 22:15:32 +00:00
Roland McGrath
8da2a78834 Formerly job.c.~57~ 1992-03-10 22:15:30 +00:00
Roland McGrath
1fc97863a0 Formerly file.c.~9~ 1992-03-09 23:17:21 +00:00
Roland McGrath
46677a6769 Initial revision 1992-03-09 23:06:05 +00:00
Roland McGrath
4f811a3de9 Formerly compatMakefile.~20~ 1992-03-09 23:00:07 +00:00
Roland McGrath
13f4412f2c Formerly function.c.~16~ 1992-03-01 20:48:57 +00:00
Roland McGrath
edbca2344d Formerly make.texinfo.~14~ 1992-02-26 04:34:35 +00:00
Roland McGrath
794fb5ac89 Formerly GNUmakefile.~52~ 1992-02-16 07:20:51 +00:00
Roland McGrath
f5c49a3f5c Initial revision 1992-02-15 22:12:14 +00:00
Roland McGrath
5adf3025db Formerly read.c.~26~ 1992-02-14 11:30:14 +00:00
Roland McGrath
24e5b78f36 Initial revision 1992-02-14 10:52:22 +00:00
Roland McGrath
ba251262db Formerly main.c.~35~ 1992-02-14 05:15:30 +00:00
Roland McGrath
0642eea2ab Formerly make.texinfo.~13~ 1992-02-12 17:07:34 +00:00
Roland McGrath
6858598bee Formerly GNUmakefile.~51~ 1992-02-06 22:12:06 +00:00
Roland McGrath
87178cb5a4 Formerly job.c.~56~ 1992-02-05 01:04:23 +00:00
Roland McGrath
3e08b8c56a Formerly make.h.~41~ 1992-01-29 23:54:37 +00:00
Roland McGrath
ba26d609a1 Initial revision 1992-01-29 23:54:36 +00:00
Robert J. Chassell
7eda2f8293 Formerly make.texinfo.~12~ 1992-01-23 22:25:20 +00:00
Roland McGrath
cb14b4eb1e Initial revision 1992-01-20 19:14:46 +00:00
Roland McGrath
d2e5ab8c57 Initial revision 1992-01-20 18:49:36 +00:00
Roland McGrath
3798621e0b Initial revision 1992-01-18 02:09:28 +00:00
Roland McGrath
94527665c2 Initial revision 1992-01-17 08:30:31 +00:00
Roland McGrath
77497793e0 Formerly misc.c.~15~ 1992-01-17 08:30:27 +00:00
Roland McGrath
6a2935d67b Formerly default.c.~12~ 1992-01-14 02:12:09 +00:00
Roland McGrath
ee02d42916 Formerly make.texinfo.~11~ 1992-01-14 00:15:26 +00:00
Roland McGrath
b859320606 Initial revision 1992-01-11 11:37:36 +00:00
Roland McGrath
1eadb68598 Initial revision 1992-01-11 11:09:59 +00:00
Roland McGrath
8ac061de69 Formerly make.texinfo.~10~ 1992-01-11 07:20:24 +00:00
Roland McGrath
45fa41ff5c Formerly make.texinfo.~9~ 1991-12-30 18:11:55 +00:00
Roland McGrath
bdb62b6fe9 Formerly make.texinfo.~8~ 1991-11-15 02:22:08 +00:00
Roland McGrath
12220aa8fd Formerly arscan.c.~17~ 1991-10-23 01:30:25 +00:00
Roland McGrath
da136cba6f Initial revision 1991-10-18 19:26:24 +00:00
Roland McGrath
a4a1d4a78d Initial revision 1991-10-08 20:20:29 +00:00
Roland McGrath
6af05c6197 Initial revision 1991-10-08 20:04:17 +00:00
Roland McGrath
42289c5f18 Formerly implicit.c.~4~ 1991-10-08 20:04:11 +00:00
Roland McGrath
fb0ffcddc8 Formerly arscan.c.~16~ 1991-10-07 22:05:49 +00:00
Roland McGrath
97d38d0817 Initial revision 1991-10-07 22:04:20 +00:00
Roland McGrath
bd3a693fd4 Initial revision 1991-09-24 04:03:40 +00:00
Roland McGrath
4575aeb1e7 Formerly make.man.~3~ 1991-09-24 03:33:24 +00:00
Roland McGrath
c6fec241bc Formerly make.texinfo.~7~ 1991-09-18 19:07:51 +00:00
Roland McGrath
b9c983dee3 Initial revision 1991-09-15 21:20:45 +00:00
Roland McGrath
1a51e308e5 Initial revision 1991-09-13 23:39:37 +00:00
Roland McGrath
462a5eabb4 Formerly rule.h.~2~ 1991-06-03 20:37:28 +00:00
Roland McGrath
59fdb0d242 Initial revision 1991-06-03 20:37:27 +00:00
Roland McGrath
19ca125ae7 Initial revision 1991-03-23 14:10:48 +00:00
Roland McGrath
47a8cea564 Formerly make.man.~2~ 1990-09-17 20:01:40 +00:00
Roland McGrath
a7e692dc7a Initial revision 1990-01-25 05:31:33 +00:00
Roland McGrath
cd20a6a67f Initial revision 1989-08-13 07:28:15 +00:00
Roland McGrath
38892f2959 Initial revision 1989-06-11 21:44:40 +00:00
Roland McGrath
83fcf12d25 Initial revision 1989-05-10 22:57:31 +00:00
Roland McGrath
db3c60d235 Minor editorial changes. 1988-07-10 17:52:55 +00:00
Roland McGrath
2153102725 Changed `Features' chapter, giving credit to some
people who may have invented some things.
1988-07-10 00:51:51 +00:00
Roland McGrath
bf81164407 Gave credit for VPATH to System V (where it was invented, but
is undocumented) as well as 4.3 BSD (where it was taken from
System V and documented).
Added the replacement of filenames found via VPATH search inside
commands to `Missing' list.  Maybe implement this soon?
1988-07-04 13:41:43 +00:00
Roland McGrath
3206072ac3 * Misc cleanup from RMS.
* Documented `word' and `words' functions.
* Bumped revision number to match make.c
1988-07-03 20:59:14 +00:00
Roland McGrath
c9be6b239c Added some more stuff about recursive references. 1988-07-03 13:07:42 +00:00
Roland McGrath
78079dd062 Misc cleanup. Fixed `Features' list slightly. 1988-07-02 17:49:14 +00:00
Roland McGrath
da1fb0f2e9 Added copying conditions. 1988-07-02 12:14:48 +00:00
Roland McGrath
b85736329a * Fixed a minor grammaticaly error.
* Second release.
1988-06-28 21:58:42 +00:00
Roland McGrath
b8342bbfa8 Added recursive variable references. 1988-06-19 16:15:50 +00:00
Roland McGrath
0bc8f78d4b Fixed yet another Texinfo error. (Sigh) 1988-06-18 01:16:59 +00:00
Roland McGrath
03e57530fa Fixed some more Texinfo errors. 1988-06-18 00:26:10 +00:00
Roland McGrath
6e427e1209 * Documented that -k will continue if it doesn't know how to make a file.
* Fixed a Texinfo error.
* Bumped revision number to match the source.
1988-06-18 00:19:49 +00:00
Roland McGrath
0bc6cc3735 * Removed Bourne shell $(a-b), etc. variable references.
* Fixed foreach documentation slightly.
* Added chapter listing features tersely.
1988-06-18 00:13:50 +00:00
Roland McGrath
6b7b5698e9 Misc cleanup by RMS.
Removed RCS log.
1988-06-14 21:38:42 +00:00
Roland McGrath
edacffc68d Added more stuff about `foreach'. 1988-06-10 11:43:00 +00:00
Roland McGrath
8d8b42b086 * Fixed a typo in the `Missing' section.
* Added an example of how to replace the System V $$@ feature
  using static pattern rules.
1988-06-03 00:07:30 +00:00
Roland McGrath
4f7ffc8c0f Added foreach' and sort' functions. 1988-05-30 21:39:16 +00:00
Roland McGrath
15c5b63713 * Removed built-in .? -> .s suffix rules.
* Misc cleanup, etc.
1988-05-26 17:55:55 +00:00
44 changed files with 26640 additions and 1807 deletions

279
GNUmakefile Normal file
View File

@@ -0,0 +1,279 @@
# GNU Make-specific makefile for GNU Make.
# Copyright (C) 1990, 1991, 1992, 1993, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA.
.PHONY: default
default:
# Set `ARCH' to a string for the type of machine.
ifndef ARCH
ifdef machine
ARCH = $(machine)
endif # machine
endif # not ARCH
override srcdir := .
override CC := $(CC)
ifeq ($(ARCH),hp300)
#customs=yes
endif
ifdef customs
override REMOTE := cstms
else
override REMOTE := stub
endif
# Get most of the information from the Unix-compatible makefile.
include compatMakefile
MAKE = $(MAKE_COMMAND) $(MAKEOVERRIDES)
# Remove autoconf magic.
prefix = /usr/local
exec_prefix = $(prefix)
extras := $(filter-out getloadavg.o @%@,$(extras)) getloadavg.o
LOADLIBES := $(filter-out @%@,$(LOADLIBES))
ALLOCA := $(filter-out @%@,$(ALLOCA))
ifdef AC_MACRODIR
configure config.h.in: $(patsubst %,$(AC_MACRODIR)/%.m4,acspecific acgeneral)
config.h.in: $(AC_MACRODIR)/acconfig.h
endif
configure: configure.in; autoconf $(ACFLAGS)
config.h.in: configure.in; autoheader $(ACFLAGS)
ifdef customs
defines := $(defines) -Ipmake/customs -Ipmake/lib/include
LOADLIBES := $(addprefix pmake/customs/,customslib.o rpc.o xlog.o) \
pmake/lib/sprite/libsprite.a
endif
ifdef ARCH
ifndef no_libc
libc_dir = /home/gd2/gnu/libc/$(ARCH)
ifneq ($(wildcard $(libc_dir)),)
ifneq ($(wildcard $(libc_dir)/works-for-make),)
#CPPFLAGS := -I$(libc_dir)/include
#LDFLAGS := -nostdlib $(libc_dir)/lib/start.o
#LOADLIBES := $(LOADLIBES) \
# $(libc_dir)/lib/mcheck-init.o \
# $(libc_dir)/lib/libc.a \
# -lgcc \
# $(libc_dir)/lib/libc.a
CC := $(CC) -b glibc
# getopt is in libc.
GETOPT =
#GETOPT_SRC = Don't clear this or dist will break.
# glob is in libc too.
GLOB =
else
CPPFLAGS := $(filter-out @%@,$(CPPFLAGS)) -Iglob
endif # works-for-make
endif # $(libc_dir)
endif # !no_libc
# We know the type of machine, so put the binaries in subdirectories.
$(ARCH)/%.o: %.c
$(COMPILE.c) -Iglob $< $(OUTPUT_OPTION)
$(ARCH)/glob/libglob.a: FORCE
$(MAKE) -C $(@D) $(@F)
FORCE:
objs := $(addprefix $(ARCH)/,$(objs))
prog := $(ARCH)/make
archpfx = $(ARCH)/
$(archpfx)load.o: load.c
$(COMPILE.c) $(LOAD_AVG) $< -o $@
$(archpfx)load.dep: load.c
$(mkdep) $(LOAD_AVG) $< | sed 's,$*\.o,& $@,' > $@
CPPFLAGS := -I$(ARCH) $(CPPFLAGS) -DHAVE_CONFIG_H $(filter-out @%@,$(defines))
ifneq "$(wildcard $(ARCH)/makefile)" ""
include $(ARCH)/makefile
endif
objs := $(objs) $(addprefix $(ARCH)/,$(ALLOCA) $(extras))
else # Not ARCH
prog := make
endif
ifneq "$(findstring gcc,$(CC))" ""
CFLAGS = -g -W -Wunused -Wpointer-arith -Wreturn-type -Wswitch
else
CFLAGS = -g
endif
LDFLAGS = -g
# Define the command to make dependencies.
ifneq "$(findstring gcc,$(CC))" ""
# Don't include system directories.
mkdep-nolib = $(CC) -MM $(CPPFLAGS)
else
mkdep-nolib = $(mkdep)
endif
mkdep = $(CC) -M $(CPPFLAGS)
depfiles = $(patsubst %.o,%.dep,$(filter %.o,$(objs)))
.PHONY: default
default: $(prog)
$(prog): $(objs) $(globdep) #$(addprefix $(ARCH)/,gmalloc.o mcheck.o)
$(CC) $(LDFLAGS) $^ $(globlib) $(LOADLIBES) -o $@.new
mv -f $@.new $@
globfiles = $(addprefix glob/,COPYING.LIB Makefile.in \
glob.c fnmatch.c glob.h fnmatch.h)
$(globfiles): stamp-glob ;
stamp-glob: /home/gd/gnu/libc/posix/glob.tar
-rm -rf glob
tar xvf $< glob
touch $@
/home/gd/gnu/libc/posix/glob.tar: force
$(MAKE) -C $(@D) $(@F) no_deps=t
.PHONY: force
force:
# Make the Unix-compatible Makefile to be distributed by appending
# the automatically-generated dependencies to compatMakefile.
ifeq ($(mkdep),$(mkdep-nolib))
nolib-deps = $(depfiles)
else
%.dep: %.c
$(mkdep-nolib) $< | sed -e 's,$*\.o,$(@:.dep=.o) $@,' > $(@:.dep=.dtm)
mv -f $(@:.dep=.dtm) $@
nolib-deps = $(patsubst $(archpfx)%,%,$(depfiles))
endif
# The distributed Makefile.in should contain deps for remote-stub only.
Makefile.in: compatMakefile $(nolib-deps:remote-%.dep=remote-stub.dep)
(sed 's/^MAKE[ ]*=.*$$/@SET_MAKE@/' $<; \
echo '# Automatically generated dependencies.'; \
sed -e 's/ [^ ]*\.dep//' -e 's=$(archpfx)==' $(filter-out $<,$^) \
) > $@
.SUFFIXES: .dep
# Maintain the automatically-generated dependencies.
ifndef no_deps
include $(depfiles)
endif
$(archpfx)%.dep: %.c
$(mkdep) $< | sed 's,$*\.o,$(@:.dep=.o) $@,' > $@
ETAGS = etags -T # for v19 etags
# Run the tests.
.PHONY: tests
testdir := $(shell ls -d1 make-test-?.? | sort -n +0.10 -0.11 +0.12 | tail -1l)
tests:# $(testdir)/run_make_tests.pl $(prog)
# cd $(<D); MAKELEVEL=0 perl $(<F)
build.sh.in: build.template compatMakefile
sed -e 's@%objs%@$(filter-out remote-% $(GLOB) $(ALLOCA) $(extras),\
$(patsubst $(archpfx)%,%,$(objs)))\
$(patsubst %.c,%.o,$(filter %.c,$(globfiles)))@' \
$< > $@.new
mv -f $@.new $@
# Make the distribution tar files.
.PHONY: dist
# Figure out the version number from the source of `version.c'.
version := \
$(strip $(shell sed -e '/=/!d' -e 's/^.*"\(.*\)";$$/\1/' < version.c))
tarfiles := make # make-doc
tarfiles := $(addsuffix -$(version).tar,$(tarfiles))
tarfiles := $(tarfiles:%=%.gz) # no more compress $(tarfiles:%=%.Z)
# Depend on default and doc so we don't ship anything that won't compile.
dist: rcs-mark default info dvi tests tarfiles
.PHONY: tarfiles
tarfiles: $(tarfiles)
ifndef dist-flavor
dist-flavor = alpha
endif
.PHONY: rcs-mark rcs-mark-alpha rcs-mark-beta
rcs-mark: rcs-mark-$(dist-flavor)
rcs-mark-alpha: RCS/[!=]*,v;rcs -sAlpha -Nmake-$(version-): $^
rcs-mark-beta: RCS/[!=]*,v;rcs -sBeta -Nmake-$(version-): $^
version- = $(subst .,-,$(version))
dist: local-inst
.PHONY: local-inst
local-inst: $(prog)
install -c -g kmem -o $(USER) -m 2755 $< /usr/local/gnubin/make
# Put the alpha distribution files in the anonymous FTP directory.
alpha-files = $(tarfiles) GNUmakefile compatMakefile $(testdir).tar.Z
dist: alpha
.PHONY: alpha
alpha-dir := ~ftp/gnu
alpha-files := $(addprefix $(alpha-dir)/,$(alpha-files))
alpha: $(alpha-dir) $(alpha-files)
$(alpha-dir)/%: %
@rm -f $@
cp $< $@
# Implicit rule to make README and README-doc.
%: %.template version.c
rm -f $@
sed 's/VERSION/$(version)/' < $< > $@
# Make sure I don't edit it by accident.
chmod a-w $@
define make-tar
@rm -fr make-$(version)
ln -s . make-$(version)
tar cvhof $@ $(addprefix make-$(version)/,$^)
rm -f make-$(version)
endef
%.Z: %; compress -c $< > $@
%.gz: %; gzip -9 -c -v $< > $@
make-doc-$(version).tar: README-doc COPYING make.dvi make.info make.info*
$(make-tar)
make-$(version).tar: README INSTALL COPYING ChangeLog NEWS \
configure Makefile.in configure.in build.sh.in mkinstalldirs \
acconfig.h $(srcs) remote-*.c $(globfiles) \
make.texinfo make-stds.texi \
make.?? make.??s make.toc make.aux make.man texinfo.tex TAGS tags \
install-sh \
make.info make.info*
$(make-tar)
ifneq (,)
tests := $(filter-out %~,$(wildcard tests/*))
make-tests-$(version).tar.Z: $(tests)
@rm -fr make-tests-$(version)
ln -s tests make-tests-$(version)
tar cvhf $(@:.Z=) $(patsubst tests/%,make-tests-$(version)/%,$^)
rm -f make-tests-$(version)
compress -f $(@:.Z=)
endif
$(archpfx)loadtest: $(archpfx)load.o

28
README.template Normal file
View File

@@ -0,0 +1,28 @@
This directory contains the VERSION test release of GNU Make.
All bugs reported for previous test releases have been fixed.
Some bugs surely remain.
For general building and installation instructions, see the file INSTALL.
If you need to build GNU Make and have no other `make' program to use,
you can use the shell script `build.sh' instead. To do this, first run
`configure' as described in INSTALL. Then, instead of typing `make' to
build the program, type `sh build.sh'. This should compile the program
in the current directory. Then you will have a Make program that you can
use for `make install', or whatever else.
It has been reported that the XLC 1.2 compiler on AIX 3.2 is buggy such
that if you compile make with `cc -O' on AIX 3.2, it will not work correctly.
It is said that using `cc' without `-O' does work.
One area that is often a problem in configuration and porting is the code
to check the system's current load average. To make it easier to test and
debug this code, you can do `make check-loadavg' to see if it works
properly on your system. (You must run `configure' beforehand, but you
need not build Make itself to run this test.)
See the file NEWS for what has changed since previous releases.
GNU Make is fully documented in make.texinfo. See the section entitled
`Problems and Bugs' for information on submitting bug reports.
GNU Make is free software. See the file COPYING for copying conditions.

14
acconfig.h Normal file
View File

@@ -0,0 +1,14 @@
/* Define to the name of the SCCS `get' command. */
#undef SCCS_GET
/* Define this if the SCCS `get' command understands the `-G<file>' option. */
#undef SCCS_GET_MINUS_G
/* Define this if the C library defines the variable `sys_siglist'. */
#undef HAVE_SYS_SIGLIST
/* Define this if the C library defines the variable `_sys_siglist'. */
#undef HAVE__SYS_SIGLIST
/* Define this if you have the `union wait' type in <sys/wait.h>. */
#undef HAVE_UNION_WAIT

492
alloca.c Normal file
View File

@@ -0,0 +1,492 @@
/* alloca.c -- allocate automatically reclaimed memory
(Mostly) portable public-domain implementation -- D A Gwyn
This implementation of the PWB library alloca function,
which is used to allocate space off the run-time stack so
that it is automatically reclaimed upon procedure exit,
was inspired by discussions with J. Q. Johnson of Cornell.
J.Otto Tennant <jot@cray.com> contributed the Cray support.
There are some preprocessor constants that can
be defined when compiling for your specific system, for
improved efficiency; however, the defaults should be okay.
The general concept of this implementation is to keep
track of all alloca-allocated blocks, and reclaim any
that are found to be deeper in the stack than the current
invocation. This heuristic does not reclaim storage as
soon as it becomes invalid, but it will do so eventually.
As a special case, alloca(0) reclaims storage without
allocating any. It is a good idea to use alloca(0) in
your main control loop, etc. to force garbage collection. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef emacs
#include "blockinput.h"
#endif
/* If compiling with GCC 2, this file's not needed. */
#if !defined (__GNUC__) || __GNUC__ < 2
/* If someone has defined alloca as a macro,
there must be some other way alloca is supposed to work. */
#ifndef alloca
#ifdef emacs
#ifdef static
/* actually, only want this if static is defined as ""
-- this is for usg, in which emacs must undefine static
in order to make unexec workable
*/
#ifndef STACK_DIRECTION
you
lose
-- must know STACK_DIRECTION at compile-time
#endif /* STACK_DIRECTION undefined */
#endif /* static */
#endif /* emacs */
/* If your stack is a linked list of frames, you have to
provide an "address metric" ADDRESS_FUNCTION macro. */
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
long i00afunc ();
#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
#else
#define ADDRESS_FUNCTION(arg) &(arg)
#endif
#if __STDC__
typedef void *pointer;
#else
typedef char *pointer;
#endif
#define NULL 0
/* Different portions of Emacs need to call different versions of
malloc. The Emacs executable needs alloca to call xmalloc, because
ordinary malloc isn't protected from input signals. On the other
hand, the utilities in lib-src need alloca to call malloc; some of
them are very simple, and don't have an xmalloc routine.
Non-Emacs programs expect this to call use xmalloc.
Callers below should use malloc. */
#ifndef emacs
#define malloc xmalloc
#endif
extern pointer malloc ();
/* Define STACK_DIRECTION if you know the direction of stack
growth for your system; otherwise it will be automatically
deduced at run-time.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
#ifndef STACK_DIRECTION
#define STACK_DIRECTION 0 /* Direction unknown. */
#endif
#if STACK_DIRECTION != 0
#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
#else /* STACK_DIRECTION == 0; need run-time code. */
static int stack_dir; /* 1 or -1 once known. */
#define STACK_DIR stack_dir
static void
find_stack_direction ()
{
static char *addr = NULL; /* Address of first `dummy', once known. */
auto char dummy; /* To get stack address. */
if (addr == NULL)
{ /* Initial entry. */
addr = ADDRESS_FUNCTION (dummy);
find_stack_direction (); /* Recurse once. */
}
else
{
/* Second entry. */
if (ADDRESS_FUNCTION (dummy) > addr)
stack_dir = 1; /* Stack grew upward. */
else
stack_dir = -1; /* Stack grew downward. */
}
}
#endif /* STACK_DIRECTION == 0 */
/* An "alloca header" is used to:
(a) chain together all alloca'ed blocks;
(b) keep track of stack depth.
It is very important that sizeof(header) agree with malloc
alignment chunk size. The following default should work okay. */
#ifndef ALIGN_SIZE
#define ALIGN_SIZE sizeof(double)
#endif
typedef union hdr
{
char align[ALIGN_SIZE]; /* To force sizeof(header). */
struct
{
union hdr *next; /* For chaining headers. */
char *deep; /* For stack depth measure. */
} h;
} header;
static header *last_alloca_header = NULL; /* -> last alloca header. */
/* Return a pointer to at least SIZE bytes of storage,
which will be automatically reclaimed upon exit from
the procedure that called alloca. Originally, this space
was supposed to be taken from the current stack frame of the
caller, but that method cannot be made to work for some
implementations of C, for example under Gould's UTX/32. */
pointer
alloca (size)
unsigned size;
{
auto char probe; /* Probes stack depth: */
register char *depth = ADDRESS_FUNCTION (probe);
#if STACK_DIRECTION == 0
if (STACK_DIR == 0) /* Unknown growth direction. */
find_stack_direction ();
#endif
/* Reclaim garbage, defined as all alloca'd storage that
was allocated from deeper in the stack than currently. */
{
register header *hp; /* Traverses linked list. */
#ifdef emacs
BLOCK_INPUT;
#endif
for (hp = last_alloca_header; hp != NULL;)
if ((STACK_DIR > 0 && hp->h.deep > depth)
|| (STACK_DIR < 0 && hp->h.deep < depth))
{
register header *np = hp->h.next;
free ((pointer) hp); /* Collect garbage. */
hp = np; /* -> next header. */
}
else
break; /* Rest are not deeper. */
last_alloca_header = hp; /* -> last valid storage. */
#ifdef emacs
UNBLOCK_INPUT;
#endif
}
if (size == 0)
return NULL; /* No allocation required. */
/* Allocate combined header + user data storage. */
{
register pointer new = malloc (sizeof (header) + size);
/* Address of header. */
((header *) new)->h.next = last_alloca_header;
((header *) new)->h.deep = depth;
last_alloca_header = (header *) new;
/* User storage begins just after header. */
return (pointer) ((char *) new + sizeof (header));
}
}
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
#ifdef DEBUG_I00AFUNC
#include <stdio.h>
#endif
#ifndef CRAY_STACK
#define CRAY_STACK
#ifndef CRAY2
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
struct stack_control_header
{
long shgrow:32; /* Number of times stack has grown. */
long shaseg:32; /* Size of increments to stack. */
long shhwm:32; /* High water mark of stack. */
long shsize:32; /* Current size of stack (all segments). */
};
/* The stack segment linkage control information occurs at
the high-address end of a stack segment. (The stack
grows from low addresses to high addresses.) The initial
part of the stack segment linkage control information is
0200 (octal) words. This provides for register storage
for the routine which overflows the stack. */
struct stack_segment_linkage
{
long ss[0200]; /* 0200 overflow words. */
long sssize:32; /* Number of words in this segment. */
long ssbase:32; /* Offset to stack base. */
long:32;
long sspseg:32; /* Offset to linkage control of previous
segment of stack. */
long:32;
long sstcpt:32; /* Pointer to task common address block. */
long sscsnm; /* Private control structure number for
microtasking. */
long ssusr1; /* Reserved for user. */
long ssusr2; /* Reserved for user. */
long sstpid; /* Process ID for pid based multi-tasking. */
long ssgvup; /* Pointer to multitasking thread giveup. */
long sscray[7]; /* Reserved for Cray Research. */
long ssa0;
long ssa1;
long ssa2;
long ssa3;
long ssa4;
long ssa5;
long ssa6;
long ssa7;
long sss0;
long sss1;
long sss2;
long sss3;
long sss4;
long sss5;
long sss6;
long sss7;
};
#else /* CRAY2 */
/* The following structure defines the vector of words
returned by the STKSTAT library routine. */
struct stk_stat
{
long now; /* Current total stack size. */
long maxc; /* Amount of contiguous space which would
be required to satisfy the maximum
stack demand to date. */
long high_water; /* Stack high-water mark. */
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
long hits; /* Number of internal buffer hits. */
long extends; /* Number of block extensions. */
long stko_mallocs; /* Block allocations by $STKOFEN. */
long underflows; /* Number of stack underflow calls ($STKRETN). */
long stko_free; /* Number of deallocations by $STKRETN. */
long stkm_free; /* Number of deallocations by $STKMRET. */
long segments; /* Current number of stack segments. */
long maxs; /* Maximum number of stack segments so far. */
long pad_size; /* Stack pad size. */
long current_address; /* Current stack segment address. */
long current_size; /* Current stack segment size. This
number is actually corrupted by STKSTAT to
include the fifteen word trailer area. */
long initial_address; /* Address of initial segment. */
long initial_size; /* Size of initial segment. */
};
/* The following structure describes the data structure which trails
any stack segment. I think that the description in 'asdef' is
out of date. I only describe the parts that I am sure about. */
struct stk_trailer
{
long this_address; /* Address of this block. */
long this_size; /* Size of this block (does not include
this trailer). */
long unknown2;
long unknown3;
long link; /* Address of trailer block of previous
segment. */
long unknown5;
long unknown6;
long unknown7;
long unknown8;
long unknown9;
long unknown10;
long unknown11;
long unknown12;
long unknown13;
long unknown14;
};
#endif /* CRAY2 */
#endif /* not CRAY_STACK */
#ifdef CRAY2
/* Determine a "stack measure" for an arbitrary ADDRESS.
I doubt that "lint" will like this much. */
static long
i00afunc (long *address)
{
struct stk_stat status;
struct stk_trailer *trailer;
long *block, size;
long result = 0;
/* We want to iterate through all of the segments. The first
step is to get the stack status structure. We could do this
more quickly and more directly, perhaps, by referencing the
$LM00 common block, but I know that this works. */
STKSTAT (&status);
/* Set up the iteration. */
trailer = (struct stk_trailer *) (status.current_address
+ status.current_size
- 15);
/* There must be at least one stack segment. Therefore it is
a fatal error if "trailer" is null. */
if (trailer == 0)
abort ();
/* Discard segments that do not contain our argument address. */
while (trailer != 0)
{
block = (long *) trailer->this_address;
size = trailer->this_size;
if (block == 0 || size == 0)
abort ();
trailer = (struct stk_trailer *) trailer->link;
if ((block <= address) && (address < (block + size)))
break;
}
/* Set the result to the offset in this segment and add the sizes
of all predecessor segments. */
result = address - block;
if (trailer == 0)
{
return result;
}
do
{
if (trailer->this_size <= 0)
abort ();
result += trailer->this_size;
trailer = (struct stk_trailer *) trailer->link;
}
while (trailer != 0);
/* We are done. Note that if you present a bogus address (one
not in any segment), you will get a different number back, formed
from subtracting the address of the first block. This is probably
not what you want. */
return (result);
}
#else /* not CRAY2 */
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
Determine the number of the cell within the stack,
given the address of the cell. The purpose of this
routine is to linearize, in some sense, stack addresses
for alloca. */
static long
i00afunc (long address)
{
long stkl = 0;
long size, pseg, this_segment, stack;
long result = 0;
struct stack_segment_linkage *ssptr;
/* Register B67 contains the address of the end of the
current stack segment. If you (as a subprogram) store
your registers on the stack and find that you are past
the contents of B67, you have overflowed the segment.
B67 also points to the stack segment linkage control
area, which is what we are really interested in. */
stkl = CRAY_STACKSEG_END ();
ssptr = (struct stack_segment_linkage *) stkl;
/* If one subtracts 'size' from the end of the segment,
one has the address of the first word of the segment.
If this is not the first segment, 'pseg' will be
nonzero. */
pseg = ssptr->sspseg;
size = ssptr->sssize;
this_segment = stkl - size;
/* It is possible that calling this routine itself caused
a stack overflow. Discard stack segments which do not
contain the target address. */
while (!(this_segment <= address && address <= stkl))
{
#ifdef DEBUG_I00AFUNC
fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
#endif
if (pseg == 0)
break;
stkl = stkl - pseg;
ssptr = (struct stack_segment_linkage *) stkl;
size = ssptr->sssize;
pseg = ssptr->sspseg;
this_segment = stkl - size;
}
result = address - this_segment;
/* If you subtract pseg from the current end of the stack,
you get the address of the previous stack segment's end.
This seems a little convoluted to me, but I'll bet you save
a cycle somewhere. */
while (pseg != 0)
{
#ifdef DEBUG_I00AFUNC
fprintf (stderr, "%011o %011o\n", pseg, size);
#endif
stkl = stkl - pseg;
ssptr = (struct stack_segment_linkage *) stkl;
size = ssptr->sssize;
pseg = ssptr->sspseg;
result += size;
}
return (result);
}
#endif /* not CRAY2 */
#endif /* CRAY */
#endif /* no alloca */
#endif /* not GCC version 2 */

317
ar.c Normal file
View File

@@ -0,0 +1,317 @@
/* Interface to `ar' archives for GNU Make.
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "make.h"
#ifndef NO_ARCHIVES
#include "file.h"
#include "dep.h"
#include <fnmatch.h>
/* Defined in arscan.c. */
extern long int ar_scan ();
extern int ar_member_touch ();
extern int ar_name_equal ();
/* Return nonzero if NAME is an archive-member reference, zero if not.
An archive-member reference is a name like `lib(member)'.
If a name like `lib((entry))' is used, a fatal error is signaled at
the attempt to use this unsupported feature. */
int
ar_name (name)
char *name;
{
char *p = index (name, '('), *end = name + strlen (name) - 1;
if (p == 0 || p == name || *end != ')')
return 0;
if (p[1] == '(' && end[-1] == ')')
fatal ("attempt to use unsupported feature: `%s'", name);
return 1;
}
/* Parse the archive-member reference NAME into the archive and member names.
Put the malloc'd archive name in *ARNAME_P if ARNAME_P is non-nil;
put the malloc'd member name in *MEMNAME_P if MEMNAME_P is non-nil. */
void
ar_parse_name (name, arname_p, memname_p)
char *name, **arname_p, **memname_p;
{
char *p = index (name, '('), *end = name + strlen (name) - 1;
if (arname_p != 0)
*arname_p = savestring (name, p - name);
if (memname_p != 0)
*memname_p = savestring (p + 1, end - (p + 1));
}
static long int ar_member_date_1 ();
/* Return the modtime of NAME. */
time_t
ar_member_date (name)
char *name;
{
char *arname;
int arname_used = 0;
char *memname;
long int val;
ar_parse_name (name, &arname, &memname);
/* Make sure we know the modtime of the archive itself because we are
likely to be called just before commands to remake a member are run,
and they will change the archive itself.
But we must be careful not to enter_file the archive itself if it does
not exist, because pattern_search assumes that files found in the data
base exist or can be made. */
{
struct file *arfile;
arfile = lookup_file (arname);
if (arfile == 0 && file_exists_p (arname))
{
arfile = enter_file (arname);
arname_used = 1;
}
if (arfile != 0)
(void) f_mtime (arfile, 0);
}
val = ar_scan (arname, ar_member_date_1, (long int) memname);
if (!arname_used)
free (arname);
free (memname);
return (val <= 0 ? (time_t) -1 : (time_t) val);
}
/* This function is called by `ar_scan' to find which member to look at. */
/* ARGSUSED */
static long int
ar_member_date_1 (desc, mem, truncated,
hdrpos, datapos, size, date, uid, gid, mode, name)
int desc;
char *mem;
int truncated;
long int hdrpos, datapos, size, date;
int uid, gid, mode;
char *name;
{
return ar_name_equal (name, mem, truncated) ? date : 0;
}
/* Set the archive-member NAME's modtime to now. */
int
ar_touch (name)
char *name;
{
char *arname, *memname;
int arname_used = 0;
register int val;
ar_parse_name (name, &arname, &memname);
/* Make sure we know the modtime of the archive itself before we
touch the member, since this will change the archive itself. */
{
struct file *arfile;
arfile = lookup_file (arname);
if (arfile == 0)
{
arfile = enter_file (arname);
arname_used = 1;
}
(void) f_mtime (arfile, 0);
}
val = 1;
switch (ar_member_touch (arname, memname))
{
case -1:
error ("touch: Archive `%s' does not exist", arname);
break;
case -2:
error ("touch: `%s' is not a valid archive", arname);
break;
case -3:
perror_with_name ("touch: ", arname);
break;
case 1:
error ("touch: Member `%s' does not exist in `%s'", memname, arname);
break;
case 0:
val = 0;
break;
default:
error ("touch: Bad return code from ar_member_touch on `%s'", name);
}
if (!arname_used)
free (arname);
free (memname);
return val;
}
/* State of an `ar_glob' run, passed to `ar_glob_match'. */
struct ar_glob_state
{
char *arname;
char *pattern;
unsigned int size;
struct nameseq *chain;
unsigned int n;
};
/* This function is called by `ar_scan' to match one archive
element against the pattern in STATE. */
static long int
ar_glob_match (desc, mem, truncated,
hdrpos, datapos, size, date, uid, gid, mode,
state)
int desc;
char *mem;
int truncated;
long int hdrpos, datapos, size, date;
int uid, gid, mode;
struct ar_glob_state *state;
{
if (fnmatch (state->pattern, mem, FNM_PATHNAME|FNM_PERIOD) == 0)
{
/* We have a match. Add it to the chain. */
struct nameseq *new = (struct nameseq *) xmalloc (state->size);
new->name = concat (state->arname, mem, ")");
new->next = state->chain;
state->chain = new;
++state->n;
}
return 0L;
}
/* Alphabetic sorting function for `qsort'. */
static int
ar_glob_alphacompare (a, b)
char **a, **b;
{
return strcmp (*a, *b);
}
/* Return nonzero if PATTERN contains any metacharacters.
Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
static int
glob_pattern_p (pattern, quote)
const char *pattern;
const int quote;
{
register const char *p;
int open = 0;
for (p = pattern; *p != '\0'; ++p)
switch (*p)
{
case '?':
case '*':
return 1;
case '\\':
if (quote)
++p;
break;
case '[':
open = 1;
break;
case ']':
if (open)
return 1;
break;
}
return 0;
}
/* Glob for MEMBER_PATTERN in archive ARNAME.
Return a malloc'd chain of matching elements (or nil if none). */
struct nameseq *
ar_glob (arname, member_pattern, size)
char *arname, *member_pattern;
unsigned int size;
{
struct ar_glob_state state;
char **names;
struct nameseq *n;
unsigned int i;
if (! glob_pattern_p (member_pattern, 1))
return 0;
/* Scan the archive for matches.
ar_glob_match will accumulate them in STATE.chain. */
i = strlen (arname);
state.arname = (char *) alloca (i + 2);
bcopy (arname, state.arname, i);
state.arname[i] = '(';
state.arname[i + 1] = '\0';
state.pattern = member_pattern;
state.size = size;
state.chain = 0;
state.n = 0;
(void) ar_scan (arname, ar_glob_match, (long int) &state);
if (state.chain == 0)
return 0;
/* Now put the names into a vector for sorting. */
names = (char **) alloca (state.n * sizeof (char *));
i = 0;
for (n = state.chain; n != 0; n = n->next)
names[i++] = n->name;
/* Sort them alphabetically. */
qsort ((char *) names, i, sizeof (*names), ar_glob_alphacompare);
/* Put them back into the chain in the sorted order. */
i = 0;
for (n = state.chain; n != 0; n = n->next)
n->name = names[i++];
return state.chain;
}
#endif /* Not NO_ARCHIVES. */

561
arscan.c Normal file
View File

@@ -0,0 +1,561 @@
/* Library function for scanning an archive file.
Copyright (C) 1987, 89, 91, 92, 93, 94 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "make.h"
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#else
#include <sys/file.h>
#endif
#ifndef NO_ARCHIVES
/* SCO Unix's compiler defines both of these. */
#ifdef M_UNIX
#undef M_XENIX
#endif
/* On the sun386i and in System V rel 3, ar.h defines two different archive
formats depending upon whether you have defined PORTAR (normal) or PORT5AR
(System V Release 1). There is no default, one or the other must be defined
to have a nonzero value. */
#if (!defined (PORTAR) || PORTAR == 0) && (!defined (PORT5AR) || PORT5AR == 0)
#undef PORTAR
#ifdef M_XENIX
/* According to Jim Sievert <jas1@rsvl.unisys.com>, for SCO XENIX defining
PORTAR to 1 gets the wrong archive format, and defining it to 0 gets the
right one. */
#define PORTAR 0
#else
#define PORTAR 1
#endif
#endif
#include <ar.h>
/* Cray's <ar.h> apparently defines this. */
#ifndef AR_HDR_SIZE
#define AR_HDR_SIZE (sizeof (struct ar_hdr))
#endif
/* Takes three arguments ARCHIVE, FUNCTION and ARG.
Open the archive named ARCHIVE, find its members one by one,
and for each one call FUNCTION with the following arguments:
archive file descriptor for reading the data,
member name,
member name might be truncated flag,
member header position in file,
member data position in file,
member data size,
member date,
member uid,
member gid,
member protection mode,
ARG.
The descriptor is poised to read the data of the member
when FUNCTION is called. It does not matter how much
data FUNCTION reads.
If FUNCTION returns nonzero, we immediately return
what FUNCTION returned.
Returns -1 if archive does not exist,
Returns -2 if archive has invalid format.
Returns 0 if have scanned successfully. */
long int
ar_scan (archive, function, arg)
char *archive;
long int (*function) ();
long int arg;
{
#ifdef AIAMAG
FL_HDR fl_header;
#else
int long_name = 0;
#endif
char *namemap = 0;
register int desc = open (archive, O_RDONLY, 0);
if (desc < 0)
return -1;
#ifdef SARMAG
{
char buf[SARMAG];
register int nread = read (desc, buf, SARMAG);
if (nread != SARMAG || bcmp (buf, ARMAG, SARMAG))
{
(void) close (desc);
return -2;
}
}
#else
#ifdef AIAMAG
{
register int nread = read (desc, (char *) &fl_header, FL_HSZ);
if (nread != FL_HSZ || bcmp (fl_header.fl_magic, AIAMAG, SAIAMAG))
{
(void) close (desc);
return -2;
}
}
#else
{
#ifndef M_XENIX
int buf;
#else
unsigned short int buf;
#endif
register int nread = read(desc, &buf, sizeof (buf));
if (nread != sizeof (buf) || buf != ARMAG)
{
(void) close (desc);
return -2;
}
}
#endif
#endif
/* Now find the members one by one. */
{
#ifdef SARMAG
register long int member_offset = SARMAG;
#else
#ifdef AIAMAG
long int member_offset;
long int last_member_offset;
sscanf (fl_header.fl_fstmoff, "%12ld", &member_offset);
sscanf (fl_header.fl_lstmoff, "%12ld", &last_member_offset);
#else
#ifndef M_XENIX
register long int member_offset = sizeof (int);
#else /* Xenix. */
register long int member_offset = sizeof (unsigned short int);
#endif /* Not Xenix. */
#endif
#endif
while (1)
{
register int nread;
struct ar_hdr member_header;
#ifdef AIAMAG
char name[256];
int name_len;
long int dateval;
int uidval, gidval;
long int data_offset;
#else
char namebuf[sizeof member_header.ar_name + 1];
char *name;
int is_namemap; /* Nonzero if this entry maps long names. */
#endif
long int eltsize;
int eltmode;
long int fnval;
if (lseek (desc, member_offset, 0) < 0)
{
(void) close (desc);
return -2;
}
#ifdef AIAMAG
#define AR_MEMHDR (AR_HDR_SIZE - sizeof (member_header._ar_name))
nread = read (desc, (char *) &member_header, AR_MEMHDR);
if (nread != AR_MEMHDR)
{
(void) close (desc);
return -2;
}
sscanf (member_header.ar_namlen, "%4d", &name_len);
nread = read (desc, name, name_len);
if (nread != name_len)
{
(void) close (desc);
return -2;
}
name[name_len] = 0;
sscanf (member_header.ar_date, "%12ld", &dateval);
sscanf (member_header.ar_uid, "%12d", &uidval);
sscanf (member_header.ar_gid, "%12d", &gidval);
sscanf (member_header.ar_mode, "%12o", &eltmode);
sscanf (member_header.ar_size, "%12ld", &eltsize);
if ((data_offset = member_offset + AR_MEMHDR + name_len + 2) % 2)
++data_offset;
fnval =
(*function) (desc, name, 0,
member_offset, data_offset, eltsize,
dateval, uidval, gidval,
eltmode, arg);
#else /* Not AIAMAG. */
nread = read (desc, (char *) &member_header, AR_HDR_SIZE);
if (nread == 0)
/* No data left means end of file; that is OK. */
break;
if (nread != AR_HDR_SIZE
#ifdef ARFMAG
|| bcmp (member_header.ar_fmag, ARFMAG, 2)
#endif
)
{
(void) close (desc);
return -2;
}
name = namebuf;
bcopy (member_header.ar_name, name, sizeof member_header.ar_name);
{
register char *p = name + sizeof member_header.ar_name;
do
*p = '\0';
while (p > name && *--p == ' ');
#ifndef AIAMAG
/* If the member name is "//" or "ARFILENAMES/" this may be
a list of file name mappings. The maximum file name
length supported by the standard archive format is 14
characters. This member will actually always be the
first or second entry in the archive, but we don't check
that. */
is_namemap = (!strcmp (name, "//")
|| !strcmp (name, "ARFILENAMES/"));
#endif /* Not AIAMAG. */
/* On some systems, there is a slash after each member name. */
if (*p == '/')
*p = '\0';
#ifndef AIAMAG
/* If the member name starts with a space or a slash, this
is an index into the file name mappings (used by GNU ar).
Otherwise if the member name looks like #1/NUMBER the
real member name appears in the element data (used by
4.4BSD). */
if (! is_namemap
&& (name[0] == ' ' || name[0] == '/')
&& namemap != 0)
{
name = namemap + atoi (name + 1);
long_name = 1;
}
else if (name[0] == '#'
&& name[1] == '1'
&& name[2] == '/')
{
int namesize = atoi (name + 3);
name = (char *) alloca (namesize + 1);
nread = read (desc, name, namesize);
if (nread != namesize)
{
close (desc);
return -2;
}
name[namesize] = '\0';
long_name = 1;
}
#endif /* Not AIAMAG. */
}
#ifndef M_XENIX
sscanf (member_header.ar_mode, "%o", &eltmode);
eltsize = atol (member_header.ar_size);
#else /* Xenix. */
eltmode = (unsigned short int) member_header.ar_mode;
eltsize = member_header.ar_size;
#endif /* Not Xenix. */
fnval =
(*function) (desc, name, ! long_name, member_offset,
member_offset + AR_HDR_SIZE, eltsize,
#ifndef M_XENIX
atol (member_header.ar_date),
atoi (member_header.ar_uid),
atoi (member_header.ar_gid),
#else /* Xenix. */
member_header.ar_date,
member_header.ar_uid,
member_header.ar_gid,
#endif /* Not Xenix. */
eltmode, arg);
#endif /* AIAMAG. */
if (fnval)
{
(void) close (desc);
return fnval;
}
#ifdef AIAMAG
if (member_offset == last_member_offset)
/* End of the chain. */
break;
sscanf (member_header.ar_nxtmem, "%12ld", &member_offset);
if (lseek (desc, member_offset, 0) != member_offset)
{
(void) close (desc);
return -2;
}
#else
/* If this member maps archive names, we must read it in. The
name map will always precede any members whose names must
be mapped. */
if (is_namemap)
{
char *clear;
char *limit;
namemap = (char *) alloca (eltsize);
nread = read (desc, namemap, eltsize);
if (nread != eltsize)
{
(void) close (desc);
return -2;
}
/* The names are separated by newlines. Some formats have
a trailing slash. Null terminate the strings for
convenience. */
limit = namemap + eltsize;
for (clear = namemap; clear < limit; clear++)
{
if (*clear == '\n')
{
*clear = '\0';
if (clear[-1] == '/')
clear[-1] = '\0';
}
}
is_namemap = 0;
}
member_offset += AR_HDR_SIZE + eltsize;
if (member_offset % 2 != 0)
member_offset++;
#endif
}
}
close (desc);
return 0;
}
/* Return nonzero iff NAME matches MEM.
If TRUNCATED is nonzero, MEM may be truncated to
sizeof (struct ar_hdr.ar_name) - 1. */
int
ar_name_equal (name, mem, truncated)
char *name, *mem;
int truncated;
{
char *p;
p = rindex (name, '/');
if (p != 0)
name = p + 1;
/* We no longer use this kludge, since we
now support long archive member names. */
#if 0 && !defined (AIAMAG) && !defined (APOLLO)
{
/* `reallylongname.o' matches `reallylongnam.o'.
If member names have a trailing slash, that's `reallylongna.o'. */
struct ar_hdr h;
unsigned int max = sizeof (h.ar_name);
unsigned int namelen, memlen;
if (strncmp (name, mem, max - 3))
return 0;
namelen = strlen (name);
memlen = strlen (mem);
if (namelen > memlen && memlen >= max - 1
&& name[namelen - 2] == '.' && name[namelen - 1] == 'o'
&& mem[memlen - 2] == '.' && mem[memlen - 1] == 'o')
return 1;
if (namelen != memlen)
return 0;
return (namelen < max - 3 || !strcmp (name + max - 3, mem + max - 3));
}
#else /* AIX or APOLLO. */
if (truncated)
{
#ifdef AIAMAG
/* TRUNCATED should never be set on this system. */
abort ();
#else
struct ar_hdr hdr;
return !strncmp (name, mem,
sizeof (hdr.ar_name) -
#ifndef __hpux
1
#else
2
#endif /* __hpux */
);
#endif
}
return !strcmp (name, mem);
#endif
}
/* ARGSUSED */
static long int
ar_member_pos (desc, mem, truncated,
hdrpos, datapos, size, date, uid, gid, mode, name)
int desc;
char *mem;
int truncated;
long int hdrpos, datapos, size, date;
int uid, gid, mode;
char *name;
{
if (!ar_name_equal (name, mem, truncated))
return 0;
return hdrpos;
}
/* Set date of member MEMNAME in archive ARNAME to current time.
Returns 0 if successful,
-1 if file ARNAME does not exist,
-2 if not a valid archive,
-3 if other random system call error (including file read-only),
1 if valid but member MEMNAME does not exist. */
int
ar_member_touch (arname, memname)
char *arname, *memname;
{
register long int pos = ar_scan (arname, ar_member_pos, (long int) memname);
register int fd;
struct ar_hdr ar_hdr;
register int i;
struct stat statbuf;
if (pos < 0)
return (int) pos;
if (!pos)
return 1;
fd = open (arname, O_RDWR, 0666);
if (fd < 0)
return -3;
/* Read in this member's header */
if (lseek (fd, pos, 0) < 0)
goto lose;
if (AR_HDR_SIZE != read (fd, (char *) &ar_hdr, AR_HDR_SIZE))
goto lose;
/* Write back the header, thus touching the archive file. */
if (lseek (fd, pos, 0) < 0)
goto lose;
if (AR_HDR_SIZE != write (fd, (char *) &ar_hdr, AR_HDR_SIZE))
goto lose;
/* The file's mtime is the time we we want. */
#ifdef EINTR
while (fstat (fd, &statbuf) < 0 && errno == EINTR);
#else
fstat (fd, &statbuf);
#endif
#if defined(ARFMAG) || defined(AIAMAG)
/* Advance member's time to that time */
for (i = 0; i < sizeof ar_hdr.ar_date; i++)
ar_hdr.ar_date[i] = ' ';
sprintf (ar_hdr.ar_date, "%ld", (long int) statbuf.st_mtime);
#ifdef AIAMAG
ar_hdr.ar_date[strlen(ar_hdr.ar_date)] = ' ';
#endif
#else
ar_hdr.ar_date = statbuf.st_mtime;
#endif
/* Write back this member's header */
if (lseek (fd, pos, 0) < 0)
goto lose;
if (AR_HDR_SIZE != write (fd, (char *) &ar_hdr, AR_HDR_SIZE))
goto lose;
close (fd);
return 0;
lose:
i = errno;
close (fd);
errno = i;
return -3;
}
#ifdef TEST
long int
describe_member (desc, name, truncated,
hdrpos, datapos, size, date, uid, gid, mode)
int desc;
char *name;
int truncated;
long int hdrpos, datapos, size, date;
int uid, gid, mode;
{
extern char *ctime ();
printf ("Member `%s'%s: %ld bytes at %ld (%ld).\n",
name, truncated ? " (name might be truncated)" : "",
size, hdrpos, datapos);
printf (" Date %s", ctime (&date));
printf (" uid = %d, gid = %d, mode = 0%o.\n", uid, gid, mode);
return 0;
}
main (argc, argv)
int argc;
char **argv;
{
ar_scan (argv[1], describe_member);
return 0;
}
#endif /* TEST. */
#endif /* NO_ARCHIVES. */

69
build.sh.in Normal file
View File

@@ -0,0 +1,69 @@
#!/bin/sh
# Shell script to build GNU Make in the absence of any `make' program.
# Copyright (C) 1993, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA.
# See Makefile.in for comments describing these variables.
srcdir='@srcdir@'
CC='@CC@'
CFLAGS='@CFLAGS@'
CPPFLAGS='@CPPFLAGS@'
LDFLAGS='@LDFLAGS@'
defines='@DEFS@ -DLIBDIR="${libdir}" -DINCLUDEDIR="${includedir}"'
ALLOCA='@ALLOCA@'
LOADLIBES='@LIBS@'
extras='@LIBOBJS@'
REMOTE='@REMOTE@'
# Common prefix for machine-independent installed files.
prefix=@prefix@
# Common prefix for machine-dependent installed files.
exec_prefix=@exec_prefix@
# Directory to find libraries in for `-lLIB'.
libdir=${exec_prefix}/lib
# Directory to search by default for included makefiles.
includedir=${prefix}/include
# Exit as soon as any command fails.
set -e
# These are all the objects we need to link together.
objs="commands.o job.o dir.o file.o misc.o main.o read.o remake.o rule.o implicit.o default.o variable.o expand.o function.o vpath.o version.o ar.o arscan.o signame.o getopt.o getopt1.o glob/glob.o glob/fnmatch.o remote-${REMOTE}.o ${extras} ${ALLOCA}"
# Compile the source files into those objects.
for file in `echo ${objs} | sed 's/\.o/.c/g'`; do
echo compiling ${file}...
$CC $CPPFLAGS $CFLAGS $defines -c \
-I. -I${srcdir} -I${srcdir}/glob ${srcdir}/$file
done
# The object files were actually all put in the current directory.
# Remove the source directory names from the list.
srcobjs="$objs"
objs=
for obj in $srcobjs; do
objs="$objs `basename $obj`"
done
# Link all the objects together.
echo linking make...
$CC $LDFLAGS $objs $LOADLIBES -o make.new
echo done
mv -f make.new make

67
build.template Normal file
View File

@@ -0,0 +1,67 @@
#!/bin/sh
# Shell script to build GNU Make in the absence of any `make' program.
# Copyright (C) 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA.
# See Makefile.in for comments describing these variables.
srcdir='@srcdir@'
CC='@CC@'
CFLAGS='@CFLAGS@'
LDFLAGS='@LDFLAGS@'
defines='@DEFS@ -DLIBDIR="${libdir}" -DINCLUDEDIR="${includedir}"'
ALLOCA='@ALLOCA@'
LOADLIBES='@LIBS@'
extras='@LIBOBJS@'
REMOTE='@REMOTE@'
# Common prefix for machine-independent installed files.
prefix=/usr/local
# Common prefix for machine-dependent installed files.
exec_prefix=/usr/local
# Directory to find libraries in for `-lXXX'.
libdir=${exec_prefix}/lib
# Directory to search by default for included makefiles.
includedir=${prefix}/include
# Exit as soon as any command fails.
set -e
# These are all the objects we need to link together.
objs="%objs% remote-${REMOTE}.o ${extras} ${ALLOCA}"
# Compile the source files into those objects.
for file in `echo ${objs} | sed 's/\.o/.c/g'`; do
echo compiling ${file}...
$CC $CFLAGS $defines -c -I. -I${srcdir} -I${srcdir}/glob ${srcdir}/$file
done
# The object files were actually all put in the current directory.
# Remove the source directory names from the list.
srcobjs="$objs"
objs=
for obj in $srcobjs; do
objs="$objs `basename $obj`"
done
# Link all the objects together.
echo linking make...
$CC $LDFLAGS $objs $LOADLIBES -o make.new
echo done
mv -f make.new make

521
commands.c Normal file
View File

@@ -0,0 +1,521 @@
/* Command processing for GNU Make.
Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "make.h"
#include "dep.h"
#include "commands.h"
#include "file.h"
#include "variable.h"
#include "job.h"
extern int remote_kill ();
#ifndef HAVE_UNISTD_H
extern int getpid ();
#endif
/* Set FILE's automatic variables up. */
static void
set_file_variables (file)
register struct file *file;
{
register char *p;
char *at, *percent, *star, *less;
#ifndef NO_ARCHIVES
/* If the target is an archive member `lib(member)',
then $@ is `lib' and $% is `member'. */
if (ar_name (file->name))
{
unsigned int len;
p = index (file->name, '(');
at = (char *) alloca (p - file->name + 1);
bcopy (file->name, at, p - file->name);
at[p - file->name] = '\0';
len = strlen (p + 1);
percent = (char *) alloca (len);
bcopy (p + 1, percent, len - 1);
percent[len - 1] = '\0';
}
else
#endif /* NO_ARCHIVES. */
{
at = file->name;
percent = "";
}
/* $* is the stem from an implicit or static pattern rule. */
if (file->stem == 0)
{
/* In Unix make, $* is set to the target name with
any suffix in the .SUFFIXES list stripped off for
explicit rules. We store this in the `stem' member. */
register struct dep *d;
char *name;
unsigned int len;
#ifndef NO_ARCHIVES
if (ar_name (file->name))
{
name = index (file->name, '(') + 1;
len = strlen (name) - 1;
}
else
#endif
{
name = file->name;
len = strlen (name);
}
for (d = enter_file (".SUFFIXES")->deps; d != 0; d = d->next)
{
unsigned int slen = strlen (dep_name (d));
if (len > slen && !strncmp (dep_name (d), name + (len - slen), slen))
{
file->stem = savestring (name, len - slen);
break;
}
}
if (d == 0)
file->stem = "";
}
star = file->stem;
/* $< is the first dependency. */
less = file->deps != 0 ? dep_name (file->deps) : "";
if (file->cmds == default_file->cmds)
/* This file got its commands from .DEFAULT.
In this case $< is the same as $@. */
less = at;
#define DEFINE_VARIABLE(name, len, value) \
(void) define_variable_for_file (name, len, value, o_automatic, 0, file)
/* Define the variables. */
DEFINE_VARIABLE ("<", 1, less);
DEFINE_VARIABLE ("*", 1, star);
DEFINE_VARIABLE ("@", 1, at);
DEFINE_VARIABLE ("%", 1, percent);
/* Compute the values for $^, $+, and $?. */
{
register unsigned int qmark_len, plus_len;
char *caret_value, *plus_value;
register char *cp;
char *qmark_value;
register char *qp;
register struct dep *d;
unsigned int len;
/* Compute first the value for $+, which is supposed to contain
duplicate dependencies as they were listed in the makefile. */
plus_len = 0;
for (d = file->deps; d != 0; d = d->next)
plus_len += strlen (dep_name (d)) + 1;
len = plus_len == 0 ? 1 : plus_len;
cp = plus_value = (char *) alloca (len);
qmark_len = plus_len; /* Will be this or less. */
for (d = file->deps; d != 0; d = d->next)
{
char *c = dep_name (d);
#ifndef NO_ARCHIVES
if (ar_name (c))
{
c = index (c, '(') + 1;
len = strlen (c) - 1;
}
else
#endif
len = strlen (c);
bcopy (c, cp, len);
cp += len;
*cp++ = ' ';
if (! d->changed)
qmark_len -= len + 1; /* Don't space in $? for this one. */
}
/* Kill the last space and define the variable. */
cp[cp > plus_value ? -1 : 0] = '\0';
DEFINE_VARIABLE ("+", 1, plus_value);
/* Make sure that no dependencies are repeated. This does not
really matter for the purpose of updating targets, but it
might make some names be listed twice for $^ and $?. */
uniquize_deps (file->deps);
/* Compute the values for $^ and $?. */
cp = caret_value = plus_value; /* Reuse the buffer; it's big enough. */
len = qmark_len == 0 ? 1 : qmark_len;
qp = qmark_value = (char *) alloca (len);
for (d = file->deps; d != 0; d = d->next)
{
char *c = dep_name (d);
#ifndef NO_ARCHIVES
if (ar_name (c))
{
c = index (c, '(') + 1;
len = strlen (c) - 1;
}
else
#endif
len = strlen (c);
bcopy (c, cp, len);
cp += len;
*cp++ = ' ';
if (d->changed)
{
bcopy (c, qp, len);
qp += len;
*qp++ = ' ';
}
}
/* Kill the last spaces and define the variables. */
cp[cp > caret_value ? -1 : 0] = '\0';
DEFINE_VARIABLE ("^", 1, caret_value);
qp[qp > qmark_value ? -1 : 0] = '\0';
DEFINE_VARIABLE ("?", 1, qmark_value);
}
#undef DEFINE_VARIABLE
}
/* Chop CMDS up into individual command lines if necessary.
Also set the `lines_flag' and `any_recurse' members. */
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.
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;
}
}
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 *));
}
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;
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;
}
}
}
/* Execute the commands to remake FILE. If they are currently executing,
return or have already finished executing, just return. Otherwise,
fork off a child process to run the first command line in the sequence. */
void
execute_file_commands (file)
struct file *file;
{
register char *p;
/* Don't go through all the preparations if
the commands are nothing but whitespace. */
for (p = file->cmds->commands; *p != '\0'; ++p)
if (!isspace (*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. */
file->update_status = 0;
notice_finished_file (file);
return;
}
/* First set the automatic variables according to this file. */
initialize_file_variables (file);
set_file_variables (file);
/* Start the commands running. */
new_job (file);
}
/* This is set while we are inside fatal_error_signal,
so things can avoid nonreentrant operations. */
int handling_fatal_signal = 0;
/* Handle fatal signals. */
RETSIGTYPE
fatal_error_signal (sig)
int sig;
{
#ifdef __MSDOS__
remove_intermediates (1);
exit (1);
#else /* Not MSDOS. */
handling_fatal_signal = 1;
/* Set the handling for this signal to the default.
It is blocked now while we run this handler. */
signal (sig, SIG_DFL);
/* A termination signal won't be sent to the entire
process group, but it means we want to kill the children. */
if (sig == SIGTERM)
{
register struct child *c;
for (c = children; c != 0; c = c->next)
if (!c->remote)
(void) kill (c->pid, SIGTERM);
}
/* If we got a signal that means the user
wanted to kill make, remove pending targets. */
if (sig == SIGTERM || sig == SIGINT || sig == SIGHUP || sig == SIGQUIT)
{
register struct child *c;
/* Remote children won't automatically get signals sent
to the process group, so we must send them. */
for (c = children; c != 0; c = c->next)
if (c->remote)
(void) remote_kill (c->pid, sig);
for (c = children; c != 0; c = c->next)
delete_child_targets (c);
/* Clean up the children. We don't just use the call below because
we don't want to print the "Waiting for children" message. */
while (job_slots_used > 0)
reap_children (1, 0);
}
else
/* Wait for our children to die. */
while (job_slots_used > 0)
reap_children (1, 1);
/* Delete any non-precious intermediate files that were made. */
remove_intermediates (1);
if (sig == SIGQUIT)
/* We don't want to send ourselves SIGQUIT, because it will
cause a core dump. Just exit instead. */
exit (1);
/* Signal the same code; this time it will really be fatal. The signal
will be unblocked when we return and arrive then to kill us. */
if (kill (getpid (), sig) < 0)
pfatal_with_name ("kill");
#endif /* MSDOS. */
}
/* Delete FILE unless it's precious or not actually a file (phony),
and it has changed on disk since we last stat'd it. */
static void
delete_target (file, on_behalf_of)
struct file *file;
char *on_behalf_of;
{
struct stat st;
if (file->precious || file->phony)
return;
#ifndef NO_ARCHIVES
if (ar_name (file->name))
{
if (ar_member_date (file->name) != file->last_mtime)
{
if (on_behalf_of)
error ("*** [%s] Archive member `%s' may be bogus; not deleted",
on_behalf_of, file->name);
else
error ("*** Archive member `%s' may be bogus; not deleted",
file->name);
}
return;
}
#endif
if (safe_stat (file->name, &st) == 0
&& S_ISREG (st.st_mode)
&& (time_t) st.st_mtime != file->last_mtime)
{
if (on_behalf_of)
error ("*** [%s] Deleting file `%s'", on_behalf_of, file->name);
else
error ("*** Deleting file `%s'", file->name);
if (unlink (file->name) < 0)
perror_with_name ("unlink: ", file->name);
}
}
/* Delete all non-precious targets of CHILD unless they were already deleted.
Set the flag in CHILD to say they've been deleted. */
void
delete_child_targets (child)
struct child *child;
{
struct dep *d;
if (child->deleted)
return;
/* Delete the target file if it changed. */
delete_target (child->file, (char *) 0);
/* Also remove any non-precious targets listed in the `also_make' member. */
for (d = child->file->also_make; d != 0; d = d->next)
delete_target (d->file, child->file->name);
child->deleted = 1;
}
/* Print out the commands in CMDS. */
void
print_commands (cmds)
register struct commands *cmds;
{
register char *s;
fputs ("# commands to execute", stdout);
if (cmds->filename == 0)
puts (" (built-in):");
else
printf (" (from `%s', line %u):\n", cmds->filename, cmds->lineno);
s = cmds->commands;
while (*s != '\0')
{
char *end;
while (isspace (*s))
++s;
end = index (s, '\n');
if (end == 0)
end = s + strlen (s);
printf ("\t%.*s\n", (int) (end - s), s);
s = end;
}
}

42
commands.h Normal file
View File

@@ -0,0 +1,42 @@
/* Definition of data structures describing shell commands for GNU Make.
Copyright (C) 1988, 1989, 1991, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Structure that gives the commands to make a file
and information about where these commands came from. */
struct commands
{
char *filename; /* File that contains commands. */
unsigned int lineno; /* Line number in file. */
char *commands; /* Commands text. */
unsigned int ncommand_lines;/* Number of command lines. */
char **command_lines; /* Commands chopped up into lines. */
char *lines_flags; /* One set of flag bits for each line. */
int any_recurse; /* Nonzero if any `lines_recurse' elt has */
/* the COMMANDS_RECURSE bit set. */
};
/* Bits in `lines_flags'. */
#define COMMANDS_RECURSE 1 /* Recurses: + or $(MAKE). */
#define COMMANDS_SILENT 2 /* Silent: @. */
#define COMMANDS_NOERROR 4 /* No errors: -. */
extern void execute_file_commands ();
extern void print_commands ();
extern void delete_child_targets ();
extern void chop_commands ();

283
compatMakefile Normal file
View File

@@ -0,0 +1,283 @@
# NOTE: If you have no `make' program at all to process this makefile, run
# `build.sh' instead.
#
# Copyright (C) 1988, 89, 91, 92, 93, 94 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, 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Makefile for GNU Make
#
# Ultrix 2.2 make doesn't expand the value of VPATH.
VPATH = @srcdir@
# This must repeat the value, because configure will remove `VPATH = .'.
srcdir = @srcdir@
CC = @CC@
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
# Define these for your system as follows:
# -DNO_ARCHIVES To disable `ar' archive support.
# -DNO_FLOAT To avoid using floating-point numbers.
# -DENUM_BITFIELDS If the compiler isn't GCC but groks enum foo:2.
# Some compilers apparently accept this
# without complaint but produce losing code,
# so beware.
# NeXT 1.0a uses an old version of GCC, which required -D__inline=inline.
# See also `config.h'.
defines = @DEFS@ -DLIBDIR=\"$(libdir)\" -DINCLUDEDIR=\"$(includedir)\"
# Which flavor of remote job execution support to use.
# The code is found in `remote-$(REMOTE).c'.
REMOTE = @REMOTE@
# If you are using the GNU C library, or have the GNU getopt functions in
# your C library, you can comment these out.
GETOPT = getopt.o getopt1.o
GETOPT_SRC = $(srcdir)/getopt.c $(srcdir)/getopt1.c $(srcdir)/getopt.h
# If you are using the GNU C library, or have the GNU glob functions in
# your C library, you can comment this out. GNU make uses special hooks
# into the glob functions to be more efficient (by using make's directory
# cache for globbing), so you must use the GNU functions even if your
# system's C library has the 1003.2 glob functions already. Also, the glob
# functions in the AIX and HPUX C libraries are said to be buggy.
GLOB = glob/libglob.a
# If your system doesn't have alloca, or the one provided is bad, define this.
ALLOCA = @ALLOCA@
ALLOCA_SRC = $(srcdir)/alloca.c
# If your system needs extra libraries loaded in, define them here.
# System V probably need -lPW for alloca. HP-UX 7.0's alloca in
# libPW.a is broken on HP9000s300 and HP9000s400 machines. Use
# alloca.c instead on those machines.
LOADLIBES = @LIBS@
# Any extra object files your system needs.
extras = @LIBOBJS@
# Common prefix for machine-independent installed files.
prefix = @prefix@
# Common prefix for machine-dependent installed files.
exec_prefix = @exec_prefix@
# Directory to install `make' in.
bindir = $(exec_prefix)/bin
# Directory to find libraries in for `-lXXX'.
libdir = $(exec_prefix)/lib
# Directory to search by default for included makefiles.
includedir = $(prefix)/include
# Directory to install the Info files in.
infodir = $(prefix)/info
# Directory to install the man page in.
mandir = $(prefix)/man/man$(manext)
# Number to put on the man page filename.
manext = 1
# Prefix to put on installed `make' binary file name.
binprefix =
# Prefix to put on installed `make' man page file name.
manprefix = $(binprefix)
# Whether or not make needs to be installed setgid.
# The value should be either `true' or `false'.
# On many systems, the getloadavg function (used to implement the `-l'
# switch) will not work unless make is installed setgid kmem.
install_setgid = @NEED_SETGID@
# Install make setgid to this group so it can read /dev/kmem.
group = @KMEM_GROUP@
# Program to install `make'.
INSTALL_PROGRAM = @INSTALL_PROGRAM@
# Program to install the man page.
INSTALL_DATA = @INSTALL_DATA@
# Generic install program.
INSTALL = @INSTALL@
# Program to format Texinfo source into Info files.
MAKEINFO = makeinfo
# Program to format Texinfo source into DVI files.
TEXI2DVI = texi2dvi
# Programs to make tags files.
ETAGS = etags -tw
CTAGS = ctags -tw
objs = commands.o job.o dir.o file.o misc.o main.o read.o remake.o \
rule.o implicit.o default.o variable.o expand.o function.o \
vpath.o version.o ar.o arscan.o signame.o remote-$(REMOTE).o \
$(GLOB) $(GETOPT) $(ALLOCA) $(extras)
srcs = $(srcdir)/commands.c $(srcdir)/job.c $(srcdir)/dir.c \
$(srcdir)/file.c $(srcdir)/getloadavg.c $(srcdir)/misc.c \
$(srcdir)/main.c $(srcdir)/read.c $(srcdir)/remake.c \
$(srcdir)/rule.c $(srcdir)/implicit.c $(srcdir)/default.c \
$(srcdir)/variable.c $(srcdir)/expand.c $(srcdir)/function.c \
$(srcdir)/vpath.c $(srcdir)/version.c \
$(srcdir)/remote-$(REMOTE).c \
$(srcdir)/ar.c $(srcdir)/arscan.c \
$(srcdir)/signame.c $(srcdir)/signame.h $(GETOPT_SRC) \
$(srcdir)/commands.h $(srcdir)/dep.h $(srcdir)/file.h \
$(srcdir)/job.h $(srcdir)/make.h $(srcdir)/rule.h \
$(srcdir)/variable.h $(ALLOCA_SRC) $(srcdir)/config.h.in
.SUFFIXES:
.SUFFIXES: .o .c .h .ps .dvi .info .texinfo
all: make
check: # No tests.
info: make.info
dvi: make.dvi
# Some makes apparently use .PHONY as the default goal is it is before `all'.
.PHONY: all check info dvi
make.info: make.texinfo
$(MAKEINFO) -I$(srcdir) $(srcdir)/make.texinfo -o make.info
make.dvi: make.texinfo
$(TEXI2DVI) $(srcdir)/make.texinfo
make.ps: make.dvi
dvi2ps make.dvi > make.ps
make: $(objs)
$(CC) $(LDFLAGS) $(objs) $(LOADLIBES) -o make.new
mv -f make.new make
# -I. is needed to find config.h in the build directory.
.c.o:
$(CC) $(defines) -c -I. -I$(srcdir) -I$(srcdir)/glob \
$(CPPFLAGS) $(CFLAGS) $< $(OUTPUT_OPTION)
# For some losing Unix makes.
SHELL = /bin/sh
MAKE = make
glob/libglob.a: FORCE config.h
cd glob; $(MAKE) libglob.a
FORCE:
tagsrcs = $(srcs) $(srcdir)/remote-*.c
TAGS: $(tagsrcs)
$(ETAGS) $(tagsrcs)
tags: $(tagsrcs)
$(CTAGS) $(tagsrcs)
.PHONY: install installdirs
install: installdirs \
$(bindir)/$(binprefix)make $(infodir)/make.info \
$(mandir)/$(manprefix)make.$(manext)
installdirs:
$(SHELL) ${srcdir}/mkinstalldirs $(bindir) $(infodir) $(mandir)
$(bindir)/$(binprefix)make: make
$(INSTALL_PROGRAM) make $@.new
@if $(install_setgid); then \
if chgrp $(group) $@.new && chmod g+s $@.new; then \
echo "chgrp $(group) $@.new && chmod g+s $@.new"; \
else \
echo "$@ needs to be owned by group $(group) and setgid;"; \
echo "otherwise the \`-l' option will probably not work."; \
echo "You may need special priveleges to install $@."; \
fi; \
else true; fi
# Some systems can't deal with renaming onto a running binary.
-rm -f $@.old
-mv $@ $@.old
mv $@.new $@
$(infodir)/make.info: make.info
if [ -r ./make.info ]; then dir=.; else dir=$(srcdir); fi; \
for file in $${dir}/make.info*; do \
name="`basename $$file`"; \
$(INSTALL_DATA) $$file \
`echo $@ | sed "s,make.info\$$,$$name,"`; \
done
# Run install-info only if it exists.
# Use `if' instead of just prepending `-' to the
# line so we notice real errors from install-info.
# We use `$(SHELL) -c' because some shells do not
# fail gracefully when there is an unknown command.
if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \
install-info --infodir=$(infodir) $$dir/make.info; \
else true; fi
$(mandir)/$(manprefix)make.$(manext): make.man
$(INSTALL_DATA) $(srcdir)/make.man $@
loadavg: loadavg.c config.h
$(CC) $(defines) -DTEST -I. -I$(srcdir) $(CFLAGS) $(LDFLAGS) \
loadavg.c $(LOADLIBES) -o $@
# We copy getloadavg.c into a different file rather than compiling it
# directly because some compilers clobber getloadavg.o in the process.
loadavg.c: getloadavg.c
ln $(srcdir)/getloadavg.c loadavg.c || \
cp $(srcdir)/getloadavg.c loadavg.c
check-loadavg: loadavg
@echo The system uptime program believes the load average to be:
-uptime
@echo The GNU load average checking code believes:
./loadavg
check: check-loadavg
.PHONY: clean realclean distclean mostlyclean
clean: glob-clean
-rm -f make loadavg *.o core make.info* make.dvi
distclean: clean glob-realclean
-rm -f Makefile config.h config.status build.sh stamp-config
-rm -f config.log config.cache
-rm -f TAGS tags
-rm -f make.?? make.??s make.log make.toc make.*aux
-rm -f loadavg.c
realclean: distclean
mostlyclean: clean
.PHONY: glob-clean glob-realclean
glob-clean glob-realclean:
cd glob; $(MAKE) $@
Makefile: config.status $(srcdir)/Makefile.in
$(SHELL) config.status
glob/Makefile: config.status $(srcdir)/glob/Makefile.in
$(SHELL) config.status
config.h: stamp-config ;
stamp-config: config.status $(srcdir)/config.h.in
$(SHELL) config.status
touch stamp-config
# These rules cause too much trouble.
#configure: configure.in
# autoconf $(ACFLAGS)
#config.h.in: configure.in
# autoheader $(ACFLAGS)
# This tells versions [3.59,3.63) of GNU make not to export all variables.
.NOEXPORT:
# The automatically generated dependencies below may omit config.h
# because it is included with ``#include <config.h>'' rather than
# ``#include "config.h"''. So we add the explicit dependency to make sure.
$(objs): config.h
# Automatically generated dependencies will be put at the end of the file.

65
configh.dos.template Normal file
View File

@@ -0,0 +1,65 @@
/* Generated automatically from configure.in by autoheader. DO NOT EDIT! */
#define INCLUDEDIR "c:/djgpp/include"
#define LIBDIR "c:/djgpp/lib"
/* Define if you have dirent.h. */
#define DIRENT
/* Define if you have the strcoll function and it is properly defined. */
#define HAVE_STRCOLL
/* Define if you have unistd.h. */
#define HAVE_UNISTD_H
/* Define as the return type of signal handlers (int or void). */
#define RETSIGTYPE void
/* Define if you have the ANSI C header files. */
#define STDC_HEADERS
/* Define if `sys_siglist' is declared by <signal.h>. */
#define SYS_SIGLIST_DECLARED
/* Define if you have getdtablesize. */
#define HAVE_GETDTABLESIZE
/* Define if you have dup2. */
#define HAVE_DUP2
/* Define if you have sys_siglist. */
#undef HAVE_SYS_SIGLIST
/* Define if you have _sys_siglist. */
#undef HAVE__SYS_SIGLIST
/* Define if you have psignal. */
#define HAVE_PSIGNAL
/* Define if you have getcwd. */
#define HAVE_GETCWD
/* Define if you have sigsetmask. */
#define HAVE_SIGSETMASK
/* Define if you have setlinebuf. */
#define HAVE_SETLINEBUF
/* Define if you have the <limits.h> header file. */
#define HAVE_LIMITS_H
/* Define if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H
/* Define if you have the <string.h> header file. */
#define HAVE_STRING_H
/* Define if you have the <memory.h> header file. */
#define HAVE_MEMORY_H
#define INCLUDEDIR "c:/djgpp/include"
#define LIBDIR "c:/djgpp/lib"
#define SCCS_GET "get"

43
configure.bat Normal file
View File

@@ -0,0 +1,43 @@
@echo off
echo Configuring MAKE for go32
rem This batch file assumes a unix-type "sed" program
update configh.dos config.h
echo # Makefile generated by "configure.bat"> Makefile
if exist config.sed del config.sed
echo ": try_sl ">> config.sed
echo "/\\$/ { ">> config.sed
echo " N ">> config.sed
echo " s/[ ]*\\\n[ ]*/ / ">> config.sed
echo " b try_sl ">> config.sed
echo "} ">> config.sed
echo "s/@srcdir@/./ ">> config.sed
echo "s/@CC@/gcc/ ">> config.sed
echo "s/@CFLAGS@/-O2 -g -DHAVE_CONFIG_H/ ">> config.sed
echo "s/@LDFLAGS@// ">> config.sed
echo "s/@RANLIB@/ranlib/ ">> config.sed
echo "s/@DEFS@// ">> config.sed
echo "s/@REMOTE@/stub/ ">> config.sed
echo "s/@ALLOCA@// ">> config.sed
echo "s/@LIBS@// ">> config.sed
echo "s/@LIBOBJS@// ">> config.sed
echo "s/@SET_MAKE@// ">> config.sed
echo "s/^Makefile *:/_Makefile:/ ">> config.sed
echo "s/^config.h *:/_config.h:/ ">> config.sed
echo "s/^defines *=.*$/defines =/ ">> config.sed
echo "/mv -f make.new make/d ">> config.sed
echo "s/cd glob; $(MAKE)/$(MAKE) -C glob/ ">> config.sed
sed -e "s/^\"//" -e "s/\"$//" -e "s/[ ]*$//" config.sed > config2.sed
sed -f config2.sed Makefile.in >> Makefile
del config.sed
del config2.sed
cd glob
call configure
cd ..

121
configure.in Normal file
View File

@@ -0,0 +1,121 @@
dnl Process this file with autoconf to produce a configure script.
AC_REVISION([$Id$])
AC_PREREQ(2.1)dnl dnl Minimum Autoconf version required.
AC_INIT(vpath.c)dnl dnl A distinctive file to look for in srcdir.
AC_CONFIG_HEADER(config.h)
AC_CONFIG_SUBDIRS(glob) dnl Run configure in glob subdirectory.
# We want these before the checks, so the checks can modify their values.
test -z "$CFLAGS" && CFLAGS=-g AC_SUBST(CFLAGS)
test -z "$LDFLAGS" && LDFLAGS=-g AC_SUBST(LDFLAGS)
AC_PROG_MAKE_SET
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_CPP dnl Later checks need this.
AC_AIX
AC_ISC_POSIX
AC_MINIX
AC_HEADER_STDC
AC_HEADER_DIRENT
AC_TYPE_UID_T dnl Also does gid_t.
AC_TYPE_GETGROUPS
AC_TYPE_PID_T
AC_TYPE_SIGNAL
AC_CHECK_HEADERS(unistd.h limits.h sys/param.h fcntl.h string.h memory.h \
sys/timeb.h)
AC_PROG_CC_C_O
AC_C_CONST dnl getopt needs this.
AC_HEADER_STAT
AC_SUBST(LIBOBJS)
AC_DEFUN(AC_CHECK_SYMBOL, [dnl
AC_MSG_CHECKING(for $1)
AC_CACHE_VAL(ac_cv_check_symbol_$1, [dnl
AC_TRY_LINK(, [extern char *sys_siglist[]; puts(*sys_siglist);],
ac_cv_check_symbol_$1=yes, ac_cv_check_symbol_$1=no)])
if test "$ac_cv_check_symbol_$1" = yes; then
changequote(,)dnl
ac_tr_symbol=`echo $1 | tr '[a-z]' '[A-Z]'`
changequote([,])dnl
AC_DEFINE_UNQUOTED(HAVE_${ac_tr_symbol})
fi
AC_MSG_RESULT($ac_cv_check_symbol_$1)])dnl
AC_CHECK_FUNCS(getdtablesize psignal \
dup2 getcwd sigsetmask getgroups setlinebuf \
seteuid setegid setreuid setregid strerror)
AC_CHECK_SYMBOL(sys_siglist)
AC_CHECK_SYMBOL(_sys_siglist)
AC_FUNC_ALLOCA
AC_FUNC_VFORK
AC_FUNC_SETVBUF_REVERSED
AC_FUNC_GETLOADAVG
AC_FUNC_STRCOLL
# Check out the wait reality.
AC_CHECK_HEADERS(sys/wait.h) AC_CHECK_FUNCS(waitpid wait3)
AC_MSG_CHECKING(for union wait)
AC_CACHE_VAL(make_cv_union_wait, [dnl
AC_TRY_LINK([#include <sys/types.h>
#include <sys/wait.h>],
[union wait status; int pid; pid = wait (&status);
#ifdef WEXITSTATUS
/* Some POSIXoid systems have both the new-style macros and the old
union wait type, and they do not work together. If union wait
conflicts with WEXITSTATUS et al, we don't want to use it at all. */
if (WEXITSTATUS (status) != 0) pid = -1;
#endif
#ifdef HAVE_WAITPID
/* Make sure union wait works with waitpid. */
pid = waitpid (-1, &status, 0);
#endif
],
[make_cv_union_wait=yes], [make_cv_union_wait=no])])
if test "$make_cv_union_wait" = yes; then
AC_DEFINE(HAVE_UNION_WAIT)
fi
AC_MSG_RESULT($make_cv_union_wait)
AC_DECL_SYS_SIGLIST
# The presence of the following is not meant to imply
# that make necessarily works on those systems.
AC_CHECK_LIB(sun, getpwnam)
AC_SUBST(REMOTE) REMOTE=stub
AC_ARG_WITH(customs, [export jobs with the Customs daemon (NOT SUPPORTED)],
[REMOTE=cstms LIBS="$LIBS libcustoms.a"])
echo checking for location of SCCS get command
if test -f /usr/sccs/get; then
SCCS_GET=/usr/sccs/get
AC_DEFINE(SCCS_GET, "/usr/sccs/get")
else
SCCS_GET=get
AC_DEFINE(SCCS_GET, "get")
fi
ac_clean_files="$ac_clean_files s.conftest conftoast" # Remove these later.
if ( /usr/sccs/admin -n s.conftest || admin -n s.conftest ) >/dev/null 2>&1 &&
test -f s.conftest; then
# We successfully created an SCCS file.
echo checking if SCCS get command understands -G
if $SCCS_GET -Gconftoast s.conftest >/dev/null 2>&1 &&
test -f conftoast; then
AC_DEFINE(SCCS_GET_MINUS_G)
fi
fi
rm -f s.conftest conftoast
AC_OUTPUT(Makefile build.sh, [
# Makefile uses this timestamp file to know when to remake Makefile,
# build.sh, and glob/Makefile.
touch stamp-config])
dnl Local Variables:
dnl comment-start: "dnl "
dnl comment-end: ""
dnl comment-start-skip: "\\bdnl\\b\\s *"
dnl compile-command: "make configure config.h.in"
dnl End:

409
default.c Normal file
View File

@@ -0,0 +1,409 @@
/* Data base of default implicit rules for GNU Make.
Copyright (C) 1988, 89, 90, 91, 92, 93, 94 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "make.h"
#include "rule.h"
#include "dep.h"
#include "file.h"
#include "commands.h"
#include "variable.h"
/* Define GCC_IS_NATIVE if gcc is the native development environment on
your system (gcc/bison/flex vs cc/yacc/lex). */
#ifdef __MSDOS__
#define GCC_IS_NATIVE
#endif
/* This is the default list of suffixes for suffix rules.
`.s' must come last, so that a `.o' file will be made from
a `.c' or `.p' or ... file rather than from a .s file. */
static char default_suffixes[]
= ".out .a .ln .o .c .cc .C .p .f .F .r .y .l .s .S \
.mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo \
.w .ch .web .sh .elc .el";
static struct pspec default_pattern_rules[] =
{
{ "(%)", "%",
"$(AR) $(ARFLAGS) $@ $<" },
/* The X.out rules are only in BSD's default set because
BSD Make has no null-suffix rules, so `foo.out' and
`foo' are the same thing. */
{ "%.out", "%",
"@rm -f $@ \n cp $< $@" },
/* Syntax is "ctangle foo.w foo.ch foo.c". */
{ "%.c", "%.w %.ch",
"$(CTANGLE) $^ $@" },
{ "%.tex", "%.w %.ch",
"$(CWEAVE) $^ $@" },
{ 0, 0, 0 }
};
static struct pspec default_terminal_rules[] =
{
/* RCS. */
{ "%", "%,v",
"+$(CHECKOUT,v)" },
{ "%", "RCS/%,v",
"+$(CHECKOUT,v)" },
/* SCCS. */
{ "%", "s.%",
"$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<" },
{ "%", "SCCS/s.%",
"$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<" },
{ 0, 0, 0 }
};
static char *default_suffix_rules[] =
{
".o",
"$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".s",
"$(LINK.s) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".S",
"$(LINK.S) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".c",
"$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".cc",
"$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".C",
"$(LINK.C) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".f",
"$(LINK.f) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".p",
"$(LINK.p) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".F",
"$(LINK.F) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".r",
"$(LINK.r) $^ $(LOADLIBES) $(LDLIBS) -o $@",
".mod",
"$(COMPILE.mod) -o $@ -e $@ $^",
".def.sym",
"$(COMPILE.def) -o $@ $<",
".sh",
"cat $< >$@ \n chmod a+x $@",
".s.o",
#if !defined(M_XENIX) || defined(__GNUC__)
"$(COMPILE.s) -o $@ $<",
#else /* Xenix. */
"$(COMPILE.s) -o$@ $<",
#endif /* Not Xenix. */
".S.o",
#if !defined(M_XENIX) || defined(__GNUC__)
"$(COMPILE.S) -o $@ $<",
#else /* Xenix. */
"$(COMPILE.S) -o$@ $<",
#endif /* Not Xenix. */
".c.o",
"$(COMPILE.c) $< $(OUTPUT_OPTION)",
".cc.o",
"$(COMPILE.cc) $< $(OUTPUT_OPTION)",
".C.o",
"$(COMPILE.C) $< $(OUTPUT_OPTION)",
".f.o",
"$(COMPILE.f) $< $(OUTPUT_OPTION)",
".p.o",
"$(COMPILE.p) $< $(OUTPUT_OPTION)",
".F.o",
"$(COMPILE.F) $< $(OUTPUT_OPTION)",
".r.o",
"$(COMPILE.r) $< $(OUTPUT_OPTION)",
".mod.o",
"$(COMPILE.mod) -o $@ $<",
".c.ln",
"$(LINT.c) -C$* $<",
".y.ln",
#ifndef __MSDOS__
"$(YACC.y) $< \n $(LINT.c) -C$* y.tab.c \n $(RM) y.tab.c",
#else
"$(YACC.y) $< \n $(LINT.c) -C$* y_tab.c \n $(RM) y_tab.c",
#endif
".l.ln",
"@$(RM) $*.c\n $(LEX.l) $< > $*.c\n$(LINT.c) -i $*.c -o $@\n $(RM) $*.c",
".y.c",
#ifndef __MSDOS__
"$(YACC.y) $< \n mv -f y.tab.c $@",
#else
"$(YACC.y) $< \n mv -f y_tab.c $@",
#endif
".l.c",
"@$(RM) $@ \n $(LEX.l) $< > $@",
".F.f",
"$(PREPROCESS.F) $< $(OUTPUT_OPTION)",
".r.f",
"$(PREPROCESS.r) $< $(OUTPUT_OPTION)",
/* This might actually make lex.yy.c if there's no %R%
directive in $*.l, but in that case why were you
trying to make $*.r anyway? */
".l.r",
"$(LEX.l) $< > $@ \n mv -f lex.yy.r $@",
".S.s",
"$(PREPROCESS.S) $< > $@",
".texinfo.info",
"$(MAKEINFO) $(MAKEINFO_FLAGS) $< -o $@",
".texi.info",
"$(MAKEINFO) $(MAKEINFO_FLAGS) $< -o $@",
".txinfo.info",
"$(MAKEINFO) $(MAKEINFO_FLAGS) $< -o $@",
".tex.dvi",
"$(TEX) $<",
".texinfo.dvi",
"$(TEXI2DVI) $(TEXI2DVI_FLAGS) $<",
".texi.dvi",
"$(TEXI2DVI) $(TEXI2DVI_FLAGS) $<",
".txinfo.dvi",
"$(TEXI2DVI) $(TEXI2DVI_FLAGS) $<",
".w.c",
"$(CTANGLE) $< - $@", /* The `-' says there is no `.ch' file. */
".web.p",
"$(TANGLE) $<",
".w.tex",
"$(CWEAVE) $< - $@", /* The `-' says there is no `.ch' file. */
".web.tex",
"$(WEAVE) $<",
0, 0,
};
static char *default_variables[] =
{
"AR", "ar",
#ifndef __hpux
"ARFLAGS", "rv",
#else
/* HPUX ar's f flag says to truncate the file names to archive member
name length in comparisons, so replacement notices the equality. */
"ARFLAGS", "rfv",
#endif
"AS", "as",
#ifdef GCC_IS_NATIVE
"CC", "gcc",
"CXX", "gcc",
#else
"CC", "cc",
"CXX", "g++",
#endif
/* 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)))",
"CO", "co",
"CPP", "$(CC) -E",
#ifdef CRAY
"CF77PPFLAGS", "-P",
"CF77PP", "/lib/cpp",
"CFT", "cft77",
"CF", "cf77",
"FC", "$(CF)",
#else /* Not CRAY. */
#ifdef _IBMR2
"FC", "xlf",
#else
#ifdef __convex__
"FC", "fc",
#else
"FC", "f77",
#endif /* __convex__ */
#endif /* _IBMR2 */
/* System V uses these, so explicit rules using them should work.
However, there is no way to make implicit rules use them and FC. */
"F77", "$(FC)",
"F77FLAGS", "$(FFLAGS)",
#endif /* Cray. */
"GET", SCCS_GET,
"LD", "ld",
#ifdef GCC_IS_NATIVE
"LEX", "flex",
#else
"LEX", "lex",
#endif
"LINT", "lint",
"M2C", "m2c",
#ifdef pyr
"PC", "pascal",
#else
#ifdef CRAY
"PC", "PASCAL",
"SEGLDR", "segldr",
#else
"PC", "pc",
#endif /* CRAY. */
#endif /* pyr. */
#ifdef GCC_IS_NATIVE
"YACC", "bison -y",
#else
"YACC", "yacc", /* Or "bison -y" */
#endif
"MAKEINFO", "makeinfo",
"TEX", "tex",
"TEXI2DVI", "texi2dvi",
"WEAVE", "weave",
"CWEAVE", "cweave",
"TANGLE", "tangle",
"CTANGLE", "ctangle",
"RM", "rm -f",
"LINK.o", "$(CC) $(LDFLAGS) $(TARGET_ARCH)",
"COMPILE.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
"LINK.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
"COMPILE.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
"COMPILE.C", "$(COMPILE.cc)",
"LINK.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
"LINK.C", "$(LINK.cc)",
"YACC.y", "$(YACC) $(YFLAGS)",
"LEX.l", "$(LEX) $(LFLAGS) -t",
"COMPILE.f", "$(FC) $(FFLAGS) $(TARGET_ARCH) -c",
"LINK.f", "$(FC) $(FFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
"COMPILE.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
"LINK.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
"COMPILE.r", "$(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -c",
"LINK.r", "$(FC) $(FFLAGS) $(RFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
"COMPILE.def", "$(M2C) $(M2FLAGS) $(DEFFLAGS) $(TARGET_ARCH)",
"COMPILE.mod", "$(M2C) $(M2FLAGS) $(MODFLAGS) $(TARGET_ARCH)",
"COMPILE.p", "$(PC) $(PFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
"LINK.p", "$(PC) $(PFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
"LINK.s", "$(CC) $(ASFLAGS) $(LDFLAGS) $(TARGET_MACH)",
"COMPILE.s", "$(AS) $(ASFLAGS) $(TARGET_MACH)",
"LINK.S", "$(CC) $(ASFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_MACH)",
"COMPILE.S", "$(CC) $(ASFLAGS) $(CPPFLAGS) $(TARGET_MACH) -c",
#if !defined(M_XENIX) || defined(__GNUC__)
"PREPROCESS.S", "$(CC) -E $(CPPFLAGS)",
#else /* Xenix. */
"PREPROCESS.S", "$(CC) -EP $(CPPFLAGS)",
#endif /* Not Xenix. */
"PREPROCESS.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -F",
"PREPROCESS.r", "$(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -F",
"LINT.c", "$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
#ifndef NO_MINUS_C_MINUS_O
#if !defined(M_XENIX) || defined(__GNUC__)
"OUTPUT_OPTION", "-o $@",
#else /* Xenix. */
"OUTPUT_OPTION", "-Fo$@",
#endif /* Not Xenix. */
#endif
#ifdef SCCS_GET_MINUS_G
"SCCS_OUTPUT_OPTION", "-G$@",
#endif
0, 0
};
/* Set up the default .SUFFIXES list. */
void
set_default_suffixes ()
{
suffix_file = enter_file (".SUFFIXES");
if (no_builtin_rules_flag)
(void) define_variable ("SUFFIXES", 8, "", o_default, 0);
else
{
char *p = default_suffixes;
suffix_file->deps = (struct dep *)
multi_glob (parse_file_seq (&p, '\0', sizeof (struct dep), 1),
sizeof (struct dep));
(void) define_variable ("SUFFIXES", 8, default_suffixes, o_default, 0);
}
}
/* Enter the default suffix rules as file rules. This used to be done in
install_default_implicit_rules, but that loses because we want the
suffix rules installed before reading makefiles, and thee pattern rules
installed after. */
void
install_default_suffix_rules ()
{
register char **s;
if (no_builtin_rules_flag)
return;
for (s = default_suffix_rules; *s != 0; s += 2)
{
register struct file *f = enter_file (s[0]);
/* Don't clobber cmds given in a makefile if there were any. */
if (f->cmds == 0)
{
f->cmds = (struct commands *) xmalloc (sizeof (struct commands));
f->cmds->filename = 0;
f->cmds->commands = s[1];
f->cmds->command_lines = 0;
}
}
}
/* Install the default pattern rules. */
void
install_default_implicit_rules ()
{
register struct pspec *p;
if (no_builtin_rules_flag)
return;
for (p = default_pattern_rules; p->target != 0; ++p)
install_pattern_rule (p, 0);
for (p = default_terminal_rules; p->target != 0; ++p)
install_pattern_rule (p, 1);
}
void
define_default_variables ()
{
register char **s;
for (s = default_variables; *s != 0; s += 2)
(void) define_variable (s[0], strlen (s[0]), s[1], o_default, 1);
}

66
dep.h Normal file
View File

@@ -0,0 +1,66 @@
/* Definitions of dependency data structures for GNU Make.
Copyright (C) 1988, 1989, 1991, 1992, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Structure representing one dependency of a file.
Each struct file's `deps' points to a chain of these,
chained through the `next'.
Note that the first two words of this match a struct nameseq. */
struct dep
{
struct dep *next;
char *name;
struct file *file;
int changed;
};
/* Structure used in chains of names, for parsing and globbing. */
struct nameseq
{
struct nameseq *next;
char *name;
};
extern struct nameseq *multi_glob (), *parse_file_seq ();
extern char *tilde_expand ();
#ifndef NO_ARCHIVES
extern struct nameseq *ar_glob ();
#endif
#ifndef iAPX286
#define dep_name(d) ((d)->name == 0 ? (d)->file->name : (d)->name)
#else
/* Buggy compiler can't hack this. */
extern char *dep_name ();
#endif
extern struct dep *read_all_makefiles ();
/* Flag bits for the second argument to `read_makefile'.
These flags are saved in the `changed' field of each
`struct dep' in the chain returned by `read_all_makefiles'. */
#define RM_NO_DEFAULT_GOAL (1 << 0) /* Do not set default goal. */
#define RM_INCLUDED (1 << 1) /* Search makefile search path. */
#define RM_DONTCARE (1 << 2) /* No error if it doesn't exist. */
#define RM_NO_TILDE (1 << 3) /* Don't expand ~ in file name. */
#define RM_NOFLAG 0

616
dir.c Normal file
View File

@@ -0,0 +1,616 @@
/* Directory hashing for GNU Make.
Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "make.h"
#if defined (POSIX) || defined (HAVE_DIRENT_H) || defined (__GNU_LIBRARY__)
#include <dirent.h>
#ifndef __GNU_LIBRARY__
#define D_NAMLEN(d) strlen((d)->d_name)
#else /* GNU C library. */
#define D_NAMLEN(d) ((d)->d_namlen)
#endif /* Not GNU C library. */
#else /* Not POSIX or HAVE_DIRENT_H. */
#define direct dirent
#define D_NAMLEN(d) ((d)->d_namlen)
#ifdef HAVE_SYS_NDIR_H
#include <sys/ndir.h>
#endif /* HAVE_SYS_NDIR_H */
#ifdef HAVE_SYS_DIR_H
#include <sys/dir.h>
#endif /* HAVE_SYS_DIR_H */
#ifdef HAVE_NDIR_H
#include <ndir.h>
#endif /* HAVE_NDIR_H */
#endif /* POSIX or HAVE_DIRENT_H or __GNU_LIBRARY__. */
#if defined (POSIX) && !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
#else
#define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
#endif /* POSIX */
#ifdef __MSDOS__
#include <ctype.h>
static char *
dosify (filename)
char *filename;
{
static char dos_filename[14];
char *df;
int i;
if (filename == 0)
return 0;
if (strpbrk (filename, "\"*+,;<=>?[\\]|") != 0)
return filename;
df = dos_filename;
/* First, transform the name part. */
for (i = 0; *filename != '\0' && i < 8 && *filename != '.'; ++i)
*df++ = tolower (*filename++);
/* Now skip to the next dot. */
while (*filename != '\0' && *filename != '.')
++filename;
if (*filename != '\0')
{
*df++ = *filename++;
for (i = 0; *filename != '\0' && i < 3 && *filename != '.'; ++i)
*df++ = tolower (*filename++);
}
/* Look for more dots. */
while (*filename != '\0' && *filename != '.')
++filename;
if (*filename == '.')
return filename;
*df = 0;
return dos_filename;
}
#endif
/* Hash table of directories. */
#ifndef DIRECTORY_BUCKETS
#define DIRECTORY_BUCKETS 199
#endif
struct directory_contents
{
struct directory_contents *next;
int dev, ino; /* Device and inode numbers of this dir. */
struct dirfile **files; /* Files in this directory. */
DIR *dirstream; /* Stream reading this directory. */
};
/* Table of directory contents hashed by device and inode number. */
static struct directory_contents *directories_contents[DIRECTORY_BUCKETS];
struct directory
{
struct directory *next;
char *name; /* Name of the directory. */
/* The directory's contents. This data may be shared by several
entries in the hash table, which refer to the same directory
(identified uniquely by `dev' and `ino') under different names. */
struct directory_contents *contents;
};
/* Table of directories hashed by name. */
static struct directory *directories[DIRECTORY_BUCKETS];
/* Never have more than this many directories open at once. */
#define MAX_OPEN_DIRECTORIES 10
static unsigned int open_directories = 0;
/* Hash table of files in each directory. */
struct dirfile
{
struct dirfile *next;
char *name; /* Name of the file. */
char impossible; /* This file is impossible. */
};
#ifndef DIRFILE_BUCKETS
#define DIRFILE_BUCKETS 107
#endif
static int dir_contents_file_exists_p ();
/* Find the directory named NAME and return its `struct directory'. */
static struct directory *
find_directory (name)
register char *name;
{
register unsigned int hash = 0;
register char *p;
register struct directory *dir;
for (p = name; *p != '\0'; ++p)
HASH (hash, *p);
hash %= DIRECTORY_BUCKETS;
for (dir = directories[hash]; dir != 0; dir = dir->next)
if (streq (dir->name, name))
break;
if (dir == 0)
{
struct stat st;
/* The directory was not found. Create a new entry for it. */
dir = (struct directory *) xmalloc (sizeof (struct directory));
dir->next = directories[hash];
directories[hash] = dir;
dir->name = savestring (name, p - name);
/* The directory is not in the name hash table.
Find its device and inode numbers, and look it up by them. */
if (safe_stat (name, &st) < 0)
/* Couldn't stat the directory. Mark this by
setting the `contents' member to a nil pointer. */
dir->contents = 0;
else
{
/* Search the contents hash table; device and inode are the key. */
struct directory_contents *dc;
hash = ((unsigned int) st.st_dev << 16) | (unsigned int) st.st_ino;
hash %= DIRECTORY_BUCKETS;
for (dc = directories_contents[hash]; dc != 0; dc = dc->next)
if (dc->dev == st.st_dev && dc->ino == st.st_ino)
break;
if (dc == 0)
{
/* Nope; this really is a directory we haven't seen before. */
dc = (struct directory_contents *)
xmalloc (sizeof (struct directory_contents));
/* Enter it in the contents hash table. */
dc->dev = st.st_dev;
dc->ino = st.st_ino;
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;
else
{
/* Allocate an array of buckets for files and zero it. */
dc->files = (struct dirfile **)
xmalloc (sizeof (struct dirfile *) * DIRFILE_BUCKETS);
bzero ((char *) dc->files,
sizeof (struct dirfile *) * DIRFILE_BUCKETS);
/* Keep track of how many directories are open. */
++open_directories;
if (open_directories == MAX_OPEN_DIRECTORIES)
/* We have too many directories open already.
Read the entire directory and then close it. */
(void) dir_contents_file_exists_p (dc, (char *) 0);
}
}
/* Point the name-hashed entry for DIR at its contents data. */
dir->contents = dc;
}
}
return dir;
}
/* Return 1 if the name FILENAME is entered in DIR's hash table.
FILENAME must contain no slashes. */
static int
dir_contents_file_exists_p (dir, filename)
register struct directory_contents *dir;
register char *filename;
{
register unsigned int hash;
register char *p;
register struct dirfile *df;
register struct dirent *d;
if (dir == 0 || dir->files == 0)
/* The directory could not be stat'd or opened. */
return 0;
#ifdef __MSDOS__
filename = dosify (filename);
#endif
hash = 0;
if (filename != 0)
{
if (*filename == '\0')
/* Checking if the directory exists. */
return 1;
for (p = filename; *p != '\0'; ++p)
HASH (hash, *p);
hash %= DIRFILE_BUCKETS;
/* Search the list of hashed files. */
for (df = dir->files[hash]; df != 0; df = df->next)
if (streq (df->name, filename))
return !df->impossible;
}
/* The file was not found in the hashed list.
Try to read the directory further. */
if (dir->dirstream == 0)
/* The directory has been all read in. */
return 0;
while ((d = readdir (dir->dirstream)) != 0)
{
/* Enter the file in the hash table. */
register unsigned int newhash = 0;
unsigned int len;
register unsigned int i;
if (!REAL_DIR_ENTRY (d))
continue;
len = D_NAMLEN (d);
while (d->d_name[len - 1] == '\0')
--len;
for (i = 0; i < len; ++i)
HASH (newhash, d->d_name[i]);
newhash %= DIRFILE_BUCKETS;
df = (struct dirfile *) xmalloc (sizeof (struct dirfile));
df->next = dir->files[newhash];
dir->files[newhash] = df;
df->name = savestring (d->d_name, len);
df->impossible = 0;
/* Check if the name matches the one we're searching for. */
if (filename != 0
&& newhash == hash && streq (d->d_name, filename))
return 1;
}
/* If the directory has been completely read in,
close the stream and reset the pointer to nil. */
if (d == 0)
{
--open_directories;
closedir (dir->dirstream);
dir->dirstream = 0;
}
return 0;
}
/* Return 1 if the name FILENAME in directory DIRNAME
is entered in the dir hash table.
FILENAME must contain no slashes. */
int
dir_file_exists_p (dirname, filename)
register char *dirname;
register char *filename;
{
return dir_contents_file_exists_p (find_directory (dirname)->contents,
filename);
}
/* Return 1 if the file named NAME exists. */
int
file_exists_p (name)
register char *name;
{
char *dirend;
char *dirname;
#ifndef NO_ARCHIVES
if (ar_name (name))
return ar_member_date (name) != (time_t) -1;
#endif
dirend = rindex (name, '/');
if (dirend == 0)
return dir_file_exists_p (".", name);
dirname = (char *) alloca (dirend - name + 1);
bcopy (name, dirname, dirend - name);
dirname[dirend - name] = '\0';
return dir_file_exists_p (dirname, dirend + 1);
}
/* Mark FILENAME as `impossible' for `file_impossible_p'.
This means an attempt has been made to search for FILENAME
as an intermediate file, and it has failed. */
void
file_impossible (filename)
register char *filename;
{
char *dirend;
register char *p = filename;
register unsigned int hash;
register struct directory *dir;
register struct dirfile *new;
dirend = rindex (p, '/');
if (dirend == 0)
dir = find_directory (".");
else
{
char *dirname = (char *) alloca (dirend - p + 1);
bcopy (p, dirname, dirend - p);
dirname[dirend - p] = '\0';
dir = find_directory (dirname);
filename = p = dirend + 1;
}
for (hash = 0; *p != '\0'; ++p)
HASH (hash, *p);
hash %= DIRFILE_BUCKETS;
if (dir->contents == 0)
{
/* The directory could not be stat'd. We allocate a contents
structure for it, but leave it out of the contents hash table. */
dir->contents = (struct directory_contents *)
xmalloc (sizeof (struct directory_contents));
dir->contents->dev = dir->contents->ino = 0;
dir->contents->files = 0;
dir->contents->dirstream = 0;
}
if (dir->contents->files == 0)
{
/* The directory was not opened; we must allocate the hash buckets. */
dir->contents->files = (struct dirfile **)
xmalloc (sizeof (struct dirfile) * DIRFILE_BUCKETS);
bzero ((char *) dir->contents->files,
sizeof (struct dirfile) * DIRFILE_BUCKETS);
}
/* Make a new entry and put it in the table. */
new = (struct dirfile *) xmalloc (sizeof (struct dirfile));
new->next = dir->contents->files[hash];
dir->contents->files[hash] = new;
new->name = savestring (filename, strlen (filename));
new->impossible = 1;
}
/* Return nonzero if FILENAME has been marked impossible. */
int
file_impossible_p (filename)
char *filename;
{
char *dirend;
register char *p = filename;
register unsigned int hash;
register struct directory_contents *dir;
register struct dirfile *next;
dirend = rindex (filename, '/');
if (dirend == 0)
dir = find_directory (".")->contents;
else
{
char *dirname = (char *) alloca (dirend - filename + 1);
bcopy (p, dirname, dirend - p);
dirname[dirend - p] = '\0';
dir = find_directory (dirname)->contents;
p = dirend + 1;
}
if (dir == 0 || dir->files == 0)
/* There are no files entered for this directory. */
return 0;
#ifdef __MSDOS__
p = filename = dosify (p);
#endif
for (hash = 0; *p != '\0'; ++p)
HASH (hash, *p);
hash %= DIRFILE_BUCKETS;
for (next = dir->files[hash]; next != 0; next = next->next)
if (streq (filename, next->name))
return next->impossible;
return 0;
}
/* Return the already allocated name in the
directory hash table that matches DIR. */
char *
dir_name (dir)
char *dir;
{
return find_directory (dir)->name;
}
/* Print the data base of directories. */
void
print_dir_data_base ()
{
register unsigned int i, dirs, files, impossible;
register struct directory *dir;
puts ("\n# Directories\n");
dirs = files = impossible = 0;
for (i = 0; i < DIRECTORY_BUCKETS; ++i)
for (dir = directories[i]; dir != 0; dir = dir->next)
{
++dirs;
if (dir->contents == 0)
printf ("# %s: could not be stat'd.\n", dir->name);
else if (dir->contents->files == 0)
printf ("# %s (device %d, inode %d): could not be opened.\n",
dir->name, dir->contents->dev, dir->contents->ino);
else
{
register unsigned int f = 0, im = 0;
register unsigned int j;
register struct dirfile *df;
for (j = 0; j < DIRFILE_BUCKETS; ++j)
for (df = dir->contents->files[j]; df != 0; df = df->next)
if (df->impossible)
++im;
else
++f;
printf ("# %s (device %d, inode %d): ",
dir->name, dir->contents->dev, dir->contents->ino);
if (f == 0)
fputs ("No", stdout);
else
printf ("%u", f);
fputs (" files, ", stdout);
if (im == 0)
fputs ("no", stdout);
else
printf ("%u", im);
fputs (" impossibilities", stdout);
if (dir->contents->dirstream == 0)
puts (".");
else
puts (" so far.");
files += f;
impossible += im;
}
}
fputs ("\n# ", stdout);
if (files == 0)
fputs ("No", stdout);
else
printf ("%u", files);
fputs (" files, ", stdout);
if (impossible == 0)
fputs ("no", stdout);
else
printf ("%u", impossible);
printf (" impossibilities in %u directories.\n", dirs);
}
/* Hooks for globbing. */
#include <glob.h>
/* Structure describing state of iterating through a directory hash table. */
struct dirstream
{
struct directory_contents *contents; /* The directory being read. */
unsigned int bucket; /* Current hash bucket. */
struct dirfile *elt; /* Current elt in bucket. */
};
/* Forward declarations. */
static __ptr_t open_dirstream __P ((const char *));
static const char *read_dirstream __P ((__ptr_t));
static __ptr_t
open_dirstream (directory)
const char *directory;
{
struct dirstream *new;
struct directory *dir = find_directory (directory);
if (dir->contents == 0 || dir->contents->files == 0)
/* DIR->contents is nil if the directory could not be stat'd.
DIR->contents->files is nil if it could not be opened. */
return 0;
/* Read all the contents of the directory now. There is no benefit
in being lazy, since glob will want to see every file anyway. */
(void) dir_contents_file_exists_p (dir->contents, (char *) 0);
new = (struct dirstream *) xmalloc (sizeof (struct dirstream));
new->contents = dir->contents;
new->bucket = 0;
new->elt = new->contents->files[0];
return (__ptr_t) new;
}
static const char *
read_dirstream (stream)
__ptr_t stream;
{
struct dirstream *const ds = (struct dirstream *) stream;
register struct dirfile *df;
while (ds->bucket < DIRFILE_BUCKETS)
{
while ((df = ds->elt) != 0)
{
ds->elt = df->next;
if (!df->impossible)
return df->name;
}
if (++ds->bucket == DIRFILE_BUCKETS)
break;
ds->elt = ds->contents->files[ds->bucket];
}
return 0;
}
void
init_dir ()
{
__glob_opendir_hook = open_dirstream;
__glob_readdir_hook = read_dirstream;
__glob_closedir_hook = (void (*) __P ((__ptr_t stream))) free;
}

472
expand.c Normal file
View File

@@ -0,0 +1,472 @@
/* Variable expansion functions for GNU Make.
Copyright (C) 1988, 1989, 1991, 1992, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "make.h"
#include "commands.h"
#include "file.h"
#include "variable.h"
/* The next two describe the variable output buffer.
This buffer is used to hold the variable-expansion of a line of the
makefile. It is made bigger with realloc whenever it is too small.
variable_buffer_length is the size currently allocated.
variable_buffer is the address of the buffer. */
static unsigned int variable_buffer_length;
static char *variable_buffer;
/* Subroutine of variable_expand and friends:
The text to add is LENGTH chars starting at STRING to the variable_buffer.
The text is added to the buffer at PTR, and the updated pointer into
the buffer is returned as the value. Thus, the value returned by
each call to variable_buffer_output should be the first argument to
the following call. */
char *
variable_buffer_output (ptr, string, length)
char *ptr, *string;
unsigned int length;
{
register unsigned int newlen = length + (ptr - variable_buffer);
if (newlen > variable_buffer_length)
{
unsigned int offset = ptr - variable_buffer;
variable_buffer_length = (newlen + 100 > 2 * variable_buffer_length
? newlen + 100
: 2 * variable_buffer_length);
variable_buffer = (char *) xrealloc (variable_buffer,
variable_buffer_length);
ptr = variable_buffer + offset;
}
bcopy (string, ptr, length);
return ptr + length;
}
/* Return a pointer to the beginning of the variable buffer. */
static char *
initialize_variable_output ()
{
/* If we don't have a variable output buffer yet, get one. */
if (variable_buffer == 0)
{
variable_buffer_length = 200;
variable_buffer = (char *) xmalloc (variable_buffer_length);
variable_buffer[0] = '\0';
}
return variable_buffer;
}
/* Recursively expand V. The returned string is malloc'd. */
char *
recursively_expand (v)
register struct variable *v;
{
char *value;
if (v->expanding)
{
/* Expanding V causes infinite recursion. Lose. */
if (reading_filename == 0)
fatal ("Recursive variable `%s' references itself (eventually)",
v->name);
else
makefile_fatal
(reading_filename, *reading_lineno_ptr,
"Recursive variable `%s' references itself (eventually)",
v->name);
}
v->expanding = 1;
value = allocated_variable_expand (v->value);
v->expanding = 0;
return value;
}
/* Warn that NAME is an undefined variable. */
#ifdef __GNUC__
__inline
#endif
static void
warn_undefined (name, length)
char *name;
unsigned int length;
{
if (warn_undefined_variables_flag)
{
static const char warnmsg[] = "warning: undefined variable `%.*s'";
if (reading_filename != 0)
makefile_error (reading_filename, *reading_lineno_ptr,
warnmsg, length, name);
else
error (warnmsg, length, name);
}
}
/* Expand a simple reference to variable NAME, which is LENGTH chars long. */
#ifdef __GNUC__
__inline
#endif
static char *
reference_variable (o, name, length)
char *o;
char *name;
unsigned int length;
{
register struct variable *v = lookup_variable (name, length);
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);
}
return o;
}
/* Scan LINE for variable references and expansion-function calls.
Build in `variable_buffer' the result of expanding the references and calls.
Return the address of the resulting string, which is null-terminated
and is valid only until the next time this function is called. */
char *
variable_expand (line)
register char *line;
{
register struct variable *v;
register char *p, *o, *p1;
p = line;
o = initialize_variable_output ();
while (1)
{
/* Copy all following uninteresting chars all at once to the
variable output buffer, and skip them. Uninteresting chars end
at the next $ or the end of the input. */
p1 = index (p, '$');
o = variable_buffer_output (o, p, p1 != 0 ? p1 - p : strlen (p) + 1);
if (p1 == 0)
break;
p = p1 + 1;
/* Dispatch on the char that follows the $. */
switch (*p)
{
case '$':
/* $$ seen means output one $ to the variable output buffer. */
o = variable_buffer_output (o, p, 1);
break;
case '(':
case '{':
/* $(...) or ${...} is the general case of substitution. */
{
char openparen = *p;
char closeparen = (openparen == '(') ? ')' : '}';
register char *beg = p + 1;
char *op, *begp;
char *end;
char *colon = 0;
op = o;
begp = p;
if (handle_function (&op, &begp))
{
o = op;
p = begp;
break;
}
/* Is there a variable reference inside the parens or braces?
If so, expand it before expanding the entire reference. */
p1 = index (beg, closeparen);
if (p1 != 0)
p1 = lindex (beg, p1, '$');
if (p1 != 0 && lindex (beg, p1, ':') == 0)
{
/* BEG now points past the opening paren or brace.
Count parens or braces until it is matched. */
int count = 0;
for (p = beg; *p != '\0'; ++p)
{
if (*p == openparen)
++count;
else if (*p == closeparen && --count < 0)
break;
else if (colon == 0 && count == 0 && *p == ':')
/* Record where we found a colon, which
indicates a substitution reference.
We want to expand the text before the
reference only. */
colon = p;
}
/* If COUNT is >= 0, there were unmatched opening parens
or braces, so we go to the simple case of a variable name
such as `$($(a)'. */
if (count < 0)
{
char *name = expand_argument (beg, colon == 0 ? p : colon);
unsigned int namelen = strlen (name);
if (colon == 0)
{
/* This is a simple reference to the expanded name. */
o = reference_variable (o, name, namelen);
free (name);
break;
}
else
{
/* This is a substitution reference to the expanded
name. We replace the pending text with a copy
containing the expanded name in place of the
original name, and then fall through to
the normal substitution reference code below. */
unsigned int restlen = strlen (colon) + 1;
beg = (char *) alloca (namelen + restlen);
bcopy (name, beg, namelen);
bcopy (colon, &beg[namelen], restlen);
/* Point COLON into the new copy. */
colon = &beg[namelen];
}
}
}
/* This is not a reference to a built-in function and
it does not contain any variable references inside.
There are several things it could be. */
if (colon == 0)
colon = index (beg, ':');
if (colon != 0 && lindex (beg, colon, closeparen) == 0)
{
/* This is a substitution reference: $(FOO:A=B). */
int count;
char *subst_beg, *subst_end, *replace_beg, *replace_end;
v = lookup_variable (beg, colon - beg);
if (v == 0)
warn_undefined (beg, colon - beg);
subst_beg = colon + 1;
count = 0;
for (p = subst_beg; *p != '\0'; ++p)
{
if (*p == openparen)
++count;
else if (*p == closeparen)
--count;
else if (*p == '=' && count <= 0)
break;
}
if (count > 0)
/* There were unmatched opening parens. */
return initialize_variable_output ();
subst_end = p;
replace_beg = p + 1;
count = 0;
for (p = replace_beg; *p != '\0'; ++p)
{
if (*p == openparen)
++count;
else if (*p == closeparen && --count < 0)
break;
}
if (count > 0)
/* There were unmatched opening parens. */
return initialize_variable_output ();
end = p;
replace_end = p;
p = expand_argument (subst_beg, subst_end);
p1 = expand_argument (replace_beg, replace_end);
if (v != 0 && *v->value != '\0')
{
char *value = (v->recursive ? recursively_expand (v)
: v->value);
char *percent = find_percent (p);
if (percent != 0)
o = patsubst_expand (o, value, p, p1,
percent, (char *) 0);
else
o = subst_expand (o, value,
p, p1, strlen (p), strlen (p1),
0, 1);
if (v->recursive)
free (value);
}
free (p);
free (p1);
}
/* No, this must be an ordinary variable reference. */
else
{
/* Look up the value of the variable. */
end = index (beg, closeparen);
if (end == 0)
{
/* Unterminated variable reference. */
if (reading_filename != 0)
makefile_fatal (reading_filename, *reading_lineno_ptr,
"unterminated variable reference");
else
fatal ("unterminated variable reference");
}
o = reference_variable (o, beg, end - beg);
}
/* Advance p past the variable reference to resume scan. */
p = end;
}
break;
case '\0':
break;
default:
if (isblank (p[-1]))
break;
/* A $ followed by a random char is a variable reference:
$a is equivalent to $(a). */
{
/* We could do the expanding here, but this way
avoids code repetition at a small performance cost. */
char name[5];
name[0] = '$';
name[1] = '(';
name[2] = *p;
name[3] = ')';
name[4] = '\0';
p1 = allocated_variable_expand (name);
o = variable_buffer_output (o, p1, strlen (p1));
free (p1);
}
break;
}
if (*p == '\0')
break;
else
++p;
}
(void) variable_buffer_output (o, "", 1);
return initialize_variable_output ();
}
/* Expand an argument for an expansion function.
The text starting at STR and ending at END is variable-expanded
into a null-terminated string that is returned as the value.
This is done without clobbering `variable_buffer' or the current
variable-expansion that is in progress. */
char *
expand_argument (str, end)
char *str, *end;
{
char *tmp;
if (*end == '\0')
tmp = str;
else
{
tmp = (char *) alloca (end - str + 1);
bcopy (str, tmp, end - str);
tmp[end - str] = '\0';
}
return allocated_variable_expand (tmp);
}
/* Expand LINE for FILE. Error messages refer to the file and line where
FILE's commands were found. Expansion uses FILE's variable set list. */
char *
variable_expand_for_file (line, file)
char *line;
register struct file *file;
{
char *result;
struct variable_set_list *save;
if (file == 0)
return variable_expand (line);
save = current_variable_set_list;
current_variable_set_list = file->variables;
reading_filename = file->cmds->filename;
reading_lineno_ptr = &file->cmds->lineno;
result = variable_expand (line);
current_variable_set_list = save;
reading_filename = 0;
reading_lineno_ptr = 0;
return result;
}
/* Like variable_expand_for_file, but the returned string is malloc'd.
This function is called a lot. It wants to be efficient. */
char *
allocated_variable_expand_for_file (line, file)
char *line;
struct file *file;
{
char *value;
char *obuf = variable_buffer;
unsigned int olen = variable_buffer_length;
variable_buffer = 0;
value = variable_expand_for_file (line, file);
#if 0
/* Waste a little memory and save time. */
value = xrealloc (value, strlen (value))
#endif
variable_buffer = obuf;
variable_buffer_length = olen;
return value;
}

555
file.c Normal file
View File

@@ -0,0 +1,555 @@
/* Target file hash table management for GNU Make.
Copyright (C) 1988, 89, 90, 91, 92, 93, 94 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "make.h"
#include "commands.h"
#include "dep.h"
#include "file.h"
#include "variable.h"
/* Hash table of files the makefile knows how to make. */
#ifndef FILE_BUCKETS
#define FILE_BUCKETS 1007
#endif
static struct file *files[FILE_BUCKETS];
/* Number of files with the `intermediate' flag set. */
unsigned int num_intermediates = 0;
/* Access the hash table of all file records.
lookup_file given a name, return the struct file * for that name,
or nil if there is none.
enter_file similar, but create one if there is none. */
struct file *
lookup_file (name)
char *name;
{
register struct file *f;
register char *n;
register unsigned int hashval;
if (*name == '\0')
abort ();
/* This is also done in parse_file_seq, so this is redundant
for names read from makefiles. It is here for names passed
on the command line. */
while (name[0] == '.' && name[1] == '/' && name[2] != '\0')
{
name += 2;
while (*name == '/')
/* Skip following slashes: ".//foo" is "foo", not "/foo". */
++name;
}
if (*name == '\0')
/* It was all slashes after a dot. */
name = "./";
hashval = 0;
for (n = name; *n != '\0'; ++n)
HASH (hashval, *n);
hashval %= FILE_BUCKETS;
for (f = files[hashval]; f != 0; f = f->next)
if (streq (f->name, name))
return f;
return 0;
}
struct file *
enter_file (name)
char *name;
{
register struct file *f, *new;
register char *n;
register unsigned int hashval;
if (*name == '\0')
abort ();
hashval = 0;
for (n = name; *n != '\0'; ++n)
HASH (hashval, *n);
hashval %= FILE_BUCKETS;
for (f = files[hashval]; f != 0; f = f->next)
if (streq (f->name, name))
break;
if (f != 0 && !f->double_colon)
return f;
new = (struct file *) xmalloc (sizeof (struct file));
bzero ((char *) new, sizeof (struct file));
new->name = name;
new->update_status = -1;
if (f == 0)
{
/* This is a completely new file. */
new->next = files[hashval];
files[hashval] = new;
}
else
{
/* There is already a double-colon entry for this file. */
new->double_colon = f;
while (f->prev != 0)
f = f->prev;
f->prev = new;
}
return new;
}
/* Rename FILE to NAME. This is not as simple as resetting
the `name' member, since it must be put in a new hash bucket,
and possibly merged with an existing file called NAME. */
void
rename_file (file, name)
register struct file *file;
char *name;
{
char *oldname = file->name;
register unsigned int oldhash;
register char *n;
while (file->renamed != 0)
file = file->renamed;
/* Find the hash values of the old and new names. */
oldhash = 0;
for (n = oldname; *n != '\0'; ++n)
HASH (oldhash, *n);
file_hash_enter (file, name, oldhash, file->name);
}
void
file_hash_enter (file, name, oldhash, oldname)
register struct file *file;
char *name;
unsigned int oldhash;
char *oldname;
{
unsigned int oldbucket = oldhash % FILE_BUCKETS;
register unsigned int newhash, newbucket;
struct file *oldfile;
register char *n;
register struct file *f;
newhash = 0;
for (n = name; *n != '\0'; ++n)
HASH (newhash, *n);
newbucket = newhash % FILE_BUCKETS;
/* Look for an existing file under the new name. */
for (oldfile = files[newbucket]; oldfile != 0; oldfile = oldfile->next)
if (streq (oldfile->name, name))
break;
if (oldhash != 0 && (newbucket != oldbucket || oldfile != 0))
{
/* Remove FILE from its hash bucket. */
struct file *lastf = 0;
for (f = files[oldbucket]; f != file; f = f->next)
lastf = f;
if (lastf == 0)
files[oldbucket] = f->next;
else
lastf->next = f->next;
}
/* Give FILE its new name. */
file->name = name;
for (f = file->double_colon; f != 0; f = f->prev)
f->name = name;
if (oldfile == 0)
{
/* There is no existing file with the new name. */
if (newbucket != oldbucket)
{
/* Put FILE in its new hash bucket. */
file->next = files[newbucket];
files[newbucket] = file;
}
}
else
{
/* There is an existing file with the new name.
We must merge FILE into the existing file. */
register struct dep *d;
if (file->cmds != 0)
{
if (oldfile->cmds == 0)
oldfile->cmds = file->cmds;
else if (file->cmds != oldfile->cmds)
{
/* We have two sets of commands. We will go with the
one given in the rule explicitly mentioning this name,
but give a message to let the user know what's going on. */
if (oldfile->cmds->filename != 0)
makefile_error (file->cmds->filename, file->cmds->lineno,
"Commands were specified for \
file `%s' at %s:%u,",
oldname, oldfile->cmds->filename,
oldfile->cmds->lineno);
else
makefile_error (file->cmds->filename, file->cmds->lineno,
"Commands for file `%s' were found by \
implicit rule search,",
oldname);
makefile_error (file->cmds->filename, file->cmds->lineno,
"but `%s' is now considered the same file \
as `%s'.",
oldname, name);
makefile_error (file->cmds->filename, file->cmds->lineno,
"Commands for `%s' will be ignored \
in favor of those for `%s'.",
name, oldname);
}
}
/* Merge the dependencies of the two files. */
d = oldfile->deps;
if (d == 0)
oldfile->deps = file->deps;
else
{
while (d->next != 0)
d = d->next;
d->next = file->deps;
}
merge_variable_set_lists (&oldfile->variables, file->variables);
if (oldfile->double_colon && !file->double_colon)
fatal ("can't rename single-colon `%s' to double-colon `%s'",
oldname, name);
if (!oldfile->double_colon && file->double_colon)
fatal ("can't rename double-colon `%s' to single-colon `%s'",
oldname, name);
if (file->last_mtime > oldfile->last_mtime)
/* %%% Kludge so -W wins on a file that gets vpathized. */
oldfile->last_mtime = file->last_mtime;
#define MERGE(field) oldfile->field |= file->field
MERGE (precious);
MERGE (tried_implicit);
MERGE (updating);
MERGE (updated);
MERGE (is_target);
MERGE (cmd_target);
MERGE (phony);
#undef MERGE
file->renamed = oldfile;
}
}
/* Remove all nonprecious intermediate files.
If SIG is nonzero, this was caused by a fatal signal,
meaning that a different message will be printed, and
the message will go to stderr rather than stdout. */
void
remove_intermediates (sig)
int sig;
{
register int i;
register struct file *f;
char doneany;
if (!sig && just_print_flag)
return;
doneany = 0;
for (i = 0; i < FILE_BUCKETS; ++i)
for (f = files[i]; f != 0; f = f->next)
if (f->intermediate && (f->dontcare || !f->precious))
{
int status;
if (just_print_flag)
status = 0;
else
{
status = unlink (f->name);
if (status < 0 && errno == ENOENT)
continue;
}
if (!f->dontcare)
{
if (sig)
error ("*** Deleting intermediate file `%s'", f->name);
else if (!silent_flag)
{
if (! doneany)
{
fputs ("rm ", stdout);
doneany = 1;
}
else
putchar (' ');
fputs (f->name, stdout);
fflush (stdout);
}
if (status < 0)
perror_with_name ("unlink: ", f->name);
}
}
if (doneany && !sig)
{
putchar ('\n');
fflush (stdout);
}
}
/* For each dependency of each file, make the `struct dep' point
at the appropriate `struct file' (which may have to be created).
Also mark the files depended on by .PRECIOUS and .PHONY. */
void
snap_deps ()
{
register struct file *f, *f2;
register struct dep *d;
register int i;
/* Enter each dependency name as a file. */
for (i = 0; i < FILE_BUCKETS; ++i)
for (f = files[i]; f != 0; f = f->next)
for (f2 = f; f2 != 0; f2 = f2->prev)
for (d = f2->deps; d != 0; d = d->next)
if (d->name != 0)
{
d->file = lookup_file (d->name);
if (d->file == 0)
d->file = enter_file (d->name);
else
free (d->name);
d->name = 0;
}
for (f = lookup_file (".PRECIOUS"); f != 0; f = f->prev)
for (d = f->deps; d != 0; d = d->next)
for (f2 = d->file; f2 != 0; f2 = f2->prev)
f2->precious = 1;
for (f = lookup_file (".PHONY"); f != 0; f = f->prev)
for (d = f->deps; d != 0; d = d->next)
for (f2 = d->file; f2 != 0; f2 = f2->prev)
{
/* Mark this file as phony and nonexistent. */
f2->phony = 1;
f2->last_mtime = (time_t) -1;
}
f = lookup_file (".EXPORT_ALL_VARIABLES");
if (f != 0 && f->is_target)
export_all_variables = 1;
f = lookup_file (".IGNORE");
if (f != 0 && f->is_target)
{
if (f->deps == 0)
ignore_errors_flag = 1;
else
for (d = f->deps; d != 0; d = d->next)
for (f2 = d->file; f2 != 0; f2 = f2->prev)
f2->command_flags |= COMMANDS_NOERROR;
}
f = lookup_file (".SILENT");
if (f != 0 && f->is_target)
{
if (f->deps == 0)
silent_flag = 1;
else
for (d = f->deps; d != 0; d = d->next)
for (f2 = d->file; f2 != 0; f2 = f2->prev)
f2->command_flags |= COMMANDS_SILENT;
}
f = lookup_file (".POSIX");
if (f != 0 && f->is_target)
posix_pedantic = 1;
}
/* Set the `command_state' member of FILE and all its `also_make's. */
void
set_command_state (file, state)
struct file *file;
int state;
{
struct dep *d;
file->command_state = state;
for (d = file->also_make; d != 0; d = d->next)
d->file->command_state = state;
}
/* Print the data base of files. */
static void
print_file (f)
struct file *f;
{
register struct dep *d;
putchar ('\n');
if (!f->is_target)
puts ("# Not a target:");
printf ("%s:%s", f->name, f->double_colon ? ":" : "");
for (d = f->deps; d != 0; d = d->next)
printf (" %s", dep_name (d));
putchar ('\n');
if (f->precious)
puts ("# Precious file (dependency of .PRECIOUS).");
if (f->phony)
puts ("# Phony target (dependency of .PHONY).");
if (f->cmd_target)
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");
if (f->stem != 0)
printf ("# Implicit/static pattern stem: `%s'\n", f->stem);
if (f->intermediate)
puts ("# File is an intermediate dependency.");
if (f->also_make != 0)
{
fputs ("# Also makes:", stdout);
for (d = f->also_make; d != 0; d = d->next)
printf (" %s", dep_name (d));
putchar ('\n');
}
if (f->last_mtime == (time_t) 0)
puts ("# Modification time never checked.");
else if (f->last_mtime == (time_t) -1)
puts ("# File does not exist.");
else
printf ("# Last modified %.24s (%ld)\n",
ctime (&f->last_mtime), (long int) f->last_mtime);
printf ("# File has%s been updated.\n",
f->updated ? "" : " not");
switch (f->command_state)
{
case cs_running:
puts ("# Commands currently running (THIS IS A BUG).");
break;
case cs_deps_running:
puts ("# Dependencies commands running (THIS IS A BUG).");
break;
case cs_not_started:
case cs_finished:
switch (f->update_status)
{
case -1:
break;
case 0:
puts ("# Successfully updated.");
break;
case 1:
puts ("# Failed to be updated.");
break;
default:
puts ("# Invalid value in `update_status' member!");
fflush (stdout);
fflush (stderr);
abort ();
}
break;
default:
puts ("# Invalid value in `command_state' member!");
fflush (stdout);
fflush (stderr);
abort ();
}
if (f->variables != 0)
print_file_variables (f);
if (f->cmds != 0)
print_commands (f->cmds);
}
void
print_file_data_base ()
{
register unsigned int i, nfiles, per_bucket;
register struct file *file;
puts ("\n# Files");
per_bucket = nfiles = 0;
for (i = 0; i < FILE_BUCKETS; ++i)
{
register unsigned int this_bucket = 0;
for (file = files[i]; file != 0; file = file->next)
{
register struct file *f;
++this_bucket;
for (f = file; f != 0; f = f->prev)
print_file (f);
}
nfiles += this_bucket;
if (this_bucket > per_bucket)
per_bucket = this_bucket;
}
if (nfiles == 0)
puts ("\n# No files.");
else
{
printf ("\n# %u files in %u hash buckets.\n", nfiles, FILE_BUCKETS);
#ifndef NO_FLOAT
printf ("# average %.1f files per bucket, max %u files in one bucket.\n",
((double) nfiles) / ((double) FILE_BUCKETS) * 100.0, per_bucket);
#endif
}
}

111
file.h Normal file
View File

@@ -0,0 +1,111 @@
/* Definition of target file data structures for GNU Make.
Copyright (C) 1988, 89, 90, 91, 92, 93, 94 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Structure that represents the info on one file
that the makefile says how to make.
All of these are chained together through `next'. */
struct file
{
struct file *next;
char *name;
struct dep *deps;
struct commands *cmds; /* Commands to execute for this target. */
int command_flags; /* Flags OR'd in for cmds; see commands.h. */
char *stem; /* Implicit stem, if an implicit
rule has been used */
struct dep *also_make; /* Targets that are made by making this. */
time_t last_mtime; /* File's modtime, if already known. */
struct file *prev; /* Previous entry for same file name;
used when there are multiple double-colon
entries for the same file. */
/* File that this file was renamed to. After any time that a
file could be renamed, call `check_renamed' (below). */
struct file *renamed;
/* List of variable sets used for this file. */
struct variable_set_list *variables;
/* Immediate dependent that caused this target to be remade,
or nil if there isn't one. */
struct file *parent;
/* For a double-colon entry, this is the first double-colon entry for
the same file. Otherwise this is null. */
struct file *double_colon;
short int update_status; /* Status of the last attempt to update,
or -1 if none has been made. */
enum /* State of the commands. */
{ /* Note: It is important that cs_not_started be zero. */
cs_not_started, /* Not yet started. */
cs_deps_running, /* Dep commands running. */
cs_running, /* Commands running. */
cs_finished /* Commands finished. */
} command_state ENUM_BITFIELD (2);
unsigned int precious:1; /* Non-0 means don't delete file on quit */
unsigned int tried_implicit:1; /* Nonzero if have searched
for implicit rule for making
this file; don't search again. */
unsigned int updating:1; /* Nonzero while updating deps of this file */
unsigned int updated:1; /* Nonzero if this file has been remade. */
unsigned int is_target:1; /* Nonzero if file is described as target. */
unsigned int cmd_target:1; /* Nonzero if file was given on cmd line. */
unsigned int phony:1; /* Nonzero if this is a phony file
i.e., a dependency of .PHONY. */
unsigned int intermediate:1;/* Nonzero if this is an intermediate file. */
unsigned int dontcare:1; /* Nonzero if no complaint is to be made if
this target cannot be remade. */
};
/* Number of intermediate files entered. */
extern unsigned int num_intermediates;
extern struct file *default_goal_file, *suffix_file, *default_file;
extern struct file *lookup_file (), *enter_file ();
extern void remove_intermediates (), snap_deps ();
extern void rename_file (), file_hash_enter ();
extern void set_command_state ();
extern time_t f_mtime ();
#define file_mtime_1(f, v) \
((f)->last_mtime != (time_t) 0 ? (f)->last_mtime : f_mtime ((f), v))
#define file_mtime(f) file_mtime_1 ((f), 1)
#define file_mtime_no_search(f) file_mtime_1 ((f), 0)
/* Modtime value to use for `infinitely new'. We used to get the current time
from the system and use that whenever we wanted `new'. But that causes
trouble when the machine running make and the machine holding a file have
different ideas about what time it is; and can also lose for `force'
targets, which need to be considered newer than anything that depends on
them, even if said dependents' modtimes are in the future.
NOTE: This assumes 32-bit `time_t's, but I cannot think of a portable way
to produce the largest representable integer of a given signed type. */
#define NEW_MTIME ((time_t) 0x7fffffff)
#define check_renamed(file) \
while ((file)->renamed != 0) (file) = (file)->renamed /* No ; here. */

1309
function.c Normal file

File diff suppressed because it is too large Load Diff

919
getloadavg.c Normal file
View File

@@ -0,0 +1,919 @@
/* Get the system load averages.
Copyright (C) 1985, 86, 87, 88, 89, 91, 92, 93, 1994
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Compile-time symbols that this file uses:
FIXUP_KERNEL_SYMBOL_ADDR() Adjust address in returned struct nlist.
KERNEL_FILE Pathname of the kernel to nlist.
LDAV_CVT() Scale the load average from the kernel.
Returns a double.
LDAV_SYMBOL Name of kernel symbol giving load average.
LOAD_AVE_TYPE Type of the load average array in the kernel.
Must be defined unless one of
apollo, DGUX, NeXT, or UMAX is defined;
otherwise, no load average is available.
NLIST_STRUCT Include nlist.h, not a.out.h, and
the nlist n_name element is a pointer,
not an array.
NLIST_NAME_UNION struct nlist has an n_un member, not n_name.
LINUX_LDAV_FILE [__linux__]: File containing load averages.
Specific system predefines this file uses, aside from setting
default values if not emacs:
apollo
BSD Real BSD, not just BSD-like.
DGUX
eunice UNIX emulator under VMS.
hpux
NeXT
sgi
sequent Sequent Dynix 3.x.x (BSD)
_SEQUENT_ Sequent DYNIX/ptx 1.x.x (SYSV)
sony_news NEWS-OS (works at least for 4.1C)
UMAX
UMAX4_3
VMS
__linux__ Linux: assumes /proc filesystem mounted.
Support from Michael K. Johnson.
__NetBSD__ NetBSD: assumes /kern filesystem mounted.
In addition, to avoid nesting many #ifdefs, we internally set
LDAV_DONE to indicate that the load average has been computed.
We also #define LDAV_PRIVILEGED if a program will require
special installation to be able to call getloadavg. */
#include <sys/types.h>
/* Both the Emacs and non-Emacs sections want this. Some
configuration files' definitions for the LOAD_AVE_CVT macro (like
sparc.h's) use macros like FSCALE, defined here. */
#ifdef unix
#include <sys/param.h>
#endif
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
/* Exclude all the code except the test program at the end
if the system has its own `getloadavg' function.
The declaration of `errno' is needed by the test program
as well as the function itself, so it comes first. */
#include <errno.h>
#ifndef errno
extern int errno;
#endif
#ifndef HAVE_GETLOADAVG
/* The existing Emacs configuration files define a macro called
LOAD_AVE_CVT, which accepts a value of type LOAD_AVE_TYPE, and
returns the load average multiplied by 100. What we actually want
is a macro called LDAV_CVT, which returns the load average as an
unmultiplied double.
For backwards compatibility, we'll define LDAV_CVT in terms of
LOAD_AVE_CVT, but future machine config files should just define
LDAV_CVT directly. */
#if !defined(LDAV_CVT) && defined(LOAD_AVE_CVT)
#define LDAV_CVT(n) (LOAD_AVE_CVT (n) / 100.0)
#endif
#if !defined (BSD) && defined (ultrix)
/* Ultrix behaves like BSD on Vaxen. */
#define BSD
#endif
#ifdef NeXT
/* NeXT in the 2.{0,1,2} releases defines BSD in <sys/param.h>, which
conflicts with the definition understood in this file, that this
really is BSD. */
#undef BSD
/* NeXT defines FSCALE in <sys/param.h>. However, we take FSCALE being
defined to mean that the nlist method should be used, which is not true. */
#undef FSCALE
#endif
/* Set values that are different from the defaults, which are
set a little farther down with #ifndef. */
/* Some shorthands. */
#if defined (HPUX) && !defined (hpux)
#define hpux
#endif
#if defined(hp300) && !defined(hpux)
#define MORE_BSD
#endif
#if defined(ultrix) && defined(mips)
#define decstation
#endif
#if defined(sun) && defined(SVR4)
#define SUNOS_5
#endif
#if defined (__osf__) && (defined (__alpha) || defined (__alpha__))
#define OSF_ALPHA
#include <sys/table.h>
#endif
#if defined (__osf__) && (defined (mips) || defined (__mips__))
#define OSF_MIPS
#include <sys/table.h>
#endif
/* UTek's /bin/cc on the 4300 has no architecture specific cpp define by
default, but _MACH_IND_SYS_TYPES is defined in <sys/types.h>. Combine
that with a couple of other things and we'll have a unique match. */
#if !defined (tek4300) && defined (unix) && defined (m68k) && defined (mc68000) && defined (mc68020) && defined (_MACH_IND_SYS_TYPES)
#define tek4300 /* Define by emacs, but not by other users. */
#endif
/* VAX C can't handle multi-line #ifs, or lines longer than 256 chars. */
#ifndef LOAD_AVE_TYPE
#ifdef MORE_BSD
#define LOAD_AVE_TYPE long
#endif
#ifdef sun
#define LOAD_AVE_TYPE long
#endif
#ifdef decstation
#define LOAD_AVE_TYPE long
#endif
#ifdef _SEQUENT_
#define LOAD_AVE_TYPE long
#endif
#ifdef sgi
#define LOAD_AVE_TYPE long
#endif
#ifdef SVR4
#define LOAD_AVE_TYPE long
#endif
#ifdef sony_news
#define LOAD_AVE_TYPE long
#endif
#ifdef sequent
#define LOAD_AVE_TYPE long
#endif
#ifdef OSF_ALPHA
#define LOAD_AVE_TYPE long
#endif
#if defined (ardent) && defined (titan)
#define LOAD_AVE_TYPE long
#endif
#ifdef tek4300
#define LOAD_AVE_TYPE long
#endif
#if defined(alliant) && defined(i860) /* Alliant FX/2800 */
#define LOAD_AVE_TYPE long
#endif
#endif /* No LOAD_AVE_TYPE. */
#ifdef OSF_ALPHA
/* <sys/param.h> defines an incorrect value for FSCALE on Alpha OSF/1,
according to ghazi@noc.rutgers.edu. */
#undef FSCALE
#define FSCALE 1024.0
#endif
#if defined(alliant) && defined(i860) /* Alliant FX/2800 */
/* <sys/param.h> defines an incorrect value for FSCALE on an
Alliant FX/2800 Concentrix 2.2, according to ghazi@noc.rutgers.edu. */
#undef FSCALE
#define FSCALE 100.0
#endif
#ifndef FSCALE
/* SunOS and some others define FSCALE in sys/param.h. */
#ifdef MORE_BSD
#define FSCALE 2048.0
#endif
#if defined(MIPS) || defined(SVR4) || defined(decstation)
#define FSCALE 256
#endif
#if defined (sgi) || defined (sequent)
/* Sometimes both MIPS and sgi are defined, so FSCALE was just defined
above under #ifdef MIPS. But we want the sgi value. */
#undef FSCALE
#define FSCALE 1000.0
#endif
#if defined (ardent) && defined (titan)
#define FSCALE 65536.0
#endif
#ifdef tek4300
#define FSCALE 100.0
#endif
#endif /* Not FSCALE. */
#if !defined (LDAV_CVT) && defined (FSCALE)
#define LDAV_CVT(n) (((double) (n)) / FSCALE)
#endif
/* VAX C can't handle multi-line #ifs, or lines longer that 256 characters. */
#ifndef NLIST_STRUCT
#ifdef MORE_BSD
#define NLIST_STRUCT
#endif
#ifdef sun
#define NLIST_STRUCT
#endif
#ifdef decstation
#define NLIST_STRUCT
#endif
#ifdef hpux
#define NLIST_STRUCT
#endif
#if defined (_SEQUENT_) || defined (sequent)
#define NLIST_STRUCT
#endif
#ifdef sgi
#define NLIST_STRUCT
#endif
#ifdef SVR4
#define NLIST_STRUCT
#endif
#ifdef sony_news
#define NLIST_STRUCT
#endif
#ifdef OSF_ALPHA
#define NLIST_STRUCT
#endif
#if defined (ardent) && defined (titan)
#define NLIST_STRUCT
#endif
#ifdef tek4300
#define NLIST_STRUCT
#endif
#ifdef butterfly
#define NLIST_STRUCT
#endif
#if defined(alliant) && defined(i860) /* Alliant FX/2800 */
#define NLIST_STRUCT
#endif
#endif /* defined (NLIST_STRUCT) */
#if defined(sgi) || (defined(mips) && !defined(BSD))
#define FIXUP_KERNEL_SYMBOL_ADDR(nl) ((nl)[0].n_value &= ~(1 << 31))
#endif
#if !defined (KERNEL_FILE) && defined (sequent)
#define KERNEL_FILE "/dynix"
#endif
#if !defined (KERNEL_FILE) && defined (hpux)
#define KERNEL_FILE "/hp-ux"
#endif
#if !defined(KERNEL_FILE) && (defined(_SEQUENT_) || defined(MIPS) || defined(SVR4) || defined(ISC) || defined (sgi) || defined(SVR4) || (defined (ardent) && defined (titan)))
#define KERNEL_FILE "/unix"
#endif
#if !defined (LDAV_SYMBOL) && defined (alliant)
#define LDAV_SYMBOL "_Loadavg"
#endif
#if !defined(LDAV_SYMBOL) && ((defined(hpux) && !defined(hp9000s300)) || defined(_SEQUENT_) || defined(SVR4) || defined(ISC) || defined(sgi) || (defined (ardent) && defined (titan)))
#define LDAV_SYMBOL "avenrun"
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdio.h>
/* LOAD_AVE_TYPE should only get defined if we're going to use the
nlist method. */
#if !defined(LOAD_AVE_TYPE) && (defined(BSD) || defined(LDAV_CVT) || defined(KERNEL_FILE) || defined(LDAV_SYMBOL))
#define LOAD_AVE_TYPE double
#endif
#ifdef LOAD_AVE_TYPE
#ifndef VMS
#ifndef NLIST_STRUCT
#include <a.out.h>
#else /* NLIST_STRUCT */
#include <nlist.h>
#endif /* NLIST_STRUCT */
#ifdef SUNOS_5
#include <fcntl.h>
#include <kvm.h>
#endif
#ifndef KERNEL_FILE
#define KERNEL_FILE "/vmunix"
#endif /* KERNEL_FILE */
#ifndef LDAV_SYMBOL
#define LDAV_SYMBOL "_avenrun"
#endif /* LDAV_SYMBOL */
#else /* VMS */
#ifndef eunice
#include <iodef.h>
#include <descrip.h>
#else /* eunice */
#include <vms/iodef.h>
#endif /* eunice */
#endif /* VMS */
#ifndef LDAV_CVT
#define LDAV_CVT(n) ((double) (n))
#endif /* !LDAV_CVT */
#endif /* LOAD_AVE_TYPE */
#ifdef NeXT
#ifdef HAVE_MACH_MACH_H
#include <mach/mach.h>
#else
#include <mach.h>
#endif
#endif /* NeXT */
#ifdef sgi
#include <sys/sysmp.h>
#endif /* sgi */
#ifdef UMAX
#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#ifdef UMAX_43
#include <machine/cpu.h>
#include <inq_stats/statistics.h>
#include <inq_stats/sysstats.h>
#include <inq_stats/cpustats.h>
#include <inq_stats/procstats.h>
#else /* Not UMAX_43. */
#include <sys/sysdefs.h>
#include <sys/statistics.h>
#include <sys/sysstats.h>
#include <sys/cpudefs.h>
#include <sys/cpustats.h>
#include <sys/procstats.h>
#endif /* Not UMAX_43. */
#endif /* UMAX */
#ifdef DGUX
#include <sys/dg_sys_info.h>
#endif
#if defined(HAVE_FCNTL_H) || defined(_POSIX_VERSION)
#include <fcntl.h>
#else
#include <sys/file.h>
#endif
/* Avoid static vars inside a function since in HPUX they dump as pure. */
#ifdef NeXT
static processor_set_t default_set;
static int getloadavg_initialized;
#endif /* NeXT */
#ifdef UMAX
static unsigned int cpus = 0;
static unsigned int samples;
#endif /* UMAX */
#ifdef DGUX
static struct dg_sys_info_load_info load_info; /* what-a-mouthful! */
#endif /* DGUX */
#ifdef LOAD_AVE_TYPE
/* File descriptor open to /dev/kmem or VMS load ave driver. */
static int channel;
/* Nonzero iff channel is valid. */
static int getloadavg_initialized;
/* Offset in kmem to seek to read load average, or 0 means invalid. */
static long offset;
#if !defined(VMS) && !defined(sgi)
static struct nlist nl[2];
#endif /* Not VMS or sgi */
#ifdef SUNOS_5
static kvm_t *kd;
#endif /* SUNOS_5 */
#endif /* LOAD_AVE_TYPE */
/* Put the 1 minute, 5 minute and 15 minute load averages
into the first NELEM elements of LOADAVG.
Return the number written (never more than 3, but may be less than NELEM),
or -1 if an error occurred. */
int
getloadavg (loadavg, nelem)
double loadavg[];
int nelem;
{
int elem = 0; /* Return value. */
#ifdef NO_GET_LOAD_AVG
#define LDAV_DONE
/* Set errno to zero to indicate that there was no particular error;
this function just can't work at all on this system. */
errno = 0;
elem = -1;
#endif
#if !defined (LDAV_DONE) && defined (__linux__)
#define LDAV_DONE
#undef LOAD_AVE_TYPE
#ifndef LINUX_LDAV_FILE
#define LINUX_LDAV_FILE "/proc/loadavg"
#endif
char ldavgbuf[40];
double load_ave[3];
int fd, count;
fd = open (LINUX_LDAV_FILE, O_RDONLY);
if (fd == -1)
return -1;
count = read (fd, ldavgbuf, 40);
(void) close (fd);
if (count <= 0)
return -1;
count = sscanf (ldavgbuf, "%lf %lf %lf",
&load_ave[0], &load_ave[1], &load_ave[2]);
if (count < 1)
return -1;
for (elem = 0; elem < nelem && elem < count; elem++)
loadavg[elem] = load_ave[elem];
return elem;
#endif /* __linux__ */
#if !defined (LDAV_DONE) && defined (__NetBSD__)
#define LDAV_DONE
#undef LOAD_AVE_TYPE
#ifndef NETBSD_LDAV_FILE
#define NETBSD_LDAV_FILE "/kern/loadavg"
#endif
unsigned long int load_ave[3], scale;
int count;
FILE *fp;
fp = fopen (NETBSD_LDAV_FILE, "r");
if (fp == NULL)
return -1;
count = fscanf (fp, "%lu %lu %lu %lu\n",
&load_ave[0], &load_ave[1], &load_ave[2],
&scale);
(void) fclose (fp);
if (count != 4)
return -1;
for (elem = 0; elem < nelem; elem++)
loadavg[elem] = (double) load_ave[elem] / (double) scale;
return elem;
#endif /* __NetBSD__ */
#if !defined (LDAV_DONE) && defined (NeXT)
#define LDAV_DONE
/* The NeXT code was adapted from iscreen 3.2. */
host_t host;
struct processor_set_basic_info info;
unsigned info_count;
/* We only know how to get the 1-minute average for this system,
so even if the caller asks for more than 1, we only return 1. */
if (!getloadavg_initialized)
{
if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS)
getloadavg_initialized = 1;
}
if (getloadavg_initialized)
{
info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host,
(processor_set_info_t) &info, &info_count)
!= KERN_SUCCESS)
getloadavg_initialized = 0;
else
{
if (nelem > 0)
loadavg[elem++] = (double) info.load_average / LOAD_SCALE;
}
}
if (!getloadavg_initialized)
return -1;
#endif /* NeXT */
#if !defined (LDAV_DONE) && defined (UMAX)
#define LDAV_DONE
/* UMAX 4.2, which runs on the Encore Multimax multiprocessor, does not
have a /dev/kmem. Information about the workings of the running kernel
can be gathered with inq_stats system calls.
We only know how to get the 1-minute average for this system. */
struct proc_summary proc_sum_data;
struct stat_descr proc_info;
double load;
register unsigned int i, j;
if (cpus == 0)
{
register unsigned int c, i;
struct cpu_config conf;
struct stat_descr desc;
desc.sd_next = 0;
desc.sd_subsys = SUBSYS_CPU;
desc.sd_type = CPUTYPE_CONFIG;
desc.sd_addr = (char *) &conf;
desc.sd_size = sizeof conf;
if (inq_stats (1, &desc))
return -1;
c = 0;
for (i = 0; i < conf.config_maxclass; ++i)
{
struct class_stats stats;
bzero ((char *) &stats, sizeof stats);
desc.sd_type = CPUTYPE_CLASS;
desc.sd_objid = i;
desc.sd_addr = (char *) &stats;
desc.sd_size = sizeof stats;
if (inq_stats (1, &desc))
return -1;
c += stats.class_numcpus;
}
cpus = c;
samples = cpus < 2 ? 3 : (2 * cpus / 3);
}
proc_info.sd_next = 0;
proc_info.sd_subsys = SUBSYS_PROC;
proc_info.sd_type = PROCTYPE_SUMMARY;
proc_info.sd_addr = (char *) &proc_sum_data;
proc_info.sd_size = sizeof (struct proc_summary);
proc_info.sd_sizeused = 0;
if (inq_stats (1, &proc_info) != 0)
return -1;
load = proc_sum_data.ps_nrunnable;
j = 0;
for (i = samples - 1; i > 0; --i)
{
load += proc_sum_data.ps_nrun[j];
if (j++ == PS_NRUNSIZE)
j = 0;
}
if (nelem > 0)
loadavg[elem++] = load / samples / cpus;
#endif /* UMAX */
#if !defined (LDAV_DONE) && defined (DGUX)
#define LDAV_DONE
/* This call can return -1 for an error, but with good args
it's not supposed to fail. The first argument is for no
apparent reason of type `long int *'. */
dg_sys_info ((long int *) &load_info,
DG_SYS_INFO_LOAD_INFO_TYPE,
DG_SYS_INFO_LOAD_VERSION_0);
if (nelem > 0)
loadavg[elem++] = load_info.one_minute;
if (nelem > 1)
loadavg[elem++] = load_info.five_minute;
if (nelem > 2)
loadavg[elem++] = load_info.fifteen_minute;
#endif /* DGUX */
#if !defined (LDAV_DONE) && defined (apollo)
#define LDAV_DONE
/* Apollo code from lisch@mentorg.com (Ray Lischner).
This system call is not documented. The load average is obtained as
three long integers, for the load average over the past minute,
five minutes, and fifteen minutes. Each value is a scaled integer,
with 16 bits of integer part and 16 bits of fraction part.
I'm not sure which operating system first supported this system call,
but I know that SR10.2 supports it. */
extern void proc1_$get_loadav ();
unsigned long load_ave[3];
proc1_$get_loadav (load_ave);
if (nelem > 0)
loadavg[elem++] = load_ave[0] / 65536.0;
if (nelem > 1)
loadavg[elem++] = load_ave[1] / 65536.0;
if (nelem > 2)
loadavg[elem++] = load_ave[2] / 65536.0;
#endif /* apollo */
#if !defined (LDAV_DONE) && defined (OSF_MIPS)
#define LDAV_DONE
struct tbl_loadavg load_ave;
table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
loadavg[elem++]
= (load_ave.tl_lscale == 0
? load_ave.tl_avenrun.d[0]
: (load_ave.tl_avenrun.l[0] / (double) load_ave.tl_lscale));
#endif /* OSF_MIPS */
#if !defined (LDAV_DONE) && defined (OSF_ALPHA)
#define LDAV_DONE
struct tbl_loadavg load_ave;
table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
for (elem = 0; elem < nelem; elem++)
loadavg[elem]
= (load_ave.tl_lscale == 0
? load_ave.tl_avenrun.d[elem]
: (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale));
#endif /* OSF_ALPHA */
#if !defined (LDAV_DONE) && defined (VMS)
/* VMS specific code -- read from the Load Ave driver. */
LOAD_AVE_TYPE load_ave[3];
static int getloadavg_initialized = 0;
#ifdef eunice
struct
{
int dsc$w_length;
char *dsc$a_pointer;
} descriptor;
#endif
/* Ensure that there is a channel open to the load ave device. */
if (!getloadavg_initialized)
{
/* Attempt to open the channel. */
#ifdef eunice
descriptor.dsc$w_length = 18;
descriptor.dsc$a_pointer = "$$VMS_LOAD_AVERAGE";
#else
$DESCRIPTOR (descriptor, "LAV0:");
#endif
if (sys$assign (&descriptor, &channel, 0, 0) & 1)
getloadavg_initialized = 1;
}
/* Read the load average vector. */
if (getloadavg_initialized
&& !(sys$qiow (0, channel, IO$_READVBLK, 0, 0, 0,
load_ave, 12, 0, 0, 0, 0) & 1))
{
sys$dassgn (channel);
getloadavg_initialized = 0;
}
if (!getloadavg_initialized)
return -1;
#endif /* VMS */
#if !defined (LDAV_DONE) && defined(LOAD_AVE_TYPE) && !defined(VMS)
/* UNIX-specific code -- read the average from /dev/kmem. */
#define LDAV_PRIVILEGED /* This code requires special installation. */
LOAD_AVE_TYPE load_ave[3];
/* Get the address of LDAV_SYMBOL. */
if (offset == 0)
{
#ifndef sgi
#ifndef NLIST_STRUCT
strcpy (nl[0].n_name, LDAV_SYMBOL);
strcpy (nl[1].n_name, "");
#else /* NLIST_STRUCT */
#ifdef NLIST_NAME_UNION
nl[0].n_un.n_name = LDAV_SYMBOL;
nl[1].n_un.n_name = 0;
#else /* not NLIST_NAME_UNION */
nl[0].n_name = LDAV_SYMBOL;
nl[1].n_name = 0;
#endif /* not NLIST_NAME_UNION */
#endif /* NLIST_STRUCT */
#ifndef SUNOS_5
if (nlist (KERNEL_FILE, nl) >= 0)
/* Omit "&& nl[0].n_type != 0 " -- it breaks on Sun386i. */
{
#ifdef FIXUP_KERNEL_SYMBOL_ADDR
FIXUP_KERNEL_SYMBOL_ADDR (nl);
#endif
offset = nl[0].n_value;
}
#endif /* !SUNOS_5 */
#else /* sgi */
int ldav_off;
ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN);
if (ldav_off != -1)
offset = (long) ldav_off & 0x7fffffff;
#endif /* sgi */
}
/* Make sure we have /dev/kmem open. */
if (!getloadavg_initialized)
{
#ifndef SUNOS_5
channel = open ("/dev/kmem", 0);
if (channel >= 0)
getloadavg_initialized = 1;
#else /* SUNOS_5 */
/* We pass 0 for the kernel, corefile, and swapfile names
to use the currently running kernel. */
kd = kvm_open (0, 0, 0, O_RDONLY, 0);
if (kd != 0)
{
/* nlist the currently running kernel. */
kvm_nlist (kd, nl);
offset = nl[0].n_value;
getloadavg_initialized = 1;
}
#endif /* SUNOS_5 */
}
/* If we can, get the load average values. */
if (offset && getloadavg_initialized)
{
/* Try to read the load. */
#ifndef SUNOS_5
if (lseek (channel, offset, 0) == -1L
|| read (channel, (char *) load_ave, sizeof (load_ave))
!= sizeof (load_ave))
{
close (channel);
getloadavg_initialized = 0;
}
#else /* SUNOS_5 */
if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave))
!= sizeof (load_ave))
{
kvm_close (kd);
getloadavg_initialized = 0;
}
#endif /* SUNOS_5 */
}
if (offset == 0 || !getloadavg_initialized)
return -1;
#endif /* LOAD_AVE_TYPE and not VMS */
#if !defined (LDAV_DONE) && defined (LOAD_AVE_TYPE) /* Including VMS. */
if (nelem > 0)
loadavg[elem++] = LDAV_CVT (load_ave[0]);
if (nelem > 1)
loadavg[elem++] = LDAV_CVT (load_ave[1]);
if (nelem > 2)
loadavg[elem++] = LDAV_CVT (load_ave[2]);
#define LDAV_DONE
#endif /* !LDAV_DONE && LOAD_AVE_TYPE */
#ifdef LDAV_DONE
return elem;
#else
/* Set errno to zero to indicate that there was no particular error;
this function just can't work at all on this system. */
errno = 0;
return -1;
#endif
}
#endif /* ! HAVE_GETLOADAVG */
#ifdef TEST
void
main (argc, argv)
int argc;
char **argv;
{
int naptime = 0;
if (argc > 1)
naptime = atoi (argv[1]);
while (1)
{
double avg[3];
int loads;
errno = 0; /* Don't be misled if it doesn't set errno. */
loads = getloadavg (avg, 3);
if (loads == -1)
{
perror ("Error getting load average");
exit (1);
}
if (loads > 0)
printf ("1-minute: %f ", avg[0]);
if (loads > 1)
printf ("5-minute: %f ", avg[1]);
if (loads > 2)
printf ("15-minute: %f ", avg[2]);
if (loads > 0)
putchar ('\n');
if (naptime == 0)
break;
sleep (naptime);
}
exit (0);
}
#endif /* TEST */

481
glob/COPYING.LIB Normal file
View File

@@ -0,0 +1,481 @@
GNU LIBRARY GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the library GPL. It is
numbered 2 because it goes with version 2 of the ordinary GPL.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Library General Public License, applies to some
specially designated Free Software Foundation software, and to any
other libraries whose authors decide to use it. You can use it for
your libraries, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if
you distribute copies of the library, or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link a program with the library, you must provide
complete object files to the recipients so that they can relink them
with the library, after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
Our method of protecting your rights has two steps: (1) copyright
the library, and (2) offer you this license which gives you legal
permission to copy, distribute and/or modify the library.
Also, for each distributor's protection, we want to make certain
that everyone understands that there is no warranty for this free
library. If the library is modified by someone else and passed on, we
want its recipients to know that what they have is not the original
version, so that any problems introduced by others will not reflect on
the original authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that companies distributing free
software will individually obtain patent licenses, thus in effect
transforming the program into proprietary software. To prevent this,
we have made it clear that any patent must be licensed for everyone's
free use or not licensed at all.
Most GNU software, including some libraries, is covered by the ordinary
GNU General Public License, which was designed for utility programs. This
license, the GNU Library General Public License, applies to certain
designated libraries. This license is quite different from the ordinary
one; be sure to read it in full, and don't assume that anything in it is
the same as in the ordinary license.
The reason we have a separate public license for some libraries is that
they blur the distinction we usually make between modifying or adding to a
program and simply using it. Linking a program with a library, without
changing the library, is in some sense simply using the library, and is
analogous to running a utility program or application program. However, in
a textual and legal sense, the linked executable is a combined work, a
derivative of the original library, and the ordinary General Public License
treats it as such.
Because of this blurred distinction, using the ordinary General
Public License for libraries did not effectively promote software
sharing, because most developers did not use the libraries. We
concluded that weaker conditions might promote sharing better.
However, unrestricted linking of non-free programs would deprive the
users of those programs of all benefit from the free status of the
libraries themselves. This Library General Public License is intended to
permit developers of non-free programs to use free libraries, while
preserving your freedom as a user of such programs to change the free
libraries that are incorporated in them. (We have not seen how to achieve
this as regards changes in header files, but we have achieved it as regards
changes in the actual functions of the Library.) The hope is that this
will lead to faster development of free libraries.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, while the latter only
works together with the library.
Note that it is possible for a library to be covered by the ordinary
General Public License rather than by this special one.
GNU LIBRARY GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library which
contains a notice placed by the copyright holder or other authorized
party saying it may be distributed under the terms of this Library
General Public License (also called "this License"). Each licensee is
addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also compile or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
c) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
d) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the source code distributed need not include anything that is normally
distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Library General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

396
gpl.texinfo Executable file
View File

@@ -0,0 +1,396 @@
@setfilename gpl.info
@unnumbered GNU GENERAL PUBLIC LICENSE
@center Version 2, June 1991
@display
Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@end display
@unnumberedsec Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software---to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
@iftex
@unnumberedsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@end iftex
@ifinfo
@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@end ifinfo
@enumerate
@item
This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The ``Program'', below,
refers to any such program or work, and a ``work based on the Program''
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term ``modification''.) Each licensee is addressed as ``you''.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
@item
You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
@item
You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
@enumerate a
@item
You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
@item
You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
@item
If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
@end enumerate
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
@item
You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
@enumerate a
@item
Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
@item
Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
@item
Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
@end enumerate
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
@item
You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
@item
You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
@item
Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
@item
If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
@item
If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
@item
The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and ``any
later version'', you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
@item
If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
@iftex
@heading NO WARRANTY
@end iftex
@ifinfo
@center NO WARRANTY
@end ifinfo
@item
BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
@item
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
@end enumerate
@iftex
@heading END OF TERMS AND CONDITIONS
@end iftex
@ifinfo
@center END OF TERMS AND CONDITIONS
@end ifinfo
@page
@unnumberedsec How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the ``copyright'' line and a pointer to where the full notice is found.
@smallexample
@var{one line to give the program's name and an idea of what it does.}
Copyright (C) 19@var{yy} @var{name of author}
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
of the License, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
@end smallexample
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
@smallexample
Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author}
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
type `show w'. This is free software, and you are welcome
to redistribute it under certain conditions; type `show c'
for details.
@end smallexample
The hypothetical commands @samp{show w} and @samp{show c} should show
the appropriate parts of the General Public License. Of course, the
commands you use may be called something other than @samp{show w} and
@samp{show c}; they could even be mouse-clicks or menu items---whatever
suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a ``copyright disclaimer'' for the program, if
necessary. Here is a sample; alter the names:
@smallexample
@group
Yoyodyne, Inc., hereby disclaims all copyright
interest in the program `Gnomovision'
(which makes passes at compilers) written
by James Hacker.
@var{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
@end group
@end smallexample
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

590
implicit.c Normal file
View File

@@ -0,0 +1,590 @@
/* Implicit rule searching for GNU Make.
Copyright (C) 1988, 89, 90, 91, 92, 93, 94 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "make.h"
#include "rule.h"
#include "dep.h"
#include "file.h"
static int pattern_search ();
/* For a FILE which has no commands specified, try to figure out some
from the implicit pattern rules.
Returns 1 if a suitable implicit rule was found,
after modifying FILE to contain the appropriate commands and deps,
or returns 0 if no implicit rule was found. */
int
try_implicit_rule (file, depth)
struct file *file;
unsigned int depth;
{
DEBUGPR ("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
(the archive search omits the archive name), it is more specific and
should come first. */
if (pattern_search (file, 0, depth, 0))
return 1;
#ifndef NO_ARCHIVES
/* If this is an archive member reference, use just the
archive member name to search for implicit rules. */
if (ar_name (file->name))
{
DEBUGPR ("Looking for archive-member implicit rule for `%s'.\n");
if (pattern_search (file, 1, depth, 0))
return 1;
}
#endif
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
and 1 is returned. If not, 0 is returned.
If ARCHIVE is nonzero, FILE->name is of the form "LIB(MEMBER)". A rule for
"(MEMBER)" will be searched for, and "(MEMBER)" will not be chopped up into
directory and filename parts.
If an intermediate file is found by pattern search, the intermediate file
is set up as a target by the recursive call and is also made a dependency
of FILE.
DEPTH is used for debugging messages. */
static int
pattern_search (file, archive, depth, recursions)
struct file *file;
int archive;
unsigned int depth;
unsigned int recursions;
{
/* Filename we are searching for a rule for. */
char *filename = archive ? index (file->name, '(') : file->name;
/* Length of FILENAME. */
unsigned int namelen = strlen (filename);
/* The last slash in FILENAME (or nil if there is none). */
char *lastslash;
/* This is a file-object used as an argument in
recursive calls. It never contains any data
except during a recursive call. */
struct file *intermediate_file = 0;
/* List of dependencies found recursively. */
struct file **intermediate_files
= (struct file **) alloca (max_pattern_deps * sizeof (struct file *));
/* List of the patterns used to find intermediate files. */
char **intermediate_patterns
= (char **) alloca (max_pattern_deps * sizeof (char *));
/* This buffer records all the dependencies actually found for a rule. */
char **found_files = (char **) alloca (max_pattern_deps * sizeof (char *));
/* Number of dep names now in FOUND_FILES. */
unsigned int deps_found;
/* Names of possible dependencies are constructed in this buffer. */
register char *depname = (char *) alloca (namelen + max_pattern_dep_length);
/* The start and length of the stem of FILENAME for the current rule. */
register char *stem;
register unsigned int stemlen;
/* Buffer in which we store all the rules that are possibly applicable. */
struct rule **tryrules
= (struct rule **) alloca (num_pattern_rules * max_pattern_targets
* sizeof (struct rule *));
/* Number of valid elements in TRYRULES. */
unsigned int nrules;
/* The numbers of the rule targets of each rule
in TRYRULES that matched the target file. */
unsigned int *matches
= (unsigned int *) alloca (num_pattern_rules * sizeof (unsigned int));
/* Each element is nonzero if LASTSLASH was used in
matching the corresponding element of TRYRULES. */
char *checked_lastslash
= (char *) alloca (num_pattern_rules * sizeof (char));
/* The index in TRYRULES of the rule we found. */
unsigned int foundrule;
/* Nonzero if should consider intermediate files as dependencies. */
int intermed_ok;
/* Nonzero if we have matched a pattern-rule target
that is not just `%'. */
int specific_rule_matched = 0;
register unsigned int i;
register struct rule *rule;
register struct dep *dep;
char *p;
#ifndef NO_ARCHIVES
if (archive || ar_name (filename))
lastslash = 0;
else
#endif
{
/* Set LASTSLASH to point at the last slash in FILENAME
but not counting any slash at the end. (foo/bar/ counts as
bar/ in directory foo/, not empty in directory foo/bar/.) */
lastslash = rindex (filename, '/');
if (lastslash != 0 && lastslash[1] == '\0')
lastslash = 0;
}
/* First see which pattern rules match this target
and may be considered. Put them in TRYRULES. */
nrules = 0;
for (rule = pattern_rules; rule != 0; rule = rule->next)
{
/* If the pattern rule has deps but no commands, ignore it.
Users cancel built-in rules by redefining them without commands. */
if (rule->deps != 0 && rule->cmds == 0)
continue;
/* If this rule is in use by a parent pattern_search,
don't use it here. */
if (rule->in_use)
{
DEBUGP2 ("Avoiding implicit rule recursion.%s%s\n", "", "");
continue;
}
for (i = 0; rule->targets[i] != 0; ++i)
{
char *target = rule->targets[i];
char *suffix = rule->suffixes[i];
int check_lastslash;
/* Rules that can match any filename and are not terminal
are ignored if we're recursing, so that they cannot be
intermediate files. */
if (recursions > 0 && target[1] == '\0' && !rule->terminal)
continue;
if (rule->lens[i] > namelen)
/* It can't possibly match. */
continue;
/* From the lengths of the filename and the pattern parts,
find the stem: the part of the filename that matches the %. */
stem = filename + (suffix - target - 1);
stemlen = namelen - rule->lens[i] + 1;
/* Set CHECK_LASTSLASH if FILENAME contains a directory
prefix and the target pattern does not contain a slash. */
check_lastslash = lastslash != 0 && index (target, '/') == 0;
if (check_lastslash)
{
/* In that case, don't include the
directory prefix in STEM here. */
unsigned int difference = lastslash - filename + 1;
if (difference > stemlen)
continue;
stemlen -= difference;
stem += difference;
}
/* Check that the rule pattern matches the text before the stem. */
if (check_lastslash)
{
if (stem > (lastslash + 1)
&& strncmp (target, lastslash + 1, stem - lastslash - 1))
continue;
}
else if (stem > filename
&& strncmp (target, filename, stem - filename))
continue;
/* Check that the rule pattern matches the text after the stem.
We could test simply use 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 (*suffix != stem[stemlen]
|| (*suffix != '\0' && !streq (&suffix[1], &stem[stemlen + 1])))
continue;
/* Record if we match a rule that not all filenames will match. */
if (target[1] != '\0')
specific_rule_matched = 1;
/* A rule with no dependencies and no commands exists solely to set
specific_rule_matched when it matches. Don't try to use it. */
if (rule->deps == 0 && rule->cmds == 0)
continue;
/* Record this rule in TRYRULES and the index of the matching
target in MATCHES. If several targets of the same rule match,
that rule will be in TRYRULES more than once. */
tryrules[nrules] = rule;
matches[nrules] = i;
checked_lastslash[nrules] = check_lastslash;
++nrules;
}
}
/* If we have found a matching rule that won't match all filenames,
retroactively reject any non-"terminal" rules that do always match. */
if (specific_rule_matched)
for (i = 0; i < nrules; ++i)
if (!tryrules[i]->terminal)
{
register unsigned int j;
for (j = 0; tryrules[i]->targets[j] != 0; ++j)
if (tryrules[i]->targets[j][1] == '\0')
break;
if (tryrules[i]->targets[j] != 0)
tryrules[i] = 0;
}
/* Try each rule once without intermediate files, then once with them. */
for (intermed_ok = 0; intermed_ok == !!intermed_ok; ++intermed_ok)
{
/* Try each pattern rule till we find one that applies.
If it does, copy the names of its dependencies (as substituted)
and store them in FOUND_FILES. DEPS_FOUND is the number of them. */
for (i = 0; i < nrules; i++)
{
int check_lastslash;
rule = tryrules[i];
/* RULE is nil when we discover that a rule,
already placed in TRYRULES, should not be applied. */
if (rule == 0)
continue;
/* Reject any terminal rules if we're
looking to make intermediate files. */
if (intermed_ok && rule->terminal)
continue;
/* Mark this rule as in use so a recursive
pattern_search won't try to use it. */
rule->in_use = 1;
/* From the lengths of the filename and the matching pattern parts,
find the stem: the part of the filename that matches the %. */
stem = filename
+ (rule->suffixes[matches[i]] - rule->targets[matches[i]]) - 1;
stemlen = namelen - rule->lens[matches[i]] + 1;
check_lastslash = checked_lastslash[i];
if (check_lastslash)
{
stem += lastslash - filename + 1;
stemlen -= (lastslash - filename) + 1;
}
DEBUGP2 ("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)
{
/* If the dependency name has a %, substitute the stem. */
p = index (dep_name (dep), '%');
if (p != 0)
{
register unsigned int i;
if (check_lastslash)
{
/* Copy directory name from the original FILENAME. */
i = lastslash - filename + 1;
bcopy (filename, depname, i);
}
else
i = 0;
bcopy (dep_name (dep), depname + i, p - dep_name (dep));
i += p - dep_name (dep);
bcopy (stem, depname + i, stemlen);
i += stemlen;
strcpy (depname + i, p + 1);
p = depname;
}
else
p = dep_name (dep);
/* P is now the actual dependency name as substituted. */
if (file_impossible_p (p))
{
/* If this dependency has already been ruled
"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 dependency `%s'.\n",
p == depname ? "implicit" : "rule", p);
tryrules[i] = 0;
break;
}
intermediate_files[deps_found] = 0;
DEBUGP2 ("Trying %s dependency `%s'.\n",
p == depname ? "implicit" : "rule", p);
/* The DEP->changed flag says that this dependency resides in a
nonexistent directory. So we normally can skip looking for
the file. However, if CHECK_LASTSLASH is set, then the
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 ((!dep->changed || check_lastslash)
&& (lookup_file (p) != 0 || file_exists_p (p)))
{
found_files[deps_found++] = savestring (p, strlen (p));
continue;
}
/* This code, given FILENAME = "lib/foo.o", dependency name
"lib/foo.c", and VPATH=src, searches for "src/lib/foo.c". */
if (vpath_search (&p, (time_t *) 0))
{
DEBUGP2 ("Found dependency as `%s'.%s\n", p, "");
found_files[deps_found++] = p;
continue;
}
/* We could not find the file in any place we should look.
Try to make this dependency as an intermediate file,
but only on the second pass. */
if (intermed_ok)
{
if (intermediate_file == 0)
intermediate_file
= (struct file *) alloca (sizeof (struct file));
DEBUGP2 ("Looking for a rule with %s file `%s'.\n",
"intermediate", p);
bzero ((char *) intermediate_file, sizeof (struct file));
intermediate_file->name = p;
if (pattern_search (intermediate_file, 0, depth + 1,
recursions + 1))
{
p = savestring (p, strlen (p));
intermediate_patterns[deps_found]
= intermediate_file->name;
intermediate_file->name = p;
intermediate_files[deps_found] = intermediate_file;
intermediate_file = 0;
/* Allocate an extra copy to go in FOUND_FILES,
because every elt of FOUND_FILES is consumed
or freed later. */
found_files[deps_found] = savestring (p, strlen (p));
++deps_found;
continue;
}
/* If we have tried to find P as an intermediate
file and failed, mark that name as impossible
so we won't go through the search again later. */
file_impossible (p);
}
/* A dependency of this rule does not exist.
Therefore, this rule fails. */
break;
}
/* This rule is no longer `in use' for recursive searches. */
rule->in_use = 0;
if (dep != 0)
{
/* This pattern rule does not apply.
If some of its dependencies succeeded,
free the data structure describing them. */
while (deps_found-- > 0)
{
register struct file *f = intermediate_files[deps_found];
free (found_files[deps_found]);
if (f != 0
&& (f->stem < f->name
|| f->stem > f->name + strlen (f->name)))
free (f->stem);
}
}
else
/* This pattern rule does apply. Stop looking for one. */
break;
}
/* If we found an applicable rule without
intermediate files, don't try with them. */
if (i < nrules)
break;
rule = 0;
}
/* RULE is nil if the loop went all the way
through the list and everything failed. */
if (rule == 0)
return 0;
foundrule = i;
/* If we are recursing, store the pattern that matched
FILENAME in FILE->name for use in upper levels. */
if (recursions > 0)
/* Kludge-o-matic */
file->name = rule->targets[matches[foundrule]];
/* FOUND_FILES lists the dependencies for the rule we found.
This includes the intermediate files, if any.
Convert them into entries on the deps-chain of FILE. */
while (deps_found-- > 0)
{
register char *s;
if (intermediate_files[deps_found] != 0)
{
/* If we need to use an intermediate file,
make sure it is entered as a target, with the info that was
found for it in the recursive pattern_search call.
We know that the intermediate file did not already exist as
a target; therefore we can assume that the deps and cmds
of F below are null before we change them. */
struct file *imf = intermediate_files[deps_found];
register struct file *f = enter_file (imf->name);
f->deps = imf->deps;
f->cmds = imf->cmds;
f->stem = imf->stem;
imf = lookup_file (intermediate_patterns[deps_found]);
if (imf != 0 && imf->precious)
f->precious = 1;
f->intermediate = 1;
f->tried_implicit = 1;
for (dep = f->deps; dep != 0; dep = dep->next)
{
dep->file = enter_file (dep->name);
dep->name = 0;
dep->file->tried_implicit |= dep->changed;
}
num_intermediates++;
}
dep = (struct dep *) xmalloc (sizeof (struct dep));
s = found_files[deps_found];
if (recursions == 0)
{
dep->name = 0;
dep->file = lookup_file (s);
if (dep->file == 0)
/* enter_file consumes S's storage. */
dep->file = enter_file (s);
else
/* A copy of S is already allocated in DEP->file->name.
So we can free S. */
free (s);
}
else
{
dep->name = s;
dep->file = 0;
dep->changed = 0;
}
if (intermediate_files[deps_found] == 0 && tryrules[foundrule]->terminal)
{
/* If the file actually existed (was not an intermediate file),
and the rule that found it was a terminal one, then we want
to mark the found file so that it will not have implicit rule
search done for it. If we are not entering a `struct file' for
it now, we indicate this with the `changed' flag. */
if (dep->file == 0)
dep->changed = 1;
else
dep->file->tried_implicit = 1;
}
dep->next = file->deps;
file->deps = dep;
}
if (!checked_lastslash[foundrule])
/* Always allocate new storage, since STEM might be
on the stack for an intermediate file. */
file->stem = savestring (stem, stemlen);
else
{
/* We want to prepend the directory from
the original FILENAME onto the stem. */
file->stem = (char *) xmalloc (((lastslash + 1) - filename)
+ stemlen + 1);
bcopy (filename, file->stem, (lastslash + 1) - filename);
bcopy (stem, file->stem + ((lastslash + 1) - filename), stemlen);
file->stem[((lastslash + 1) - filename) + stemlen] = '\0';
}
file->cmds = rule->cmds;
/* Put the targets other than the one that
matched into FILE's `also_make' member. */
/* If there was only one target, there is nothing to do. */
if (rule->targets[1] != 0)
for (i = 0; rule->targets[i] != 0; ++i)
if (i != matches[foundrule])
{
struct dep *new = (struct dep *) xmalloc (sizeof (struct dep));
new->name = p = (char *) xmalloc (rule->lens[i] + stemlen + 1);
bcopy (rule->targets[i], p,
rule->suffixes[i] - rule->targets[i] - 1);
p += rule->suffixes[i] - rule->targets[i] - 1;
bcopy (stem, p, stemlen);
p += stemlen;
bcopy (rule->suffixes[i], p,
rule->lens[i] - (rule->suffixes[i] - rule->targets[i]) + 1);
new->file = enter_file (new->name);
new->next = file->also_make;
file->also_make = new;
}
return 1;
}

1640
job.c Normal file

File diff suppressed because it is too large Load Diff

63
job.h Normal file
View File

@@ -0,0 +1,63 @@
/* Definitions for managing subprocesses in GNU Make.
Copyright (C) 1992, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Structure describing a running or dead child process. */
struct child
{
struct child *next; /* Link in the chain. */
struct file *file; /* File being remade. */
char **environment; /* Environment for commands. */
char **command_lines; /* Array of variable-expanded cmd lines. */
unsigned int command_line; /* Index into above. */
char *command_ptr; /* Ptr into command_lines[command_line]. */
pid_t pid; /* Child process's ID number. */
unsigned int remote:1; /* Nonzero if executing remotely. */
unsigned int noerror:1; /* Nonzero if commands contained a `-'. */
unsigned int good_stdin:1; /* Nonzero if this child has a good stdin. */
unsigned int deleted:1; /* Nonzero if targets have been deleted. */
};
extern struct child *children;
extern void new_job ();
extern void reap_children ();
extern void start_waiting_jobs ();
extern char **construct_command_argv ();
extern void child_execute_job ();
extern void exec_command ();
extern unsigned int job_slots_used;
#ifdef POSIX
extern void unblock_sigs ();
#else
#ifdef HAVE_SIGSETMASK
extern int fatal_signal_mask;
#define unblock_sigs() sigsetmask (0)
#else
#define unblock_sigs()
#endif
#endif

1940
main.c Normal file

File diff suppressed because it is too large Load Diff

628
make-stds.texi Normal file
View File

@@ -0,0 +1,628 @@
@comment This file is included by both standards.texi and make.texinfo.
@comment It was broken out of standards.texi on 1/6/93 by roland.
@node Makefile Conventions
@chapter Makefile Conventions
@comment standards.texi does not print an index, but make.texinfo does.
@cindex makefile, conventions for
@cindex conventions for makefiles
@cindex standards for makefiles
This chapter describes conventions for writing the Makefiles for GNU programs.
@menu
* Makefile Basics::
* Utilities in Makefiles::
* Standard Targets::
* Command Variables::
* Directory Variables::
@end menu
@node Makefile Basics
@section General Conventions for Makefiles
Every Makefile should contain this line:
@example
SHELL = /bin/sh
@end example
@noindent
to avoid trouble on systems where the @code{SHELL} variable might be
inherited from the environment. (This is never a problem with GNU
@code{make}.)
Different @code{make} programs have incompatible suffix lists and
implicit rules, and this sometimes creates confusion or misbehavior. So
it is a good idea to set the suffix list explicitly using only the
suffixes you need in the particular Makefile, like this:
@example
.SUFFIXES:
.SUFFIXES: .c .o
@end example
@noindent
The first line clears out the suffix list, the second introduces all
suffixes which may be subject to implicit rules in this Makefile.
Don't assume that @file{.} is in the path for command execution. When
you need to run programs that are a part of your package during the
make, please make sure that it uses @file{./} if the program is built as
part of the make or @file{$(srcdir)/} if the file is an unchanging part
of the source code. Without one of these prefixes, the current search
path is used.
The distinction between @file{./} and @file{$(srcdir)/} is important
when using the @samp{--srcdir} option to @file{configure}. A rule of
the form:
@smallexample
foo.1 : foo.man sedscript
sed -e sedscript foo.man > foo.1
@end smallexample
@noindent
will fail when the current directory is not the source directory,
because @file{foo.man} and @file{sedscript} are not in the current
directory.
When using GNU @code{make}, relying on @samp{VPATH} to find the source
file will work in the case where there is a single dependency file,
since the @file{make} automatic variable @samp{$<} will represent the
source file wherever it is. (Many versions of @code{make} set @samp{$<}
only in implicit rules.) A makefile target like
@smallexample
foo.o : bar.c
$(CC) -I. -I$(srcdir) $(CFLAGS) -c bar.c -o foo.o
@end smallexample
@noindent
should instead be written as
@smallexample
foo.o : bar.c
$(CC) -I. -I$(srcdir) $(CFLAGS) -c $< -o $@@
@end smallexample
@noindent
in order to allow @samp{VPATH} to work correctly. When the target has
multiple dependencies, using an explicit @samp{$(srcdir)} is the easiest
way to make the rule work well. For example, the target above for
@file{foo.1} is best written as:
@smallexample
foo.1 : foo.man sedscript
sed -e $(srcdir)/sedscript $(srcdir)/foo.man > $@@
@end smallexample
@node Utilities in Makefiles
@section Utilities in Makefiles
Write the Makefile commands (and any shell scripts, such as
@code{configure}) to run in @code{sh}, not in @code{csh}. Don't use any
special features of @code{ksh} or @code{bash}.
The @code{configure} script and the Makefile rules for building and
installation should not use any utilities directly except these:
@example
cat cmp cp echo egrep expr grep
ln mkdir mv pwd rm rmdir sed test touch
@end example
Stick to the generally supported options for these programs. For
example, don't use @samp{mkdir -p}, convenient as it may be, because
most systems don't support it.
The Makefile rules for building and installation can also use compilers
and related programs, but should do so via @code{make} variables so that the
user can substitute alternatives. Here are some of the programs we
mean:
@example
ar bison cc flex install ld lex
make makeinfo ranlib texi2dvi yacc
@end example
Use the following @code{make} variables:
@example
$(AR) $(BISON) $(CC) $(FLEX) $(INSTALL) $(LD) $(LEX)
$(MAKE) $(MAKEINFO) $(RANLIB) $(TEXI2DVI) $(YACC)
@end example
When you use @code{ranlib}, you should make sure nothing bad happens if
the system does not have @code{ranlib}. Arrange to ignore an error
from that command, and print a message before the command to tell the
user that failure of the @code{ranlib} command does not mean a problem.
If you use symbolic links, you should implement a fallback for systems
that don't have symbolic links.
It is ok to use other utilities in Makefile portions (or scripts)
intended only for particular systems where you know those utilities to
exist.
@node Standard Targets
@section Standard Targets for Users
All GNU programs should have the following targets in their Makefiles:
@table @samp
@item all
Compile the entire program. This should be the default target. This
target need not rebuild any documentation files; Info files should
normally be included in the distribution, and DVI files should be made
only when explicitly asked for.
@item install
Compile the program and copy the executables, libraries, and so on to
the file names where they should reside for actual use. If there is a
simple test to verify that a program is properly installed, this target
should run that test.
The commands should create all the directories in which files are to be
installed, if they don't already exist. This includes the directories
specified as the values of the variables @code{prefix} and
@code{exec_prefix}, as well as all subdirectories that are needed.
One way to do this is by means of an @code{installdirs} target
as described below.
Use @samp{-} before any command for installing a man page, so that
@code{make} will ignore any errors. This is in case there are systems
that don't have the Unix man page documentation system installed.
The way to install Info files is to copy them into @file{$(infodir)}
with @code{$(INSTALL_DATA)} (@pxref{Command Variables}), and then run
the @code{install-info} program if it is present. @code{install-info}
is a script that edits the Info @file{dir} file to add or update the
menu entry for the given Info file; it will be part of the Texinfo package.
Here is a sample rule to install an Info file:
@comment This example has been carefully formatted for the Make manual.
@comment Please do not reformat it without talking to roland@gnu.ai.mit.edu.
@smallexample
$(infodir)/foo.info: foo.info
# There may be a newer info file in . than in srcdir.
-if test -f foo.info; then d=.; \
else d=$(srcdir); fi; \
$(INSTALL_DATA) $$d/foo.info $@@; \
# Run install-info only if it exists.
# Use `if' instead of just prepending `-' to the
# line so we notice real errors from install-info.
# We use `$(SHELL) -c' because some shells do not
# fail gracefully when there is an unknown command.
if $(SHELL) -c 'install-info --version' \
>/dev/null 2>&1; then \
install-info --infodir=$(infodir) $$d/foo.info; \
else true; fi
@end smallexample
@item uninstall
Delete all the installed files that the @samp{install} target would
create (but not the noninstalled files such as @samp{make all} would
create).
@comment The gratuitous blank line here is to make the table look better
@comment in the printed Make manual. Please leave it in.
@item clean
Delete all files from the current directory that are normally created by
building the program. Don't delete the files that record the
configuration. Also preserve files that could be made by building, but
normally aren't because the distribution comes with them.
Delete @file{.dvi} files here if they are not part of the distribution.
@item distclean
Delete all files from the current directory that are created by
configuring or building the program. If you have unpacked the source
and built the program without creating any other files, @samp{make
distclean} should leave only the files that were in the distribution.
@item mostlyclean
Like @samp{clean}, but may refrain from deleting a few files that people
normally don't want to recompile. For example, the @samp{mostlyclean}
target for GCC does not delete @file{libgcc.a}, because recompiling it
is rarely necessary and takes a lot of time.
@item realclean
Delete everything from the current directory that can be reconstructed
with this Makefile. This typically includes everything deleted by
@code{distclean}, plus more: C source files produced by Bison, tags tables,
Info files, and so on.
One exception, however: @samp{make realclean} should not delete
@file{configure} even if @file{configure} can be remade using a rule in
the Makefile. More generally, @samp{make realclean} should not delete
anything that needs to exist in order to run @file{configure}
and then begin to build the program.
@item TAGS
Update a tags table for this program.
@item info
Generate any Info files needed. The best way to write the rules is as
follows:
@smallexample
info: foo.info
foo.info: foo.texi chap1.texi chap2.texi
$(MAKEINFO) $(srcdir)/foo.texi
@end smallexample
@noindent
You must define the variable @code{MAKEINFO} in the Makefile. It should
run the @code{makeinfo} program, which is part of the Texinfo
distribution.
@item dvi
Generate DVI files for all TeXinfo documentation.
For example:
@smallexample
dvi: foo.dvi
foo.dvi: foo.texi chap1.texi chap2.texi
$(TEXI2DVI) $(srcdir)/foo.texi
@end smallexample
@noindent
You must define the variable @code{TEXI2DVI} in the Makefile. It should
run the program @code{texi2dvi}, which is part of the Texinfo
distribution. Alternatively, write just the dependencies, and allow GNU
Make to provide the command.
@item dist
Create a distribution tar file for this program. The tar file should be
set up so that the file names in the tar file start with a subdirectory
name which is the name of the package it is a distribution for. This
name can include the version number.
For example, the distribution tar file of GCC version 1.40 unpacks into
a subdirectory named @file{gcc-1.40}.
The easiest way to do this is to create a subdirectory appropriately
named, use @code{ln} or @code{cp} to install the proper files in it, and
then @code{tar} that subdirectory.
The @code{dist} target should explicitly depend on all non-source files
that are in the distribution, to make sure they are up to date in the
distribution.
@xref{Releases, , Making Releases, standards, GNU Coding Standards}.
@item check
Perform self-tests (if any). The user must build the program before
running the tests, but need not install the program; you should write
the self-tests so that they work when the program is built but not
installed.
@end table
The following targets are suggested as conventional names, for programs
in which they are useful.
@table @code
@item installcheck
Perform installation tests (if any). The user must build and install
the program before running the tests. You should not assume that
@file{$(bindir)} is in the search path.
@item installdirs
It's useful to add a target named @samp{installdirs} to create the
directories where files are installed, and their parent directories.
There is a script called @file{mkinstalldirs} which is convenient for
this; find it in the Texinfo package.@c It's in /gd/gnu/lib/mkinstalldirs.
You can use a rule like this:
@comment This has been carefully formatted to look decent in the Make manual.
@comment Please be sure not to make it extend any further to the right.--roland
@smallexample
# Make sure all installation directories (e.g. $(bindir))
# actually exist by making them if necessary.
installdirs: mkinstalldirs
$(srcdir)/mkinstalldirs $(bindir) $(datadir) \
$(libdir) $(infodir) \
$(mandir)
@end smallexample
@end table
@node Command Variables
@section Variables for Specifying Commands
Makefiles should provide variables for overriding certain commands, options,
and so on.
In particular, you should run most utility programs via variables.
Thus, if you use Bison, have a variable named @code{BISON} whose default
value is set with @samp{BISON = bison}, and refer to it with
@code{$(BISON)} whenever you need to use Bison.
File management utilities such as @code{ln}, @code{rm}, @code{mv}, and
so on, need not be referred to through variables in this way, since users
don't need to replace them with other programs.
Each program-name variable should come with an options variable that is
used to supply options to the program. Append @samp{FLAGS} to the
program-name variable name to get the options variable name---for
example, @code{BISONFLAGS}. (The name @code{CFLAGS} is an exception to
this rule, but we keep it because it is standard.) Use @code{CPPFLAGS}
in any compilation command that runs the preprocessor, and use
@code{LDFLAGS} in any compilation command that does linking as well as
in any direct use of @code{ld}.
If there are C compiler options that @emph{must} be used for proper
compilation of certain files, do not include them in @code{CFLAGS}.
Users expect to be able to specify @code{CFLAGS} freely themselves.
Instead, arrange to pass the necessary options to the C compiler
independently of @code{CFLAGS}, by writing them explicitly in the
compilation commands or by defining an implicit rule, like this:
@smallexample
CFLAGS = -g
ALL_CFLAGS = -I. $(CFLAGS)
.c.o:
$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<
@end smallexample
Do include the @samp{-g} option in @code{CFLAGS}, because that is not
@emph{required} for proper compilation. You can consider it a default
that is only recommended. If the package is set up so that it is
compiled with GCC by default, then you might as well include @samp{-O}
in the default value of @code{CFLAGS} as well.
Put @code{CFLAGS} last in the compilation command, after other variables
containing compiler options, so the user can use @code{CFLAGS} to
override the others.
Every Makefile should define the variable @code{INSTALL}, which is the
basic command for installing a file into the system.
Every Makefile should also define the variables @code{INSTALL_PROGRAM}
and @code{INSTALL_DATA}. (The default for each of these should be
@code{$(INSTALL)}.) Then it should use those variables as the commands
for actual installation, for executables and nonexecutables
respectively. Use these variables as follows:
@example
$(INSTALL_PROGRAM) foo $(bindir)/foo
$(INSTALL_DATA) libfoo.a $(libdir)/libfoo.a
@end example
@noindent
Always use a file name, not a directory name, as the second argument of
the installation commands. Use a separate command for each file to be
installed.
@node Directory Variables
@section Variables for Installation Directories
Installation directories should always be named by variables, so it is
easy to install in a nonstandard place. The standard names for these
variables are described below. They are based on a standard filesystem
layout; variants of it are used in SVR4, 4.4BSD, Linux, Ultrix v4, and
other modern operating systems.
These two variables set the root for the installation. All the other
installation directories should be subdirectories of one of these two,
and nothing should be directly installed into these two directories.
@table @samp
@item prefix
A prefix used in constructing the default values of the variables listed
below. The default value of @code{prefix} should be @file{/usr/local}
When building the complete GNU system, the prefix will be empty and
@file{/usr} will be a symbolic link to @file{/}.
@item exec_prefix
A prefix used in constructing the default values of some of the
variables listed below. The default value of @code{exec_prefix} should
be @code{$(prefix)}.
Generally, @code{$(exec_prefix)} is used for directories that contain
machine-specific files (such as executables and subroutine libraries),
while @code{$(prefix)} is used directly for other directories.
@end table
Executable programs are installed in one of the following directories.
@table @samp
@item bindir
The directory for installing executable programs that users can run.
This should normally be @file{/usr/local/bin}, but write it as
@file{$(exec_prefix)/bin}.
@item sbindir
The directory for installing executable programs that can be run from
the shell, but are only generally useful to system administrators. This
should normally be @file{/usr/local/sbin}, but write it as
@file{$(exec_prefix)/sbin}.
@item libexecdir
@comment This paragraph adjusted to avoid overfull hbox --roland 5jul94
The directory for installing executable programs to be run by other
programs rather than by users. This directory should normally be
@file{/usr/local/libexec}, but write it as @file{$(exec_prefix)/libexec}.
@end table
Data files used by the program during its execution are divided into
categories in two ways.
@itemize @bullet
@item
Some files are normally modified by programs; others are never normally
modified (though users may edit some of these).
@item
Some files are architecture-independent and can be shared by all
machines at a site; some are architecture-dependent and can be shared
only by machines of the same kind and operating system; others may never
be shared between two machines.
@end itemize
This makes for six different possibilities. However, we want to
discourage the use of architecture-dependent files, aside from of object
files and libraries. It is much cleaner to make other data files
architecture-independent, and it is generally not hard.
Therefore, here are the variables makefiles should use to specify
directories:
@table @samp
@item datadir
The directory for installing read-only architecture independent data
files. This should normally be @file{/usr/local/share}, but write it as
@file{$(prefix)/share}. As a special exception, see @file{$(infodir)}
and @file{$(includedir)} below.
@item sysconfdir
The directory for installing read-only data files that pertain to a
single machine--that is to say, files for configuring a host. Mailer
and network configuration files, @file{/etc/passwd}, and so forth belong
here. All the files in this directory should be ordinary ASCII text
files. This directory should normally be @file{/usr/local/etc}, but
write it as @file{$(prefix)/etc}.
@c rewritten to avoid overfull hbox --tower
Do not install executables
@c here
in this directory (they probably
belong in @file{$(libexecdir)} or @file{$(sbindir))}. Also do not
install files that are modified in the normal course of their use
(programs whose purpose is to change the configuration of the system
excluded). Those probably belong in @file{$(localstatedir)}.
@item sharedstatedir
The directory for installing architecture-independent data files which
the programs modify while they run. This should normally be
@file{/usr/local/com}, but write it as @file{$(prefix)/com}.
@item localstatedir
The directory for installing data files which the programs modify while
they run, and that pertain to one specific machine. Users should never
need to modify files in this directory to configure the package's
operation; put such configuration information in separate files that go
in @file{datadir} or @file{$(sysconfdir)}. @file{$(localstatedir)}
should normally be @file{/usr/local/var}, but write it as
@file{$(prefix)/var}.
@item libdir
The directory for object files and libraries of object code. Do not
install executables here, they probably belong in @file{$(libexecdir)}
instead. The value of @code{libdir} should normally be
@file{/usr/local/lib}, but write it as @file{$(exec_prefix)/lib}.
@item infodir
The directory for installing the Info files for this package. By
default, it should be @file{/usr/local/info}, but it should be written
as @file{$(prefix)/info}.
@item includedir
@c rewritten to avoid overfull hbox --roland
The directory for installing header files to be included by user
programs with the C @samp{#include} preprocessor directive. This
should normally be @file{/usr/local/include}, but write it as
@file{$(prefix)/include}.
Most compilers other than GCC do not look for header files in
@file{/usr/local/include}. So installing the header files this way is
only useful with GCC. Sometimes this is not a problem because some
libraries are only really intended to work with GCC. But some libraries
are intended to work with other compilers. They should install their
header files in two places, one specified by @code{includedir} and one
specified by @code{oldincludedir}.
@item oldincludedir
The directory for installing @samp{#include} header files for use with
compilers other than GCC. This should normally be @file{/usr/include}.
The Makefile commands should check whether the value of
@code{oldincludedir} is empty. If it is, they should not try to use
it; they should cancel the second installation of the header files.
A package should not replace an existing header in this directory unless
the header came from the same package. Thus, if your Foo package
provides a header file @file{foo.h}, then it should install the header
file in the @code{oldincludedir} directory if either (1) there is no
@file{foo.h} there or (2) the @file{foo.h} that exists came from the Foo
package.
To tell whether @file{foo.h} came from the Foo package, put a magic
string in the file---part of a comment---and grep for that string.
@end table
Unix-style man pages are installed in one of the following:
@table @samp
@item mandir
The directory for installing the man pages (if any) for this package.
It should include the suffix for the proper section of the
manual---usually @samp{1} for a utility. It will normally be
@file{/usr/local/man/man1}, but you should write it as
@file{$(prefix)/man/man1}.
@item man1dir
The directory for installing section 1 man pages.
@item man2dir
The directory for installing section 2 man pages.
@item @dots{}
Use these names instead of @samp{mandir} if the package needs to install man
pages in more than one section of the manual.
@strong{Don't make the primary documentation for any GNU software be a
man page. Write a manual in Texinfo instead. Man pages are just for
the sake of people running GNU software on Unix, which is a secondary
application only.}
@item manext
The file name extension for the installed man page. This should contain
a period followed by the appropriate digit; it should normally be @samp{.1}.
@item man1ext
The file name extension for installed section 1 man pages.
@item man2ext
The file name extension for installed section 2 man pages.
@item @dots{}
Use these names instead of @samp{manext} if the package needs to install man
pages in more than one section of the manual.
@end table
And finally, you should set the following variable:
@table @samp
@item srcdir
The directory for the sources being compiled. The value of this
variable is normally inserted by the @code{configure} shell script.
@end table
For example:
@smallexample
@c I have changed some of the comments here slightly to fix an overfull
@c hbox, so the make manual can format correctly. --roland
# Common prefix for installation directories.
# NOTE: This directory must exist when you start the install.
prefix = /usr/local
exec_prefix = $(prefix)
# Where to put the executable for the command `gcc'.
bindir = $(exec_prefix)/bin
# Where to put the directories used by the compiler.
libexecdir = $(exec_prefix)/libexec
# Where to put the Info files.
infodir = $(prefix)/info
@end smallexample
If your program installs a large number of files into one of the
standard user-specified directories, it might be useful to group them
into a subdirectory particular to that program. If you do this, you
should write the @code{install} rule to create these subdirectories.
Do not expect the user to include the subdirectory name in the value of
any of the variables listed above. The idea of having a uniform set of
variable names for installation directories is to enable the user to
specify the exact same values for several different GNU packages. In
order for this to be useful, all the packages must be designed so that
they will work sensibly when the user does so.

302
make.1 Normal file
View File

@@ -0,0 +1,302 @@
.TH MAKE 1L "22 August 1989" "GNU" "LOCAL USER COMMANDS"
.SH NAME
make \- GNU make utility to maintain groups of programs
.SH SYNOPSIS
.B "make "
[
.B \-f
makefile ] [ option ] ...
target ...
.SH WARNING
This man paage is an extract of the documentation of
.I GNU make .
It is updated only occasionally, because the GNU project does not use nroff.
For complete, current documentation, refer to the Info file
.B make
or the DVI file
.B make.dvi
which are made from the Texinfo source file
.BR make.texinfo .
.SH DESCRIPTION
.LP
The purpose of the
.I make
utility is to determine automatically which
pieces of a large program need to be recompiled, and issue the commands to
recompile them.
This manual describes the GNU implementation of
.IR make ,
which was written by Richard Stallman and Roland McGrath.
Our examples show C programs, since they are most common, but you can use
.I make
with any programming language whose compiler can be run with a
shell command.
In fact,
.I make
is not limited to programs.
You can use it to describe any task where some files must be
updated automatically from others whenever the others change.
.LP
To prepare to use
.IR make ,
you must write a file called the
.I makefile
that describes the relationships among files in your program, and the
states the commands for updating each file.
In a program, typically the executable file is updated from object
files, which are in turn made by compiling source files.
.LP
Once a suitable makefile exists, each time you change some source files,
this simple shell command:
.sp 1
.RS
.B make
.RE
.sp 1
suffices to perform all necessary recompilations.
The
.I make
program uses the makefile data base and the last-modification times
of the files to decide which of the files need to be updated.
For each of those files, it issues the commands recorded in the data base.
.LP
.I make
executes commands in the
.I makefile
to update
one or more target
.IR names ,
where
.I name
is typically a program.
If no
.B \-f
option is present,
.I make
will look for the makefiles
.IR GNUmakefile ,
.IR makefile ,
and
.IR Makefile ,
in that order.
.LP
Normally you should call your makefile either
.I makefile
or
.IR Makefile .
(We recommend
.I Makefile
because it appears prominently near the beginning of a directory
listing, right near other important files such as
.IR README .)
The first name checked,
.IR GNUmakefile ,
is not recommended for most makefiles.
You should use this name if you have a makefile that is specific to GNU
.IR make ,
and will not be understood by other versions of
.IR make .
If
.I makefile
is `\-', the standard input is read.
.LP
.I make
updates a target if it depends on prerequisite files
that have been modified since the target was last modified,
or if the target does not exist.
.SH OPTIONS
.sp 1
.TP 0.5i
.B \-b
.TP 0.5i
.B \-m
These options are ignored for compatibility with other versions of
.IR make .
.TP 0.5i
.BI "\-C " dir
Change to directory
.I dir
before reading the makefiles or doing anything else.
If multiple
.B \-C
options are specified, each is interpreted relative to the
previous one:
.BR "\-C " /
.BR "\-C " etc
is equivalent to
.BR "\-C " /etc.
This is typically used with recursive invocations of
.IR make .
.TP 0.5i
.B \-d
Print debugging information in addition to normal processing.
The debugging information says which files are being considered for
remaking, which file-times are being compared and with what results,
which files actually need to be remade, which implicit rules are
considered and which are applied---everything interesting about how
.I make
decides what to do.
.TP 0.5i
.B \-e
Give variables taken from the environment precedence
over variables from makefiles.
.TP 0.5i
.BI "\-f " file
Use
.I file
as a makefile.
.TP 0.5i
.B \-i
Ignore all errors in commands executed to remake files.
.TP 0.5i
.BI "\-I " dir
Specifies a directory
.I dir
to search for included makefiles.
If several
.B \-I
options are used to specify several directories, the directories are
searched in the order specified.
Unlike the arguments to other flags of
.IR make ,
directories given with
.B \-I
flags may come directly after the flag:
.BI \-I dir
is allowed, as well as
.BI "\-I " dir.
This syntax is allowed for compatibility with the C
preprocessor's
.B \-I
flag.
.TP 0.5i
.BI "\-j " jobs
Specifies the number of jobs (commands) to run simultaneously.
If there is more than one
.B \-j
option, the last one is effective.
If the
.B \-j
option is given without an argument,
.IR make
will not limit the number of jobs that can run simultaneously.
.TP 0.5i
.B \-k
Continue as much as possible after an error.
While the target that failed, and those that depend on it, cannot
be remade, the other dependencies of these targets can be processed
all the same.
.TP 0.5i
.B \-l
.TP 0.5i
.BI "\-l " load
Specifies that no new jobs (commands) should be started if there are
others jobs running and the load average is at least
.I load
(a floating-point number).
With no argument, removes a previous load limit.
.TP 0.5i
.B \-n
Print the commands that would be executed, but do not execute them.
.TP 0.5i
.BI "\-o " file
Do not remake the file
.I file
even if it is older than its dependencies, and do not remake anything
on account of changes in
.IR file .
Essentially the file is treated as very old and its rules are ignored.
.TP 0.5i
.B \-p
Print the data base (rules and variable values) that results from
reading the makefiles; then execute as usual or as otherwise
specified.
This also prints the version information given by the
.B \-v
switch (see below).
To print the data base without trying to remake any files, use
.B make
.B \-p
.BI \-f /dev/null.
.TP 0.5i
.B \-q
``Question mode''.
Do not run any commands, or print anything; just return an exit status
that is zero if the specified targets are already up to date, nonzero
otherwise.
.TP 0.5i
.B \-r
Eliminate use of the built-in implicit rules.
Also clear out the default list of suffixes for suffix rules.
.TP 0.5i
.B \-s
Silent operation; do not print the commands as they are executed.
.TP 0.5i
.B \-S
Cancel the effect of the
.B \-k
option.
This is never necessary except in a recursive
.I make
where
.B \-k
might be inherited from the top-level
.I make
via MAKEFLAGS or if you set
.B \-k
in MAKEFLAGS in your environment.
.TP 0.5i
.B \-t
Touch files (mark them up to date without really changing them)
instead of running their commands.
This is used to pretend that the commands were done, in order to fool
future invocations of
.IR make .
.TP 0.5i
.B \-v
Print the version of the
.I make
program plus a copyright, a list of authors and a notice that there
is no warranty.
After this information is printed, processing continues normally.
To get this information without doing anything else, use
.B make
.B \-v
.BI \-f /dev/null.
.TP 0.5i
.B \-w
Print a message containing the working directory
before and after other processing.
This may be useful for tracking down errors from complicated nests of
recursive
.I make
commands.
.TP 0.5i
.BI "\-W " file
Pretend that the target
.I file
has just been modified.
When used with the
.B \-n
flag, this shows you what would happen if you were to modify that file.
Without
.BR \-n ,
it is almost the same as running a
.I touch
command on the given file before running
.IR make ,
except that the modification time is changed only in the imagination of
.IR make .
.SH "SEE ALSO"
.PD 0
.TP 2.0i
/usr/local/doc/gnumake.dvi
.I
The GNU Make Manual
.PD
.SH BUGS
See the chapter `Problems and Bugs' in
.I "The GNU Make Manual" .
.SH AUTHOR
This manual page contributed by Dennis Morse of Stanford University.
It has been reworked by Roland McGrath.

351
make.h Normal file
View File

@@ -0,0 +1,351 @@
/* Miscellaneous global declarations and portability cruft for GNU Make.
Copyright (C) 1988, 89, 90, 91, 92, 93, 94 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* AIX requires this to be the first thing in the file. */
#if defined (_AIX) && !defined (__GNUC__)
#pragma alloca
#endif
/* We use <config.h> instead of "config.h" so that a compilation
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
(which it would do because make.h was found in $srcdir). */
#include <config.h>
#undef HAVE_CONFIG_H
#define HAVE_CONFIG_H
#ifdef CRAY
/* This must happen before #include <signal.h> so
that the declaration therein is changed. */
#define signal bsdsignal
#endif
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <stdio.h>
#include <ctype.h>
#ifdef HAVE_SYS_TIMEB_H
/* SCO 3.2 "devsys 4.2" has a prototype for `ftime' in <time.h> that bombs
unless <sys/timeb.h> has been included first. Does every system have a
<sys/timeb.h>? If any does not, configure should check for it. */
#include <sys/timeb.h>
#endif
#include <time.h>
#include <errno.h>
#ifndef errno
extern int errno;
#endif
#ifndef isblank
#define isblank(c) ((c) == ' ' || (c) == '\t')
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
/* Ultrix's unistd.h always defines _POSIX_VERSION, but you only get
POSIX.1 behavior with `cc -YPOSIX', which predefines POSIX itself! */
#if defined (_POSIX_VERSION) && !defined (ultrix)
#define POSIX
#endif
#endif
/* Some systems define _POSIX_VERSION but are not really POSIX.1. */
#if (defined (butterfly) || defined (__arm) || \
(defined (__mips) && defined (_SYSTYPE_SVR3)) || \
(defined (sequent) && defined (i386)))
#undef POSIX
#endif
#if !defined (POSIX) && defined (_AIX) && defined (_POSIX_SOURCE)
#define POSIX
#endif
#if !defined (HAVE_SYS_SIGLIST) && defined (HAVE__SYS_SIGLIST)
#define sys_siglist _sys_siglist
#define HAVE_SYS_SIGLIST /* Now we have it. */
/* It was declared in <signal.h>, with who knows what type.
Don't declare it again and risk conflicting. */
#define SYS_SIGLIST_DECLARED
#endif
#ifdef HAVE_SYS_SIGLIST
#ifndef SYS_SIGLIST_DECLARED
extern char *sys_siglist[];
#endif
#else
#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
#ifndef sigmask
#define sigmask(sig) (1 << ((sig) - 1))
#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifndef PATH_MAX
#ifndef POSIX
#define PATH_MAX MAXPATHLEN
#endif /* Not POSIX. */
#endif /* No PATH_MAX. */
#ifndef MAXPATHLEN
#define MAXPATHLEN 1024
#endif /* No MAXPATHLEN. */
#ifdef PATH_MAX
#define GET_PATH_MAX PATH_MAX
#define PATH_VAR(var) char var[PATH_MAX]
#else
#define NEED_GET_PATH_MAX
extern unsigned int get_path_max ();
#define GET_PATH_MAX (get_path_max ())
#define PATH_VAR(var) char *var = (char *) alloca (GET_PATH_MAX)
#endif
#ifdef STAT_MACROS_BROKEN
#ifdef S_ISREG
#undef S_ISREG
#endif
#ifdef S_ISDIR
#undef S_ISDIR
#endif
#endif /* STAT_MACROS_BROKEN. */
#ifndef S_ISREG
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
#endif
#ifndef S_ISDIR
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif
#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__))
#include <stdlib.h>
#include <string.h>
#define ANSI_STRING
#else /* No standard headers. */
#ifdef HAVE_STRING_H
#include <string.h>
#define ANSI_STRING
#else
#include <strings.h>
#endif
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif
extern char *malloc (), *realloc ();
extern void free ();
extern void qsort ();
extern void abort (), exit ();
#endif /* Standard headers. */
#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
#ifndef bzero
#define bzero(s, n) memset ((s), 0, (n))
#endif
#ifndef bcopy
#define bcopy(s, d, n) memcpy ((d), (s), (n))
#endif
#else /* Not ANSI_STRING. */
#ifndef bcmp
extern int bcmp ();
#endif
#ifndef bzero
extern void bzero ();
#endif
#ifndef bcopy
extern void bcopy ();
#endif
#endif /* ANSI_STRING. */
#undef ANSI_STRING
/* SCO Xenix has a buggy macro definition in <string.h>. */
#undef strerror
#ifndef ANSI_STRING
extern char *strerror ();
#endif
#ifdef __GNUC__
#undef alloca
#define alloca(n) __builtin_alloca (n)
#else /* Not GCC. */
#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#else /* Not HAVE_ALLOCA_H. */
#ifndef _AIX
extern char *alloca ();
#endif /* Not AIX. */
#endif /* HAVE_ALLOCA_H. */
#endif /* GCC. */
#ifndef iAPX286
#define streq(a, b) \
((a) == (b) || \
(*(a) == *(b) && (*(a) == '\0' || !strcmp ((a) + 1, (b) + 1))))
#else
/* Buggy compiler can't handle this. */
#define streq(a, b) (strcmp ((a), (b)) == 0)
#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)))
#if defined(__GNUC__) || defined(ENUM_BITFIELDS)
#define ENUM_BITFIELD(bits) :bits
#else
#define ENUM_BITFIELD(bits)
#endif
#ifdef __MSDOS__
#define PATH_SEPARATOR_CHAR ';'
#else
#define PATH_SEPARATOR_CHAR ':'
#endif
extern void die ();
extern void message (), fatal (), error ();
extern void makefile_error (), makefile_fatal ();
extern void pfatal_with_name (), perror_with_name ();
extern char *savestring (), *concat ();
extern char *xmalloc (), *xrealloc ();
extern char *find_next_token (), *next_token (), *end_of_token ();
extern void collapse_continuations (), remove_comments ();
extern char *sindex (), *lindex ();
extern int alpha_compare ();
extern void print_spaces ();
extern struct dep *copy_dep_chain ();
extern char *find_char_unquote (), *find_percent ();
#ifndef NO_ARCHIVES
extern int ar_name ();
extern void ar_parse_name ();
extern int ar_touch ();
extern time_t ar_member_date ();
#endif
extern void dir_load ();
extern int dir_file_exists_p (), file_exists_p (), file_impossible_p ();
extern void file_impossible ();
extern char *dir_name ();
extern void define_default_variables ();
extern void set_default_suffixes (), install_default_suffix_rules ();
extern void install_default_implicit_rules (), count_implicit_rule_limits ();
extern void convert_to_pattern (), create_pattern_rule ();
extern void build_vpath_lists (), construct_vpath_list ();
extern int vpath_search ();
extern void construct_include_path ();
extern void uniquize_deps ();
extern int update_goal_chain ();
extern void notice_finished_file ();
extern void user_access (), make_access (), child_access ();
#ifdef HAVE_VFORK_H
#include <vfork.h>
#endif
/* We omit these declarations on non-POSIX systems which define _POSIX_VERSION,
because such systems often declare the in header files anyway. */
#if !defined (__GNU_LIBRARY__) && !defined (POSIX) && !defined (_POSIX_VERSION)
extern long int atol ();
extern long int lseek ();
#endif /* Not GNU C library or POSIX. */
#ifdef HAVE_GETCWD
extern char *getcwd ();
#else
extern char *getwd ();
#define getcwd(buf, len) getwd (buf)
#endif
extern char **environ;
extern char *reading_filename;
extern unsigned int *reading_lineno_ptr;
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 env_overrides, no_builtin_rules_flag, print_version_flag;
extern int print_directory_flag, warn_undefined_variables_flag;
extern int posix_pedantic;
extern unsigned int job_slots;
extern double max_load_average;
extern char *program;
extern char *starting_directory;
extern unsigned int makelevel;
extern char *version_string, *remote_description;
extern unsigned int commands_started;
extern int handling_fatal_signal;
#define DEBUGPR(msg) \
do if (debug_flag) { print_spaces (depth); printf (msg, file->name); \
fflush (stdout); } while (0)

File diff suppressed because it is too large Load Diff

738
misc.c Normal file
View File

@@ -0,0 +1,738 @@
/* Miscellaneous generic support functions for GNU Make.
Copyright (C) 1988, 89, 90, 91, 92, 93, 94 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "make.h"
#include "dep.h"
/* Compare strings *S1 and *S2.
Return negative if the first is less, positive if it is greater,
zero if they are equal. */
int
alpha_compare (s1, s2)
char **s1, **s2;
{
if (**s1 != **s2)
return **s1 - **s2;
return strcmp (*s1, *s2);
}
/* Discard each backslash-newline combination from LINE.
Backslash-backslash-newline combinations become backslash-newlines.
This is done by copying the text at LINE into itself. */
void
collapse_continuations (line)
char *line;
{
register char *in, *out, *p;
register int backslash;
register unsigned int bs_write;
in = index (line, '\n');
if (in == 0)
return;
out = in;
if (out > line)
while (out[-1] == '\\')
--out;
while (*in != '\0')
{
/* BS_WRITE gets the number of quoted backslashes at
the end just before IN, and BACKSLASH gets nonzero
if the next character is quoted. */
backslash = 0;
bs_write = 0;
for (p = in - 1; p >= line && *p == '\\'; --p)
{
if (backslash)
++bs_write;
backslash = !backslash;
/* It should be impossible to go back this far without exiting,
but if we do, we can't get the right answer. */
if (in == out - 1)
abort ();
}
/* Output the appropriate number of backslashes. */
while (bs_write-- > 0)
*out++ = '\\';
/* Skip the newline. */
++in;
/* If the newline is quoted, discard following whitespace
and any preceding whitespace; leave just one space. */
if (backslash)
{
in = next_token (in);
while (out > line && isblank (out[-1]))
--out;
*out++ = ' ';
}
else
/* If the newline isn't quoted, put it in the output. */
*out++ = '\n';
/* Now copy the following line to the output.
Stop when we find backslashes followed by a newline. */
while (*in != '\0')
if (*in == '\\')
{
p = in + 1;
while (*p == '\\')
++p;
if (*p == '\n')
{
in = p;
break;
}
while (in < p)
*out++ = *in++;
}
else
*out++ = *in++;
}
*out = '\0';
}
/* Remove comments from LINE.
This is done by copying the text at LINE onto itself. */
void
remove_comments (line)
char *line;
{
char *comment;
comment = find_char_unquote (line, '#', 0);
if (comment != 0)
/* Cut off the line at the #. */
*comment = '\0';
}
/* Print N spaces (used by DEBUGPR for target-depth). */
void
print_spaces (n)
register unsigned int n;
{
while (n-- > 0)
putchar (' ');
}
/* Return a newly-allocated string whose contents
concatenate those of s1, s2, s3. */
char *
concat (s1, s2, s3)
register char *s1, *s2, *s3;
{
register unsigned int len1, len2, len3;
register char *result;
len1 = *s1 != '\0' ? strlen (s1) : 0;
len2 = *s2 != '\0' ? strlen (s2) : 0;
len3 = *s3 != '\0' ? strlen (s3) : 0;
result = (char *) xmalloc (len1 + len2 + len3 + 1);
if (*s1 != '\0')
bcopy (s1, result, len1);
if (*s2 != '\0')
bcopy (s2, result + len1, len2);
if (*s3 != '\0')
bcopy (s3, result + len1 + len2, len3);
*(result + len1 + len2 + len3) = '\0';
return result;
}
/* Print a message on stdout. */
void
message (s1, s2, s3, s4, s5, s6)
char *s1, *s2, *s3, *s4, *s5, *s6;
{
if (makelevel == 0)
printf ("%s: ", program);
else
printf ("%s[%u]: ", program, makelevel);
printf (s1, s2, s3, s4, s5, s6);
putchar ('\n');
fflush (stdout);
}
/* Print an error message and exit. */
/* VARARGS1 */
void
fatal (s1, s2, s3, s4, s5, s6)
char *s1, *s2, *s3, *s4, *s5, *s6;
{
if (makelevel == 0)
fprintf (stderr, "%s: *** ", program);
else
fprintf (stderr, "%s[%u]: *** ", program, makelevel);
fprintf (stderr, s1, s2, s3, s4, s5, s6);
fputs (". Stop.\n", stderr);
die (2);
}
/* Print error message. `s1' is printf control string, `s2' is arg for it. */
/* VARARGS1 */
void
error (s1, s2, s3, s4, s5, s6)
char *s1, *s2, *s3, *s4, *s5, *s6;
{
if (makelevel == 0)
fprintf (stderr, "%s: ", program);
else
fprintf (stderr, "%s[%u]: ", program, makelevel);
fprintf (stderr, s1, s2, s3, s4, s5, s6);
putc ('\n', stderr);
fflush (stderr);
}
void
makefile_error (file, lineno, s1, s2, s3, s4, s5, s6)
char *file;
unsigned int lineno;
char *s1, *s2, *s3, *s4, *s5, *s6;
{
fprintf (stderr, "%s:%u: ", file, lineno);
fprintf (stderr, s1, s2, s3, s4, s5, s6);
putc ('\n', stderr);
fflush (stderr);
}
void
makefile_fatal (file, lineno, s1, s2, s3, s4, s5, s6)
char *file;
unsigned int lineno;
char *s1, *s2, *s3, *s4, *s5, *s6;
{
fprintf (stderr, "%s:%u: *** ", file, lineno);
fprintf (stderr, s1, s2, s3, s4, s5, s6);
fputs (". Stop.\n", stderr);
die (2);
}
#ifndef HAVE_STRERROR
#undef strerror
char *
strerror (errnum)
int errnum;
{
extern int errno, sys_nerr;
extern char *sys_errlist[];
static char buf[] = "Unknown error 12345678901234567890";
if (errno < sys_nerr)
return sys_errlist[errnum];
sprintf ("Unknown error %d", buf, errnum);
return buf;
}
#endif
/* Print an error message from errno. */
void
perror_with_name (str, name)
char *str, *name;
{
error ("%s%s: %s", str, name, strerror (errno));
}
/* Print an error message from errno and exit. */
void
pfatal_with_name (name)
char *name;
{
fatal ("%s: %s", name, strerror (errno));
/* NOTREACHED */
}
/* Like malloc but get fatal error if memory is exhausted. */
#undef xmalloc
#undef xrealloc
char *
xmalloc (size)
unsigned int size;
{
char *result = (char *) malloc (size);
if (result == 0)
fatal ("virtual memory exhausted");
return result;
}
char *
xrealloc (ptr, size)
char *ptr;
unsigned int size;
{
char *result = (char *) realloc (ptr, size);
if (result == 0)
fatal ("virtual memory exhausted");
return result;
}
char *
savestring (str, length)
char *str;
unsigned int length;
{
register char *out = (char *) xmalloc (length + 1);
if (length > 0)
bcopy (str, out, length);
out[length] = '\0';
return out;
}
/* Search string BIG (length BLEN) for an occurrence of
string SMALL (length SLEN). Return a pointer to the
beginning of the first occurrence, or return nil if none found. */
char *
sindex (big, blen, small, slen)
char *big;
unsigned int blen;
char *small;
unsigned int slen;
{
register unsigned int b;
if (blen < 1)
blen = strlen (big);
if (slen < 1)
slen = strlen (small);
for (b = 0; b < blen; ++b)
if (big[b] == *small && !strncmp (&big[b + 1], small + 1, slen - 1))
return (&big[b]);
return 0;
}
/* Limited INDEX:
Search through the string STRING, which ends at LIMIT, for the character C.
Returns a pointer to the first occurrence, or nil if none is found.
Like INDEX except that the string searched ends where specified
instead of at the first null. */
char *
lindex (s, limit, c)
register char *s, *limit;
int c;
{
while (s < limit)
if (*s++ == c)
return s - 1;
return 0;
}
/* Return the address of the first whitespace or null in the string S. */
char *
end_of_token (s)
char *s;
{
while (*s != '\0' && !isblank (*s))
++s;
return s;
}
/* Return the address of the first nonwhitespace or null in the string S. */
char *
next_token (s)
char *s;
{
register char *p = s;
while (isblank (*p))
++p;
return p;
}
/* Find the next token in PTR; return the address of it, and store the
length of the token into *LENGTHPTR if LENGTHPTR is not nil. */
char *
find_next_token (ptr, lengthptr)
char **ptr;
unsigned int *lengthptr;
{
char *p = next_token (*ptr);
char *end;
if (*p == '\0')
return 0;
*ptr = end = end_of_token (p);
if (lengthptr != 0)
*lengthptr = end - p;
return p;
}
/* Copy a chain of `struct dep', making a new chain
with the same contents as the old one. */
struct dep *
copy_dep_chain (d)
register struct dep *d;
{
register struct dep *c;
struct dep *firstnew = 0;
struct dep *lastnew;
while (d != 0)
{
c = (struct dep *) xmalloc (sizeof (struct dep));
bcopy ((char *) d, (char *) c, sizeof (struct dep));
if (c->name != 0)
c->name = savestring (c->name, strlen (c->name));
c->next = 0;
if (firstnew == 0)
firstnew = lastnew = c;
else
lastnew = lastnew->next = c;
d = d->next;
}
return firstnew;
}
#ifdef iAPX286
/* The losing compiler on this machine can't handle this macro. */
char *
dep_name (dep)
struct dep *dep;
{
return dep->name == 0 ? dep->file->name : dep->name;
}
#endif
#ifdef GETLOADAVG_PRIVILEGED
#ifdef POSIX
/* Hopefully if a system says it's POSIX.1 and has the setuid and setgid
functions, they work as POSIX.1 says. Some systems (Alpha OSF/1 1.2,
for example) which claim to be POSIX.1 also have the BSD setreuid and
setregid functions, but they don't work as in BSD and only the POSIX.1
way works. */
#undef HAVE_SETREUID
#undef HAVE_SETREGID
#else /* Not POSIX. */
/* Some POSIX.1 systems have the seteuid and setegid functions. In a
POSIX-like system, they are the best thing to use. However, some
non-POSIX systems have them too but they do not work in the POSIX style
and we must use setreuid and setregid instead. */
#undef HAVE_SETEUID
#undef HAVE_SETEGID
#endif /* POSIX. */
#ifndef HAVE_UNISTD_H
extern int getuid (), getgid (), geteuid (), getegid ();
extern int setuid (), setgid ();
#ifdef HAVE_SETEUID
extern int seteuid ();
#else
#ifdef HAVE_SETREUID
extern int setreuid ();
#endif /* Have setreuid. */
#endif /* Have seteuid. */
#ifdef HAVE_SETEGID
extern int setegid ();
#else
#ifdef HAVE_SETREGID
extern int setregid ();
#endif /* Have setregid. */
#endif /* Have setegid. */
#endif /* No <unistd.h>. */
/* Keep track of the user and group IDs for user- and make- access. */
static int user_uid = -1, user_gid = -1, make_uid = -1, make_gid = -1;
#define access_inited (user_uid != -1)
static enum { make, user } current_access;
/* Under -d, write a message describing the current IDs. */
static void
log_access (flavor)
char *flavor;
{
if (! debug_flag)
return;
/* All the other debugging messages go to stdout,
but we write this one to stderr because it might be
run in a child fork whose stdout is piped. */
fprintf (stderr, "%s access: user %d (real %d), group %d (real %d)\n",
flavor, geteuid (), getuid (), getegid (), getgid ());
fflush (stderr);
}
static void
init_access ()
{
user_uid = getuid ();
user_gid = getgid ();
make_uid = geteuid ();
make_gid = getegid ();
/* Do these ever fail? */
if (user_uid == -1 || user_gid == -1 || make_uid == -1 || make_gid == -1)
pfatal_with_name ("get{e}[gu]id");
log_access ("Initialized");
current_access = make;
}
#endif /* GETLOADAVG_PRIVILEGED */
/* Give the process appropriate permissions for access to
user data (i.e., to stat files, or to spawn a child process). */
void
user_access ()
{
#ifdef GETLOADAVG_PRIVILEGED
if (!access_inited)
init_access ();
if (current_access == user)
return;
/* We are in "make access" mode. This means that the effective user and
group IDs are those of make (if it was installed setuid or setgid).
We now want to set the effective user and group IDs to the real IDs,
which are the IDs of the process that exec'd make. */
#ifdef HAVE_SETEUID
/* Modern systems have the seteuid/setegid calls which set only the
effective IDs, which is ideal. */
if (seteuid (user_uid) < 0)
pfatal_with_name ("user_access: seteuid");
#else /* Not HAVE_SETEUID. */
#ifndef HAVE_SETREUID
/* System V has only the setuid/setgid calls to set user/group IDs.
There is an effective ID, which can be set by setuid/setgid.
It can be set (unless you are root) only to either what it already is
(returned by geteuid/getegid, now in make_uid/make_gid),
the real ID (return by getuid/getgid, now in user_uid/user_gid),
or the saved set ID (what the effective ID was before this set-ID
executable (make) was exec'd). */
if (setuid (user_uid) < 0)
pfatal_with_name ("user_access: setuid");
#else /* HAVE_SETREUID. */
/* In 4BSD, the setreuid/setregid calls set both the real and effective IDs.
They may be set to themselves or each other. So you have two alternatives
at any one time. If you use setuid/setgid, the effective will be set to
the real, leaving only one alternative. Using setreuid/setregid, however,
you can toggle between your two alternatives by swapping the values in a
single setreuid or setregid call. */
if (setreuid (make_uid, user_uid) < 0)
pfatal_with_name ("user_access: setreuid");
#endif /* Not HAVE_SETREUID. */
#endif /* HAVE_SETEUID. */
#ifdef HAVE_SETEGID
if (setegid (user_gid) < 0)
pfatal_with_name ("user_access: setegid");
#else
#ifndef HAVE_SETREGID
if (setgid (user_gid) < 0)
pfatal_with_name ("user_access: setgid");
#else
if (setregid (make_gid, user_gid) < 0)
pfatal_with_name ("user_access: setregid");
#endif
#endif
current_access = user;
log_access ("User");
#endif /* GETLOADAVG_PRIVILEGED */
}
/* Give the process appropriate permissions for access to
make data (i.e., the load average). */
void
make_access ()
{
#ifdef GETLOADAVG_PRIVILEGED
if (!access_inited)
init_access ();
if (current_access == make)
return;
/* See comments in user_access, above. */
#ifdef HAVE_SETEUID
if (seteuid (make_uid) < 0)
pfatal_with_name ("make_access: seteuid");
#else
#ifndef HAVE_SETREUID
if (setuid (make_uid) < 0)
pfatal_with_name ("make_access: setuid");
#else
if (setreuid (user_uid, make_uid) < 0)
pfatal_with_name ("make_access: setreuid");
#endif
#endif
#ifdef HAVE_SETEGID
if (setegid (make_gid) < 0)
pfatal_with_name ("make_access: setegid");
#else
#ifndef HAVE_SETREGID
if (setgid (make_gid) < 0)
pfatal_with_name ("make_access: setgid");
#else
if (setregid (user_gid, make_gid) < 0)
pfatal_with_name ("make_access: setregid");
#endif
#endif
current_access = make;
log_access ("Make");
#endif /* GETLOADAVG_PRIVILEGED */
}
/* Give the process appropriate permissions for a child process.
This is like user_access, but you can't get back to make_access. */
void
child_access ()
{
#ifdef GETLOADAVG_PRIVILEGED
if (!access_inited)
abort ();
/* Set both the real and effective UID and GID to the user's.
They cannot be changed back to make's. */
#ifndef HAVE_SETREUID
if (setuid (user_uid) < 0)
pfatal_with_name ("child_access: setuid");
#else
if (setreuid (user_uid, user_uid) < 0)
pfatal_with_name ("child_access: setreuid");
#endif
#ifndef HAVE_SETREGID
if (setgid (user_gid) < 0)
pfatal_with_name ("child_access: setgid");
#else
if (setregid (user_gid, user_gid) < 0)
pfatal_with_name ("child_access: setregid");
#endif
log_access ("Child");
#endif /* GETLOADAVG_PRIVILEGED */
}
#ifdef NEED_GET_PATH_MAX
unsigned int
get_path_max ()
{
static unsigned int value;
if (value == 0)
{
long int x = pathconf ("/", _PC_PATH_MAX);
if (x > 0)
value = x;
else
return MAXPATHLEN;
}
return value;
}
#endif
/* On some systems, stat can return EINTR. */
int
safe_stat (name, buf)
char *name;
struct stat *buf;
{
int ret;
#ifdef EINTR
do
#endif
ret = stat (name, buf);
#ifdef EINTR
while (ret < 0 && errno == EINTR);
#endif
return ret;
}

2042
read.c Normal file

File diff suppressed because it is too large Load Diff

1046
remake.c Normal file

File diff suppressed because it is too large Load Diff

270
remote-cstms.c Normal file
View File

@@ -0,0 +1,270 @@
/* GNU Make remote job exportation interface to the Customs daemon.
THIS CODE IS NOT SUPPORTED BY THE GNU PROJECT.
Please do not send bug reports or questions about it to
the Make maintainers.
Copyright (C) 1988, 1989, 1992, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "make.h"
#include "commands.h"
#include "job.h"
#include <sys/time.h>
#include <netdb.h>
#define __STRICT_BSD__ /* Don't make conflicting declarations. */
#include "customs.h"
char *remote_description = "Customs";
/* File name of the Customs `export' client command.
A full path name can be used to avoid some path-searching overhead. */
#define EXPORT_COMMAND "/usr/local/bin/export"
/* ExportPermit gotten by start_remote_job_p, and used by start_remote_job. */
static ExportPermit permit;
/* Normalized path name of the current directory. */
static char *normalized_cwd;
/* Return nonzero if the next job should be done remotely. */
int
start_remote_job_p ()
{
static int inited = 0;
int status;
/* Allow the user to turn off job exportation
(useful while he is debugging Customs, for example). */
if (getenv ("GNU_MAKE_NO_CUSTOMS") != 0)
return 0;
if (!inited)
{
/* For secure Customs, make is installed setuid root and
Customs requires a privileged source port be used. */
make_access ();
/* Ping the daemon once to see if it is there. */
inited = Customs_Ping () == RPC_SUCCESS ? 1 : -1;
/* Return to normal user access. */
user_access ();
if (starting_directory == 0)
/* main couldn't figure it out. */
inited = -1;
else
{
/* Normalize the current directory path name to something
that should work on all machines exported to. */
normalized_cwd = (char *) xmalloc (GET_PATH_MAX);
strcpy (normalized_cwd, starting_directory);
if (Customs_NormPath (normalized_cwd, GET_PATH_MAX) < 0)
/* Path normalization failure means using Customs
won't work, but it's not really an error. */
inited = -1;
}
}
if (inited < 0)
return 0;
status = Customs_Host (EXPORT_SAME, &permit);
if (status != RPC_SUCCESS)
{
if (debug_flag)
printf ("Customs won't export: %s\n", Rpc_ErrorMessage (status));
return 0;
}
return !CUSTOMS_FAIL (&permit.addr);
}
/* Start a remote job running the command in ARGV, with environment from
ENVP. It gets standard input from STDIN_FD. On failure, return
nonzero. On success, return zero, and set *USED_STDIN to nonzero if it
will actually use STDIN_FD, zero if not, set *ID_PTR to a unique
identification, and set *IS_REMOTE to nonzero if the job is remote, zero
if it is local (meaning *ID_PTR is a process ID). */
int
start_remote_job (argv, envp, stdin_fd, is_remote, id_ptr, used_stdin)
char **argv, **envp;
int stdin_fd;
int *is_remote;
int *id_ptr;
int *used_stdin;
{
extern int vfork (), execve ();
char waybill[MAX_DATA_SIZE], msg[128];
struct timeval timeout;
struct sockaddr_in sin;
int len;
int retsock, retport, sock;
Rpc_Stat status;
int pid;
/* Create the return socket. */
retsock = Rpc_UdpCreate (True, 0);
if (retsock < 0)
{
error ("exporting: Couldn't create return socket.");
return 1;
}
/* Get the return socket's port number. */
len = sizeof (sin);
if (getsockname (retsock, (struct sockaddr *) &sin, &len) < 0)
{
(void) close (retsock);
perror_with_name ("exporting: ", "getsockname");
return 1;
}
retport = sin.sin_port;
/* Create the TCP socket for talking to the remote child. */
sock = Rpc_TcpCreate (False, 0);
/* Create a WayBill to give to the server. */
len = Customs_MakeWayBill (&permit, normalized_cwd, argv[0], argv,
envp, retport, waybill);
/* Modify the waybill as if the remote child had done `child_access ()'. */
{
WayBill *wb = (WayBill *) waybill;
wb->euid = wb->ruid;
wb->rgid = wb->rgid;
}
/* Send the request to the server, timing out in 20 seconds. */
timeout.tv_usec = 0;
timeout.tv_sec = 20;
sin.sin_family = AF_INET;
sin.sin_port = htons (Customs_Port ());
sin.sin_addr = permit.addr;
status = Rpc_Call (sock, &sin, (Rpc_Proc) CUSTOMS_IMPORT,
len, (Rpc_Opaque) waybill,
sizeof(msg), (Rpc_Opaque) msg,
1, &timeout);
if (status != RPC_SUCCESS)
{
(void) close (retsock);
(void) close (sock);
error ("exporting: %s", Rpc_ErrorMessage (status));
return 1;
}
else if (msg[0] != 'O' || msg[1] != 'k' || msg[2] != '\0')
{
(void) close (retsock);
(void) close (sock);
error ("CUSTOMS_IMPORT: %s", msg);
return 1;
}
else if (debug_flag)
{
struct hostent *host = gethostbyaddr (&permit.addr, sizeof (permit.addr),
AF_INET);
printf ("Job exported to %s ID %u\n",
host == 0 ? inet_ntoa (permit.addr) : host->h_name,
permit.id);
}
fflush (stdout);
fflush (stderr);
pid = vfork ();
if (pid < 0)
{
/* The fork failed! */
perror_with_name ("vfork", "");
return 1;
}
else if (pid == 0)
{
/* Child side. Run `export' to handle the connection. */
static char sock_buf[20], retsock_buf[20], id_buf[20];
static char *new_argv[6] =
{ EXPORT_COMMAND, "-id", sock_buf, retsock_buf, id_buf, 0 };
/* Set up the arguments. */
(void) sprintf (sock_buf, "%d", sock);
(void) sprintf (retsock_buf, "%d", retsock);
(void) sprintf (id_buf, "%x", permit.id);
/* Get the right stdin. */
if (stdin_fd != 0)
(void) dup2 (stdin_fd, 0);
/* Unblock signals in the child. */
unblock_sigs ();
/* Run the command. */
exec_command (new_argv, envp);
}
/* Parent side. Return the `export' process's ID. */
(void) close (retsock);
(void) close (sock);
*is_remote = 0;
*id_ptr = pid;
return 0;
}
/* Get the status of a dead remote child. Block waiting for one to die
if BLOCK is nonzero. Set *EXIT_CODE_PTR to the exit status, *SIGNAL_PTR
to the termination signal or zero if it exited normally, and *COREDUMP_PTR
nonzero if it dumped core. Return the ID of the child that died,
0 if we would have to block and !BLOCK, or < 0 if there were none. */
int
remote_status (exit_code_ptr, signal_ptr, coredump_ptr, block)
int *exit_code_ptr, *signal_ptr, *coredump_ptr;
int block;
{
return -1;
}
/* Block asynchronous notification of remote child death.
If this notification is done by raising the child termination
signal, do not block that signal. */
void
block_remote_children ()
{
return;
}
/* Restore asynchronous notification of remote child death.
If this is done by raising the child termination signal,
do not unblock that signal. */
void
unblock_remote_children ()
{
return;
}
/* Send signal SIG to child ID. Return 0 if successful, -1 if not. */
int
remote_kill (id, sig)
int id;
int sig;
{
return -1;
}

92
remote-stub.c Normal file
View File

@@ -0,0 +1,92 @@
/* Template for the remote job exportation interface to GNU Make.
Copyright (C) 1988, 1989, 1992, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "make.h"
#include "commands.h"
char *remote_description = 0;
/* Return nonzero if the next job should be done remotely. */
int
start_remote_job_p ()
{
return 0;
}
/* Start a remote job running the command in ARGV,
with environment from ENVP. It gets standard input from STDIN_FD. On
failure, return nonzero. On success, return zero, and set *USED_STDIN
to nonzero if it will actually use STDIN_FD, zero if not, set *ID_PTR to
a unique identification, and set *IS_REMOTE to zero if the job is local,
nonzero if it is remote (meaning *ID_PTR is a process ID). */
int
start_remote_job (argv, envp, stdin_fd, is_remote, id_ptr, used_stdin)
char **argv, **envp;
int stdin_fd;
int *is_remote;
int *id_ptr;
int *used_stdin;
{
return -1;
}
/* Get the status of a dead remote child. Block waiting for one to die
if BLOCK is nonzero. Set *EXIT_CODE_PTR to the exit status, *SIGNAL_PTR
to the termination signal or zero if it exited normally, and *COREDUMP_PTR
nonzero if it dumped core. Return the ID of the child that died,
0 if we would have to block and !BLOCK, or < 0 if there were none. */
int
remote_status (exit_code_ptr, signal_ptr, coredump_ptr, block)
int *exit_code_ptr, *signal_ptr, *coredump_ptr;
int block;
{
errno = ECHILD;
return -1;
}
/* Block asynchronous notification of remote child death.
If this notification is done by raising the child termination
signal, do not block that signal. */
void
block_remote_children ()
{
return;
}
/* Restore asynchronous notification of remote child death.
If this is done by raising the child termination signal,
do not unblock that signal. */
void
unblock_remote_children ()
{
return;
}
/* Send signal SIG to child ID. Return 0 if successful, -1 if not. */
int
remote_kill (id, sig)
int id;
int sig;
{
return -1;
}

571
rule.c Normal file
View File

@@ -0,0 +1,571 @@
/* Pattern and suffix rule internals for GNU Make.
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "make.h"
#include "commands.h"
#include "dep.h"
#include "file.h"
#include "variable.h"
#include "rule.h"
static void freerule ();
/* Chain of all pattern rules. */
struct rule *pattern_rules;
/* Pointer to last rule in the chain, so we can add onto the end. */
struct rule *last_pattern_rule;
/* Number of rules in the chain. */
unsigned int num_pattern_rules;
/* Maximum number of target patterns of any pattern rule. */
unsigned int max_pattern_targets;
/* Maximum number of dependencies of any pattern rule. */
unsigned int max_pattern_deps;
/* Maximum length of the name of a dependencies of any pattern rule. */
unsigned int max_pattern_dep_length;
/* Pointer to structure for the file .SUFFIXES
whose dependencies are the suffixes to be searched. */
struct file *suffix_file;
/* Maximum length of a suffix. */
unsigned int maxsuffix;
/* Compute the maximum dependency length and maximum number of
dependencies of all implicit rules. Also sets the subdir
flag for a rule when appropriate, possibly removing the rule
completely when appropriate. */
void
count_implicit_rule_limits ()
{
char *name;
unsigned int namelen;
register struct rule *rule, *lastrule;
num_pattern_rules = max_pattern_targets = max_pattern_deps = 0;
max_pattern_dep_length = 0;
name = 0;
namelen = 0;
rule = pattern_rules;
lastrule = 0;
while (rule != 0)
{
unsigned int ndeps = 0;
register struct dep *dep;
struct rule *next = rule->next;
unsigned int ntargets;
++num_pattern_rules;
ntargets = 0;
while (rule->targets[ntargets] != 0)
++ntargets;
if (ntargets > max_pattern_targets)
max_pattern_targets = ntargets;
for (dep = rule->deps; dep != 0; dep = dep->next)
{
unsigned int len = strlen (dep->name);
char *p = rindex (dep->name, '/');
char *p2 = p != 0 ? index (dep->name, '%') : 0;
ndeps++;
if (len > max_pattern_dep_length)
max_pattern_dep_length = len;
if (p != 0 && p2 > p)
{
/* There is a slash before the % in the dep name.
Extract the directory name. */
if (p == dep->name)
++p;
if (p - dep->name > namelen)
{
if (name != 0)
free (name);
namelen = p - dep->name;
name = (char *) xmalloc (namelen + 1);
}
bcopy (dep->name, name, p - dep->name);
name[p - dep->name] = '\0';
/* In the deps of an implicit rule the `changed' flag
actually indicates that the dependency is in a
nonexistent subdirectory. */
dep->changed = !dir_file_exists_p (name, "");
if (dep->changed && *name == '/')
{
/* The name is absolute and the directory does not exist.
This rule can never possibly match, since this dependency
can never possibly exist. So just remove the rule from
the list. */
freerule (rule, lastrule);
--num_pattern_rules;
goto end_main_loop;
}
}
else
/* This dependency does not reside in a subdirectory. */
dep->changed = 0;
}
if (ndeps > max_pattern_deps)
max_pattern_deps = ndeps;
lastrule = rule;
end_main_loop:
rule = next;
}
if (name != 0)
free (name);
}
/* Create a pattern rule from a suffix rule.
TARGET is the target suffix; SOURCE is the source suffix.
CMDS are the commands.
If TARGET is nil, it means the target pattern should be `(%.o)'.
If SOURCE is nil, it means there should be no deps. */
static void
convert_suffix_rule (target, source, cmds)
char *target, *source;
struct commands *cmds;
{
char *targname, *targpercent, *depname;
char **names, **percents;
struct dep *deps;
unsigned int len;
if (target == 0)
/* Special case: TARGET being nil means we are defining a
`.X.a' suffix rule; the target pattern is always `(%.o)'. */
{
targname = savestring ("(%.o)", 5);
targpercent = targname + 1;
}
else
{
/* Construct the target name. */
len = strlen (target);
targname = xmalloc (1 + len + 1);
targname[0] = '%';
bcopy (target, targname + 1, len + 1);
targpercent = targname;
}
names = (char **) xmalloc (2 * sizeof (char *));
percents = (char **) alloca (2 * sizeof (char *));
names[0] = targname;
percents[0] = targpercent;
names[1] = percents[1] = 0;
if (source == 0)
deps = 0;
else
{
/* Construct the dependency name. */
len = strlen (source);
depname = xmalloc (1 + len + 1);
depname[0] = '%';
bcopy (source, depname + 1, len + 1);
deps = (struct dep *) xmalloc (sizeof (struct dep));
deps->next = 0;
deps->name = depname;
}
create_pattern_rule (names, percents, 0, deps, cmds, 0);
}
/* Convert old-style suffix rules to pattern rules.
All rules for the suffixes on the .SUFFIXES list
are converted and added to the chain of pattern rules. */
void
convert_to_pattern ()
{
register struct dep *d, *d2;
register struct file *f;
register char *rulename;
register unsigned int slen, s2len;
/* Compute maximum length of all the suffixes. */
maxsuffix = 0;
for (d = suffix_file->deps; d != 0; d = d->next)
{
register unsigned int namelen = strlen (dep_name (d));
if (namelen > maxsuffix)
maxsuffix = namelen;
}
rulename = (char *) alloca ((maxsuffix * 2) + 1);
for (d = suffix_file->deps; d != 0; d = d->next)
{
/* Make a rule that is just the suffix, with no deps or commands.
This rule exists solely to disqualify match-anything rules. */
convert_suffix_rule (dep_name (d), (char *) 0, (struct commands *) 0);
f = d->file;
if (f->cmds != 0)
/* Record a pattern for this suffix's null-suffix rule. */
convert_suffix_rule ("", dep_name (d), f->cmds);
/* Record a pattern for each of this suffix's two-suffix rules. */
slen = strlen (dep_name (d));
bcopy (dep_name (d), rulename, slen);
for (d2 = suffix_file->deps; d2 != 0; d2 = d2->next)
{
s2len = strlen (dep_name (d2));
if (slen == s2len && streq (dep_name (d), dep_name (d2)))
continue;
bcopy (dep_name (d2), rulename + slen, s2len + 1);
f = lookup_file (rulename);
if (f == 0 || f->cmds == 0)
continue;
if (s2len == 2 && rulename[slen] == '.' && rulename[slen + 1] == 'a')
/* A suffix rule `.X.a:' generates the pattern rule `(%.o): %.X'.
It also generates a normal `%.a: %.X' rule below. */
convert_suffix_rule ((char *) 0, /* Indicates `(%.o)'. */
dep_name (d),
f->cmds);
/* The suffix rule `.X.Y:' is converted
to the pattern rule `%.Y: %.X'. */
convert_suffix_rule (dep_name (d2), dep_name (d), f->cmds);
}
}
}
/* Install the pattern rule RULE (whose fields have been filled in)
at the end of the list (so that any rules previously defined
will take precedence). If this rule duplicates a previous one
(identical target and dependencies), the old one is replaced
if OVERRIDE is nonzero, otherwise this new one is thrown out.
When an old rule is replaced, the new one is put at the end of the
list. Return nonzero if RULE is used; zero if not. */
int
new_pattern_rule (rule, override)
register struct rule *rule;
int override;
{
register struct rule *r, *lastrule;
register unsigned int i, j;
rule->in_use = 0;
rule->terminal = 0;
rule->next = 0;
/* Search for an identical rule. */
lastrule = 0;
for (r = pattern_rules; r != 0; lastrule = r, r = r->next)
for (i = 0; rule->targets[i] != 0; ++i)
{
for (j = 0; r->targets[j] != 0; ++j)
if (!streq (rule->targets[i], r->targets[j]))
break;
if (r->targets[j] == 0)
/* All the targets matched. */
{
register struct dep *d, *d2;
for (d = rule->deps, d2 = r->deps;
d != 0 && d2 != 0; d = d->next, d2 = d2->next)
if (!streq (dep_name (d), dep_name (d2)))
break;
if (d == 0 && d2 == 0)
/* All the dependencies matched. */
if (override)
{
/* Remove the old rule. */
freerule (r, lastrule);
/* Install the new one. */
if (pattern_rules == 0)
pattern_rules = rule;
else
last_pattern_rule->next = rule;
last_pattern_rule = rule;
/* We got one. Stop looking. */
goto matched;
}
else
{
/* The old rule stays intact. Destroy the new one. */
freerule (rule, (struct rule *) 0);
return 0;
}
}
}
matched:;
if (r == 0)
{
/* There was no rule to replace. */
if (pattern_rules == 0)
pattern_rules = rule;
else
last_pattern_rule->next = rule;
last_pattern_rule = rule;
}
return 1;
}
/* Install an implicit pattern rule based on the three text strings
in the structure P points to. These strings come from one of
the arrays of default implicit pattern rules.
TERMINAL specifies what the `terminal' field of the rule should be. */
void
install_pattern_rule (p, terminal)
struct pspec *p;
int terminal;
{
register struct rule *r;
char *ptr;
r = (struct rule *) xmalloc (sizeof (struct rule));
r->targets = (char **) xmalloc (2 * sizeof (char *));
r->suffixes = (char **) xmalloc (2 * sizeof (char *));
r->lens = (unsigned int *) xmalloc (2 * sizeof (unsigned int));
r->targets[1] = 0;
r->suffixes[1] = 0;
r->lens[1] = 0;
r->lens[0] = strlen (p->target);
/* These will all be string literals, but we malloc space for
them anyway because somebody might want to free them later on. */
r->targets[0] = savestring (p->target, r->lens[0]);
r->suffixes[0] = find_percent (r->targets[0]);
if (r->suffixes[0] == 0)
/* Programmer-out-to-lunch error. */
abort ();
else
++r->suffixes[0];
ptr = p->dep;
r->deps = (struct dep *) multi_glob (parse_file_seq (&ptr, '\0',
sizeof (struct dep), 1),
sizeof (struct dep));
if (new_pattern_rule (r, 0))
{
r->terminal = terminal;
r->cmds = (struct commands *) xmalloc (sizeof (struct commands));
r->cmds->filename = 0;
r->cmds->lineno = 0;
/* These will all be string literals, but we malloc space for them
anyway because somebody might want to free them later. */
r->cmds->commands = savestring (p->commands, strlen (p->commands));
r->cmds->command_lines = 0;
}
}
/* Free all the storage used in RULE and take it out of the
pattern_rules chain. LASTRULE is the rule whose next pointer
points to RULE. */
static void
freerule (rule, lastrule)
register struct rule *rule, *lastrule;
{
struct rule *next = rule->next;
register unsigned int i;
for (i = 0; rule->targets[i] != 0; ++i)
free (rule->targets[i]);
free ((char *) rule->targets);
free ((char *) rule->suffixes);
free ((char *) rule->lens);
/* We can't free the storage for the commands because there
are ways that they could be in more than one place:
* If the commands came from a suffix rule, they could also be in
the `struct file's for other suffix rules or plain targets given
on the same makefile line.
* If two suffixes that together make a two-suffix rule were each
given twice in the .SUFFIXES list, and in the proper order, two
identical pattern rules would be created and the second one would
be discarded here, but both would contain the same `struct commands'
pointer from the `struct file' for the suffix rule. */
free ((char *) rule);
if (pattern_rules == rule)
if (lastrule != 0)
abort ();
else
pattern_rules = next;
else if (lastrule != 0)
lastrule->next = next;
if (last_pattern_rule == rule)
last_pattern_rule = lastrule;
}
/* Create a new pattern rule with the targets in the nil-terminated
array TARGETS. If TARGET_PERCENTS is not nil, it is an array of
pointers into the elements of TARGETS, where the `%'s are.
The new rule has dependencies DEPS and commands from COMMANDS.
It is a terminal rule if TERMINAL is nonzero. This rule overrides
identical rules with different commands if OVERRIDE is nonzero.
The storage for TARGETS and its elements is used and must not be freed
until the rule is destroyed. The storage for TARGET_PERCENTS is not used;
it may be freed. */
void
create_pattern_rule (targets, target_percents,
terminal, deps, commands, override)
char **targets, **target_percents;
int terminal;
struct dep *deps;
struct commands *commands;
int override;
{
register struct rule *r = (struct rule *) xmalloc (sizeof (struct rule));
register unsigned int max_targets, i;
r->cmds = commands;
r->deps = deps;
r->targets = targets;
max_targets = 2;
r->lens = (unsigned int *) xmalloc (2 * sizeof (unsigned int));
r->suffixes = (char **) xmalloc (2 * sizeof (char *));
for (i = 0; targets[i] != 0; ++i)
{
if (i == max_targets - 1)
{
max_targets += 5;
r->lens = (unsigned int *)
xrealloc ((char *) r->lens, max_targets * sizeof (unsigned int));
r->suffixes = (char **)
xrealloc ((char *) r->suffixes, max_targets * sizeof (char *));
}
r->lens[i] = strlen (targets[i]);
r->suffixes[i] = (target_percents == 0 ? find_percent (targets[i])
: target_percents[i]) + 1;
if (r->suffixes[i] == 0)
abort ();
}
if (i < max_targets - 1)
{
r->lens = (unsigned int *) xrealloc ((char *) r->lens,
(i + 1) * sizeof (unsigned int));
r->suffixes = (char **) xrealloc ((char *) r->suffixes,
(i + 1) * sizeof (char *));
}
if (new_pattern_rule (r, override))
r->terminal = terminal;
}
/* Print the data base of rules. */
static void /* Useful to call from gdb. */
print_rule (r)
struct rule *r;
{
register unsigned int i;
register struct dep *d;
for (i = 0; r->targets[i] != 0; ++i)
{
fputs (r->targets[i], stdout);
if (r->targets[i + 1] != 0)
putchar (' ');
else
putchar (':');
}
if (r->terminal)
putchar (':');
for (d = r->deps; d != 0; d = d->next)
printf (" %s", dep_name (d));
putchar ('\n');
if (r->cmds != 0)
print_commands (r->cmds);
}
void
print_rule_data_base ()
{
register unsigned int rules, terminal;
register struct rule *r;
puts ("\n# Implicit Rules");
rules = terminal = 0;
for (r = pattern_rules; r != 0; r = r->next)
{
++rules;
putchar ('\n');
print_rule (r);
if (r->terminal)
++terminal;
}
if (rules == 0)
puts ("\n# No implicit rules.");
else
{
printf ("\n# %u implicit rules, %u", rules, terminal);
#ifndef NO_FLOAT
printf (" (%.1f%%)", (double) terminal / (double) rules * 100.0);
#endif
puts (" terminal.");
}
if (num_pattern_rules != rules)
fatal ("BUG: num_pattern_rules wrong! %u != %u",
num_pattern_rules, rules);
}

53
rule.h Normal file
View File

@@ -0,0 +1,53 @@
/* Definitions for using pattern rules in GNU Make.
Copyright (C) 1988, 1989, 1991, 1992, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Structure used for pattern rules. */
struct rule
{
struct rule *next;
char **targets; /* Targets of the rule. */
unsigned int *lens; /* Lengths of each target. */
char **suffixes; /* Suffixes (after `%') of each target. */
struct dep *deps; /* Dependencies of the rule. */
struct commands *cmds; /* Commands to execute. */
char terminal; /* If terminal (double-colon). */
char in_use; /* If in use by a parent pattern_search. */
};
/* For calling install_pattern_rule. */
struct pspec
{
char *target, *dep, *commands;
};
extern struct rule *pattern_rules;
extern struct rule *last_pattern_rule;
extern unsigned int num_pattern_rules;
extern unsigned int max_pattern_deps;
extern unsigned int max_pattern_targets;
extern unsigned int max_pattern_dep_length;
extern struct file *suffix_file;
extern unsigned int maxsuffix;
extern void install_pattern_rule ();
int new_pattern_rule ();

275
signame.c Normal file
View File

@@ -0,0 +1,275 @@
/* Convert between signal names and numbers.
Copyright (C) 1990, 1992, 1993 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; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <sys/types.h> /* Some systems need this for <signal.h>. */
#include <signal.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
/* Some systems do not define NSIG in <signal.h>. */
#ifndef NSIG
#ifdef _NSIG
#define NSIG _NSIG
#else
#define NSIG 32
#endif
#endif
#if !__STDC__
#define const
#endif
#include "signame.h"
#ifndef HAVE_SYS_SIGLIST
/* There is too much variation in Sys V signal numbers and names, so
we must initialize them at runtime. */
static const char undoc[] = "unknown signal";
const char *sys_siglist[NSIG];
#else /* HAVE_SYS_SIGLIST. */
#ifndef SYS_SIGLIST_DECLARED
extern char *sys_siglist[];
#endif /* Not SYS_SIGLIST_DECLARED. */
#endif /* Not HAVE_SYS_SIGLIST. */
/* Table of abbreviations for signals. Note: A given number can
appear more than once with different abbreviations. */
typedef struct
{
int number;
const char *abbrev;
} num_abbrev;
static num_abbrev sig_table[NSIG*2];
/* Number of elements of sig_table used. */
static int sig_table_nelts = 0;
/* Enter signal number NUMBER into the tables with ABBREV and NAME. */
static void
init_sig (number, abbrev, name)
int number;
const char *abbrev;
const char *name;
{
#ifndef HAVE_SYS_SIGLIST
sys_siglist[number] = name;
#endif
sig_table[sig_table_nelts].number = number;
sig_table[sig_table_nelts++].abbrev = abbrev;
}
void
signame_init ()
{
#ifndef HAVE_SYS_SIGLIST
int i;
/* Initialize signal names. */
for (i = 0; i < NSIG; i++)
sys_siglist[i] = undoc;
#endif /* !HAVE_SYS_SIGLIST */
/* Initialize signal names. */
#if defined (SIGHUP)
init_sig (SIGHUP, "HUP", "Hangup");
#endif
#if defined (SIGINT)
init_sig (SIGINT, "INT", "Interrupt");
#endif
#if defined (SIGQUIT)
init_sig (SIGQUIT, "QUIT", "Quit");
#endif
#if defined (SIGILL)
init_sig (SIGILL, "ILL", "Illegal Instruction");
#endif
#if defined (SIGTRAP)
init_sig (SIGTRAP, "TRAP", "Trace/breakpoint trap");
#endif
/* If SIGIOT == SIGABRT, we want to print it as SIGABRT because
SIGABRT is in ANSI and POSIX.1 and SIGIOT isn't. */
#if defined (SIGABRT)
init_sig (SIGABRT, "ABRT", "Aborted");
#endif
#if defined (SIGIOT)
init_sig (SIGIOT, "IOT", "IOT trap");
#endif
#if defined (SIGEMT)
init_sig (SIGEMT, "EMT", "EMT trap");
#endif
#if defined (SIGFPE)
init_sig (SIGFPE, "FPE", "Floating point exception");
#endif
#if defined (SIGKILL)
init_sig (SIGKILL, "KILL", "Killed");
#endif
#if defined (SIGBUS)
init_sig (SIGBUS, "BUS", "Bus error");
#endif
#if defined (SIGSEGV)
init_sig (SIGSEGV, "SEGV", "Segmentation fault");
#endif
#if defined (SIGSYS)
init_sig (SIGSYS, "SYS", "Bad system call");
#endif
#if defined (SIGPIPE)
init_sig (SIGPIPE, "PIPE", "Broken pipe");
#endif
#if defined (SIGALRM)
init_sig (SIGALRM, "ALRM", "Alarm clock");
#endif
#if defined (SIGTERM)
init_sig (SIGTERM, "TERM", "Terminated");
#endif
#if defined (SIGUSR1)
init_sig (SIGUSR1, "USR1", "User defined signal 1");
#endif
#if defined (SIGUSR2)
init_sig (SIGUSR2, "USR2", "User defined signal 2");
#endif
/* If SIGCLD == SIGCHLD, we want to print it as SIGCHLD because that
is what is in POSIX.1. */
#if defined (SIGCHLD)
init_sig (SIGCHLD, "CHLD", "Child exited");
#endif
#if defined (SIGCLD)
init_sig (SIGCLD, "CLD", "Child exited");
#endif
#if defined (SIGPWR)
init_sig (SIGPWR, "PWR", "Power failure");
#endif
#if defined (SIGTSTP)
init_sig (SIGTSTP, "TSTP", "Stopped");
#endif
#if defined (SIGTTIN)
init_sig (SIGTTIN, "TTIN", "Stopped (tty input)");
#endif
#if defined (SIGTTOU)
init_sig (SIGTTOU, "TTOU", "Stopped (tty output)");
#endif
#if defined (SIGSTOP)
init_sig (SIGSTOP, "STOP", "Stopped (signal)");
#endif
#if defined (SIGXCPU)
init_sig (SIGXCPU, "XCPU", "CPU time limit exceeded");
#endif
#if defined (SIGXFSZ)
init_sig (SIGXFSZ, "XFSZ", "File size limit exceeded");
#endif
#if defined (SIGVTALRM)
init_sig (SIGVTALRM, "VTALRM", "Virtual timer expired");
#endif
#if defined (SIGPROF)
init_sig (SIGPROF, "PROF", "Profiling timer expired");
#endif
#if defined (SIGWINCH)
/* "Window size changed" might be more accurate, but even if that
is all that it means now, perhaps in the future it will be
extended to cover other kinds of window changes. */
init_sig (SIGWINCH, "WINCH", "Window changed");
#endif
#if defined (SIGCONT)
init_sig (SIGCONT, "CONT", "Continued");
#endif
#if defined (SIGURG)
init_sig (SIGURG, "URG", "Urgent I/O condition");
#endif
#if defined (SIGIO)
/* "I/O pending" has also been suggested. A disadvantage is
that signal only happens when the process has
asked for it, not everytime I/O is pending. Another disadvantage
is the confusion from giving it a different name than under Unix. */
init_sig (SIGIO, "IO", "I/O possible");
#endif
#if defined (SIGWIND)
init_sig (SIGWIND, "WIND", "SIGWIND");
#endif
#if defined (SIGPHONE)
init_sig (SIGPHONE, "PHONE", "SIGPHONE");
#endif
#if defined (SIGPOLL)
init_sig (SIGPOLL, "POLL", "I/O possible");
#endif
#if defined (SIGLOST)
init_sig (SIGLOST, "LOST", "Resource lost");
#endif
#if defined (SIGDANGER)
init_sig (SIGDANGER, "DANGER", "Danger signal");
#endif
}
/* Return the abbreviation for signal NUMBER. */
char *
sig_abbrev (number)
int number;
{
int i;
if (sig_table_nelts == 0)
signame_init ();
for (i = 0; i < sig_table_nelts; i++)
if (sig_table[i].number == number)
return (char *)sig_table[i].abbrev;
return NULL;
}
/* Return the signal number for an ABBREV, or -1 if there is no
signal by that name. */
int
sig_number (abbrev)
const char *abbrev;
{
int i;
if (sig_table_nelts == 0)
signame_init ();
/* Skip over "SIG" if present. */
if (abbrev[0] == 'S' && abbrev[1] == 'I' && abbrev[2] == 'G')
abbrev += 3;
for (i = 0; i < sig_table_nelts; i++)
if (abbrev[0] == sig_table[i].abbrev[0]
&& strcmp (abbrev, sig_table[i].abbrev) == 0)
return sig_table[i].number;
return -1;
}
#ifndef HAVE_PSIGNAL
/* Print to standard error the name of SIGNAL, preceded by MESSAGE and
a colon, and followed by a newline. */
void
psignal (signal, message)
int signal;
const char *message;
{
if (signal <= 0 || signal >= NSIG)
fprintf (stderr, "%s: unknown signal", message);
else
fprintf (stderr, "%s: %s\n", message, sys_siglist[signal]);
}
#endif

57
signame.h Normal file
View File

@@ -0,0 +1,57 @@
/* Convert between signal names and numbers.
Copyright (C) 1990, 1992, 1993 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; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#if defined (__STDC__) && __STDC__
/* Initialize `sys_siglist'. */
void signame_init (void);
/* Return the abbreviation (e.g. ABRT, FPE, etc.) for signal NUMBER.
Do not return this as a const char *. The caller might want to
assign it to a char *. */
char *sig_abbrev (int number);
/* Return the signal number for an ABBREV, or -1 if there is no
signal by that name. */
int sig_number (const char *abbrev);
/* Avoid conflicts with a system header file that might define these two. */
#ifndef HAVE_PSIGNAL
/* Print to standard error the name of SIGNAL, preceded by MESSAGE and
a colon, and followed by a newline. */
void psignal (int signal, const char *message);
#endif
#if !defined (HAVE_SYS_SIGLIST)
/* Names for signals from 0 to NSIG-1. */
extern const char *sys_siglist[];
#endif
#else
void signame_init ();
char *sig_abbrev ();
int sig_number ();
#if !defined (HAVE_SYS_SIGLIST) && !defined (HAVE_PSIGNAL)
void psignal ();
#endif
#if !defined (HAVE_SYS_SIGLIST)
extern char *sys_siglist[];
#endif
#endif

822
variable.c Normal file
View File

@@ -0,0 +1,822 @@
/* Internals of variables for GNU Make.
Copyright (C) 1988, 89, 90, 91, 92, 93, 94 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "make.h"
#include "commands.h"
#include "variable.h"
#include "dep.h"
#include "file.h"
/* Hash table of all global variable definitions. */
#ifndef VARIABLE_BUCKETS
#define VARIABLE_BUCKETS 523
#endif
#ifndef PERFILE_VARIABLE_BUCKETS
#define PERFILE_VARIABLE_BUCKETS 23
#endif
#ifndef SMALL_SCOPE_VARIABLE_BUCKETS
#define SMALL_SCOPE_VARIABLE_BUCKETS 13
#endif
static struct variable *variable_table[VARIABLE_BUCKETS];
static struct variable_set global_variable_set
= { variable_table, VARIABLE_BUCKETS };
static struct variable_set_list global_setlist
= { 0, &global_variable_set };
struct variable_set_list *current_variable_set_list = &global_setlist;
/* Implement variables. */
/* Define variable named NAME with value VALUE in SET. VALUE is copied.
LENGTH is the length of NAME, which does not need to be null-terminated.
ORIGIN specifies the origin of the variable (makefile, command line
or environment).
If RECURSIVE is nonzero a flag is set in the variable saying
that it should be recursively re-expanded. */
static struct variable *
define_variable_in_set (name, length, value, origin, recursive, set)
char *name;
unsigned int length;
char *value;
enum variable_origin origin;
int recursive;
struct variable_set *set;
{
register unsigned int i;
register unsigned int hashval;
register struct variable *v;
hashval = 0;
for (i = 0; i < length; ++i)
HASH (hashval, name[i]);
hashval %= set->buckets;
for (v = set->table[hashval]; v != 0; v = v->next)
if (*v->name == *name
&& !strncmp (v->name + 1, name + 1, length - 1)
&& v->name[length] == '\0')
break;
if (env_overrides && origin == o_env)
origin = o_env_override;
if (v != 0)
{
if (env_overrides && v->origin == o_env)
/* V came from in the environment. Since it was defined
before the switches were parsed, it wasn't affected by -e. */
v->origin = o_env_override;
/* A variable of this name is already defined.
If the old definition is from a stronger source
than this one, don't redefine it. */
if ((int) origin >= (int) v->origin)
{
if (v->value != 0)
free (v->value);
v->value = savestring (value, strlen (value));
v->origin = origin;
v->recursive = recursive;
}
return v;
}
/* Create a new variable definition and add it to the hash table. */
v = (struct variable *) xmalloc (sizeof (struct variable));
v->name = savestring (name, length);
v->value = savestring (value, strlen (value));
v->origin = origin;
v->recursive = recursive;
v->expanding = 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. */
struct variable *
lookup_variable (name, length)
char *name;
unsigned int length;
{
register struct variable_set_list *setlist;
register unsigned int i;
register unsigned int rawhash = 0;
for (i = 0; i < length; ++i)
HASH (rawhash, name[i]);
for (setlist = current_variable_set_list;
setlist != 0; setlist = setlist->next)
{
register struct variable_set *set = setlist->set;
register unsigned int hashval = rawhash % set->buckets;
register struct variable *v;
for (v = set->table[hashval]; v != 0; v = v->next)
if (*v->name == *name
&& !strncmp (v->name + 1, name + 1, length - 1)
&& v->name[length] == 0)
return v;
}
return 0;
}
/* 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. */
void
initialize_file_variables (file)
struct file *file;
{
register struct variable_set_list *l = file->variables;
if (l == 0)
{
l = (struct variable_set_list *)
xmalloc (sizeof (struct variable_set_list));
l->set = (struct variable_set *) xmalloc (sizeof (struct variable_set));
l->set->buckets = PERFILE_VARIABLE_BUCKETS;
l->set->table = (struct variable **)
xmalloc (l->set->buckets * sizeof (struct variable *));
bzero ((char *) l->set->table,
l->set->buckets * sizeof (struct variable *));
file->variables = l;
}
if (file->parent == 0)
l->next = &global_setlist;
else
{
if (file->parent->variables == 0)
initialize_file_variables (file->parent);
l->next = file->parent->variables;
}
}
/* Pop the top set off the current variable set list,
and free all its storage. */
void
pop_variable_scope ()
{
register struct variable_set_list *setlist = current_variable_set_list;
register struct variable_set *set = setlist->set;
register unsigned int i;
current_variable_set_list = setlist->next;
free ((char *) setlist);
for (i = 0; i < set->buckets; ++i)
{
register struct variable *next = set->table[i];
while (next != 0)
{
register struct variable *v = next;
next = v->next;
free (v->name);
free ((char *) v);
}
}
free ((char *) set->table);
free ((char *) set);
}
/* Create a new variable set and push it on the current setlist. */
void
push_new_variable_scope ()
{
register struct variable_set_list *setlist;
register struct variable_set *set;
set = (struct variable_set *) xmalloc (sizeof (struct variable_set));
set->buckets = SMALL_SCOPE_VARIABLE_BUCKETS;
set->table = (struct variable **)
xmalloc (set->buckets * sizeof (struct variable *));
bzero ((char *) set->table, set->buckets * sizeof (struct variable *));
setlist = (struct variable_set_list *)
xmalloc (sizeof (struct variable_set_list));
setlist->set = set;
setlist->next = current_variable_set_list;
current_variable_set_list = setlist;
}
/* Merge SET1 into SET0, freeing unused storage in SET1. */
static void
merge_variable_sets (set0, set1)
struct variable_set *set0, *set1;
{
register unsigned int bucket1;
for (bucket1 = 0; bucket1 < set1->buckets; ++bucket1)
{
register struct variable *v1 = set1->table[bucket1];
while (v1 != 0)
{
struct variable *next = v1->next;
unsigned int bucket0;
register struct variable *v0;
if (set1->buckets >= set0->buckets)
bucket0 = bucket1;
else
{
register char *n;
bucket0 = 0;
for (n = v1->name; *n != '\0'; ++n)
HASH (bucket0, *n);
}
bucket0 %= set0->buckets;
for (v0 = set0->table[bucket0]; v0 != 0; v0 = v0->next)
if (streq (v0->name, v1->name))
break;
if (v0 == 0)
{
/* There is no variable in SET0 with the same name. */
v1->next = set0->table[bucket0];
set0->table[bucket0] = v1;
}
else
{
/* The same variable exists in both sets.
SET0 takes precedence. */
free (v1->value);
free ((char *) v1);
}
v1 = next;
}
}
}
/* Merge SETLIST1 into SETLIST0, freeing unused storage in SETLIST1. */
void
merge_variable_set_lists (setlist0, setlist1)
struct variable_set_list **setlist0, *setlist1;
{
register struct variable_set_list *list0 = *setlist0;
struct variable_set_list *last0 = 0;
while (setlist1 != 0 && list0 != 0)
{
struct variable_set_list *next = setlist1;
setlist1 = setlist1->next;
merge_variable_sets (list0->set, next->set);
free ((char *) next);
last0 = list0;
list0 = list0->next;
}
if (setlist1 != 0)
{
if (last0 == 0)
*setlist0 = setlist1;
else
last0->next = setlist1;
}
}
/* Define the automatic variables, and record the addresses
of their structures so we can change their values quickly. */
void
define_automatic_variables ()
{
extern char default_shell[];
register struct variable *v;
char buf[200];
sprintf (buf, "%u", makelevel);
(void) define_variable ("MAKELEVEL", 9, buf, o_env, 0);
sprintf (buf, "%s%s%s",
version_string,
(remote_description == 0 || remote_description[0] == '\0')
? "" : "-",
(remote_description == 0 || remote_description[0] == '\0')
? "" : remote_description);
(void) define_variable ("MAKE_VERSION", 12, buf, o_default, 0);
/* This won't override any definition, but it
will provide one if there isn't one there. */
v = define_variable ("SHELL", 5, default_shell, o_default, 0);
v->export = v_export; /* Always export SHELL. */
/* Don't let SHELL come from the environment. */
if (*v->value == '\0' || v->origin == o_env || v->origin == o_env_override)
{
free (v->value);
v->origin = o_file;
v->value = savestring (default_shell, strlen (default_shell));
}
/* Make sure MAKEFILES gets exported if it is set. */
v = define_variable ("MAKEFILES", 9, "", o_default, 0);
v->export = v_ifset;
/* Define the magic D and F variables in terms of
the automatic variables they are variations of. */
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);
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);
define_variable ("+D", 2, "$(patsubst %/,%,$(dir $+))", o_automatic, 1);
define_variable ("@F", 2, "$(notdir $@)", o_automatic, 1);
define_variable ("%F", 2, "$(notdir $%)", o_automatic, 1);
define_variable ("*F", 2, "$(notdir $*)", o_automatic, 1);
define_variable ("<F", 2, "$(notdir $<)", o_automatic, 1);
define_variable ("?F", 2, "$(notdir $?)", o_automatic, 1);
define_variable ("^F", 2, "$(notdir $^)", o_automatic, 1);
define_variable ("+F", 2, "$(notdir $+)", o_automatic, 1);
}
int export_all_variables;
/* Create a new environment for FILE's commands.
If FILE is nil, this is for the `shell' function.
The child's MAKELEVEL variable is incremented. */
char **
target_environment (file)
struct file *file;
{
struct variable_set_list *set_list;
register struct variable_set_list *s;
struct variable_bucket
{
struct variable_bucket *next;
struct variable *variable;
};
struct variable_bucket **table;
unsigned int buckets;
register unsigned int i;
register unsigned nvariables;
char **result;
unsigned int mklev_hash;
if (file == 0)
set_list = current_variable_set_list;
else
set_list = file->variables;
/* Find the lowest number of buckets in any set in the list. */
s = set_list;
buckets = s->set->buckets;
for (s = s->next; s != 0; s = s->next)
if (s->set->buckets < buckets)
buckets = s->set->buckets;
/* Find the hash value of the bucket `MAKELEVEL' will fall into. */
{
char *p = "MAKELEVEL";
mklev_hash = 0;
while (*p != '\0')
HASH (mklev_hash, *p++);
}
/* Temporarily allocate a table with that many buckets. */
table = (struct variable_bucket **)
alloca (buckets * sizeof (struct variable_bucket *));
bzero ((char *) table, buckets * sizeof (struct variable_bucket *));
/* Run through all the variable sets in the list,
accumulating variables in TABLE. */
nvariables = 0;
for (s = set_list; s != 0; s = s->next)
{
register struct variable_set *set = s->set;
for (i = 0; i < set->buckets; ++i)
{
register struct variable *v;
for (v = set->table[i]; v != 0; v = v->next)
{
unsigned int j = i % buckets;
register struct variable_bucket *ov;
register char *p = v->name;
if (i == mklev_hash % set->buckets
&& streq (v->name, "MAKELEVEL"))
/* Don't include MAKELEVEL because it will be
added specially at the end. */
continue;
switch (v->export)
{
case v_default:
if (v->origin == o_default || v->origin == o_automatic)
/* Only export default variables by explicit request. */
continue;
if (! export_all_variables
&& v->origin != o_command
&& v->origin != o_env && v->origin != o_env_override)
continue;
if (*p != '_' && (*p < 'A' || *p > 'Z')
&& (*p < 'a' || *p > 'z'))
continue;
for (++p; *p != '\0'; ++p)
if (*p != '_' && (*p < 'a' || *p > 'z')
&& (*p < 'A' || *p > 'Z') && (*p < '0' || *p > '9'))
break;
if (*p != '\0')
continue;
case v_export:
break;
case v_noexport:
continue;
case v_ifset:
if (v->origin == o_default)
continue;
break;
}
for (ov = table[j]; ov != 0; ov = ov->next)
if (streq (v->name, ov->variable->name))
break;
if (ov == 0)
{
register struct variable_bucket *entry;
entry = (struct variable_bucket *)
alloca (sizeof (struct variable_bucket));
entry->next = table[j];
entry->variable = v;
table[j] = entry;
++nvariables;
}
}
}
}
result = (char **) xmalloc ((nvariables + 2) * sizeof (char *));
nvariables = 0;
for (i = 0; i < buckets; ++i)
{
register struct variable_bucket *b;
for (b = table[i]; b != 0; b = b->next)
{
register struct variable *v = b->variable;
/* If V is recursively expanded and didn't come from the environment,
expand its value. If it came from the environment, it should
go back into the environment unchanged. */
if (v->recursive
&& v->origin != o_env && v->origin != o_env_override)
{
char *value = recursively_expand (v);
result[nvariables++] = concat (v->name, "=", value);
free (value);
}
else
result[nvariables++] = concat (v->name, "=", v->value);
}
}
result[nvariables] = (char *) xmalloc (100);
(void) sprintf (result[nvariables], "MAKELEVEL=%u", makelevel + 1);
result[++nvariables] = 0;
return result;
}
/* Try to interpret LINE (a null-terminated string) as a variable definition.
ORIGIN may be o_file, o_override, o_env, o_env_override,
or o_command specifying that the variable definition comes
from a makefile, an override directive, the environment with
or without the -e switch, or the command line.
A variable definition has the form "name = value" or "name := value".
Any whitespace around the "=" or ":=" is removed. The first form
defines a variable that is recursively re-evaluated. The second form
defines a variable whose value is variable-expanded at the time of
definition and then is evaluated only once at the time of expansion.
If a variable was defined, a pointer to its `struct variable' is returned.
If not, NULL is returned. */
struct variable *
try_variable_definition (filename, lineno, line, origin)
char *filename;
unsigned int lineno;
char *line;
enum variable_origin origin;
{
register int c;
register char *p = line;
register char *beg;
register char *end;
enum { bogus, simple, recursive, append } flavor = bogus;
char *name, *expanded_name, *value;
struct variable *v;
while (1)
{
c = *p++;
if (c == '\0' || c == '#')
return 0;
if (c == '=')
{
end = p - 1;
flavor = recursive;
break;
}
else if (c == ':')
if (*p == '=')
{
end = p++ - 1;
flavor = simple;
break;
}
else
/* A colon other than := is a rule line, not a variable defn. */
return 0;
else if (c == '+' && *p == '=')
{
end = p++ - 1;
flavor = append;
break;
}
}
beg = next_token (line);
while (end > beg && isblank (end[-1]))
--end;
p = next_token (p);
/* Expand the name, so "$(foo)bar = baz" works. */
name = (char *) alloca (end - beg + 1);
bcopy (beg, name, end - beg);
name[end - beg] = '\0';
expanded_name = allocated_variable_expand (name);
if (expanded_name[0] == '\0')
{
if (filename == 0)
fatal ("empty variable name");
else
makefile_fatal (filename, lineno, "empty variable name");
}
/* Calculate the variable's new value in VALUE. */
switch (flavor)
{
case bogus:
/* Should not be possible. */
abort ();
return 0;
case simple:
/* A simple variable definition "var := value". Expand the value. */
value = variable_expand (p);
break;
case recursive:
/* A recursive variable definition "var = value".
The value is used verbatim. */
value = p;
break;
case append:
/* An appending variable definition "var += value".
Extract the old value and append the new one. */
v = lookup_variable (expanded_name, strlen (expanded_name));
if (v == 0)
{
/* There was no old value.
This becomes a normal recursive definition. */
value = p;
flavor = recursive;
}
else
{
/* Paste the old and new values together in VALUE. */
unsigned int oldlen, newlen;
if (v->recursive)
/* The previous definition of the variable was recursive.
The new value comes from the unexpanded old and new values. */
flavor = recursive;
else
/* The previous definition of the variable was simple.
The new value comes from the old value, which was expanded
when it was set; and from the expanded new value. */
p = variable_expand (p);
oldlen = strlen (v->value);
newlen = strlen (p);
value = (char *) alloca (oldlen + 1 + newlen + 1);
bcopy (v->value, value, oldlen);
value[oldlen] = ' ';
bcopy (p, &value[oldlen + 1], newlen + 1);
}
}
v = define_variable (expanded_name, strlen (expanded_name),
value, origin, flavor == recursive);
free (expanded_name);
return v;
}
/* Print information for variable V, prefixing it with PREFIX. */
static void
print_variable (v, prefix)
register struct variable *v;
char *prefix;
{
char *origin;
switch (v->origin)
{
case o_default:
origin = "default";
break;
case o_env:
origin = "environment";
break;
case o_file:
origin = "makefile";
break;
case o_env_override:
origin = "environment under -e";
break;
case o_command:
origin = "command line";
break;
case o_override:
origin = "`override' directive";
break;
case o_automatic:
origin = "automatic";
break;
case o_invalid:
default:
abort ();
break;
}
printf ("# %s\n", origin);
fputs (prefix, stdout);
/* Is this a `define'? */
if (v->recursive && index (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 ? "" : ":");
/* Check if the value is just whitespace. */
p = next_token (v->value);
if (p != v->value && *p == '\0')
/* All whitespace. */
printf ("$(subst ,,%s)", v->value);
else if (v->recursive)
fputs (v->value, stdout);
else
/* Double up dollar signs. */
for (p = v->value; *p != '\0'; ++p)
{
if (*p == '$')
putchar ('$');
putchar (*p);
}
putchar ('\n');
}
}
/* Print all the variables in SET. PREFIX is printed before
the actual variable definitions (everything else is comments). */
static void
print_variable_set (set, prefix)
register struct variable_set *set;
char *prefix;
{
register unsigned int i, nvariables, per_bucket;
register struct variable *v;
per_bucket = nvariables = 0;
for (i = 0; i < set->buckets; ++i)
{
register unsigned int this_bucket = 0;
for (v = set->table[i]; v != 0; v = v->next)
{
++this_bucket;
print_variable (v, prefix);
}
nvariables += this_bucket;
if (this_bucket > per_bucket)
per_bucket = this_bucket;
}
if (nvariables == 0)
puts ("# No variables.");
else
{
printf ("# %u variables in %u hash buckets.\n",
nvariables, set->buckets);
#ifndef NO_FLOAT
printf ("# average of %.1f variables per bucket, \
max %u in one bucket.\n",
(double) nvariables / (double) set->buckets,
per_bucket);
#endif
}
}
/* Print the data base of variables. */
void
print_variable_data_base ()
{
puts ("\n# Variables\n");
print_variable_set (&global_variable_set, "");
}
/* Print all the local variables of FILE. */
void
print_file_variables (file)
struct file *file;
{
if (file->variables != 0)
print_variable_set (file->variables->set, "# ");
}

100
variable.h Normal file
View File

@@ -0,0 +1,100 @@
/* Definitions for using variables in GNU Make.
Copyright (C) 1988, 1989, 1990, 1991, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Codes in a variable definition saying where the definition came from.
Increasing numeric values signify less-overridable definitions. */
enum variable_origin
{
o_default, /* Variable from the default set. */
o_env, /* Variable from environment. */
o_file, /* Variable given in a makefile. */
o_env_override, /* Variable from environment, if -e. */
o_command, /* Variable given by user. */
o_override, /* Variable from an `override' directive. */
o_automatic, /* Automatic variable -- cannot be set. */
o_invalid /* Core dump time. */
};
/* Structure that represents one variable definition.
Each bucket of the hash table is a chain of these,
chained through `next'. */
struct variable
{
struct variable *next; /* Link in the chain. */
char *name; /* Variable name. */
char *value; /* Variable value. */
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. */
enum
{
v_export, /* Export this variable. */
v_noexport, /* Don't export this variable. */
v_ifset, /* Export it if it has a non-default value. */
v_default /* Decide in target_environment. */
} export ENUM_BITFIELD (2);
};
/* Structure that represents a variable set. */
struct variable_set
{
struct variable **table; /* Hash table of variables. */
unsigned int buckets; /* Number of hash buckets in `table'. */
};
/* Structure that represents a list of variable sets. */
struct variable_set_list
{
struct variable_set_list *next; /* Link in the chain. */
struct variable_set *set; /* Variable set. */
};
extern struct variable_set_list *current_variable_set_list;
extern void push_new_variable_scope (), pop_variable_scope ();
extern int handle_function ();
extern char *variable_buffer_output ();
extern char *variable_expand (), *variable_expand_for_file ();
extern char *allocated_variable_expand_for_file ();
#define allocated_variable_expand(line) \
allocated_variable_expand_for_file (line, (struct file *) 0)
extern char *expand_argument ();
extern void define_automatic_variables ();
extern void initialize_file_variables ();
extern void print_file_variables ();
extern void merge_variable_set_lists ();
extern struct variable *try_variable_definition ();
extern struct variable *lookup_variable (), *define_variable ();
extern struct variable *define_variable_for_file ();
extern int pattern_matches ();
extern char *subst_expand (), *patsubst_expand (), *recursively_expand ();
extern char **target_environment ();
extern int export_all_variables;

487
vpath.c Normal file
View File

@@ -0,0 +1,487 @@
/* Implementation of pattern-matching file search paths for GNU Make.
Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "make.h"
#include "file.h"
#include "variable.h"
/* Structure used to represent a selective VPATH searchpath. */
struct vpath
{
struct vpath *next; /* Pointer to next struct in the linked list. */
char *pattern; /* The pattern to match. */
char *percent; /* Pointer into `pattern' where the `%' is. */
unsigned int patlen;/* Length of the pattern. */
char **searchpath; /* Null-terminated list of directories. */
unsigned int maxlen;/* Maximum length of any entry in the list. */
};
/* Linked-list of all selective VPATHs. */
static struct vpath *vpaths;
/* Structure for the general VPATH given in the variable. */
static struct vpath *general_vpath;
static int selective_vpath_search ();
/* Reverse the chain of selective VPATH lists so they
will be searched in the order given in the makefiles
and construct the list from the VPATH variable. */
void
build_vpath_lists ()
{
register struct vpath *new = 0;
register struct vpath *old, *nexto;
register char *p;
/* Reverse the chain. */
for (old = vpaths; old != 0; old = nexto)
{
nexto = old->next;
old->next = new;
new = old;
}
vpaths = new;
/* If there is a VPATH variable with a nonnull value, construct the
general VPATH list from it. We use variable_expand rather than just
calling lookup_variable so that it will be recursively expanded. */
{
/* Turn off --warn-undefined-variables while we expand SHELL and IFS. */
int save = warn_undefined_variables_flag;
warn_undefined_variables_flag = 0;
p = variable_expand ("$(strip $(VPATH))");
warn_undefined_variables_flag = save;
}
if (*p != '\0')
{
/* Save the list of vpaths. */
struct vpath *save_vpaths = vpaths;
/* Empty `vpaths' so the new one will have no next, and `vpaths'
will still be nil if P contains no existing directories. */
vpaths = 0;
/* Parse P. */
construct_vpath_list ("%", p);
/* Store the created path as the general path,
and restore the old list of vpaths. */
general_vpath = vpaths;
vpaths = save_vpaths;
}
}
/* Construct the VPATH listing for the pattern and searchpath given.
This function is called to generate selective VPATH lists and also for
the general VPATH list (which is in fact just a selective VPATH that
is applied to everything). The returned pointer is either put in the
linked list of all selective VPATH lists or in the GENERAL_VPATH
variable.
If SEARCHPATH is nil, remove all previous listings with the same
pattern. If PATTERN is nil, remove all VPATH listings.
Existing and readable directories that are not "." given in the
searchpath separated by colons are loaded into the directory hash
table if they are not there already and put in the VPATH searchpath
for the given pattern with trailing slashes stripped off if present
(and if the directory is not the root, "/").
The length of the longest entry in the list is put in the structure as well.
The new entry will be at the head of the VPATHS chain. */
void
construct_vpath_list (pattern, dirpath)
char *pattern, *dirpath;
{
register unsigned int elem;
register char *p;
register char **vpath;
register unsigned int maxvpath;
unsigned int maxelem;
char *percent;
if (pattern != 0)
{
pattern = savestring (pattern, strlen (pattern));
percent = find_percent (pattern);
}
if (dirpath == 0)
{
/* Remove matching listings. */
register struct vpath *path, *lastpath;
lastpath = 0;
path = vpaths;
while (path != 0)
{
struct vpath *next = path->next;
if (pattern == 0
|| (((percent == 0 && path->percent == 0)
|| (percent - pattern == path->percent - path->pattern))
&& streq (pattern, path->pattern)))
{
/* Remove it from the linked list. */
if (lastpath == 0)
vpaths = path->next;
else
lastpath->next = next;
/* Free its unused storage. */
free (path->pattern);
free ((char *) path->searchpath);
free ((char *) path);
}
else
lastpath = path;
path = next;
}
if (pattern != 0)
free (pattern);
return;
}
/* Figure out the maximum number of VPATH entries and
put it in MAXELEM. We start with 2, one before the
first colon and one nil, the list terminator and
increment our estimated number for each colon or blank we find. */
maxelem = 2;
p = dirpath;
while (*p != '\0')
if (*p++ == PATH_SEPARATOR_CHAR || isblank (*p))
++maxelem;
vpath = (char **) xmalloc (maxelem * sizeof (char *));
maxvpath = 0;
/* Skip over any initial colons and blanks. */
p = dirpath;
while (*p == PATH_SEPARATOR_CHAR || isblank (*p))
++p;
elem = 0;
while (*p != '\0')
{
char *v;
unsigned int len;
/* Find the end of this entry. */
v = p;
while (*p != '\0' && *p != PATH_SEPARATOR_CHAR && !isblank (*p))
++p;
len = p - v;
/* Make sure there's no trailing slash,
but still allow "/" as a directory. */
if (len > 1 && p[-1] == '/')
--len;
if (len > 1 || *v != '.')
{
v = savestring (v, len);
/* Verify that the directory actually exists. */
if (dir_file_exists_p (v, ""))
{
/* It does. Put it in the list. */
vpath[elem++] = dir_name (v);
free (v);
if (len > maxvpath)
maxvpath = len;
}
else
/* The directory does not exist. Omit from the list. */
free (v);
}
/* Skip over colons and blanks between entries. */
while (*p == PATH_SEPARATOR_CHAR || isblank (*p))
++p;
}
if (elem > 0)
{
struct vpath *path;
/* ELEM is now incremented one element past the last
entry, to where the nil-pointer terminator goes.
Usually this is maxelem - 1. If not, shrink down. */
if (elem < (maxelem - 1))
vpath = (char **) xrealloc ((char *) vpath,
(elem + 1) * sizeof (char *));
/* Put the nil-pointer terminator on the end of the VPATH list. */
vpath[elem] = 0;
/* Construct the vpath structure and put it into the linked list. */
path = (struct vpath *) xmalloc (sizeof (struct vpath));
path->searchpath = vpath;
path->maxlen = maxvpath;
path->next = vpaths;
vpaths = path;
/* Set up the members. */
path->pattern = pattern;
path->percent = percent;
path->patlen = strlen (pattern);
}
else
{
/* There were no entries, so free whatever space we allocated. */
free ((char *) vpath);
if (pattern != 0)
free (pattern);
}
}
/* Search the VPATH list whose pattern matches *FILE for a directory
where the name pointed to by FILE exists. If it is found, we set *FILE to
the newly malloc'd name of the existing file, *MTIME_PTR (if MTIME_PTR is
not NULL) to its modtime (or zero if no stat call was done), and return 1.
Otherwise we return 0. */
int
vpath_search (file, mtime_ptr)
char **file;
time_t *mtime_ptr;
{
register struct vpath *v;
/* If there are no VPATH entries or FILENAME starts at the root,
there is nothing we can do. */
if (**file == '/' || (vpaths == 0 && general_vpath == 0))
return 0;
for (v = vpaths; v != 0; v = v->next)
if (pattern_matches (v->pattern, v->percent, *file))
if (selective_vpath_search (v, file, mtime_ptr))
return 1;
if (general_vpath != 0
&& selective_vpath_search (general_vpath, file, mtime_ptr))
return 1;
return 0;
}
/* Search the given VPATH list for a directory where the name pointed
to by FILE exists. If it is found, we set *FILE to the newly malloc'd
name of the existing file, *MTIME_PTR (if MTIME_PTR is not NULL) to
its modtime (or zero if no stat call was done), and we return 1.
Otherwise we return 0. */
static int
selective_vpath_search (path, file, mtime_ptr)
struct vpath *path;
char **file;
time_t *mtime_ptr;
{
int not_target;
char *name, *n;
char *filename;
register char **vpath = path->searchpath;
unsigned int maxvpath = path->maxlen;
register unsigned int i;
unsigned int flen, vlen, name_dplen;
int exists = 0;
/* Find out if *FILE is a target.
If and only if it is NOT a target, we will accept prospective
files that don't exist but are mentioned in a makefile. */
{
struct file *f = lookup_file (*file);
not_target = f == 0 || !f->is_target;
}
flen = strlen (*file);
/* Split *FILE into a directory prefix and a name-within-directory.
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, '/');
name_dplen = n != 0 ? n - *file : 0;
filename = name_dplen > 0 ? n + 1 : *file;
if (name_dplen > 0)
flen -= name_dplen + 1;
/* Allocate enough space for the biggest VPATH entry,
a slash, the directory prefix that came with *FILE,
another slash (although this one may not always be
necessary), the filename, and a null terminator. */
name = (char *) alloca (maxvpath + 1 + name_dplen + 1 + flen + 1);
/* Try each VPATH entry. */
for (i = 0; vpath[i] != 0; ++i)
{
int exists_in_cache = 0;
n = name;
/* Put the next VPATH entry into NAME at N and increment N past it. */
vlen = strlen (vpath[i]);
bcopy (vpath[i], n, vlen);
n += vlen;
/* Add the directory prefix already in *FILE. */
if (name_dplen > 0)
{
*n++ = '/';
bcopy (*file, n, name_dplen);
n += name_dplen;
}
/* Now add the name-within-directory at the end of NAME. */
if (n != name && n[-1] != '/')
{
*n = '/';
bcopy (filename, n + 1, flen + 1);
}
else
bcopy (filename, n, flen + 1);
/* Check if the file is mentioned in a makefile. If *FILE is not
a target, that is enough for us to decide this file exists.
If *FILE is a target, then the file must be mentioned in the
makefile also as a target to be chosen.
The restriction that *FILE must not be a target for a
makefile-mentioned file to be chosen was added by an
inadequately commented change in July 1990; I am not sure off
hand what problem it fixes.
In December 1993 I loosened of this restriction to allow a file
to be chosen if it is mentioned as a target in a makefile. This
seem logical. */
{
struct file *f = lookup_file (name);
if (f != 0)
exists = not_target || f->is_target;
}
if (!exists)
{
/* That file wasn't mentioned in the makefile.
See if it actually exists. */
/* Clobber a null into the name at the last slash.
Now NAME is the name of the directory to look in. */
*n = '\0';
/* We know the directory is in the hash table now because either
construct_vpath_list or the code just above put it there.
Does the file we seek exist in it? */
exists_in_cache = exists = dir_file_exists_p (name, filename);
}
if (exists)
{
/* The file is in the directory cache.
Now check that it actually exists in the filesystem.
The cache may be out of date. When vpath thinks a file
exists, but stat fails for it, confusion results in the
higher levels. */
struct stat st;
/* Put the slash back in NAME. */
*n = '/';
if (!exists_in_cache /* Makefile-mentioned file need not exist. */
|| safe_stat (name, &st) == 0) /* Does it really exist? */
{
/* We have found a file.
Store the name we found into *FILE for the caller. */
*file = savestring (name, (n + 1 - name) + flen);
if (mtime_ptr != 0)
/* Store the modtime into *MTIME_PTR for the caller.
If we have had no need to stat the file here,
we record a zero modtime to indicate this. */
*mtime_ptr = exists_in_cache ? st.st_mtime : (time_t) 0;
return 1;
}
else
exists = 0;
}
}
return 0;
}
/* Print the data base of VPATH search paths. */
void
print_vpath_data_base ()
{
register unsigned int nvpaths;
register struct vpath *v;
puts ("\n# VPATH Search Paths\n");
nvpaths = 0;
for (v = vpaths; v != 0; v = v->next)
{
register unsigned int i;
++nvpaths;
printf ("vpath %s ", v->pattern);
for (i = 0; v->searchpath[i] != 0; ++i)
printf ("%s%c", v->searchpath[i],
v->searchpath[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR);
}
if (vpaths == 0)
puts ("# No `vpath' search paths.");
else
printf ("\n# %u `vpath' search paths.\n", nvpaths);
if (general_vpath == 0)
puts ("\n# No general (`VPATH' variable) search path.");
else
{
register char **path = general_vpath->searchpath;
register unsigned int i;
fputs ("\n# General (`VPATH' variable) search path:\n# ", stdout);
for (i = 0; path[i] != 0; ++i)
printf ("%s%c", path[i],
path[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR);
}
}