xref: /illumos-gate/usr/src/cmd/make/bin/rep.cc (revision e7afc443)
110d63b7dSRichard Lowe /*
210d63b7dSRichard Lowe  * CDDL HEADER START
310d63b7dSRichard Lowe  *
410d63b7dSRichard Lowe  * The contents of this file are subject to the terms of the
510d63b7dSRichard Lowe  * Common Development and Distribution License (the "License").
610d63b7dSRichard Lowe  * You may not use this file except in compliance with the License.
710d63b7dSRichard Lowe  *
810d63b7dSRichard Lowe  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910d63b7dSRichard Lowe  * or http://www.opensolaris.org/os/licensing.
1010d63b7dSRichard Lowe  * See the License for the specific language governing permissions
1110d63b7dSRichard Lowe  * and limitations under the License.
1210d63b7dSRichard Lowe  *
1310d63b7dSRichard Lowe  * When distributing Covered Code, include this CDDL HEADER in each
1410d63b7dSRichard Lowe  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510d63b7dSRichard Lowe  * If applicable, add the following below this CDDL HEADER, with the
1610d63b7dSRichard Lowe  * fields enclosed by brackets "[]" replaced with your own identifying
1710d63b7dSRichard Lowe  * information: Portions Copyright [yyyy] [name of copyright owner]
1810d63b7dSRichard Lowe  *
1910d63b7dSRichard Lowe  * CDDL HEADER END
2010d63b7dSRichard Lowe  */
2110d63b7dSRichard Lowe /*
2210d63b7dSRichard Lowe  * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
2310d63b7dSRichard Lowe  * Use is subject to license terms.
2410d63b7dSRichard Lowe  */
2510d63b7dSRichard Lowe 
2610d63b7dSRichard Lowe /*
2710d63b7dSRichard Lowe  *	rep.c
2810d63b7dSRichard Lowe  *
2910d63b7dSRichard Lowe  *	This file handles the .nse_depinfo file
3010d63b7dSRichard Lowe  */
3110d63b7dSRichard Lowe 
3210d63b7dSRichard Lowe /*
3310d63b7dSRichard Lowe  * Included files
3410d63b7dSRichard Lowe  */
3510d63b7dSRichard Lowe #include <mk/defs.h>
3610d63b7dSRichard Lowe #include <mksh/misc.h>		/* retmem() */
3710d63b7dSRichard Lowe #include <vroot/report.h>	/* NSE_DEPINFO */
3810d63b7dSRichard Lowe 
3910d63b7dSRichard Lowe /*
4010d63b7dSRichard Lowe  * Static variables
4110d63b7dSRichard Lowe  */
4210d63b7dSRichard Lowe static	Recursive_make	recursive_list;
4310d63b7dSRichard Lowe static	Recursive_make	*bpatch = &recursive_list;
4410d63b7dSRichard Lowe static	Boolean		changed;
4510d63b7dSRichard Lowe 
4610d63b7dSRichard Lowe /*
4710d63b7dSRichard Lowe  * File table of contents
4810d63b7dSRichard Lowe  */
4910d63b7dSRichard Lowe 
5010d63b7dSRichard Lowe 
5110d63b7dSRichard Lowe /*
5210d63b7dSRichard Lowe  *	report_recursive_init()
5310d63b7dSRichard Lowe  *
5410d63b7dSRichard Lowe  *	Read the .nse_depinfo file and make a list of all the
5510d63b7dSRichard Lowe  *	.RECURSIVE entries.
5610d63b7dSRichard Lowe  *
5710d63b7dSRichard Lowe  *	Parameters:
5810d63b7dSRichard Lowe  *
5910d63b7dSRichard Lowe  *	Static variables used:
6010d63b7dSRichard Lowe  *		bpatch		Points to slot where next cell should be added
6110d63b7dSRichard Lowe  *
6210d63b7dSRichard Lowe  *	Global variables used:
6310d63b7dSRichard Lowe  *		recursive_name	The Name ".RECURSIVE", compared against
6410d63b7dSRichard Lowe  */
6510d63b7dSRichard Lowe 
6610d63b7dSRichard Lowe void
report_recursive_init(void)6710d63b7dSRichard Lowe report_recursive_init(void)
6810d63b7dSRichard Lowe {
6910d63b7dSRichard Lowe 	char		*search_dir;
7010d63b7dSRichard Lowe 	char		nse_depinfo[MAXPATHLEN];
7110d63b7dSRichard Lowe 	FILE		*fp;
7210d63b7dSRichard Lowe 	int		line_size, line_index;
7310d63b7dSRichard Lowe 	wchar_t		*line;
7410d63b7dSRichard Lowe 	wchar_t		*bigger_line;
7510d63b7dSRichard Lowe 	wchar_t		*colon;
7610d63b7dSRichard Lowe 	wchar_t		*dollar;
7710d63b7dSRichard Lowe 	Recursive_make	rp;
7810d63b7dSRichard Lowe 
7910d63b7dSRichard Lowe 	/*
8010d63b7dSRichard Lowe 	 * This routine can be called more than once,  don't do
8110d63b7dSRichard Lowe 	 * anything after the first time.
8210d63b7dSRichard Lowe 	 */
8310d63b7dSRichard Lowe 	if (depinfo_already_read) {
8410d63b7dSRichard Lowe 		return;
8510d63b7dSRichard Lowe 	} else {
8610d63b7dSRichard Lowe 		depinfo_already_read = true;
8710d63b7dSRichard Lowe 	}
8810d63b7dSRichard Lowe 
8910d63b7dSRichard Lowe 	search_dir = getenv("NSE_DEP");
9010d63b7dSRichard Lowe 	if (search_dir == NULL) {
9110d63b7dSRichard Lowe 		return;
9210d63b7dSRichard Lowe 	}
9310d63b7dSRichard Lowe 	(void) sprintf(nse_depinfo, "%s/%s", search_dir, NSE_DEPINFO);
9410d63b7dSRichard Lowe 	fp = fopen(nse_depinfo, "r");
9510d63b7dSRichard Lowe 	if (fp == NULL) {
9610d63b7dSRichard Lowe 		return;
9710d63b7dSRichard Lowe 	}
9810d63b7dSRichard Lowe 	line_size = MAXPATHLEN;
9910d63b7dSRichard Lowe 	line_index = line_size - 1;
10010d63b7dSRichard Lowe 	line = ALLOC_WC(line_size);
10110d63b7dSRichard Lowe 	Wstring rns(recursive_name);
10210d63b7dSRichard Lowe 	wchar_t * wcb = rns.get_string();
10310d63b7dSRichard Lowe 	while (fgetws(line, line_size, fp) != NULL) {
10410d63b7dSRichard Lowe 		while (wcslen(line) == line_index) {
10510d63b7dSRichard Lowe 			if (line[wcslen(line) - 1] == '\n') {
10610d63b7dSRichard Lowe 				continue;
10710d63b7dSRichard Lowe 			}
10810d63b7dSRichard Lowe 			bigger_line = ALLOC_WC(2 * line_size);
10910d63b7dSRichard Lowe 			wcscpy(bigger_line, line);
11010d63b7dSRichard Lowe 			retmem(line);
11110d63b7dSRichard Lowe 			line = bigger_line;
11210d63b7dSRichard Lowe 			if (fgetws(&line[line_index], line_size, fp) == NULL)
11310d63b7dSRichard Lowe 				continue;
11410d63b7dSRichard Lowe 			line_index = 2 * line_index;
11510d63b7dSRichard Lowe 			line_size = 2 * line_size;
11610d63b7dSRichard Lowe 		}
11710d63b7dSRichard Lowe 
11810d63b7dSRichard Lowe 		colon = (wchar_t *) wcschr(line, (int) colon_char);
11910d63b7dSRichard Lowe 		if (colon == NULL) {
12010d63b7dSRichard Lowe 			continue;
12110d63b7dSRichard Lowe 		}
12210d63b7dSRichard Lowe 		dollar = (wchar_t *) wcschr(line, (int) dollar_char);
12310d63b7dSRichard Lowe 		line[wcslen(line) - 1] = (int) nul_char;
12410d63b7dSRichard Lowe 		if (IS_WEQUALN(&colon[2], wcb,
12510d63b7dSRichard Lowe 	            (int) recursive_name->hash.length)) {
12610d63b7dSRichard Lowe 			/*
12710d63b7dSRichard Lowe 			 * If this entry is an old entry, ignore it
12810d63b7dSRichard Lowe 			 */
12910d63b7dSRichard Lowe 			MBSTOWCS(wcs_buffer, DEPINFO_FMT_VERSION);
13010d63b7dSRichard Lowe 			if (dollar == NULL ||
13110d63b7dSRichard Lowe 			    !IS_WEQUALN(wcs_buffer, (dollar+1) - VER_LEN, VER_LEN)){
13210d63b7dSRichard Lowe 				continue;
13310d63b7dSRichard Lowe 			    }
13410d63b7dSRichard Lowe 			rp = ALLOC(Recursive_make);
13510d63b7dSRichard Lowe 			(void) memset((char *) rp, 0, sizeof (Recursive_make_rec));
13610d63b7dSRichard Lowe 			/*
13710d63b7dSRichard Lowe 			 * set conditional_macro_string if string is present
13810d63b7dSRichard Lowe 			 */
13910d63b7dSRichard Lowe 			rp->oldline = (wchar_t *) wcsdup(line);
14010d63b7dSRichard Lowe 			if ( dollar != NULL ){
14110d63b7dSRichard Lowe 				rp->cond_macrostring =
14210d63b7dSRichard Lowe 				    (wchar_t *) wcsdup(dollar - VER_LEN + 1);
14310d63b7dSRichard Lowe 			}
14410d63b7dSRichard Lowe 			/*
14510d63b7dSRichard Lowe 			 * get target name into recursive struct
14610d63b7dSRichard Lowe 			 */
14710d63b7dSRichard Lowe 			*colon = (int) nul_char;
14810d63b7dSRichard Lowe 			rp->target = (wchar_t *) wcsdup(line);
14910d63b7dSRichard Lowe 			*bpatch = rp;
15010d63b7dSRichard Lowe 			bpatch = &rp->next;
15110d63b7dSRichard Lowe 		}
15210d63b7dSRichard Lowe 	}
15310d63b7dSRichard Lowe 	(void) fclose(fp);
15410d63b7dSRichard Lowe }
15510d63b7dSRichard Lowe 
15610d63b7dSRichard Lowe /*
15710d63b7dSRichard Lowe  *	report_recursive_dep(target, line)
15810d63b7dSRichard Lowe  *
15910d63b7dSRichard Lowe  *	Report a target as recursive.
16010d63b7dSRichard Lowe  *
16110d63b7dSRichard Lowe  *	Parameters:
16210d63b7dSRichard Lowe  *		line		Dependency line reported
16310d63b7dSRichard Lowe  *
16410d63b7dSRichard Lowe  *	Static variables used:
16510d63b7dSRichard Lowe  *		bpatch		Points to slot where next cell should be added
16610d63b7dSRichard Lowe  *		changed		Written if report set changed
16710d63b7dSRichard Lowe  */
16810d63b7dSRichard Lowe void
report_recursive_dep(Name target,wchar_t * line)16910d63b7dSRichard Lowe report_recursive_dep(Name target, wchar_t *line)
17010d63b7dSRichard Lowe {
17110d63b7dSRichard Lowe 	Recursive_make	rp;
17210d63b7dSRichard Lowe 	wchar_t		rec_buf[STRING_BUFFER_LENGTH];
17310d63b7dSRichard Lowe 	String_rec	string;
17410d63b7dSRichard Lowe 
17510d63b7dSRichard Lowe 	INIT_STRING_FROM_STACK(string, rec_buf);
17610d63b7dSRichard Lowe 	cond_macros_into_string(target, &string);
17710d63b7dSRichard Lowe 	/*
17810d63b7dSRichard Lowe 	 * find an applicable recursive entry, if there isn't one, create it
17910d63b7dSRichard Lowe 	 */
18010d63b7dSRichard Lowe 	rp = find_recursive_target(target);
18110d63b7dSRichard Lowe 	if (rp == NULL) {
18210d63b7dSRichard Lowe 		rp = ALLOC(Recursive_make);
18310d63b7dSRichard Lowe 		(void) memset((char *) rp, 0, sizeof (Recursive_make_rec));
18410d63b7dSRichard Lowe 		wchar_t * wcb = get_wstring(target->string_mb); // XXX Tolik: needs retmem
18510d63b7dSRichard Lowe                 rp->target = wcb;
18610d63b7dSRichard Lowe 		rp->newline = (wchar_t *) wcsdup(line);
18710d63b7dSRichard Lowe 		rp->cond_macrostring = (wchar_t *) wcsdup(rec_buf);
18810d63b7dSRichard Lowe 		*bpatch = rp;
18910d63b7dSRichard Lowe 		bpatch = &rp->next;
19010d63b7dSRichard Lowe 		changed = true;
19110d63b7dSRichard Lowe 	} else {
19210d63b7dSRichard Lowe 		if ((rp->oldline != NULL) && !IS_WEQUAL(rp->oldline, line)) {
19310d63b7dSRichard Lowe 			rp->newline = (wchar_t *) wcsdup(line);
19410d63b7dSRichard Lowe 			changed = true;
19510d63b7dSRichard Lowe 		}
19610d63b7dSRichard Lowe 		rp->removed = false;
19710d63b7dSRichard Lowe 	}
19810d63b7dSRichard Lowe }
19910d63b7dSRichard Lowe 
20010d63b7dSRichard Lowe /*
20110d63b7dSRichard Lowe  *	find_recursive_target(target)
20210d63b7dSRichard Lowe  *
20310d63b7dSRichard Lowe  *	Search the list for a given target.
20410d63b7dSRichard Lowe  *
20510d63b7dSRichard Lowe  *	Return value:
20610d63b7dSRichard Lowe  *				The target cell
20710d63b7dSRichard Lowe  *
20810d63b7dSRichard Lowe  *	Parameters:
20910d63b7dSRichard Lowe  *		target		The target we need
21010d63b7dSRichard Lowe  *		top_level_target more info used to determinde the
21110d63b7dSRichard Lowe  *				 target we need
21210d63b7dSRichard Lowe  *
21310d63b7dSRichard Lowe  *	Static variables used:
21410d63b7dSRichard Lowe  *		recursive_list	The list of targets
21510d63b7dSRichard Lowe  */
21610d63b7dSRichard Lowe Recursive_make
find_recursive_target(Name target)21710d63b7dSRichard Lowe find_recursive_target(Name target)
21810d63b7dSRichard Lowe {
21910d63b7dSRichard Lowe 	Recursive_make	rp;
22010d63b7dSRichard Lowe 	String_rec	string;
22110d63b7dSRichard Lowe 	wchar_t		rec_buf[STRING_BUFFER_LENGTH];
22210d63b7dSRichard Lowe 
22310d63b7dSRichard Lowe 	INIT_STRING_FROM_STACK(string, rec_buf);
22410d63b7dSRichard Lowe 	cond_macros_into_string(target, &string);
22510d63b7dSRichard Lowe 
22610d63b7dSRichard Lowe 	Wstring tstr(target);
22710d63b7dSRichard Lowe 	wchar_t * wcb = tstr.get_string();
22810d63b7dSRichard Lowe 	for (rp = recursive_list; rp != NULL; rp = rp->next) {
22910d63b7dSRichard Lowe 		/*
23010d63b7dSRichard Lowe 		 * If this entry has already been removed, ignore it.
23110d63b7dSRichard Lowe 		 */
23210d63b7dSRichard Lowe 		if (rp->removed)
23310d63b7dSRichard Lowe 			continue;
23410d63b7dSRichard Lowe 		/*
23510d63b7dSRichard Lowe 		 * If this target, and the target on the list are the same
23610d63b7dSRichard Lowe 		 * and if one of them contains conditional macro info, while
23710d63b7dSRichard Lowe 		 * the other doesn't,  remove this entry from the list of
23810d63b7dSRichard Lowe 		 * recursive entries.  This can only happen if the Makefile
23910d63b7dSRichard Lowe 		 * has changed to no longer contain conditional macros.
24010d63b7dSRichard Lowe 		 */
24110d63b7dSRichard Lowe 		if (IS_WEQUAL(rp->target, wcb)) {
24210d63b7dSRichard Lowe 			if (rp->cond_macrostring[VER_LEN] == '\0' &&
24310d63b7dSRichard Lowe 			    string.buffer.start[VER_LEN] != '\0'){
24410d63b7dSRichard Lowe 				rp->removed = true;
24510d63b7dSRichard Lowe 				continue;
24610d63b7dSRichard Lowe 			} else if (rp->cond_macrostring[VER_LEN] != '\0' &&
24710d63b7dSRichard Lowe 			    string.buffer.start[VER_LEN] == '\0'){
24810d63b7dSRichard Lowe 				rp->removed = true;
24910d63b7dSRichard Lowe 				continue;
25010d63b7dSRichard Lowe 			}
25110d63b7dSRichard Lowe 		}
25210d63b7dSRichard Lowe 		/*
25310d63b7dSRichard Lowe 		 * If this is not a VERS2 entry,  only need to match
25410d63b7dSRichard Lowe 		 * the target name.  toptarg information from VERS1 entries
25510d63b7dSRichard Lowe 		 * are ignored.
25610d63b7dSRichard Lowe 		 */
25710d63b7dSRichard Lowe 		MBSTOWCS(wcs_buffer, DEPINFO_FMT_VERSION);
25810d63b7dSRichard Lowe 		if (IS_WEQUALN(wcs_buffer, string.buffer.start, VER_LEN)) {
25910d63b7dSRichard Lowe 			if (IS_WEQUAL(rp->cond_macrostring,
26010d63b7dSRichard Lowe 			    string.buffer.start) &&
26110d63b7dSRichard Lowe 			    IS_WEQUAL(rp->target, wcb)) {
26210d63b7dSRichard Lowe 				return rp;
26310d63b7dSRichard Lowe 			}
26410d63b7dSRichard Lowe 		} else {
26510d63b7dSRichard Lowe 			if (IS_WEQUAL(rp->target, wcb)) {
26610d63b7dSRichard Lowe 				return rp;
26710d63b7dSRichard Lowe 			}
26810d63b7dSRichard Lowe 		}
26910d63b7dSRichard Lowe 	}
27010d63b7dSRichard Lowe 	return NULL;
27110d63b7dSRichard Lowe }
27210d63b7dSRichard Lowe 
27310d63b7dSRichard Lowe /*
27410d63b7dSRichard Lowe  *	remove_recursive_dep(target, top_level_target)
27510d63b7dSRichard Lowe  *
27610d63b7dSRichard Lowe  *	Mark a target as no longer recursive.
27710d63b7dSRichard Lowe  *
27810d63b7dSRichard Lowe  *	Parameters:
27910d63b7dSRichard Lowe  *		target		The target we want to remove
28010d63b7dSRichard Lowe  *		top_level_target target we want to remove must be built from
28110d63b7dSRichard Lowe  *				 the same top level target
28210d63b7dSRichard Lowe  *
28310d63b7dSRichard Lowe  *	Static variables used:
28410d63b7dSRichard Lowe  *		changed		Written if report set changed
28510d63b7dSRichard Lowe  */
28610d63b7dSRichard Lowe void
remove_recursive_dep(Name target)28710d63b7dSRichard Lowe remove_recursive_dep(Name target)
28810d63b7dSRichard Lowe {
28910d63b7dSRichard Lowe 	Recursive_make	rp;
29010d63b7dSRichard Lowe 
29110d63b7dSRichard Lowe 	rp = find_recursive_target(target);
29210d63b7dSRichard Lowe 
29310d63b7dSRichard Lowe 	if ( rp != NULL ) {
29410d63b7dSRichard Lowe 		rp->removed = true;
29510d63b7dSRichard Lowe 		changed = true;
29610d63b7dSRichard Lowe 		if(rp->target) {
29710d63b7dSRichard Lowe 			retmem(rp->target);
29810d63b7dSRichard Lowe 			rp->target = NULL;
29910d63b7dSRichard Lowe 		}
30010d63b7dSRichard Lowe 		if(rp->newline) {
30110d63b7dSRichard Lowe 			retmem(rp->newline);
30210d63b7dSRichard Lowe 			rp->newline = NULL;
30310d63b7dSRichard Lowe 		}
30410d63b7dSRichard Lowe 		if(rp->oldline) {
30510d63b7dSRichard Lowe 			retmem(rp->oldline);
30610d63b7dSRichard Lowe 			rp->oldline = NULL;
30710d63b7dSRichard Lowe 		}
30810d63b7dSRichard Lowe 		if(rp->cond_macrostring) {
30910d63b7dSRichard Lowe 			retmem(rp->cond_macrostring);
31010d63b7dSRichard Lowe 			rp->cond_macrostring = NULL;
31110d63b7dSRichard Lowe 		}
31210d63b7dSRichard Lowe 	}
31310d63b7dSRichard Lowe }
31410d63b7dSRichard Lowe 
31510d63b7dSRichard Lowe 
31610d63b7dSRichard Lowe /* gather_recursive_deps()
31710d63b7dSRichard Lowe  *
31810d63b7dSRichard Lowe  *	Create or update list of recursive targets.
31910d63b7dSRichard Lowe  */
32010d63b7dSRichard Lowe void
gather_recursive_deps(void)32110d63b7dSRichard Lowe gather_recursive_deps(void)
32210d63b7dSRichard Lowe {
32310d63b7dSRichard Lowe 	Name_set::iterator	np, e;
32410d63b7dSRichard Lowe 	String_rec		rec;
32510d63b7dSRichard Lowe 	wchar_t			rec_buf[STRING_BUFFER_LENGTH];
326*e7afc443SToomas Soome 	Property	lines;
32710d63b7dSRichard Lowe 	Boolean			has_recursive;
32810d63b7dSRichard Lowe 	Dependency		dp;
32910d63b7dSRichard Lowe 
33010d63b7dSRichard Lowe 	report_recursive_init();
33110d63b7dSRichard Lowe 
33210d63b7dSRichard Lowe 	/* Go thru all targets and dump recursive dependencies */
33310d63b7dSRichard Lowe 	for (np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
33410d63b7dSRichard Lowe 		if (np->has_recursive_dependency){
33510d63b7dSRichard Lowe 			has_recursive = false;
33610d63b7dSRichard Lowe 			/*
33710d63b7dSRichard Lowe 			 * start .RECURSIVE line with target:
33810d63b7dSRichard Lowe 			 */
33910d63b7dSRichard Lowe 			INIT_STRING_FROM_STACK(rec, rec_buf);
34010d63b7dSRichard Lowe 			APPEND_NAME(np, &rec, FIND_LENGTH);
34110d63b7dSRichard Lowe 			append_char((int) colon_char, &rec);
34210d63b7dSRichard Lowe 			append_char((int) space_char, &rec);
34310d63b7dSRichard Lowe 
34410d63b7dSRichard Lowe 			for (lines = get_prop(np->prop,recursive_prop);
34510d63b7dSRichard Lowe 			    lines != NULL;
34610d63b7dSRichard Lowe 			    lines = get_prop(lines->next, recursive_prop)) {
34710d63b7dSRichard Lowe 				/*
34810d63b7dSRichard Lowe 				 * if entry is already in depinfo
34910d63b7dSRichard Lowe 				 * file or entry was not built, ignore it
35010d63b7dSRichard Lowe 				 */
35110d63b7dSRichard Lowe 				if (lines->body.recursive.in_depinfo)
35210d63b7dSRichard Lowe 					continue;
35310d63b7dSRichard Lowe 				if (!lines->body.recursive.has_built)
35410d63b7dSRichard Lowe 					continue;
35510d63b7dSRichard Lowe 				has_recursive = true;
35610d63b7dSRichard Lowe 				lines->body.recursive.in_depinfo=true;
35710d63b7dSRichard Lowe 
35810d63b7dSRichard Lowe 				/*
35910d63b7dSRichard Lowe 				* Write the remainder of the
36010d63b7dSRichard Lowe 				* .RECURSIVE line
36110d63b7dSRichard Lowe 				*/
36210d63b7dSRichard Lowe 				APPEND_NAME(recursive_name, &rec,
36310d63b7dSRichard Lowe 				    FIND_LENGTH);
36410d63b7dSRichard Lowe 				append_char((int) space_char, &rec);
36510d63b7dSRichard Lowe 				APPEND_NAME(lines->body.recursive.directory,
36610d63b7dSRichard Lowe 					&rec, FIND_LENGTH);
36710d63b7dSRichard Lowe 				append_char((int) space_char, &rec);
36810d63b7dSRichard Lowe 				APPEND_NAME(lines->body.recursive.target,
36910d63b7dSRichard Lowe 					&rec, FIND_LENGTH);
37010d63b7dSRichard Lowe 				append_char((int) space_char, &rec);
37110d63b7dSRichard Lowe 
37210d63b7dSRichard Lowe 				/* Complete list of makefiles used */
37310d63b7dSRichard Lowe 				for (dp = lines->body.recursive.makefiles;
37410d63b7dSRichard Lowe 				    dp != NULL;
37510d63b7dSRichard Lowe 				    dp = dp->next) {
37610d63b7dSRichard Lowe 					APPEND_NAME(dp->name, &rec,  FIND_LENGTH);
37710d63b7dSRichard Lowe 					append_char((int) space_char, &rec);
37810d63b7dSRichard Lowe 				}
37910d63b7dSRichard Lowe 			}
38010d63b7dSRichard Lowe 			/*
38110d63b7dSRichard Lowe 			 * dump list of conditional targets,
38210d63b7dSRichard Lowe 			 * and report recursive entry, if needed
38310d63b7dSRichard Lowe 			 */
38410d63b7dSRichard Lowe 			cond_macros_into_string(np, &rec);
38510d63b7dSRichard Lowe 			if (has_recursive){
38610d63b7dSRichard Lowe 				report_recursive_dep(np, rec.buffer.start);
38710d63b7dSRichard Lowe 			}
38810d63b7dSRichard Lowe 
38910d63b7dSRichard Lowe 		} else if ( np->has_built ) {
39010d63b7dSRichard Lowe 			remove_recursive_dep(np);
39110d63b7dSRichard Lowe 		}
39210d63b7dSRichard Lowe 	}
39310d63b7dSRichard Lowe }
39410d63b7dSRichard Lowe 
395