/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Copyright 2016 RackTop Systems.
*/
/*
* doname.c
*
* Figure out which targets are out of date and rebuild them
*/
/*
* Included files
*/
#include <alloca.h> /* alloca() */
#include <fcntl.h>
#include <poll.h>
#include <libintl.h>
#include <signal.h>
#include <stropts.h>
#include <unistd.h> /* close() */
/*
* Defined macros
*/
// Sleep for .1 seconds between stat()'s
/*
* typedefs & structs
*/
/*
* Static variables
*/
static int second_pass = 0;
/*
* File table of contents
*/
extern Doname doname_check(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic);
extern Doname doname(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic);
static Boolean check_dependencies(Doname *result, Property line, Boolean do_get, Name target, Name true_target, Boolean doing_subtree, Chain *out_of_date_tail, Property old_locals, Boolean implicit, Property *command, Name less, Boolean rechecking_target, Boolean recheck_conditionals);
static void check_read_state_file(void);
extern void reset_locals(register Name target, register Property old_locals, register Property conditional, register int index);
// From read2.cc
/*
* DONE.
*
* doname_check(target, do_get, implicit, automatic)
*
* Will call doname() and then inspect the return value
*
* Return value:
* Indication if the build failed or not
*
* Parameters:
* target The target to build
* do_get Passed thru to doname()
* implicit Passed thru to doname()
* automatic Are we building a hidden dependency?
*
* Global variables used:
* build_failed_seen Set if -k is on and error occurs
* continue_after_error Indicates that -k is on
* report_dependencies No error msg if -P is on
*/
doname_check(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic)
{
case build_ok:
second_pass = 0;
return build_ok;
case build_running:
second_pass = 0;
return build_running;
case build_failed:
if (!continue_after_error) {
}
build_failed_seen = true;
second_pass = 0;
return build_failed;
case build_dont_know:
/*
* If we can't figure out how to build an automatic
* (hidden) dependency, we just ignore it.
* We later declare the target to be out of date just in
* case something changed.
* Also, don't complain if just reporting the dependencies
* and not building anything.
*/
if (automatic || (report_dependencies_level > 0)) {
second_pass = 0;
return build_dont_know;
}
if(first_time) {
first_time = 0;
second_pass = 1;
goto try_again;
}
second_pass = 0;
if (continue_after_error && !svr4) {
build_failed_seen = true;
return build_failed;
}
break;
}
#ifdef lint
return build_failed;
#endif
}
void
{
dependency != NULL;
}
}
}
{
Dyntarget p;
int i;
i = 0;
if(i > 0) {
return(target);
}
}
pp++;
i = 0;
continue;
}
i++;
pp++;
if(i > 0) {
return(target);
}
}
break;
}
}
}
return(NULL);
}
/*
* DONE.
*
* doname(target, do_get, implicit)
*
* Chases all files the target depends on and builds any that
* are out of date. If the target is out of date it is then rebuilt.
*
* Return value:
* Indiates if build failed or nt
*
* Parameters:
* target Target to build
* do_get Run sccs get is nessecary
* implicit doname is trying to find an implicit rule
*
* Global variables used:
* assign_done True if command line assgnment has happened
* commands_done Preserved for the case that we need local value
* debug_level Should we trace make's actions?
* default_rule The rule for ".DEFAULT", used as last resort
* empty_name The Name "", used when looking for single sfx
* keep_state Indicates that .KEEP_STATE is on
* parallel True if building in parallel
* recursion_level Used for tracing
* report_dependencies make -P is on
*/
doname(register Name target, register Boolean do_get, register Boolean implicit, register Boolean automatic)
{
register int auto_count;
return build_running;
}
/*
* If this target is a member of target group and one of the
* other members of the group is running, mark this target
* as running.
*/
target_group != NULL;
false);
return build_running;
}
}
}
/*
* If the target is a constructed one for a "::" target,
* we need to consider that.
*/
if (target->has_target_prop) {
if (true_target->colon_splits > 0) {
/* Make sure we have a valid time for :: targets */
}
}
}
(void) exists(true_target);
/*
* If the target has been processed, we don't need to do it again,
* unless it depends on conditional macros or a delayed assignment,
* or it has been done when KEEP_STATE is on.
*/
return build_ok;
} else {
recheck_conditionals = true;
}
}
/* A dynamic macro subtree is being built */
doing_subtree = true;
if (!target->checking_subtree) {
/*
* This target has been started before and therefore
* not all dependencies have to be built.
*/
restart = true;
}
restart = true;
/*
} else if (parallel &&
keep_state &&
(target->conditional_cnt > 0)) {
if (!parallel_ok(target, false)) {
add_subtree(target, recursion_level, do_get, implicit);
target->state = build_running;
return build_running;
}
*/
}
/*
* If KEEP_STATE is on, we have to rebuild the target if the
* building of it caused new automatic dependencies to be reported.
* This is where we restart the build.
*/
}
/* Init all local variables */
auto_count = 0;
/*
* If this target has never been built before, mark all
* of the dependencies as never built.
*/
dependency != NULL;
dependency->built = false;
}
}
/* Save the set of automatic depes defined for this target */
if (keep_state &&
Name *p;
/*
* First run thru the dependency list to see how many
* autos there are.
*/
dependency != NULL;
auto_count++;
}
}
/* Create vector to hold the current autos */
/* Copy them */
dependency != NULL;
*p++ = dependency->name;
}
}
}
if (debug_level > 1) {
(void) printf("%*sdoname(%s)\n",
"",
}
/* Avoid infinite loops */
return build_ok;
}
/* Activate conditional macros for the target */
if (!target->added_pattern_conditionals) {
target->added_pattern_conditionals = true;
}
if (target->conditional_cnt > 0) {
sizeof (Property_rec));
}
/*
* after making the call to dynamic_dependecies unconditional we can handle
* target names that are same as file name. In this case $$@ in the
* dependencies did not mean anything. WIth this change it expands it
* as expected.
*/
if (!target->has_depe_list_expanded)
{
}
/*
* FIRST SECTION -- GO THROUGH DEPENDENCIES AND COLLECT EXPLICIT
* COMMANDS TO RUN
*/
if (check_dependencies(&result,
line,
&command,
less,
return build_running;
}
}
}
/*
* If the target is a :: type, do not try to find the rule for the target,
* all actions will be taken by separate branches.
* Else, we try to find an implicit rule using various methods,
* we quit as soon as one is found.
*
* [tolik, 12 Sep 2002] Do not try to find implicit rule for the target
* being rechecked - the target is being rechecked means that it already
* has explicit dependencies derived from an implicit rule found
* in previous step.
*/
/* Look for percent matched rule */
if ((result == build_dont_know) &&
switch (find_percent_rule(
&command,
case build_failed:
break;
case build_running:
false);
if (target->conditional_cnt > 0) {
0);
}
return build_running;
case build_ok:
break;
}
}
/* Look for double suffix rule */
if (result == build_dont_know) {
NULL)) {
switch (find_ar_suffix_rule(target,
&command,
case build_failed:
break;
case build_running:
false);
if (target->conditional_cnt > 0) {
0);
}
return build_running;
default:
/* ALWAYS bind $% for old style */
/* ar rules */
line =
}
break;
}
} else {
switch (find_double_suffix_rule(target,
&command,
case build_failed:
break;
case build_running:
false);
if (target->conditional_cnt > 0) {
prop,
0);
}
return build_running;
}
}
}
/* Look for single suffix rule */
/* /tolik/
* I commented !implicit to fix bug 1247448: Suffix Rules failed when combine with Pattern Matching Rules.
* This caused problem with SVR4 tilde rules (infinite recursion). So I made some changes in "implicit.cc"
*/
/* /tolik, 06.21.96/
* Regression! See BugId 1255360
* If more than one percent rules are defined for the same target then
* the behaviour of 'make' with my previous fix may be different from one
* of the 'old make'.
* The global variable second_pass (maybe it should be an argument to doname())
* is intended to avoid this regression. It is set in doname_check().
* First, 'make' will work as it worked before. Only when it is
* going to say "don't know how to make target" it sets second_pass to true and
* run 'doname' again but now trying to use Single Suffix Rules.
*/
switch (find_suffix_rule(target,
&command,
case build_failed:
break;
case build_running:
false);
if (target->conditional_cnt > 0) {
0);
}
return build_running;
}
}
/* Try to sccs get */
(result == build_dont_know) &&
do_get) {
}
/* Use .DEFAULT rule if it is defined. */
(result == build_dont_know) &&
default_rule &&
!implicit) {
/* Make sure we have a line prop */
if (true_target->is_member) {
} else {
}
if (build_unconditional || out_of_date) {
if (debug_level > 0) {
"",
}
}
}
}
/* We say "target up to date" if no cmd were executed for the target */
if (!target->is_double_colon_parent) {
commands_done = false;
}
silent = silent_all;
if (posix)
{
if (!silent)
{
}
if (!ignore_errors)
{
}
}
int doname_dyntarget = 0;
/* Run commands if any. */
if (result != build_failed) {
}
switch (result) {
case build_running:
implicit);
}
}
if (target->conditional_cnt > 0) {
0);
}
return build_running;
case build_serial:
implicit);
}
}
if (target->conditional_cnt > 0) {
0);
}
return build_running;
case build_ok:
/* If all went OK set a nice timestamp */
}
break;
}
} else {
/*
* If no command was found for the target, and it doesn't
* exist, and it is mentioned as a target in the makefile,
* we say it is extremely new and that it is OK.
*/
}
}
/*
* Trying dynamic targets.
*/
if(!doname_dyntarget) {
doname_dyntarget = 1;
if (!target->has_depe_list_expanded) {
}
if (check_dependencies(&result,
line,
&command,
less,
{
return build_running;
}
}
}
goto r_command;
}
}
/*
* If the file exists, it is OK that we couldnt figure
* out how to build it.
*/
(result == build_dont_know)) {
}
}
/*
* Some of the following is duplicated in the function finish_doname.
* If anything is changed here, check to see if it needs to be
* changed there.
*/
}
}
if (target->conditional_cnt > 0) {
0);
}
/* Propagate the timestamp from the member file to the member*/
}
}
/*
* Check if we found any new auto dependencies when we
* built the target.
*/
automatics)) {
if (debug_level > 0) {
(void) printf(gettext("%*sTarget `%s' acquired new dependencies from build, rechecking all dependencies\n"),
"",
}
rechecking_target = true;
goto recheck_target;
}
if (rechecking_target && !commands_done) {
}
return result;
}
/*
* DONE.
*
* check_dependencies(result, line, do_get,
* target, true_target, doing_subtree, out_of_date_tail,
* old_locals, implicit, command, less, rechecking_target)
*
* Return value:
* True returned if some dependencies left running
*
* Parameters:
* result Pointer to cell we update if build failed
* line We get the dependencies from here
* do_get Allow use of sccs get in recursive doname()
* target The target to chase dependencies for
* true_target The real one for :: and lib(member)
* doing_subtree True if building a conditional macro subtree
* out_of_date_tail Used to set the $? list
* old_locals Used for resetting the local macros
* implicit Called when scanning for implicit rules?
* command Place to stuff command
* less Set to $< value
*
* Global variables used:
* command_changed Set if we suspect .make.state needs rewrite
* debug_level Should we trace actions?
* force The Name " FORCE", compared against
* recursion_level Used for tracing
* rewrite_statefile Set if .make.state needs rewriting
* wait_name The Name ".WAIT", compared against
*/
static Boolean
check_dependencies(Doname *result, Property line, Boolean do_get, Name target, Name true_target, Boolean doing_subtree, Chain *out_of_date_tail, Property old_locals, Boolean implicit, Property *command, Name less, Boolean rechecking_target, Boolean recheck_conditionals)
{
}
dependencies_running = false;
/*
* Run thru all the dependencies and call doname() recursively
* on each of them.
*/
dependency != NULL;
if (!dependency->automatic &&
/*
* We only bother with the autos when rechecking
*/
continue;
}
/*
* The special target .WAIT means finish all of
* the prior dependencies before continuing.
*/
if (dependencies_running) {
break;
}
(dependencies_running)) {
/*
* If we can't execute the current dependency in
* parallel, hold off the dependency processing
* to preserve the order of the dependencies.
*/
break;
} else {
if (true_target->is_member) {
}
if (dependency->built ||
} else {
false,
}
/* should compare only secs, cause lib members does not have nsec time resolution */
true;
}
} else {
true;
}
}
dependency->built = true;
switch (dep_result) {
case build_running:
dependencies_running = true;
continue;
case build_failed:
*result = build_failed;
break;
case build_dont_know:
/*
* If make can't figure out how to make a dependency, maybe the dependency
* is out of date. In this case, we just declare the target out of date
* and go on. If we really need the dependency, the make'ing of the target
* will fail. This will only happen for automatic (hidden) dependencies.
*/
if(!recheck_conditionals) {
}
/*
* Make sure the dependency is not saved
* in the state file.
*/
dependency->stale = true;
true;
if (debug_level > 0) {
}
break;
}
target->depends_on_conditional = true;
}
}
/*
* Propagate new timestamp from "member" to
* "lib.a(member)".
*/
/* Collect the timestamp of the youngest dependency */
/* Correction: do not consider nanosecs for members */
}
if (debug_level > 1) {
"",
"",
}
}
/* Build the $? list */
if (true_target->is_member) {
if (this_dependency_changed == true) {
} else {
/* Dina:
* The next statement is commented
* out as a fix for bug #1051032.
* if dependency hasn't changed
* then there's no need to invalidate
* true_target. This statemnt causes
* make to take much longer to process
* an already-built archive. Soren
* said it was a quick fix for some
* problem he doesn't remember.
true_target->stat.time = file_no_time;
*/
(void) exists(true_target);
}
} else {
(void) exists(true_target);
}
} else {
}
if ((build_unconditional || out_of_date) &&
(dependency->stale == false)) {
member_prop) != NULL)) {
(*out_of_date_tail)->name =
member_prop)->
} else {
(*out_of_date_tail)->name =
}
if (debug_level > 0) {
"",
} else {
"",
}
}
}
}
}
}
if (dependencies_running) {
if (doing_subtree) {
if (target->conditional_cnt > 0) {
0);
}
return true;
} else {
false);
if (target->conditional_cnt > 0) {
0);
}
return true;
}
}
/*
* Collect the timestamp of the youngest double colon target
* dependency.
*/
if (target->is_double_colon_parent) {
dependency != NULL;
}
}
}
}
}
/*
* After scanning all the dependencies, we check the rule
* if we found one.
*/
}
/* Check if the target is out of date */
if (true_target->is_member) {
} else {
}
if (build_unconditional || out_of_date){
if(!recheck_conditionals) {
}
}
if(gnu_style) {
// set $< for explicit rule
}
// set $* for explicit rule
register wchar_t *target_end;
register int suffix_length;
if (true_target->is_member &&
NULL)) {
}
continue;
(target_end - suffix_length),
suffix_length)) {
continue;
}
);
}
// set result = build_ok so that implicit rules are not used.
if(*result == build_dont_know) {
}
}
}
}
return false;
}
/*
* dynamic_dependencies(target)
*
* Checks if any dependency contains a macro ref
* If so, it replaces the dependency with the expanded version.
* Here, "$@" gets translated to target->string. That is
* the current name on the left of the colon in the
* makefile. Thus,
* xyz: s.$@.c
* translates into
* xyz: s.xyz.c
*
* Also, "$(@F)" translates to the same thing without a preceeding
* directory path (if one exists).
* Note, to enter "$@" on a dependency line in a makefile
* "$$@" must be typed. This is because make expands
* macros in dependency lists upon reading them.
* dynamic_dependencies() also expands file wildcards.
* If there are any Shell meta characters in the name,
* search the directory, and replace the dependency
* with the set of files the pattern matches
*
* Parameters:
* target Target to sanitize dependencies for
*
* Global variables used:
* c_at The Name "@", used to set macro value
* debug_level Should we trace actions?
* dot The Name ".", used to read directory
* recursion_level Used for tracing
*/
void
{
register wchar_t *p;
register wchar_t *start;
wchar_t *library;
return;
}
/* If the target is constructed from a "::" target we consider that */
if (target->has_target_prop) {
}
/* Scan all dependencies and process the ones that contain "$" chars */
dependency != NULL;
continue;
}
target->has_depe_list_expanded = true;
/* The make macro $@ is bound to the target name once per */
/* invocation of dynamic_dependencies() */
if (!set_at) {
set_at = true;
}
/* Expand this dependency string */
/* Scan the expanded string. It could contain whitespace */
/* which mean it expands to several dependencies */
start++;
}
/* Remove the cell (later) if the macro was empty */
}
/* azv 10/26/95 to fix bug BID_1170218 */
if ((start[0] == (int) period_char) &&
start += 2;
}
/* azv */
first_member = NULL;
/* We use the original dependency cell for the first */
/* dependency from the expansion */
reuse_cell = true;
/* We also have to deal with dependencies that expand to */
/* lib.a(members) notation */
if ((*p == (int) parenleft_char)) {
start = p + 1;
start++;
}
break;
}
}
do {
/* First skip whitespace */
if ((*p == (int) nul_char) ||
iswspace(*p) ||
(*p == (int) parenright_char)) {
break;
}
}
/* Enter dependency from expansion */
if (p != start) {
/* Create new dependency cell if */
/* this is not the first dependency */
/* picked from the expansion */
if (!reuse_cell) {
}
reuse_cell = false;
/* Internalize the dependency name */
// tolik. Fix for bug 4110429: inconsistent expansion for macros that
// include "//" and "/./"
//dependency->name = GETNAME(start, p - start);
if ((debug_level > 0) &&
(first_member == NULL)) {
"",
}
p = start;
}
} while ((*p != (int) nul_char) &&
(*p != (int) parenright_char));
/* If the expansion was of lib.a(members) format we now */
/* enter the proper member cells */
if (first_member != NULL) {
/* Scan the new dependencies and transform them from */
/* "foo" to "lib.a(foo)" */
/* Build "lib.a(foo)" name */
&string,
&string,
/* Replace "foo" with "lib.a(foo)" */
first_member->name =
if (string.free_after_use) {
}
if (debug_level > 0) {
"",
first_member->name->
}
/* Add member property to member */
if (first_member == dependency) {
break;
}
}
}
}
/* Then scan all the dependencies again. This time we want to expand */
/* shell file wildcards */
dependency != NULL;
dependency = *remove) {
continue;
}
/* If dependency name string contains shell wildcards */
/* replace the name with the expansion */
(int) parenleft_char)) != NULL) {
/* lib(*) type pattern */
wcb.get_string(),
(int) nul_char;
start + 1,
(int) nul_char;
} else {
wcb.get_string(),
(int) nul_char;
}
p = pattern;
} else {
p = start+1;
}
/* The expansion is handled by the read_dir() routine*/
} else {
}
} else {
}
}
/* Then unbind $@ */
}
/*
* DONE.
*
* run_command(line)
*
* Takes one Cmd_line and runs the commands from it.
*
* Return value:
* Indicates if the command failed or not
*
* Parameters:
* line The command line to run
*
* Global variables used:
* commands_done Set if we do run command
* current_line Set to the line we run a command from
* current_target Set to the target we run a command for
* file_number Used to form temp file name
* keep_state Indicates that .KEEP_STATE is on
* make_state The Name ".make.state", used to check timestamp
* parallel True if currently building in parallel
* parallel_process_cnt Count of parallel processes running
* quest Indicates that make -q is on
* rewrite_statefile Set if we do run a command
* sunpro_dependencies The Name "SUNPRO_DEPENDENCIES", set value
* temp_file_directory Used to form temp fie name
* temp_file_name Set to the name of the temp file
* touch Indicates that make -t is on
*/
static Doname
{
wchar_t *string;
target->rechecking_target = false;
return build_ok;
}
/*
* Build the command if we know the target is out of date,
* or if we want to check cmd consistency.
*/
/* Hack for handling conditional macros in DMake. */
}
}
/* Never mind */
return build_ok;
}
/* If quest, then exit(1) because the target is out of date */
if (quest) {
if (posix) {
}
exit_status = 1;
exit(1);
}
/* We actually had to do something this time */
rewrite_statefile = commands_done = true;
/*
* If this is an sccs command, we have to do some extra checking
* and possibly complain. If the file can't be gotten because it's
* checked out, we complain and behave as if the command was
* executed eventhough we ignored the command.
*/
if (!touch &&
}
/*
* If KEEP_STATE is on, we make sure we have the timestamp for
* we reread .make.state after the command. We also setup the
* environment variable that asks utilities to report dependencies.
*/
if (!touch &&
keep_state &&
!remember_only) {
(void) exists(make_state);
(temp_file_directory[0] == '/')) {
tmp_file_path[0] = '\0';
} else {
}
"%s/.make.dependency.%08x.%d.%d",
getpid(),
file_number++);
if (*from == (int) space_char) {
*to++ = (int) backslash_char;
}
}
*to++ = (int) space_char;
(void) SETVAR(sunpro_dependencies,
false);
} else {
}
/*
* In case we are interrupted, we need to know what was going on.
*/
/*
* We also need to be able to save an empty command instead of the
* interrupted one in .make.state.
*/
current_line = line;
if (remember_only) {
/* Empty block!!! */
} else if (touch) {
if (posix) {
}
} else {
/*
* If this is not a touch run, we need to execute the
* proper command(s) for the target.
*/
if (parallel) {
if (!parallel_ok(target, true)) {
/*
* We are building in parallel, but
* this target must be built in serial.
*/
/*
* If nothing else is building,
* do this one, else wait.
*/
if (parallel_process_cnt == 0) {
} else {
current_line = NULL;
/*
line->body.line.command_used = NULL;
*/
return build_serial;
}
} else {
switch (result) {
case build_running:
return build_running;
case build_serial:
if (parallel_process_cnt == 0) {
} else {
current_line = NULL;
NULL;
return build_serial;
}
}
}
} else {
}
}
if (report_dependencies_level == 0){
}
current_line = NULL;
return result;
}
/*
* execute_serial(line)
*
* Runs thru the command line for the target and
* executes the rules one by one.
*
* Return value:
* The result of the command build
*
* Parameters:
* line The command to execute
*
* Static variables used:
*
* Global variables used:
* continue_after_error -k flag
* do_not_exec_rule -n flag
* report_dependencies -P flag
* silent Don't echo commands before executing
* temp_file_name Temp file for auto dependencies
* vpath_defined If true, translate path for command
*/
{
int child_pid = 0;
int filed;
target->has_recursive_dependency = false;
// We have to create a copy of the rules chain for processing because
// the original one can be destroyed during .make.state file rereading.
} else {
}
}
if (command) {
}
continue;
}
if (vpath_defined) {
rule->command_line =
}
/* Echo command line, maybe. */
!silent &&
(report_dependencies_level == 0)) {
}
/* Do assignment if command line prefixed with "=" */
} else if (report_dependencies_level == 0) {
/* Execute command line. */
/* ds 98.04.23 bug #4085164. make should always show error messages */
false,
/* BOOLEAN(rule->silent &&
rule->ignore_error), */
target);
}
} else {
}
if (result == build_failed) {
}
if (!continue_after_error) {
}
/*
* Make sure a failing command is not
* saved in .make.state.
*/
break;
} else {
}
}
}
}
if (temp_file_name != NULL) {
}
}
}
if(spro) {
/*
* Do not return memory allocated for SUNPRO_DEPENDENCIES
* It will be returned in setvar_daemon() in macro.cc
*/
// retmem_mb(val);
}
}
return result;
}
/*
* vpath_translation(cmd)
*
* Translates one command line by
* checking each word. If the word has an alias it is translated.
*
* Return value:
* The translated command
*
* Parameters:
* cmd Command to translate
*
* Global variables used:
*/
{
wchar_t *p;
wchar_t *start;
return cmd;
}
p = wcb.get_string();
while (*p != (int) nul_char) {
append_char(*p++, &new_cmd);
}
start = p;
p++;
}
if (cmd->has_vpath_alias_prop) {
&new_cmd,
} else {
}
}
if (new_cmd.free_after_use) {
}
return cmd;
}
/*
* check_state(temp_file_name)
*
* Reads and checks the state changed by the previously executed command.
*
* Parameters:
* temp_file_name The auto dependency temp file
*
* Global variables used:
*/
void
{
if (!keep_state) {
return;
}
/*
* Then read the temp file that now might
* contain dependency reports from utilities
*/
/*
* And reread .make.state if it
* changed (the command ran recursive makes)
*/
if (temp_file_name != NULL) {
}
}
/*
* read_dependency_file(filename)
*
* Read the temp file used for reporting dependencies to make
*
* Parameters:
* filename The name of the file with the state info
*
* Global variables used:
* makefile_type The type of makefile being read
* read_trace_level Debug flag
* temp_file_number The always increasing number for unique files
* trace_reader Debug flag
*/
static void
{
return;
}
if (read_trace_level > 1) {
trace_reader = true;
}
(void) read_simple_file(filename,
false,
false,
false,
false,
false,
false);
trace_reader = false;
}
}
/*
* check_read_state_file()
*
* Check if .make.state has changed
* If it has we reread it
*
* Parameters:
*
* Global variables used:
* make_state Make state file name
* makefile_type Type of makefile being read
* read_trace_level Debug flag
* trace_reader Debug flag
*/
static void
check_read_state_file(void)
{
return;
}
/* Make sure we clear the old cached contents of .make.state */
}
if (read_trace_level > 1) {
trace_reader = true;
}
(void) read_simple_file(make_state,
false,
false,
false,
false,
false,
true);
trace_reader = false;
}
/*
* do_assign(line, target)
*
* Handles runtime assignments for command lines prefixed with "=".
*
* Parameters:
* line The command that contains an assignment
* target The Name of the target, used for error reports
*
* Global variables used:
* assign_done Set to indicate doname needs to reprocess
*/
static void
{
register wchar_t *equal;
/*
* If any runtime assignments are done, doname() must reprocess all
* targets in the future since the macro values used to build the
* command lines for the targets might have changed.
*/
assign_done = true;
/* Skip white space. */
string++;
}
/* Find "+=" or "=". */
(*equal != (int) equal_char)) {
equal++;
}
/* Internalize macro name. */
/* Skip over "+=" "=". */
(*equal == (int) equal_char) ||
equal++;
}
switch (*equal) {
case nul_char:
case plus_char:
append = true;
equal++;
break;
}
equal++;
/* Skip over whitespace in front of value. */
equal++;
}
/* Enter new macro value. */
append);
}
/*
* build_command_strings(target, line)
*
* Builds the command string to used when
* building a target. If the string is different from the previous one
* is_out_of_date is set.
*
* Parameters:
* target Target to build commands for
* line Where to stuff result
*
* Global variables used:
* c_at The Name "@", used to set macro value
* command_changed Set if command is different from old
* debug_level Should we trace activities?
* do_not_exec_rule Always echo when running -n
* empty_name The Name "", used for empty rule
* funny Semantics of characters
* ignore_errors Used to init field for line
* is_conditional Set to false befor evaling macro, checked
* after expanding macros
* keep_state Indicates that .KEEP_STATE is on
* make_word_mentioned Set by macro eval, inits field for cmd
* query The Name "?", used to set macro value
* query_mentioned Set by macro eval, inits field for cmd
* recursion_level Used for tracing
* silent Used to init field for line
*/
static void
{
wchar_t *start;
}
/* We have to check if a target depends on conditional macros */
/* Targets that do must be reprocessed by doname() each time around */
/* since the macro values used when building the target might have */
/* changed */
conditional_macro_used = false;
/* If we are building a lib.a(member) target $@ should be bound */
/* to lib.a */
}
/* If we are building a "::" help target $@ should be bound to */
/* the real target name */
/* A lib.a(member) target is never :: */
if (target->has_target_prop) {
}
/* Bind the magic macros that make supplies */
if (tmp_name->has_vpath_alias_prop) {
}
}
if (tmp_name->has_vpath_alias_prop) {
}
}
if (tmp_name->has_vpath_alias_prop) {
}
}
if (tmp_name->has_vpath_alias_prop) {
}
}
/* $? is seldom used and it is expensive to build */
/* so we store the list form and build the string on demand */
(*query_list_tail)->name =
}
}
(void) setvar_daemon(query,
(Name) query_list,
false,
false,
/* build $^ */
dependency != NULL;
/* skip automatic dependencies */
if (!dependency->automatic) {
(dependency->stale == false)) {
(*hat_list_tail)->name =
} else {
}
(*hat_list_tail)->name =
}
}
}
}
}
(void) setvar_daemon(hat,
false,
false,
/* We have two command sequences we need to handle */
/* The old one that we probably read from .make.state */
/* and the new one we are building that will replace the old one */
/* Even when KEEP_STATE is not on we build a new command sequence and store */
/* it in the line prop. This command sequence is then executed by */
/* run_command(). If KEEP_STATE is on it is also later written to */
/* .make.state. The routine replaces the old command line by line with the */
/* new one trying to reuse Cmd_lines */
/* If there is no old command_used we have to start creating */
/* Cmd_lines to keep the new cmd in */
new_command_longer = true;
}
/* Run thru the template for the new command and build the expanded */
/* new command lines */
for (;
command_template != NULL;
/* If there is no old command_used Cmd_line we need to */
/* create one and say that cmd consistency failed */
new_command_longer = true;
}
/* Prepare the Cmd_line for the processing */
/* The command line prefixes "@-=?" are stripped and that */
/* information is saved in the Cmd_line */
used->always_exec = false;
/* Expand the macros in the command line */
false;
/* If the macro $(MAKE) is mentioned in the command */
/* "make -n" runs actually execute the command */
/* Strip the prefixes */
for (;
start++) {
switch (*start) {
case question_char:
used->ignore_command_dependency = true;
break;
case exclam_char:
used->ignore_command_dependency = false;
break;
case equal_char:
break;
case hyphen_char:
used->ignore_error = true;
break;
case at_char:
if (!do_not_exec_rule) {
}
break;
case plus_char:
if(posix) {
used->always_exec = true;
}
break;
}
}
/* If all command lines of the template are prefixed with "?"*/
/* the VIRTUAL_ROOT is not used for cmd consistency checks */
if (!used->ignore_command_dependency) {
ignore_all_command_dependency = false;
}
/* Internalize the expanded and stripped command line */
new_command_longer = false;
}
/* Compare it with the old one for command consistency */
if (keep_state &&
if (debug_level > 0) {
'\0') {
"",
"",
used->
} else {
(void) printf(gettext("%*sBuilding %s because new command \n\t%s\n%*sdifferent from empty old command\n"),
"",
"");
}
}
command_changed = true;
}
}
if (command_line.free_after_use) {
}
}
/* Check if the old command is longer than the new for */
/* command consistency */
if (keep_state &&
if (debug_level > 0) {
"",
}
command_changed = true;
}
}
/* Check if the new command is longer than the old command for */
/* command consistency */
if (new_command_longer &&
keep_state) {
if (debug_level > 0) {
"",
}
command_changed = true;
}
/* Unbind the magic macros */
if (query_list != NULL) {
}
}
if (conditional_macro_used) {
target->depends_on_conditional = true;
}
}
/*
* touch_command(line, target, result)
*
* If this is an "make -t" run we do this.
* We touch all targets in the target group ("foo + fie:") if any.
*
* Return value:
* Indicates if the command failed or not
*
* Parameters:
* line The command line to update
* target The target we are touching
* result Initial value for the result we return
*
* Global variables used:
* do_not_exec_rule Indicates that -n is on
* silent Do not echo commands
*/
static Doname
{
/*
* Build a touch command that can be passed
* to dosys(). If KEEP_STATE is on, "make -t"
* will save the proper command, not the
* "touch" in .make.state.
*/
if (name->has_vpath_alias_prop) {
}
if (touch_string.free_after_use) {
}
if (!silent ||
(target_group == NULL)) {
}
/* Run the touch command, or simulate it */
if (!do_not_exec_rule) {
false,
false,
false,
false,
name);
} else {
}
} else {
}
if (target_group == NULL) {
} else {
}
if (target_group != NULL) {
} else {
}
}
return result;
}
/*
* update_target(line, result)
*
* updates the status of a target after executing its commands.
*
* Parameters:
* line The command line block to update
* result Indicates that build is OK so can update
*
* Global variables used:
* do_not_exec_rule Indicates that -n is on
* touch Fake the new timestamp if we are just touching
*/
void
{
/*
* [tolik] Additional fix for bug 1063790. It was fixed
* for serial make long ago, but DMake dumps core when
* target is a symlink and sccs file is newer then target.
* In this case, finish_children() calls update_target()
* with line==NULL.
*/
/* XXX. Should we do anything here? */
return;
}
if (do_not_exec_rule ||
touch ||
/* If we are simulating execution we need to fake a */
/* new timestamp for the target we didnt build */
} else {
/*
* If we really built the target we read the new
* timestamp.
* Fix for bug #1110906: if .c file is newer than
* the corresponding .o file which is in an archive
* file, make will compile the .c file but it won't
* update the object in the .a file.
*/
}
}
}
/* If the target is part of a group we need to propagate the */
/* result of the run to all members */
target_group != NULL;
}
}
}
/*
* sccs_get(target, command)
*
* Figures out if it possible to sccs get a file
* and builds the command to do it if it is.
*
* Return value:
* Indicates if sccs get failed or not
*
* Parameters:
* target Target to get
* command Where to deposit command to use
*
* Global variables used:
* debug_level Should we trace activities?
* recursion_level Used for tracing
* sccs_get_rule The rule to used for sccs getting
*/
static Doname
{
register int result;
register wchar_t *p;
int sym_link_depth = 0;
/* For sccs, we need to chase symlinks. */
if (sym_link_depth++ > 90) {
fatal(gettext("Can't read symbolic link `%s': Number of symbolic links encountered during path name traversal exceeds 90."),
}
/* Read the value of the link. */
link,
sizeof(link),
NULL,
if (result == -1) {
}
/* Use the value to build the proper filename. */
if ((link[0] != slash_char) &&
}
/* Replace the old name with the translated name. */
if (string.free_after_use) {
}
}
/*
* read_dir() also reads the ?/SCCS dir and saves information
* about which files have SCSC/s. files.
*/
}
case DONT_KNOW_SCCS:
/* We dont know by now there is no SCCS/s.* */
case NO_SCCS:
/*
* If there is no SCCS/s.* but the plain file exists,
* we say things are OK.
*/
return build_ok;
}
/* If we cant find the plain file, we give up. */
return build_dont_know;
case HAS_SCCS:
/*
* Pay dirt. We now need to figure out if the plain file
* is out of date relative to the SCCS/s.* file.
*/
break;
}
if ((!target->has_complained &&
(sccs_time != file_doesnt_exist) &&
(sccs_get_rule != NULL))) {
/* only checking */
return build_ok;
}
/*
* We provide a command line for the target. The line is a
* "sccs get" command from default.mk.
*/
/*
* And only if the plain file is out of date do we
* request execution of the command.
*/
if (debug_level > 0) {
"",
}
}
}
}
}
/*
* Also make sure the rule is build with $* and $<
* bound properly.
*/
return build_ok;
}
return build_dont_know;
}
/*
* read_directory_of_file(file)
*
* Reads the directory the specified file lives in.
*
* Parameters:
* file The file we need to read dir for
*
* Global variables used:
* dot The Name ".", used as the default dir
*/
void
{
(int) slash_char);
if (usr_include == NULL) {
}
/*
* If the filename contains a "/" we have to extract the path
* Else the path defaults to ".".
*/
if (p != NULL) {
/*
* Check some popular directories first to possibly
* save time. Compare string length first to gain speed.
*/
wcb,
length)) {
wcb,
length)) {
} else {
}
}
(wchar_t *) NULL,
(wchar_t *) NULL);
}
/*
* add_pattern_conditionals(target)
*
* Scan the list of conditionals defined for pattern targets and add any
* that match this target to its list of conditionals.
*
* Parameters:
* target The target we should add conditionals for
*
* Global variables used:
* conditionals The list of pattern conditionals
*/
static void
{
wchar_t *pattern;
wchar_t *percent;
int length;
conditional != NULL;
if (pattern[1] != 0) {
/* Check for possible buffer under-read */
continue;
}
continue;
}
}
break;
}
}
} else {
}
}
}
/*
* set_locals(target, old_locals)
*
* Sets any conditional macros for the target.
* Each target carries a possibly empty set of conditional properties.
*
* Parameters:
* target The target to set conditional macros for
* old_locals Space to store old values in
*
* Global variables used:
* debug_level Should we trace activity?
* is_conditional We need to preserve this value
* recursion_level Used for tracing
*/
void
{
register int i;
if (target->dont_activate_cond_values) {
return;
}
/* Scan the list of conditional properties and apply each one */
conditional != NULL;
i++) {
/* Save the old value */
if (debug_level > 1) {
"");
}
/* Set the conditional value. Macros are expanded when the */
/* macro is refd as usual */
}
}
/* Put this target on the front of the chain of conditional targets */
}
/*
* reset_locals(target, old_locals, conditional, index)
*
* Removes any conditional macros for the target.
*
* Parameters:
* target The target we are retoring values for
* old_locals The values to restore
* conditional The first conditional block for the target
* index into the old_locals vector
* Global variables used:
* debug_level Should we trace activities?
* recursion_level Used for tracing
*/
void
reset_locals(register Name target, register Property old_locals, register Property conditional, register int index)
{
if (target->dont_activate_cond_values) {
return;
}
/* Scan the list of conditional properties and restore the old value */
/* to each one Reverse the order relative to when we assigned macros */
if (this_conditional != NULL) {
} else {
/* Remove conditional target from chain */
if (conditional_targets == NULL ||
} else {
}
}
}
if (debug_level > 1) {
"",
} else {
"",
}
}
}
/*
* check_auto_dependencies(target, auto_count, automatics)
*
* Returns true if the target now has a dependency
* it didn't previously have (saved on automatics).
*
* Return value:
* true if new dependency found
*
* Parameters:
* target Target we check
* auto_count Number of old automatic vars
* automatics Saved old automatics
*
* Global variables used:
* keep_state Indicates that .KEEP_STATE is on
*/
{
Name *p;
int n;
if (keep_state) {
return false;
}
/* Go thru new list of automatic depes */
dependency != NULL;
/* And make sure that each one existed before we */
/* built the target */
for (n = auto_count, p = automatics;
n > 0;
n--) {
if (*p++ == dependency->name) {
/* If we can find it on the */
/* saved list of autos we */
/* are OK */
goto not_new;
}
}
/* But if we scan over the old list */
/* of auto. without finding it it is */
/* new and we must check it */
return true;
}
not_new:;
}
return false;
} else {
return false;
}
}
// Recursively delete each of the Chain struct on the chain.
static void
{
return;
} else {
}
}
return(build_ok);
}
/*
* If the target is a constructed one for a "::" target,
* we need to consider that.
*/
if (target->has_target_prop) {
}
(void) exists(true_target);
return(build_running);
}
}
/* get line property for the target */
/* first check for explicit rule */
}
/* try to find pattern rule */
if (result == build_dont_know) {
}
/* try to find double suffix rule */
if (result == build_dont_know) {
} else {
}
} else {
}
}
/* try to find suffix rule */
}
/* check for sccs */
if (result == build_dont_know) {
}
/* try to find dyn target */
if (result == build_dont_know) {
}
}
/* check whether target was mentioned in makefile */
if (result == build_dont_know) {
}
}
/* result */
return result;
}