#include <mk/defs.h>
#include <mksh/macro.h>
#include <mksh/misc.h>
#include <libintl.h>
static wchar_t WIDE_NULL[1] = {(wchar_t) nul_char};
extern Doname find_suffix_rule(Name target, Name target_body, Name target_suffix, Property *command, Boolean rechecking);
extern Doname find_ar_suffix_rule(Name target, Name true_target, Property *command, Boolean rechecking);
extern Doname find_double_suffix_rule(Name target, Property *command, Boolean rechecking);
extern void build_suffix_list(Name target_suffix);
extern Doname find_percent_rule(Name target, Property *command, Boolean rechecking);
static void create_target_group_and_dependencies_list(Name target, Percent pat_rule, String percent);
static Boolean match_found_with_pattern(Name target, Percent pat_rule, String percent, wchar_t *percent_buf);
static void construct_string_from_pattern(Percent pat_rule, String percent, String result);
static Boolean dependency_exists(Name target, Property line);
extern Property maybe_append_prop(Name, Property_id);
extern void add_target_to_chain(Name target, Chain * query);
static Boolean actual_doname = false;
static Boolean we_are_in_tilde = false;
Doname
find_suffix_rule(Name target, Name target_body, Name target_suffix, Property *command, Boolean rechecking)
{
static wchar_t static_string_buf_3M [ 3 * MAXPATHLEN ];
Name true_target = target;
wchar_t *sourcename = (wchar_t*)static_string_buf_3M;
wchar_t *put_suffix;
Property source_suffix;
Name source;
Doname result;
Property line;
extern Boolean tilde_rule;
Boolean name_found = true;
Boolean posix_tilde_attempt = true;
int src_len = MAXPATHLEN + strlen(target_body->string_mb);
if(we_are_in_tilde) {
we_are_in_tilde = false;
return(build_dont_know);
}
if (target->has_target_prop) {
true_target = get_prop(target->prop,
target_prop)->body.target.target;
}
if (debug_level > 1) {
(void) printf("%*sfind_suffix_rule(%s,%s,%s)\n",
recursion_level,
"",
true_target->string_mb,
target_body->string_mb,
target_suffix->string_mb);
}
if (command != NULL) {
if ((true_target->suffix_scan_done == true) && (*command == NULL)) {
return build_ok;
}
}
true_target->suffix_scan_done = true;
read_directory_of_file(target_body);
if (!target_suffix->has_read_suffixes) {
build_suffix_list(target_suffix);
}
if (src_len >= sizeof(static_string_buf_3M)) {
sourcename = ALLOC_WC(src_len);
}
(void) mbstowcs(sourcename,
target_body->string_mb,
(int) target_body->hash.length);
put_suffix = sourcename + target_body->hash.length;
if (target_suffix->has_suffixes) {
posix_attempts:
for (source_suffix = get_prop(target_suffix->prop,
suffix_prop);
source_suffix != NULL;
source_suffix = get_prop(source_suffix->next,
suffix_prop)) {
(void) mbstowcs(put_suffix,
source_suffix->body.
suffix.suffix->string_mb,
(int) source_suffix->body.
suffix.suffix->hash.length);
put_suffix[source_suffix->body.
suffix.suffix->hash.length] =
(int) nul_char;
if (debug_level > 1) {
WCSTOMBS(mbs_buffer, sourcename);
(void) printf(gettext("%*sTrying %s\n"),
recursion_level,
"",
mbs_buffer);
}
source = getname_fn(sourcename, FIND_LENGTH, false, &name_found);
if(vpath_defined && !posix && !svr4) {
(void) exists(source);
}
if (!source->stat.is_file) {
if(!(posix|svr4))
{
if(!name_found) {
free_name(source);
}
continue;
}
if(source->string_mb[source->hash.length - 1] == '~' &&
( svr4 || posix_tilde_attempt ) )
{
char *p, *np;
char *tmpbuf;
tmpbuf = getmem(source->hash.length + 8);
memset(tmpbuf,0,source->hash.length + 8);
source->string_mb[source->hash.length - 1] = '\0';
if(p = (char *) memchr((char *)source->string_mb,'/',source->hash.length))
{
while(1) {
if(np = (char *) memchr((char *)p+1,'/',source->hash.length - (p - source->string_mb))) {
p = np;
} else {break;}
}
strncpy(tmpbuf, source->string_mb, p - source->string_mb + 1);
strcat(tmpbuf, "s.");
strcat(tmpbuf, p+1);
retmem((wchar_t *) source->string_mb);
source->string_mb = tmpbuf;
} else {
strcpy(tmpbuf, "s.");
strcat(tmpbuf, source->string_mb);
retmem((wchar_t *) source->string_mb);
source->string_mb = tmpbuf;
}
source->hash.length = strlen(source->string_mb);
if(exists(source) == file_doesnt_exist)
continue;
tilde_rule = true;
we_are_in_tilde = true;
} else {
if(!name_found) {
free_name(source);
}
continue;
}
} else {
if(posix && posix_tilde_attempt) {
if(exists(source) == file_doesnt_exist) {
if(!name_found) {
free_name(source);
}
continue;
}
}
}
if (command != NULL) {
if(!name_found) {
store_name(source);
}
if (dependency_exists(source,
get_prop(target->prop,
line_prop))) {
result = (Doname) source->state;
} else {
#if 0
result = doname(source,
(Boolean) source_suffix->body.
suffix.suffix->with_squiggle,
true);
#else
result = doname(source,
true,
true);
#endif
}
} else {
result = target_can_be_built(source);
if (result == build_ok) {
return result;
} else {
if(!name_found) {
free_name(source);
}
continue;
}
}
switch (result) {
case build_dont_know:
if (source->stat.time == file_doesnt_exist) {
if(!name_found) {
free_name(source);
}
continue;
}
case build_running:
if(!name_found) {
store_name(source);
}
true_target->suffix_scan_done = false;
line = maybe_append_prop(target, line_prop);
enter_dependency(line, source, false);
line->body.line.target = true_target;
return build_running;
case build_ok:
if(!name_found) {
store_name(source);
}
break;
case build_failed:
if(!name_found) {
store_name(source);
}
if (sourcename != static_string_buf_3M) {
retmem(sourcename);
}
return build_failed;
}
if (debug_level > 1) {
WCSTOMBS(mbs_buffer, sourcename);
(void) printf(gettext("%*sFound %s\n"),
recursion_level,
"",
mbs_buffer);
}
if (source->depends_on_conditional) {
target->depends_on_conditional = true;
}
line = maybe_append_prop(target, line_prop);
if (*command == NULL) {
*command = line;
}
if ((source->stat.time > (*command)->body.line.dependency_time) &&
(debug_level > 1)) {
(void) printf(gettext("%*sDate(%s)=%s Date-dependencies(%s)=%s\n"),
recursion_level,
"",
source->string_mb,
time_to_string(source->
stat.time),
true_target->string_mb,
time_to_string((*command)->
body.line.
dependency_time));
}
(*command)->body.line.dependency_time =
MAX((*command)->body.line.dependency_time,
source->stat.time);
Boolean out_of_date;
if (target->is_member) {
out_of_date = (Boolean) OUT_OF_DATE_SEC(target->stat.time,
(*command)->body.line.dependency_time);
} else {
out_of_date = (Boolean) OUT_OF_DATE(target->stat.time,
(*command)->body.line.dependency_time);
}
if (build_unconditional || out_of_date) {
if(!rechecking) {
line->body.line.is_out_of_date = true;
}
if (debug_level > 0) {
(void) printf(gettext("%*sBuilding %s using suffix rule for %s%s because it is out of date relative to %s\n"),
recursion_level,
"",
true_target->string_mb,
source_suffix->body.suffix.suffix->string_mb,
target_suffix->string_mb,
source->string_mb);
}
}
line->body.line.sccs_command = false;
if (line->body.line.command_template == NULL) {
line->body.line.command_template =
source_suffix->body.suffix.command_template;
}
enter_dependency(line, source, false);
line->body.line.target = true_target;
line->body.line.star = target_body;
if(svr4|posix) {
char * p;
char tstr[256];
extern Boolean dollarless_flag;
extern Name dollarless_value;
if(tilde_rule) {
MBSTOWCS(wcs_buffer, source->string_mb);
dollarless_value = GETNAME(wcs_buffer,FIND_LENGTH);
}
else {
dollarless_flag = false;
}
}
line->body.line.less = source;
line->body.line.percent = NULL;
add_target_to_chain(source, &(line->body.line.query));
if (sourcename != static_string_buf_3M) {
retmem(sourcename);
}
return build_ok;
}
if(posix && posix_tilde_attempt) {
posix_tilde_attempt = false;
goto posix_attempts;
}
if ((command != NULL) &&
((*command) != NULL) &&
((*command)->body.line.star == NULL)) {
(*command)->body.line.star = target_body;
}
}
if (sourcename != static_string_buf_3M) {
retmem(sourcename);
}
return build_dont_know;
}
Doname
find_ar_suffix_rule(Name target, Name true_target, Property *command, Boolean rechecking)
{
wchar_t *target_end;
Dependency suffix;
int suffix_length;
Property line;
Name body;
static Name dot_a;
Wstring targ_string(true_target);
Wstring suf_string;
if (dot_a == NULL) {
MBSTOWCS(wcs_buffer, ".a");
dot_a = GETNAME(wcs_buffer, FIND_LENGTH);
}
target_end = targ_string.get_string() + true_target->hash.length;
if (debug_level > 1) {
(void) printf("%*sfind_ar_suffix_rule(%s)\n",
recursion_level,
"",
true_target->string_mb);
}
for (suffix = suffixes; suffix != NULL; suffix = suffix->next) {
suffix_length = suffix->name->hash.length;
suf_string.init(suffix->name);
if (!IS_WEQUALN(suf_string.get_string(),
target_end - suffix_length,
suffix_length)) {
goto not_this_one;
}
target->suffix_scan_done = false;
body = GETNAME(targ_string.get_string(),
(int)(true_target->hash.length -
suffix_length));
we_are_in_tilde = false;
switch (find_suffix_rule(target,
body,
dot_a,
command,
rechecking)) {
case build_ok:
line = get_prop(target->prop, line_prop);
line->body.line.star = body;
return build_ok;
case build_running:
return build_running;
}
not_this_one:;
}
return build_dont_know;
}
Doname
find_double_suffix_rule(Name target, Property *command, Boolean rechecking)
{
Name true_target = target;
Name target_body;
wchar_t *target_end;
Dependency suffix;
int suffix_length;
Boolean scanned_once = false;
Boolean name_found = true;
Wstring targ_string;
Wstring suf_string;
if (target->has_target_prop) {
true_target = get_prop(target->prop,
target_prop)->body.target.target;
}
targ_string.init(true_target);
target_end = targ_string.get_string() + true_target->hash.length;
if (debug_level > 1) {
(void) printf("%*sfind_double_suffix_rule(%s)\n",
recursion_level,
"",
true_target->string_mb);
}
for (suffix = suffixes; suffix != NULL; suffix = suffix->next) {
target->suffix_scan_done = false;
true_target->suffix_scan_done = false;
suffix_length = suffix->name->hash.length;
suf_string.init(suffix->name);
if (true_target->hash.length < suffix_length) {
goto not_this_one;
} else if (!IS_WEQUALN(suf_string.get_string(),
(target_end - suffix_length),
suffix_length)) {
goto not_this_one;
}
we_are_in_tilde = false;
target_body = GETNAME(
targ_string.get_string(),
(int)(true_target->hash.length - suffix_length)
);
switch (find_suffix_rule(target,
target_body,
suffix->name,
command,
rechecking)) {
case build_ok:
return build_ok;
case build_running:
return build_running;
}
if (true_target->suffix_scan_done == true) {
scanned_once = true;
}
not_this_one:;
}
if (scanned_once)
true_target->suffix_scan_done = true;
return build_dont_know;
}
void
build_suffix_list(Name target_suffix)
{
Dependency source_suffix;
wchar_t rule_name[MAXPATHLEN];
Property line;
Property suffix;
Name rule;
if ((suffixes == NULL) || !working_on_targets) {
return;
}
if (debug_level > 1) {
(void) printf("%*sbuild_suffix_list(%s) ",
recursion_level,
"",
target_suffix->string_mb);
}
target_suffix->has_read_suffixes = true;
for (source_suffix = suffixes;
source_suffix != NULL;
source_suffix = source_suffix->next) {
(void) mbstowcs(rule_name,
source_suffix->name->string_mb,
(int) source_suffix->name->hash.length);
(void) mbstowcs(rule_name + source_suffix->name->hash.length,
target_suffix->string_mb,
(int) target_suffix->hash.length);
if (((rule = getname_fn(rule_name,
(int) (source_suffix->name->
hash.length +
target_suffix->hash.length),
true)) != NULL) &&
((line = get_prop(rule->prop, line_prop)) != NULL)) {
if (debug_level > 1) {
(void) printf("%s ", rule->string_mb);
}
target_suffix->has_suffixes = true;
suffix = append_prop(target_suffix, suffix_prop);
suffix->body.suffix.suffix = source_suffix->name;
suffix->body.suffix.command_template =
line->body.line.command_template;
}
}
if (debug_level > 1) {
(void) printf("\n");
}
}
Doname
find_percent_rule(Name target, Property *command, Boolean rechecking)
{
Percent pat_rule, pat_depe;
Name depe_to_check;
Dependency depe;
Property line;
String_rec string;
wchar_t string_buf[STRING_BUFFER_LENGTH];
String_rec percent;
wchar_t percent_buf[STRING_BUFFER_LENGTH];
Name true_target = target;
Name less;
Boolean nonpattern_less;
Boolean dep_name_found = false;
Doname result = build_dont_know;
Percent rule_candidate = NULL;
Boolean rule_maybe_ok;
Boolean is_pattern;
if (target->has_target_prop) {
true_target = get_prop(target->prop,
target_prop)->body.target.target;
}
if (target->has_long_member_name) {
true_target = get_prop(target->prop,
long_member_name_prop)->body.long_member_name.member_name;
}
if (debug_level > 1) {
(void) printf(gettext("%*sLooking for %% rule for %s\n"),
recursion_level,
"",
true_target->string_mb);
}
for (pat_rule = percent_list;
pat_rule != NULL;
pat_rule = pat_rule->next) {
if (pat_rule->being_expanded == true) {
continue;
}
rule_maybe_ok = true;
less = NULL;
nonpattern_less = true;
if (!match_found_with_pattern(true_target, pat_rule, &percent, percent_buf)) {
continue;
}
if (pat_rule->dependencies != NULL) {
for (pat_depe = pat_rule->dependencies;
pat_depe != NULL;
pat_depe = pat_depe->next) {
result = build_dont_know;
dep_name_found = true;
if (pat_depe->name->percent) {
is_pattern = true;
INIT_STRING_FROM_STACK(string, string_buf);
construct_string_from_pattern(pat_depe, &percent, &string);
depe_to_check = getname_fn(string.buffer.start,
FIND_LENGTH,
false,
&dep_name_found
);
if ((less == NULL) || nonpattern_less) {
less = depe_to_check;
nonpattern_less = false;
}
} else {
is_pattern = false;
depe_to_check = pat_depe->name;
if(depe_to_check->dollar) {
INIT_STRING_FROM_STACK(string, string_buf);
expand_value(depe_to_check, &string, false);
depe_to_check = getname_fn(string.buffer.start,
FIND_LENGTH,
false,
&dep_name_found
);
}
if (less == NULL) {
less = depe_to_check;
}
}
if (depe_to_check == empty_name) {
result = build_ok;
} else {
if (debug_level > 1) {
(void) printf(gettext("%*sTrying %s\n"),
recursion_level,
"",
depe_to_check->string_mb);
}
pat_rule->being_expanded = true;
int save_debug_level = debug_level;
debug_level = 0;
if (dependency_exists(depe_to_check,
get_prop(target->prop,
line_prop)))
{
result = (Doname) depe_to_check->state;
} else {
if(actual_doname) {
result = doname(depe_to_check, true, true);
} else {
result = target_can_be_built(depe_to_check);
}
if(!dep_name_found) {
if(result != build_ok && result != build_running) {
free_name(depe_to_check);
} else {
store_name(depe_to_check);
}
}
}
if(result != build_ok && is_pattern) {
rule_maybe_ok = false;
}
debug_level = save_debug_level;
}
if (pat_depe->name->percent) {
if (string.free_after_use) {
retmem(string.buffer.start);
}
}
if (result != build_ok && result != build_running) {
pat_rule->being_expanded = false;
break;
}
}
} else {
result = build_ok;
}
if (result == build_ok || result == build_running) {
break;
}
if(rule_maybe_ok && rule_candidate == NULL) {
rule_candidate = pat_rule;
}
}
if (result != build_ok && result != build_running) {
if(rule_candidate) {
pat_rule = rule_candidate;
} else {
return build_dont_know;
}
}
if (command == NULL) {
if(pat_rule != NULL) {
pat_rule->being_expanded = false;
}
return result;
}
if (debug_level > 1) {
(void) printf(gettext("%*sMatched %s:"),
recursion_level,
"",
target->string_mb);
for (pat_depe = pat_rule->dependencies;
pat_depe != NULL;
pat_depe = pat_depe->next) {
if (pat_depe->name->percent) {
INIT_STRING_FROM_STACK(string, string_buf);
construct_string_from_pattern(pat_depe, &percent, &string);
depe_to_check = GETNAME(string.buffer.start, FIND_LENGTH);
} else {
depe_to_check = pat_depe->name;
if(depe_to_check->dollar) {
INIT_STRING_FROM_STACK(string, string_buf);
expand_value(depe_to_check, &string, false);
depe_to_check = GETNAME(string.buffer.start, FIND_LENGTH);
}
}
if (depe_to_check != empty_name) {
(void) printf(" %s", depe_to_check->string_mb);
}
}
(void) printf(gettext(" from: %s:"),
pat_rule->name->string_mb);
for (pat_depe = pat_rule->dependencies;
pat_depe != NULL;
pat_depe = pat_depe->next) {
(void) printf(" %s", pat_depe->name->string_mb);
}
(void) printf("\n");
}
if (true_target->colons == no_colon) {
true_target->colons = one_colon;
}
create_target_group_and_dependencies_list(target, pat_rule, &percent);
line = get_prop(target->prop, line_prop);
*command = line;
while(line->body.line.query != NULL) {
Chain to_free = line->body.line.query;
line->body.line.query = line->body.line.query->next;
retmem_mb((char *) to_free);
}
if (line->body.line.dependencies != NULL) {
for (depe = line->body.line.dependencies;
depe != NULL;
depe = depe->next) {
actual_doname = true;
result = doname_check(depe->name, true, true, depe->automatic);
actual_doname = false;
if (result == build_failed) {
pat_rule->being_expanded = false;
return build_failed;
}
if (result == build_running) {
pat_rule->being_expanded = false;
return build_running;
}
if ((depe->name->stat.time > line->body.line.dependency_time) &&
(debug_level > 1)) {
(void) printf(gettext("%*sDate(%s)=%s Date-dependencies(%s)=%s\n"),
recursion_level,
"",
depe->name->string_mb,
time_to_string(depe->name->stat.time),
true_target->string_mb,
time_to_string(line->body.line.dependency_time));
}
line->body.line.dependency_time =
MAX(line->body.line.dependency_time, depe->name->stat.time);
Boolean out_of_date;
if (target->is_member || depe->name->is_member) {
out_of_date = (Boolean) OUT_OF_DATE_SEC(target->stat.time, depe->name->stat.time);
} else {
out_of_date = (Boolean) OUT_OF_DATE(target->stat.time, depe->name->stat.time);
}
if (build_unconditional || out_of_date) {
if(!rechecking) {
line->body.line.is_out_of_date = true;
}
add_target_to_chain(depe->name, &(line->body.line.query));
if (debug_level > 0) {
(void) printf(gettext("%*sBuilding %s using pattern rule %s:"),
recursion_level,
"",
true_target->string_mb,
pat_rule->name->string_mb);
for (pat_depe = pat_rule->dependencies;
pat_depe != NULL;
pat_depe = pat_depe->next) {
(void) printf(" %s", pat_depe->name->string_mb);
}
(void) printf(gettext(" because it is out of date relative to %s\n"),
depe->name->string_mb);
}
}
}
} else {
if ((true_target->stat.time <= file_doesnt_exist) ||
(true_target->stat.time < line->body.line.dependency_time)) {
if(!rechecking) {
line->body.line.is_out_of_date = true;
}
if (debug_level > 0) {
(void) printf(gettext("%*sBuilding %s using pattern rule %s: "),
recursion_level,
"",
true_target->string_mb,
pat_rule->name->string_mb,
(target->stat.time > file_doesnt_exist) ?
gettext("because it is out of date") :
gettext("because it does not exist"));
}
}
}
Name lmn_target = true_target;
if (true_target->has_long_member_name) {
lmn_target = get_prop(true_target->prop, long_member_name_prop)->body.long_member_name.member_name;
}
line->body.line.sccs_command = false;
line->body.line.target = true_target;
line->body.line.command_template = pat_rule->command_template;
line->body.line.star = GETNAME(percent.buffer.start, FIND_LENGTH);
line->body.line.less = less;
if (lmn_target->parenleft) {
Wstring lmn_string(lmn_target);
wchar_t *left = (wchar_t *) wcschr(lmn_string.get_string(), (int) parenleft_char);
wchar_t *right = (wchar_t *) wcschr(lmn_string.get_string(), (int) parenright_char);
if ((left == NULL) || (right == NULL)) {
line->body.line.percent = NULL;
} else {
line->body.line.percent = GETNAME(left + 1, right - left - 1);
}
} else {
line->body.line.percent = NULL;
}
pat_rule->being_expanded = false;
return result;
}
static Boolean
match_found_with_pattern(Name target, Percent pat_rule, String percent, wchar_t *percent_buf) {
String_rec string;
wchar_t string_buf[STRING_BUFFER_LENGTH];
Name prefix = pat_rule->patterns[0];
int prefix_length;
Wstring targ_string(target);
Wstring pref_string(prefix);
Wstring suf_string;
if (prefix->dollar) {
INIT_STRING_FROM_STACK(string, string_buf);
expand_value(prefix, &string, false);
prefix_length = string.text.p - string.buffer.start;
if ((string.buffer.start[0] == (int) period_char) &&
(string.buffer.start[1] == (int) slash_char)) {
string.buffer.start += 2;
prefix_length -= 2;
}
if (!targ_string.equaln(string.buffer.start, prefix_length)) {
return false;
}
} else {
prefix_length = prefix->hash.length;
if (!targ_string.equaln(&pref_string, prefix_length)) {
return false;
}
}
Name suffix = pat_rule->patterns[pat_rule->patterns_total - 1];
suf_string.init(suffix);
int suffix_length;
if (suffix->dollar) {
INIT_STRING_FROM_STACK(string, string_buf);
expand_value(suffix, &string, false);
suffix_length = string.text.p - string.buffer.start;
if(suffix_length > target->hash.length) {
return false;
}
if (!targ_string.equal(string.buffer.start, target->hash.length - suffix_length)) {
return false;
}
} else {
suffix_length = (int) suffix->hash.length;
if(suffix_length > target->hash.length) {
return false;
}
if (!targ_string.equal(&suf_string, target->hash.length - suffix_length)) {
return false;
}
}
Boolean match_found = false;
int percent_length = target->hash.length - prefix_length - suffix_length;
while (!match_found && (percent_length >= 0)) {
INIT_STRING_FROM_STACK(string, string_buf);
percent->buffer.start = percent_buf;
percent->text.p = percent_buf;
percent->text.end = NULL;
percent->free_after_use = false;
percent->buffer.end = percent_buf + STRING_BUFFER_LENGTH;
targ_string.append_to_str(percent, prefix_length, percent_length);
construct_string_from_pattern(pat_rule, percent, &string);
if (targ_string.equal(string.buffer.start, 0)) {
match_found = true;
} else {
percent_length--;
}
}
return match_found;
}
static void
create_target_group_and_dependencies_list(Name target, Percent pat_rule, String percent) {
String_rec string;
wchar_t string_buf[STRING_BUFFER_LENGTH];
Percent pat_depe;
Name depe;
Property line = maybe_append_prop(target, line_prop);
Chain new_target_group = NULL;
Chain *new_target_group_tail = &new_target_group;
Chain group_member;
for (pat_depe = pat_rule->dependencies; pat_depe != NULL; pat_depe = pat_depe->next) {
if (pat_depe->name->percent) {
INIT_STRING_FROM_STACK(string, string_buf);
construct_string_from_pattern(pat_depe, percent, &string);
depe = GETNAME(string.buffer.start, FIND_LENGTH);
if (depe != empty_name) {
enter_dependency(line, depe, false);
}
} else {
depe = pat_depe->name;
if(depe->dollar) {
INIT_STRING_FROM_STACK(string, string_buf);
expand_value(depe, &string, false);
depe = GETNAME(string.buffer.start, FIND_LENGTH);
}
enter_dependency(line, depe, false);
}
}
for (group_member = pat_rule->target_group; group_member != NULL; group_member = group_member->next) {
Name new_target = group_member->name;
if (group_member->name->percent) {
INIT_STRING_FROM_STACK(string, string_buf);
construct_string_from_pattern(group_member->percent_member, percent, &string);
new_target = GETNAME(string.buffer.start, FIND_LENGTH);
if (new_target == empty_name) {
continue;
}
}
Chain tgm;
for (tgm = new_target_group; tgm != NULL; tgm = tgm->next) {
if (new_target == tgm->name) {
break;
}
}
if (tgm != NULL) {
continue;
}
(*new_target_group_tail) = ALLOC(Chain);
(*new_target_group_tail)->name = new_target;
(*new_target_group_tail)->next = NULL;
new_target_group_tail = &(*new_target_group_tail)->next;
}
line->body.line.target_group = new_target_group;
for (group_member = new_target_group; group_member != NULL; group_member = group_member->next) {
if (group_member->name != target) {
group_member->name->prop = target->prop;
group_member->name->conditional_cnt = target->conditional_cnt;
}
}
}
static void
construct_string_from_pattern(Percent pat_rule, String percent, String result) {
for (int i = 0; i < pat_rule->patterns_total; i++) {
if (pat_rule->patterns[i]->dollar) {
expand_value(pat_rule->patterns[i],
result,
false);
} else {
append_string(pat_rule->patterns[i]->string_mb,
result,
pat_rule->patterns[i]->hash.length);
}
if (i < pat_rule->patterns_total - 1) {
append_string(percent->buffer.start,
result,
percent->text.p - percent->buffer.start);
}
}
if ((result->buffer.start[0] == (int) period_char) &&
(result->buffer.start[1] == (int) slash_char)) {
result->buffer.start += 2;
}
}
static Boolean
dependency_exists(Name target, Property line)
{
Dependency dp;
if (line == NULL) {
return false;
}
for (dp = line->body.line.dependencies; dp != NULL; dp = dp->next) {
if (dp->name == target) {
return true;
}
}
return false;
}
void
add_target_to_chain(Name target, Chain * query)
{
if (target->is_member && (get_prop(target->prop, member_prop) != NULL)) {
target = get_prop(target->prop, member_prop)->body.member.member;
}
Chain *query_tail;
for (query_tail = query; *query_tail != NULL; query_tail = &(*query_tail)->next) {
if ((*query_tail)->name == target) {
return;
}
}
*query_tail = ALLOC(Chain);
(*query_tail)->name = target;
(*query_tail)->next = NULL;
}