#include <mk/defs.h>
#include <mksh/dosys.h>
#include <mksh/macro.h>
#include <mksh/misc.h>
#include <stdarg.h>
#include <libintl.h>
static Boolean built_last_make_run_seen;
static Name_vector enter_member_name(wchar_t *lib_start, wchar_t *member_start, wchar_t *string_end, Name_vector current_names, Name_vector *extra_names);
extern Name normalize_name(wchar_t *name_string, int length);
static void read_suffixes_list(Name_vector depes);
static void make_relative(wchar_t *to, wchar_t *result);
static void print_rule(Cmd_line command);
static void sh_transform(Name *name, Name *value);
Name_vector
enter_name(String string, Boolean tail_present, wchar_t *string_start, wchar_t *string_end, Name_vector current_names, Name_vector *extra_names, Boolean *target_group_seen)
{
Name name;
wchar_t *cp;
wchar_t ch;
if (tail_present) {
append_string(string_start, string, string_end - string_start);
string_start = string->buffer.start;
string_end = string->text.p;
}
ch = *string_end;
*string_end = (int) nul_char;
for (cp = (wchar_t *) wcschr(string_start, (int) parenleft_char);
cp != NULL;
cp = (wchar_t *) wcschr(cp + 1, (int) parenleft_char)) {
if (*(cp - 1) != (int) dollar_char) {
*string_end = ch;
return enter_member_name(string_start,
cp,
string_end,
current_names,
extra_names);
}
}
*string_end = ch;
if (makefile_type == reading_cpp_file) {
name = normalize_name(string_start, string_end - string_start);
} else {
name = normalize_name(string_start, string_end - string_start);
}
if(current_names->used != 0 && current_names->names[current_names->used-1] == plus) {
if(name == plus) {
return current_names;
}
}
if (current_names->used == VSIZEOF(current_names->names)) {
if (current_names->next != NULL) {
current_names = current_names->next;
} else {
current_names->next = *extra_names;
*extra_names = NULL;
current_names = current_names->next;
current_names->used = 0;
current_names->next = NULL;
}
}
current_names->target_group[current_names->used] = NULL;
current_names->names[current_names->used++] = name;
if (name == plus) {
*target_group_seen = true;
}
if (tail_present && string->free_after_use) {
retmem(string->buffer.start);
}
return current_names;
}
static Name_vector
enter_member_name(wchar_t *lib_start, wchar_t *member_start, wchar_t *string_end, Name_vector current_names, Name_vector *extra_names)
{
Boolean entry = false;
wchar_t buffer[STRING_BUFFER_LENGTH];
Name lib;
Name member;
Name name;
Property prop;
wchar_t *memberp;
wchar_t *q;
int paren_count;
Boolean has_dollar;
wchar_t *cq;
Name long_member_name = NULL;
lib = GETNAME(lib_start, member_start - lib_start);
lib->is_member = true;
member_start++;
if (*member_start == (int) parenleft_char) {
entry = true;
member_start++;
}
(void) wcsncpy(buffer, lib_start, member_start - lib_start);
memberp = buffer + (member_start-lib_start);
while (1) {
long_member_name = NULL;
for (;
(member_start < string_end) && iswspace(*member_start);
member_start++);
for (cq = memberp, has_dollar = false, paren_count = 0;
(member_start < string_end) &&
((*member_start != (int) parenright_char) ||
(paren_count > 0)) &&
!iswspace(*member_start);
*cq++ = *member_start++) {
switch (*member_start) {
case parenleft_char:
paren_count++;
break;
case parenright_char:
paren_count--;
break;
case dollar_char:
has_dollar = true;
}
}
member = GETNAME(memberp, cq - memberp);
*cq = 0;
if ((q = (wchar_t *) wcsrchr(memberp, (int) slash_char)) == NULL) {
q = memberp;
}
if ((cq - q > (int) ar_member_name_len) &&
!has_dollar) {
*cq++ = (int) parenright_char;
if (entry) {
*cq++ = (int) parenright_char;
}
long_member_name = GETNAME(buffer, cq - buffer);
cq = q + (int) ar_member_name_len;
}
*cq++ = (int) parenright_char;
if (entry) {
*cq++ = (int) parenright_char;
}
name = GETNAME(buffer, cq - buffer);
name->is_member = lib->is_member;
if (long_member_name != NULL) {
prop = append_prop(name, long_member_name_prop);
name->has_long_member_name = true;
prop->body.long_member_name.member_name =
long_member_name;
}
prop = append_prop(name, member_prop);
prop->body.member.library = lib;
if (entry) {
prop->body.member.entry = member;
prop->body.member.member = NULL;
} else {
prop->body.member.entry = NULL;
prop->body.member.member = member;
}
if (current_names->used == VSIZEOF(current_names->names)) {
if (current_names->next != NULL) {
current_names = current_names->next;
} else {
if (*extra_names == NULL) {
current_names =
current_names->next =
ALLOC(Name_vector);
} else {
current_names =
current_names->next =
*extra_names;
*extra_names = NULL;
}
current_names->used = 0;
current_names->next = NULL;
}
}
current_names->target_group[current_names->used] = NULL;
current_names->names[current_names->used++] = name;
while (iswspace(*member_start)) {
member_start++;
}
if ((*member_start == (int) parenright_char) ||
(member_start >= string_end)) {
return current_names;
}
}
}
Name
normalize_name(wchar_t *name_string, int length)
{
static Name dotdot;
wchar_t *string = ALLOC_WC(length + 1);
wchar_t *string2;
wchar_t *cdp;
wchar_t *current_component;
Name name;
int count;
if (dotdot == NULL) {
MBSTOWCS(wcs_buffer, "..");
dotdot = GETNAME(wcs_buffer, FIND_LENGTH);
}
while ((length > 1) &&
(name_string[0] == (int) period_char) &&
(name_string[1] == (int) slash_char)) {
name_string += 2;
length -= 2;
while ((length > 0) && (name_string[0] == (int) slash_char)) {
name_string++;
length--;
}
}
cdp = string;
while (length > 0) {
if (((length > 2) &&
(name_string[0] == (int) slash_char) &&
(name_string[1] == (int) period_char) &&
(name_string[2] == (int) slash_char)) ||
((length == 2) &&
(name_string[0] == (int) slash_char) &&
(name_string[1] == (int) period_char))) {
name_string += 2;
length -= 2;
continue;
}
if ((length > 1) &&
(name_string[0] == (int) slash_char) &&
(name_string[1] == (int) slash_char)) {
name_string++;
length--;
continue;
}
*cdp++ = *name_string++;
length--;
}
*cdp = (int) nul_char;
removed_one:
name_string = string;
string2 = name_string;
current_component =
cdp =
string =
ALLOC_WC((length = wcslen(name_string)) + 1);
while (length > 0) {
if (((length > 3) &&
(name_string[0] == (int) slash_char) &&
(name_string[1] == (int) period_char) &&
(name_string[2] == (int) period_char) &&
(name_string[3] == (int) slash_char)) ||
((length == 3) &&
(name_string[0] == (int) slash_char) &&
(name_string[1] == (int) period_char) &&
(name_string[2] == (int) period_char))) {
if (((count = cdp - current_component) != 0) &&
(exists(name = GETNAME(string, cdp - string)) > file_doesnt_exist) &&
(!name->stat.is_sym_link)) {
name = GETNAME(current_component, count);
if(name != dotdot) {
cdp = current_component;
name_string += 3;
length -= 3;
if (length > 0) {
name_string++;
length--;
while (length > 0) {
*cdp++ = *name_string++;
length--;
}
}
*cdp = (int) nul_char;
retmem(string2);
goto removed_one;
}
}
}
if ((*cdp++ = *name_string++) == (int) slash_char) {
current_component = cdp;
}
length--;
}
*cdp = (int) nul_char;
if (string[0] == (int) nul_char) {
name = dot;
} else {
name = GETNAME(string, FIND_LENGTH);
}
retmem(string);
retmem(string2);
return name;
}
Chain
find_target_groups(Name_vector target_list, int i, Boolean reset)
{
static Chain target_group = NULL;
static Chain tail_target_group = NULL;
static Name *next;
static Boolean clear_target_group = false;
if (reset) {
target_group = NULL;
tail_target_group = NULL;
clear_target_group = false;
}
if (clear_target_group) {
clear_target_group = false;
target_group = NULL;
}
if (i + 1 != target_list->used) {
next = &target_list->names[i + 1];
} else {
next = (target_list->next != NULL) ?
&target_list->next->names[0] : NULL;
}
switch ((target_group ? 1 : 0) +
(next && (*next == plus) ?
2 : 0)) {
case 0:
break;
case 1:
clear_target_group = true;
case 3:
tail_target_group->next = ALLOC(Chain);
tail_target_group = tail_target_group->next;
tail_target_group->next = NULL;
tail_target_group->name = target_list->names[i];
break;
case 2:
target_group = tail_target_group = ALLOC(Chain);
target_group->next = NULL;
target_group->name = target_list->names[i];
break;
}
target_list->target_group[i] = target_group;
if ((next != NULL) &&
(*next == plus)) {
*next = NULL;
}
return (tail_target_group);
}
void
enter_dependencies(Name target, Chain target_group, Name_vector depes, Cmd_line command, Separator separator)
{
int i;
Property line;
Name name;
Name directory;
wchar_t *namep;
char *mb_namep;
Dependency dp;
Dependency *dpp;
Property line2;
wchar_t relative[MAXPATHLEN];
int recursive_state;
Boolean register_as_auto;
Boolean not_auto_found;
char *slash;
Wstring depstr;
if ((depes->used >= 3) &&
(depes->names[0] == recursive_name)) {
target->has_recursive_dependency = true;
depes->names[0] = NULL;
recursive_state = 0;
dp = NULL;
dpp = &dp;
for (; depes != NULL; depes = depes->next) {
for (i = 0; i < depes->used; i++) {
if (depes->names[i] != NULL) {
switch (recursive_state++) {
case 0:
{
depstr.init(depes->names[i]);
make_relative(depstr.get_string(),
relative);
directory =
GETNAME(relative,
FIND_LENGTH);
}
break;
case 1:
name = depes->names[i];
break;
default:
*dpp = ALLOC(Dependency);
(*dpp)->next = NULL;
(*dpp)->name = depes->names[i];
(*dpp)->automatic = false;
(*dpp)->stale = false;
(*dpp)->built = false;
dpp = &((*dpp)->next);
break;
}
}
}
}
for (line = get_prop(target->prop, recursive_prop);
line != NULL;
line = get_prop(line->next, recursive_prop)) {
if ((line->body.recursive.directory == directory) &&
(line->body.recursive.target == name)) {
line->body.recursive.makefiles = dp;
line->body.recursive.has_built =
(Boolean)
(makefile_type == reading_cpp_file);
return;
}
}
line2 = append_prop(target, recursive_prop);
line2->body.recursive.directory = directory;
line2->body.recursive.target = name;
line2->body.recursive.makefiles = dp;
line2->body.recursive.has_built =
(Boolean) (makefile_type == reading_cpp_file);
line2->body.recursive.in_depinfo = false;
return;
}
Wstring tstr(target);
wchar_t * wcb = tstr.get_string();
if ((makefile_type == reading_makefile) &&
(default_target_to_build == NULL) &&
((wcb[0] != (int) period_char) ||
wcschr(wcb, (int) slash_char))) {
if (target->hash.length != 0)
default_target_to_build = target;
}
if (makefile_type == reading_makefile) {
if (target->colons == no_colon) {
target->colons = separator;
} else {
if (target->colons != separator) {
fatal_reader(gettext(":/:: conflict for target `%s'"),
target->string_mb);
}
}
if (target->colons == two_colon) {
if (depes->used == 0) {
depes->used = 1;
depes->names[0] = force;
}
target->stat.is_precious = true;
mb_namep = getmem((int) (strlen(target->string_mb) + 10));
namep = ALLOC_WC((int) (target->hash.length + 10));
slash = strrchr(target->string_mb, (int) slash_char);
if (slash == NULL) {
(void) sprintf(mb_namep,
"%d@%s",
target->colon_splits++,
target->string_mb);
} else {
*slash = 0;
(void) sprintf(mb_namep,
"%s/%d@%s",
target->string_mb,
target->colon_splits++,
slash + 1);
*slash = (int) slash_char;
}
MBSTOWCS(namep, mb_namep);
retmem_mb(mb_namep);
name = GETNAME(namep, FIND_LENGTH);
retmem(namep);
if (trace_reader) {
(void) printf("%s:\t", target->string_mb);
}
line2 = maybe_append_prop(target, line_prop);
enter_dependency(line2, name, true);
line2->body.line.target = target;
maybe_append_prop(name, target_prop)->
body.target.target = target;
target->is_double_colon_parent = true;
name->is_double_colon = true;
name->has_target_prop = true;
if (trace_reader) {
(void) printf("\n");
}
(target = name)->stat.is_file = true;
}
}
line = maybe_append_prop(target, line_prop);
line->body.line.target = target;
switch (makefile_type) {
case reading_makefile:
if (command != NULL) {
if (line->body.line.command_template != NULL) {
line->body.line.command_template_redefined =
true;
if ((wcb[0] == (int) period_char) &&
!wcschr(wcb, (int) slash_char)) {
line->body.line.command_template =
command;
}
} else {
line->body.line.command_template = command;
}
} else {
if ((wcb[0] == (int) period_char) &&
!wcschr(wcb, (int) slash_char)) {
line->body.line.command_template = command;
}
}
break;
case rereading_statefile:
if (!built_last_make_run_seen) {
for (Cmd_line next, cmd = command; cmd != NULL; cmd = next) {
next = cmd->next;
free(cmd);
}
return;
}
built_last_make_run_seen = false;
command_changed = true;
target->ran_command = true;
case reading_statefile:
if (command != NULL) {
for (Cmd_line next, cmd = line->body.line.command_used;
cmd != NULL; cmd = next) {
next = cmd->next;
free(cmd);
}
line->body.line.command_used = command;
}
case reading_cpp_file:
if (target->temp_file_number == temp_file_number) {
break;
}
target->temp_file_number = temp_file_number;
command_changed = true;
if (line != NULL) {
for (dp = line->body.line.dependencies;
dp != NULL;
dp = dp->next) {
if (dp->automatic) {
dp->stale = true;
}
}
}
break;
default:
fatal_reader(gettext("Internal error. Unknown makefile type %d"),
makefile_type);
}
if (line->body.line.target_group != NULL) {
if (target_group != NULL) {
fatal_reader(gettext("Too many target groups for target `%s'"),
target->string_mb);
}
} else {
line->body.line.target_group = target_group;
}
if (trace_reader) {
(void) printf("%s:\t", target->string_mb);
}
register_as_auto = BOOLEAN(makefile_type != reading_makefile);
not_auto_found = false;
for (;
(depes != NULL) && !not_auto_found;
depes = depes->next) {
for (i = 0; i < depes->used; i++) {
if (depes->names[i] == not_auto) {
not_auto_found = true;
break;
}
enter_dependency(line,
depes->names[i],
register_as_auto);
}
}
if (trace_reader) {
(void) printf("\n");
print_rule(command);
}
}
void
enter_dependency(Property line, Name depe, Boolean automatic)
{
Dependency dp;
Dependency *insert;
if (trace_reader) {
(void) printf("%s ", depe->string_mb);
}
for (insert = &line->body.line.dependencies, dp = *insert;
dp != NULL;
insert = &dp->next, dp = *insert) {
if ((dp->name == depe) && (depe != wait_name)) {
if (dp->automatic) {
dp->automatic = automatic;
if (automatic) {
dp->built = false;
depe->stat.is_file = true;
}
}
dp->stale = false;
return;
}
}
dp = *insert = ALLOC(Dependency);
dp->name = depe;
dp->next = NULL;
dp->automatic = automatic;
dp->stale = false;
dp->built = false;
depe->stat.is_file = true;
if ((makefile_type == reading_makefile) &&
(line != NULL) &&
(line->body.line.target != NULL)) {
line->body.line.target->has_regular_dependency = true;
}
}
Percent
enter_percent(Name target, Chain target_group, Name_vector depes, Cmd_line command)
{
Percent result = ALLOC(Percent);
Percent depe;
Percent *depe_tail = &result->dependencies;
Percent *insert;
wchar_t *cp, *cp1;
Name_vector nvp;
int i;
int pattern;
result->next = NULL;
result->patterns = NULL;
result->patterns_total = 0;
result->command_template = command;
result->being_expanded = false;
result->name = target;
result->dependencies = NULL;
result->target_group = target_group;
Wstring wcb(target);
cp = wcb.get_string();
while (true) {
cp = (wchar_t *) wcschr(cp, (int) percent_char);
if (cp != NULL) {
result->patterns_total++;
cp++;
} else {
break;
}
}
result->patterns_total++;
result->patterns = (Name *) getmem(sizeof(Name) * result->patterns_total);
cp = wcb.get_string();
pattern = 0;
while (true) {
cp1 = (wchar_t *) wcschr(cp, (int) percent_char);
if (cp1 != NULL) {
result->patterns[pattern] = GETNAME(cp, cp1 - cp);
cp = cp1 + 1;
pattern++;
} else {
result->patterns[pattern] = GETNAME(cp, (int) target->hash.length - (cp - wcb.get_string()));
break;
}
}
Wstring wcb1;
for (nvp = depes; nvp != NULL; nvp = nvp->next) {
for (i = 0; i < nvp->used; i++) {
depe = ALLOC(Percent);
depe->next = NULL;
depe->patterns = NULL;
depe->patterns_total = 0;
depe->name = nvp->names[i];
depe->dependencies = NULL;
depe->command_template = NULL;
depe->being_expanded = false;
depe->target_group = NULL;
*depe_tail = depe;
depe_tail = &depe->next;
if (depe->name->percent) {
wcb1.init(depe->name);
cp = wcb1.get_string();
while (true) {
cp = (wchar_t *) wcschr(cp, (int) percent_char);
if (cp != NULL) {
depe->patterns_total++;
cp++;
} else {
break;
}
}
depe->patterns_total++;
depe->patterns = (Name *) getmem(sizeof(Name) * depe->patterns_total);
cp = wcb1.get_string();
pattern = 0;
while (true) {
cp1 = (wchar_t *) wcschr(cp, (int) percent_char);
if (cp1 != NULL) {
depe->patterns[pattern] = GETNAME(cp, cp1 - cp);
cp = cp1 + 1;
pattern++;
} else {
depe->patterns[pattern] = GETNAME(cp, (int) depe->name->hash.length - (cp - wcb1.get_string()));
break;
}
}
}
}
}
for (insert = &percent_list; (*insert) != NULL; insert = &(*insert)->next);
*insert = result;
if (trace_reader) {
(void) printf("%s:", result->name->string_mb);
for (depe = result->dependencies; depe != NULL; depe = depe->next) {
(void) printf(" %s", depe->name->string_mb);
}
(void) printf("\n");
print_rule(command);
}
return result;
}
Dyntarget
enter_dyntarget(Name target)
{
Dyntarget result = ALLOC(Dyntarget);
Dyntarget p;
Dyntarget *insert;
int i;
result->next = NULL;
result->name = target;
for (insert = &dyntarget_list, p = *insert;
p != NULL;
insert = &p->next, p = *insert);
*insert = result;
if (trace_reader) {
(void) printf("Dynamic target %s:\n", result->name->string_mb);
}
return( result);
}
void
special_reader(Name target, Name_vector depes, Cmd_line command)
{
int n;
switch (target->special_reader) {
case svr4_special:
if (depes->used != 0) {
fatal_reader(gettext("Illegal dependencies for target `%s'"),
target->string_mb);
}
svr4 = true;
posix = false;
keep_state = false;
all_parallel = false;
only_parallel = false;
if (trace_reader) {
(void) printf("%s:\n", svr4_name->string_mb);
}
break;
case posix_special:
if(svr4)
break;
if (depes->used != 0) {
fatal_reader(gettext("Illegal dependencies for target `%s'"),
target->string_mb);
}
posix = true;
sccs_get_rule = sccs_get_posix_rule;
keep_state = false;
MBSTOWCS(wcs_buffer, "/usr/xpg4/bin/sh");
(void) SETVAR(shell_name, GETNAME(wcs_buffer, FIND_LENGTH), false);
if (trace_reader) {
(void) printf("%s:\n", posix_name->string_mb);
}
break;
case built_last_make_run_special:
built_last_make_run_seen = true;
break;
case default_special:
if (depes->used != 0) {
warning(gettext("Illegal dependency list for target `%s'"),
target->string_mb);
}
default_rule = command;
if (trace_reader) {
(void) printf("%s:\n",
default_rule_name->string_mb);
print_rule(command);
}
break;
case ignore_special:
if ((depes->used != 0) &&(!posix)){
fatal_reader(gettext("Illegal dependencies for target `%s'"),
target->string_mb);
}
if (depes->used == 0)
{
ignore_errors_all = true;
}
if(svr4) {
ignore_errors_all = true;
break;
}
for (; depes != NULL; depes = depes->next) {
for (n = 0; n < depes->used; n++) {
depes->names[n]->ignore_error_mode = true;
}
}
if (trace_reader) {
(void) printf("%s:\n", ignore_name->string_mb);
}
break;
case keep_state_special:
if(svr4)
break;
if(posix)
break;
if (depes->used != 0) {
fatal_reader(gettext("Illegal dependencies for target `%s'"),
target->string_mb);
}
keep_state = true;
if (trace_reader) {
(void) printf("%s:\n",
dot_keep_state->string_mb);
}
break;
case keep_state_file_special:
if(svr4)
break;
if(posix)
break;
keep_state = true;
if (depes->used != 0) {
if((!make_state) ||(!strcmp(make_state->string_mb,".make.state"))) {
make_state = depes->names[0];
}
}
break;
case make_version_special:
if(svr4)
break;
if (depes->used != 1) {
fatal_reader(gettext("Illegal dependency list for target `%s'"),
target->string_mb);
}
if (depes->names[0] != current_make_version) {
if (!IS_EQUAL(depes->names[0]->string_mb,
"VERSION-1.1") ||
!IS_EQUAL(current_make_version->string_mb,
"VERSION-1.0")) {
warning(gettext("Version mismatch between current version `%s' and `%s'"),
current_make_version->string_mb,
depes->names[0]->string_mb);
}
}
break;
case no_parallel_special:
if(svr4)
break;
if (depes->used == 0) {
only_parallel = true;
all_parallel = false;
}
for (; depes != NULL; depes = depes->next) {
for (n = 0; n < depes->used; n++) {
if (trace_reader) {
(void) printf("%s:\t%s\n",
no_parallel_name->string_mb,
depes->names[n]->string_mb);
}
depes->names[n]->no_parallel = true;
depes->names[n]->parallel = false;
}
}
break;
case parallel_special:
if(svr4)
break;
if (depes->used == 0) {
all_parallel = true;
only_parallel = false;
}
for (; depes != NULL; depes = depes->next) {
for (n = 0; n < depes->used; n++) {
if (trace_reader) {
(void) printf("%s:\t%s\n",
parallel_name->string_mb,
depes->names[n]->string_mb);
}
depes->names[n]->parallel = true;
depes->names[n]->no_parallel = false;
}
}
break;
case localhost_special:
if(svr4)
break;
if (depes->used == 0) {
only_parallel = true;
all_parallel = false;
}
for (; depes != NULL; depes = depes->next) {
for (n = 0; n < depes->used; n++) {
if (trace_reader) {
(void) printf("%s:\t%s\n",
localhost_name->string_mb,
depes->names[n]->string_mb);
}
depes->names[n]->no_parallel = true;
depes->names[n]->parallel = false;
depes->names[n]->localhost = true;
}
}
break;
case precious_special:
if (depes->used == 0) {
all_precious = true;
} else {
all_precious = false;
}
if(svr4) {
all_precious = true;
break;
}
for (; depes != NULL; depes = depes->next) {
for (n = 0; n < depes->used; n++) {
if (trace_reader) {
(void) printf("%s:\t%s\n",
precious->string_mb,
depes->names[n]->string_mb);
}
depes->names[n]->stat.is_precious = true;
}
}
break;
case sccs_get_special:
if (depes->used != 0) {
fatal_reader(gettext("Illegal dependencies for target `%s'"),
target->string_mb);
}
sccs_get_rule = command;
sccs_get_org_rule = command;
if (trace_reader) {
(void) printf("%s:\n", sccs_get_name->string_mb);
print_rule(command);
}
break;
case sccs_get_posix_special:
if (depes->used != 0) {
fatal_reader(gettext("Illegal dependencies for target `%s'"),
target->string_mb);
}
sccs_get_posix_rule = command;
if (trace_reader) {
(void) printf("%s:\n", sccs_get_posix_name->string_mb);
print_rule(command);
}
break;
case get_posix_special:
if (depes->used != 0) {
fatal_reader(gettext("Illegal dependencies for target `%s'"),
target->string_mb);
}
get_posix_rule = command;
if (trace_reader) {
(void) printf("%s:\n", get_posix_name->string_mb);
print_rule(command);
}
break;
case get_special:
if(!svr4) {
break;
}
if (depes->used != 0) {
fatal_reader(gettext("Illegal dependencies for target `%s'"),
target->string_mb);
}
get_rule = command;
sccs_get_rule = command;
if (trace_reader) {
(void) printf("%s:\n", get_name->string_mb);
print_rule(command);
}
break;
case silent_special:
if ((depes->used != 0) && (!posix)){
fatal_reader(gettext("Illegal dependencies for target `%s'"),
target->string_mb);
}
if (depes->used == 0)
{
silent_all = true;
}
if(svr4) {
silent_all = true;
break;
}
for (; depes != NULL; depes = depes->next) {
for (n = 0; n < depes->used; n++) {
depes->names[n]->silent_mode = true;
}
}
if (trace_reader) {
(void) printf("%s:\n", silent_name->string_mb);
}
break;
case suffixes_special:
read_suffixes_list(depes);
break;
default:
fatal_reader(gettext("Internal error: Unknown special reader"));
}
}
static void
read_suffixes_list(Name_vector depes)
{
int n;
Dependency dp;
Dependency *insert_dep;
Name np;
Name np2;
Boolean first = true;
if (depes->used == 0) {
for (Name_set::iterator np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
np->with_squiggle =
np->without_squiggle =
false;
}
suffixes = NULL;
if (trace_reader) {
(void) printf("%s:\n", suffixes_name->string_mb);
}
return;
}
Wstring str;
for (; depes != NULL; depes = depes->next) {
for (n = 0; n < depes->used; n++) {
np = depes->names[n];
for (insert_dep = &suffixes, dp = *insert_dep;
dp != NULL;
insert_dep = &dp->next, dp = *insert_dep) {
if (dp->name == np) {
goto duplicate_suffix;
}
}
if (trace_reader) {
if (first) {
(void) printf("%s:\t",
suffixes_name->string_mb);
first = false;
}
(void) printf("%s ", depes->names[n]->string_mb);
}
if(!(posix|svr4)) {
str.init(np);
wchar_t * wcb = str.get_string();
if (wcb[np->hash.length - 1] ==
(int) tilde_char) {
np2 = GETNAME(wcb,
(int)(np->hash.length - 1));
np2->with_squiggle = true;
if (np2->without_squiggle) {
continue;
}
np = np2;
}
}
np->without_squiggle = true;
dp = *insert_dep = ALLOC(Dependency);
insert_dep = &dp->next;
dp->next = NULL;
dp->name = np;
dp->built = false;
duplicate_suffix:;
}
}
if (trace_reader) {
(void) printf("\n");
}
}
static void
make_relative(wchar_t *to, wchar_t *result)
{
wchar_t *from;
wchar_t *allocated;
wchar_t *cp;
wchar_t *tocomp;
int ncomps;
int i;
int len;
if (to[0] != (int) slash_char) {
(void) wcscpy(result, to);
return;
}
MBSTOWCS(wcs_buffer, get_current_path());
from = allocated = (wchar_t *) wcsdup(wcs_buffer);
ncomps = 1;
for (cp = from; *cp != (int) nul_char; cp++) {
if (*cp == (int) slash_char) {
ncomps++;
}
}
result[0] = (int) nul_char;
tocomp = to;
while ((*from != (int) nul_char) && (*from == *to)) {
if (*from == (int) slash_char) {
ncomps--;
tocomp = &to[1];
}
from++;
to++;
}
if (*from == (int) nul_char) {
if (*to == (int) nul_char) {
MBSTOWCS(wcs_buffer, ".");
(void) wcscpy(result, wcs_buffer);
retmem(allocated);
return;
}
if (*to == (int) slash_char) {
ncomps--;
tocomp = &to[1];
}
} else if ((*from == (int) slash_char) && (*to == (int) nul_char)) {
ncomps--;
tocomp = to;
}
for (i = 0; i < ncomps; i++) {
MBSTOWCS(wcs_buffer, "../");
(void) wcscat(result, wcs_buffer);
}
if (*tocomp == (int) nul_char) {
len = wcslen(result);
result[len - 1] = (int) nul_char;
} else {
(void) wcscat(result, tocomp);
}
retmem(allocated);
return;
}
static void
print_rule(Cmd_line command)
{
for (; command != NULL; command = command->next) {
(void) printf("\t%s\n", command->command_line->string_mb);
}
}
void
enter_conditional(Name target, Name name, Name value, Boolean append)
{
Property conditional;
static int sequence;
Name orig_target = target;
if (name == target_arch) {
enter_conditional(target, virtual_root, virtual_root, false);
}
if (target->percent) {
target = conditionals;
}
if (name->colon) {
sh_transform(&name, &value);
}
if (target->percent) {
target = conditionals;
}
target->conditional_cnt++;
maybe_append_prop(name, macro_prop)->body.macro.is_conditional = true;
conditional = append_prop(target, conditional_prop);
conditional->body.conditional.target = orig_target;
conditional->body.conditional.name = name;
conditional->body.conditional.value = value;
conditional->body.conditional.sequence = sequence++;
conditional->body.conditional.append = append;
if (trace_reader) {
if (value == NULL) {
(void) printf("%s := %s %c=\n",
target->string_mb,
name->string_mb,
append ?
(int) plus_char : (int) space_char);
} else {
(void) printf("%s := %s %c= %s\n",
target->string_mb,
name->string_mb,
append ?
(int) plus_char : (int) space_char,
value->string_mb);
}
}
}
void
enter_equal(Name name, Name value, Boolean append)
{
wchar_t *string;
Name temp;
if (name->colon) {
sh_transform(&name, &value);
}
(void) SETVAR(name, value, append);
Wstring nms(name);
wchar_t * wcb = nms.get_string();
string = wcb;
if (string[0]=='F' &&
string[1]=='C' &&
string[2]=='\0') {
MBSTOWCS(wcs_buffer, "F77");
temp = GETNAME(wcs_buffer, FIND_LENGTH);
(void) SETVAR(temp, value, append);
}
if (trace_reader) {
if (value == NULL) {
(void) printf("%s %c=\n",
name->string_mb,
append ?
(int) plus_char : (int) space_char);
} else {
(void) printf("%s %c= %s\n",
name->string_mb,
append ?
(int) plus_char : (int) space_char,
value->string_mb);
}
}
}
static void
sh_transform(Name *name, Name *value)
{
wchar_t *colon;
String_rec command;
String_rec destination;
wchar_t buffer[1000];
wchar_t buffer1[1000];
static wchar_t colon_sh[4];
static wchar_t colon_shell[7];
if (colon_sh[0] == (int) nul_char) {
MBSTOWCS(colon_sh, ":sh");
MBSTOWCS(colon_shell, ":shell");
}
Wstring nms((*name));
wchar_t * wcb = nms.get_string();
colon = (wchar_t *) wcsrchr(wcb, (int) colon_char);
if ((colon != NULL) && (IS_WEQUAL(colon, colon_sh) || IS_WEQUAL(colon, colon_shell))) {
INIT_STRING_FROM_STACK(destination, buffer);
if(*value == NULL) {
buffer[0] = 0;
} else {
Wstring wcb1((*value));
if (IS_WEQUAL(colon, colon_shell)) {
INIT_STRING_FROM_STACK(command, buffer1);
expand_value(*value, &command, false);
} else {
command.text.p = wcb1.get_string() + (*value)->hash.length;
command.text.end = command.text.p;
command.buffer.start = wcb1.get_string();
command.buffer.end = command.text.p;
}
sh_command2string(&command, &destination);
}
(*value) = GETNAME(destination.buffer.start, FIND_LENGTH);
*colon = (int) nul_char;
(*name) = GETNAME(wcb, FIND_LENGTH);
*colon = (int) colon_char;
}
}
void
fatal_reader(char * pattern, ...)
{
va_list args;
char message[1000];
va_start(args, pattern);
if (file_being_read != NULL) {
WCSTOMBS(mbs_buffer, file_being_read);
if (line_number != 0) {
(void) sprintf(message,
gettext("%s, line %d: %s"),
mbs_buffer,
line_number,
pattern);
} else {
(void) sprintf(message,
"%s: %s",
mbs_buffer,
pattern);
}
pattern = message;
}
(void) fflush(stdout);
(void) fprintf(stderr, gettext("%s: Fatal error in reader: "),
getprogname());
(void) vfprintf(stderr, pattern, args);
(void) fprintf(stderr, "\n");
va_end(args);
if (temp_file_name != NULL) {
(void) fprintf(stderr,
gettext("%s: Temp-file %s not removed\n"),
getprogname(),
temp_file_name->string_mb);
temp_file_name = NULL;
}
if (report_pwd) {
(void) fprintf(stderr,
gettext("Current working directory %s\n"),
get_current_path());
}
(void) fflush(stderr);
exit_status = 1;
exit(1);
}