#include <mk/defs.h>
#include <mksh/misc.h>
#include <vroot/report.h>
static Recursive_make recursive_list;
static Recursive_make *bpatch = &recursive_list;
static Boolean changed;
void
report_recursive_init(void)
{
char *search_dir;
char nse_depinfo[MAXPATHLEN];
FILE *fp;
int line_size, line_index;
wchar_t *line;
wchar_t *bigger_line;
wchar_t *colon;
wchar_t *dollar;
Recursive_make rp;
if (depinfo_already_read) {
return;
} else {
depinfo_already_read = true;
}
search_dir = getenv("NSE_DEP");
if (search_dir == NULL) {
return;
}
(void) sprintf(nse_depinfo, "%s/%s", search_dir, NSE_DEPINFO);
fp = fopen(nse_depinfo, "r");
if (fp == NULL) {
return;
}
line_size = MAXPATHLEN;
line_index = line_size - 1;
line = ALLOC_WC(line_size);
Wstring rns(recursive_name);
wchar_t * wcb = rns.get_string();
while (fgetws(line, line_size, fp) != NULL) {
while (wcslen(line) == line_index) {
if (line[wcslen(line) - 1] == '\n') {
continue;
}
bigger_line = ALLOC_WC(2 * line_size);
wcscpy(bigger_line, line);
retmem(line);
line = bigger_line;
if (fgetws(&line[line_index], line_size, fp) == NULL)
continue;
line_index = 2 * line_index;
line_size = 2 * line_size;
}
colon = (wchar_t *) wcschr(line, (int) colon_char);
if (colon == NULL) {
continue;
}
dollar = (wchar_t *) wcschr(line, (int) dollar_char);
line[wcslen(line) - 1] = (int) nul_char;
if (IS_WEQUALN(&colon[2], wcb,
(int) recursive_name->hash.length)) {
MBSTOWCS(wcs_buffer, DEPINFO_FMT_VERSION);
if (dollar == NULL ||
!IS_WEQUALN(wcs_buffer, (dollar+1) - VER_LEN, VER_LEN)){
continue;
}
rp = ALLOC(Recursive_make);
(void) memset((char *) rp, 0, sizeof (Recursive_make_rec));
rp->oldline = (wchar_t *) wcsdup(line);
if ( dollar != NULL ){
rp->cond_macrostring =
(wchar_t *) wcsdup(dollar - VER_LEN + 1);
}
*colon = (int) nul_char;
rp->target = (wchar_t *) wcsdup(line);
*bpatch = rp;
bpatch = &rp->next;
}
}
(void) fclose(fp);
}
void
report_recursive_dep(Name target, wchar_t *line)
{
Recursive_make rp;
wchar_t rec_buf[STRING_BUFFER_LENGTH];
String_rec string;
INIT_STRING_FROM_STACK(string, rec_buf);
cond_macros_into_string(target, &string);
rp = find_recursive_target(target);
if (rp == NULL) {
rp = ALLOC(Recursive_make);
(void) memset((char *) rp, 0, sizeof (Recursive_make_rec));
wchar_t * wcb = get_wstring(target->string_mb);
rp->target = wcb;
rp->newline = (wchar_t *) wcsdup(line);
rp->cond_macrostring = (wchar_t *) wcsdup(rec_buf);
*bpatch = rp;
bpatch = &rp->next;
changed = true;
} else {
if ((rp->oldline != NULL) && !IS_WEQUAL(rp->oldline, line)) {
rp->newline = (wchar_t *) wcsdup(line);
changed = true;
}
rp->removed = false;
}
}
Recursive_make
find_recursive_target(Name target)
{
Recursive_make rp;
String_rec string;
wchar_t rec_buf[STRING_BUFFER_LENGTH];
INIT_STRING_FROM_STACK(string, rec_buf);
cond_macros_into_string(target, &string);
Wstring tstr(target);
wchar_t * wcb = tstr.get_string();
for (rp = recursive_list; rp != NULL; rp = rp->next) {
if (rp->removed)
continue;
if (IS_WEQUAL(rp->target, wcb)) {
if (rp->cond_macrostring[VER_LEN] == '\0' &&
string.buffer.start[VER_LEN] != '\0'){
rp->removed = true;
continue;
} else if (rp->cond_macrostring[VER_LEN] != '\0' &&
string.buffer.start[VER_LEN] == '\0'){
rp->removed = true;
continue;
}
}
MBSTOWCS(wcs_buffer, DEPINFO_FMT_VERSION);
if (IS_WEQUALN(wcs_buffer, string.buffer.start, VER_LEN)) {
if (IS_WEQUAL(rp->cond_macrostring,
string.buffer.start) &&
IS_WEQUAL(rp->target, wcb)) {
return rp;
}
} else {
if (IS_WEQUAL(rp->target, wcb)) {
return rp;
}
}
}
return NULL;
}
void
remove_recursive_dep(Name target)
{
Recursive_make rp;
rp = find_recursive_target(target);
if ( rp != NULL ) {
rp->removed = true;
changed = true;
if(rp->target) {
retmem(rp->target);
rp->target = NULL;
}
if(rp->newline) {
retmem(rp->newline);
rp->newline = NULL;
}
if(rp->oldline) {
retmem(rp->oldline);
rp->oldline = NULL;
}
if(rp->cond_macrostring) {
retmem(rp->cond_macrostring);
rp->cond_macrostring = NULL;
}
}
}
void
gather_recursive_deps(void)
{
Name_set::iterator np, e;
String_rec rec;
wchar_t rec_buf[STRING_BUFFER_LENGTH];
Property lines;
Boolean has_recursive;
Dependency dp;
report_recursive_init();
for (np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
if (np->has_recursive_dependency){
has_recursive = false;
INIT_STRING_FROM_STACK(rec, rec_buf);
APPEND_NAME(np, &rec, FIND_LENGTH);
append_char((int) colon_char, &rec);
append_char((int) space_char, &rec);
for (lines = get_prop(np->prop,recursive_prop);
lines != NULL;
lines = get_prop(lines->next, recursive_prop)) {
if (lines->body.recursive.in_depinfo)
continue;
if (!lines->body.recursive.has_built)
continue;
has_recursive = true;
lines->body.recursive.in_depinfo=true;
APPEND_NAME(recursive_name, &rec,
FIND_LENGTH);
append_char((int) space_char, &rec);
APPEND_NAME(lines->body.recursive.directory,
&rec, FIND_LENGTH);
append_char((int) space_char, &rec);
APPEND_NAME(lines->body.recursive.target,
&rec, FIND_LENGTH);
append_char((int) space_char, &rec);
for (dp = lines->body.recursive.makefiles;
dp != NULL;
dp = dp->next) {
APPEND_NAME(dp->name, &rec, FIND_LENGTH);
append_char((int) space_char, &rec);
}
}
cond_macros_into_string(np, &rec);
if (has_recursive){
report_recursive_dep(np, rec.buffer.start);
}
} else if ( np->has_built ) {
remove_recursive_dep(np);
}
}
}