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  * Included files
2810d63b7dSRichard Lowe  */
2910d63b7dSRichard Lowe #include <mk/defs.h>
3010d63b7dSRichard Lowe #include <mksh/misc.h>		/* get_prop() */
3110d63b7dSRichard Lowe 
3210d63b7dSRichard Lowe /*
3310d63b7dSRichard Lowe  * File table of contents
3410d63b7dSRichard Lowe  */
35*e7afc443SToomas Soome void   print_dependencies(Name target, Property line);
36*e7afc443SToomas Soome static void	print_deps(Name target, Property line);
3710d63b7dSRichard Lowe static void	print_more_deps(Name target, Name name);
3810d63b7dSRichard Lowe static void	print_filename(Name name);
3910d63b7dSRichard Lowe static Boolean	should_print_dep(Property line);
4010d63b7dSRichard Lowe static void	print_forest(Name target);
4110d63b7dSRichard Lowe static void	print_deplist(Dependency head);
42*e7afc443SToomas Soome void		print_value(Name value, Daemon daemon);
43*e7afc443SToomas Soome static void	print_rule(Name target);
4410d63b7dSRichard Lowe static	void	print_rec_info(Name target);
4510d63b7dSRichard Lowe static Boolean	is_out_of_date(Property line);
4610d63b7dSRichard Lowe extern void depvar_print_results (void);
4710d63b7dSRichard Lowe 
4810d63b7dSRichard Lowe /*
4910d63b7dSRichard Lowe  *	print_dependencies(target, line)
5010d63b7dSRichard Lowe  *
5110d63b7dSRichard Lowe  *	Print all the dependencies of a target. First print all the Makefiles.
5210d63b7dSRichard Lowe  *	Then print all the dependencies. Finally, print all the .INIT
5310d63b7dSRichard Lowe  *	dependencies.
5410d63b7dSRichard Lowe  *
5510d63b7dSRichard Lowe  *	Parameters:
5610d63b7dSRichard Lowe  *		target		The target we print dependencies for
5710d63b7dSRichard Lowe  *		line		We get the dependency list from here
5810d63b7dSRichard Lowe  *
5910d63b7dSRichard Lowe  *	Global variables used:
6010d63b7dSRichard Lowe  *		done		The Name ".DONE"
6110d63b7dSRichard Lowe  *		init		The Name ".INIT"
6210d63b7dSRichard Lowe  *		makefiles_used	List of all makefiles read
6310d63b7dSRichard Lowe  */
6410d63b7dSRichard Lowe void
print_dependencies(Name target,Property line)65*e7afc443SToomas Soome print_dependencies(Name target, Property line)
6610d63b7dSRichard Lowe {
6710d63b7dSRichard Lowe 	Dependency	dp;
6810d63b7dSRichard Lowe 	static Boolean	makefiles_printed = false;
6910d63b7dSRichard Lowe 
7010d63b7dSRichard Lowe 	if (target_variants) {
7110d63b7dSRichard Lowe 		depvar_print_results();
7210d63b7dSRichard Lowe 	}
7310d63b7dSRichard Lowe 
7410d63b7dSRichard Lowe 	if (!makefiles_printed) {
7510d63b7dSRichard Lowe 		/*
7610d63b7dSRichard Lowe 		 * Search the makefile list for the primary makefile,
7710d63b7dSRichard Lowe 		 * then print it and its inclusions.  After that go back
7810d63b7dSRichard Lowe 		 * and print the default.mk file and its inclusions.
7910d63b7dSRichard Lowe 		 */
8010d63b7dSRichard Lowe 		for (dp = makefiles_used; dp != NULL; dp = dp->next) {
8110d63b7dSRichard Lowe 			if (dp->name == primary_makefile) {
8210d63b7dSRichard Lowe 				break;
8310d63b7dSRichard Lowe 			}
8410d63b7dSRichard Lowe 		}
8510d63b7dSRichard Lowe 		if (dp) {
8610d63b7dSRichard Lowe 			print_deplist(dp);
8710d63b7dSRichard Lowe 			for (dp = makefiles_used; dp != NULL; dp = dp->next) {
8810d63b7dSRichard Lowe 				if (dp->name == primary_makefile) {
8910d63b7dSRichard Lowe 					break;
9010d63b7dSRichard Lowe 				}
9110d63b7dSRichard Lowe 				(void)printf(" %s", dp->name->string_mb);
9210d63b7dSRichard Lowe 			}
9310d63b7dSRichard Lowe 		}
9410d63b7dSRichard Lowe 		(void) printf("\n");
9510d63b7dSRichard Lowe 		makefiles_printed = true;
9610d63b7dSRichard Lowe 	}
9710d63b7dSRichard Lowe 	print_deps(target, line);
9810d63b7dSRichard Lowe /*
9910d63b7dSRichard Lowe 	print_more_deps(target, init);
10010d63b7dSRichard Lowe 	print_more_deps(target, done);
10110d63b7dSRichard Lowe  */
10210d63b7dSRichard Lowe 	if (target_variants) {
10310d63b7dSRichard Lowe 		print_forest(target);
10410d63b7dSRichard Lowe 	}
10510d63b7dSRichard Lowe }
10610d63b7dSRichard Lowe 
10710d63b7dSRichard Lowe /*
10810d63b7dSRichard Lowe  *	print_more_deps(target, name)
10910d63b7dSRichard Lowe  *
11010d63b7dSRichard Lowe  *	Print some special dependencies.
11110d63b7dSRichard Lowe  *	These are the dependencies for the .INIT and .DONE targets.
11210d63b7dSRichard Lowe  *
11310d63b7dSRichard Lowe  *	Parameters:
11410d63b7dSRichard Lowe  *		target		Target built during make run
11510d63b7dSRichard Lowe  *		name		Special target to print dependencies for
11610d63b7dSRichard Lowe  *
11710d63b7dSRichard Lowe  *	Global variables used:
11810d63b7dSRichard Lowe  */
11910d63b7dSRichard Lowe static void
print_more_deps(Name target,Name name)12010d63b7dSRichard Lowe print_more_deps(Name target, Name name)
12110d63b7dSRichard Lowe {
12210d63b7dSRichard Lowe 	Property	line;
123*e7afc443SToomas Soome 	Dependency	dependencies;
12410d63b7dSRichard Lowe 
12510d63b7dSRichard Lowe 	line = get_prop(name->prop, line_prop);
12610d63b7dSRichard Lowe 	if (line != NULL && line->body.line.dependencies != NULL) {
12710d63b7dSRichard Lowe 		(void) printf("%s:\t", target->string_mb);
12810d63b7dSRichard Lowe 		print_deplist(line->body.line.dependencies);
12910d63b7dSRichard Lowe 		(void) printf("\n");
13010d63b7dSRichard Lowe 		for (dependencies= line->body.line.dependencies;
13110d63b7dSRichard Lowe 		     dependencies != NULL;
13210d63b7dSRichard Lowe 		     dependencies= dependencies->next) {
13310d63b7dSRichard Lowe 	                 print_deps(dependencies->name,
13410d63b7dSRichard Lowe 				 get_prop(dependencies->name->prop, line_prop));
13510d63b7dSRichard Lowe 		}
13610d63b7dSRichard Lowe 	}
13710d63b7dSRichard Lowe }
13810d63b7dSRichard Lowe 
13910d63b7dSRichard Lowe /*
14010d63b7dSRichard Lowe  *	print_deps(target, line, go_recursive)
14110d63b7dSRichard Lowe  *
14210d63b7dSRichard Lowe  *	Print a regular dependency list.  Append to this information which
14310d63b7dSRichard Lowe  *	indicates whether or not the target is recursive.
14410d63b7dSRichard Lowe  *
14510d63b7dSRichard Lowe  *	Parameters:
14610d63b7dSRichard Lowe  *		target		target to print dependencies for
14710d63b7dSRichard Lowe  *		line		We get the dependency list from here
14810d63b7dSRichard Lowe  *		go_recursive	Should we show all dependencies recursively?
14910d63b7dSRichard Lowe  *
15010d63b7dSRichard Lowe  *	Global variables used:
15110d63b7dSRichard Lowe  *		recursive_name	The Name ".RECURSIVE", printed
15210d63b7dSRichard Lowe  */
15310d63b7dSRichard Lowe static void
print_deps(Name target,Property line)154*e7afc443SToomas Soome print_deps(Name target, Property line)
15510d63b7dSRichard Lowe {
156*e7afc443SToomas Soome 	Dependency	dep;
15710d63b7dSRichard Lowe 
15810d63b7dSRichard Lowe 	if ((target->dependency_printed) ||
15910d63b7dSRichard Lowe 	    (target == force)) {
16010d63b7dSRichard Lowe 		return;
16110d63b7dSRichard Lowe 	}
16210d63b7dSRichard Lowe 	target->dependency_printed = true;
16310d63b7dSRichard Lowe 
16410d63b7dSRichard Lowe 	/* only print entries that are actually derived and are not leaf
16510d63b7dSRichard Lowe 	 * files and are not the result of sccs get.
16610d63b7dSRichard Lowe 	 */
16710d63b7dSRichard Lowe 	if (should_print_dep(line)) {
16810d63b7dSRichard Lowe 		if ((report_dependencies_level == 2) ||
16910d63b7dSRichard Lowe 		    (report_dependencies_level == 4)) {
17010d63b7dSRichard Lowe 			if (is_out_of_date(line)) {
17110d63b7dSRichard Lowe 			        (void) printf("1 ");
17210d63b7dSRichard Lowe 			} else {
17310d63b7dSRichard Lowe 			        (void) printf("0 ");
17410d63b7dSRichard Lowe 			}
17510d63b7dSRichard Lowe 		}
17610d63b7dSRichard Lowe 		print_filename(target);
17710d63b7dSRichard Lowe 		(void) printf(":\t");
17810d63b7dSRichard Lowe 		print_deplist(line->body.line.dependencies);
17910d63b7dSRichard Lowe 		print_rec_info(target);
18010d63b7dSRichard Lowe 		(void) printf("\n");
18110d63b7dSRichard Lowe 		for (dep = line->body.line.dependencies;
18210d63b7dSRichard Lowe 		     dep != NULL;
18310d63b7dSRichard Lowe 		     dep = dep->next) {
18410d63b7dSRichard Lowe 			print_deps(dep->name,
18510d63b7dSRichard Lowe 			           get_prop(dep->name->prop, line_prop));
18610d63b7dSRichard Lowe 		}
18710d63b7dSRichard Lowe 	}
18810d63b7dSRichard Lowe }
18910d63b7dSRichard Lowe 
19010d63b7dSRichard Lowe static Boolean
is_out_of_date(Property line)19110d63b7dSRichard Lowe is_out_of_date(Property line)
19210d63b7dSRichard Lowe {
19310d63b7dSRichard Lowe 	Dependency	dep;
19410d63b7dSRichard Lowe 	Property	line2;
19510d63b7dSRichard Lowe 
19610d63b7dSRichard Lowe 	if (line == NULL) {
19710d63b7dSRichard Lowe 		return false;
19810d63b7dSRichard Lowe 	}
19910d63b7dSRichard Lowe 	if (line->body.line.is_out_of_date) {
20010d63b7dSRichard Lowe 		return true;
20110d63b7dSRichard Lowe 	}
20210d63b7dSRichard Lowe 	for (dep = line->body.line.dependencies;
20310d63b7dSRichard Lowe 	     dep != NULL;
20410d63b7dSRichard Lowe 	     dep = dep->next) {
20510d63b7dSRichard Lowe 		line2 = get_prop(dep->name->prop, line_prop);
20610d63b7dSRichard Lowe 		if (is_out_of_date(line2)) {
20710d63b7dSRichard Lowe 			line->body.line.is_out_of_date = true;
20810d63b7dSRichard Lowe 			return true;
20910d63b7dSRichard Lowe 		}
21010d63b7dSRichard Lowe 	}
21110d63b7dSRichard Lowe 	return false;
21210d63b7dSRichard Lowe }
21310d63b7dSRichard Lowe 
21410d63b7dSRichard Lowe /*
21510d63b7dSRichard Lowe  * Given a dependency print it and all its siblings.
21610d63b7dSRichard Lowe  */
21710d63b7dSRichard Lowe static void
print_deplist(Dependency head)21810d63b7dSRichard Lowe print_deplist(Dependency head)
21910d63b7dSRichard Lowe {
22010d63b7dSRichard Lowe 	Dependency	dp;
22110d63b7dSRichard Lowe 
22210d63b7dSRichard Lowe 	for (dp = head; dp != NULL; dp = dp->next) {
22310d63b7dSRichard Lowe 		if ((report_dependencies_level != 2) ||
22410d63b7dSRichard Lowe 		    ((!dp->automatic) ||
22510d63b7dSRichard Lowe 		     (dp->name->is_double_colon))) {
22610d63b7dSRichard Lowe 			if (dp->name != force) {
22710d63b7dSRichard Lowe 				putwchar(' ');
22810d63b7dSRichard Lowe 				print_filename(dp->name);
22910d63b7dSRichard Lowe 			}
23010d63b7dSRichard Lowe 		}
23110d63b7dSRichard Lowe 	}
23210d63b7dSRichard Lowe }
23310d63b7dSRichard Lowe 
23410d63b7dSRichard Lowe /*
23510d63b7dSRichard Lowe  * Print the name of a file for the -P option.
23610d63b7dSRichard Lowe  * If the file is a directory put on a trailing slash.
23710d63b7dSRichard Lowe  */
23810d63b7dSRichard Lowe static void
print_filename(Name name)23910d63b7dSRichard Lowe print_filename(Name name)
24010d63b7dSRichard Lowe {
24110d63b7dSRichard Lowe 	(void) printf("%s", name->string_mb);
24210d63b7dSRichard Lowe /*
24310d63b7dSRichard Lowe 	if (name->stat.is_dir) {
24410d63b7dSRichard Lowe 		putwchar('/');
24510d63b7dSRichard Lowe 	}
24610d63b7dSRichard Lowe  */
24710d63b7dSRichard Lowe }
24810d63b7dSRichard Lowe 
24910d63b7dSRichard Lowe /*
25010d63b7dSRichard Lowe  *	should_print_dep(line)
25110d63b7dSRichard Lowe  *
25210d63b7dSRichard Lowe  *	Test if we should print the dependencies of this target.
25310d63b7dSRichard Lowe  *	The line must exist and either have children dependencies
25410d63b7dSRichard Lowe  *	or have a command that is not an SCCS command.
25510d63b7dSRichard Lowe  *
25610d63b7dSRichard Lowe  *	Return value:
25710d63b7dSRichard Lowe  *				true if the dependencies should be printed
25810d63b7dSRichard Lowe  *
25910d63b7dSRichard Lowe  *	Parameters:
26010d63b7dSRichard Lowe  *		line		We get the dependency list from here
26110d63b7dSRichard Lowe  *
26210d63b7dSRichard Lowe  *	Global variables used:
26310d63b7dSRichard Lowe  */
26410d63b7dSRichard Lowe static Boolean
should_print_dep(Property line)26510d63b7dSRichard Lowe should_print_dep(Property line)
26610d63b7dSRichard Lowe {
26710d63b7dSRichard Lowe 	if (line == NULL) {
26810d63b7dSRichard Lowe 		return false;
26910d63b7dSRichard Lowe 	}
27010d63b7dSRichard Lowe 	if (line->body.line.dependencies != NULL) {
27110d63b7dSRichard Lowe 		return true;
27210d63b7dSRichard Lowe 	}
27310d63b7dSRichard Lowe 	if (line->body.line.sccs_command) {
27410d63b7dSRichard Lowe 		return false;
27510d63b7dSRichard Lowe 	}
27610d63b7dSRichard Lowe 	return true;
27710d63b7dSRichard Lowe }
27810d63b7dSRichard Lowe 
27910d63b7dSRichard Lowe /*
28010d63b7dSRichard Lowe  * Print out the root nodes of all the dependency trees
28110d63b7dSRichard Lowe  * in this makefile.
28210d63b7dSRichard Lowe  */
28310d63b7dSRichard Lowe static void
print_forest(Name target)28410d63b7dSRichard Lowe print_forest(Name target)
28510d63b7dSRichard Lowe {
28610d63b7dSRichard Lowe 	Name_set::iterator np, e;
28710d63b7dSRichard Lowe 	Property	line;
28810d63b7dSRichard Lowe 
28910d63b7dSRichard Lowe 	for (np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
29010d63b7dSRichard Lowe 			if (np->is_target && !np->has_parent && np != target) {
29110d63b7dSRichard Lowe 				(void) doname_check(np, true, false, false);
29210d63b7dSRichard Lowe 				line = get_prop(np->prop, line_prop);
29310d63b7dSRichard Lowe 				printf("-\n");
29410d63b7dSRichard Lowe 				print_deps(np, line);
29510d63b7dSRichard Lowe 			}
29610d63b7dSRichard Lowe 	}
29710d63b7dSRichard Lowe }
29810d63b7dSRichard Lowe 
29910d63b7dSRichard Lowe 
30010d63b7dSRichard Lowe /*
30110d63b7dSRichard Lowe  *	This is a set  of routines for dumping the internal make state
30210d63b7dSRichard Lowe  *	Used for the -p option
30310d63b7dSRichard Lowe  */
30410d63b7dSRichard Lowe void
print_value(Name value,Daemon daemon)305*e7afc443SToomas Soome print_value(Name value, Daemon daemon)
30610d63b7dSRichard Lowe {
30710d63b7dSRichard Lowe 	Chain			cp;
30810d63b7dSRichard Lowe 
30910d63b7dSRichard Lowe 	if (value == NULL)
31010d63b7dSRichard Lowe 		(void)printf("=\n");
31110d63b7dSRichard Lowe 	else
31210d63b7dSRichard Lowe 		switch (daemon) {
31310d63b7dSRichard Lowe 		    case no_daemon:
31410d63b7dSRichard Lowe 			(void)printf("= %s\n", value->string_mb);
31510d63b7dSRichard Lowe 			break;
31610d63b7dSRichard Lowe 		    case chain_daemon:
31710d63b7dSRichard Lowe 			for (cp= (Chain) value; cp != NULL; cp= cp->next)
31810d63b7dSRichard Lowe 				(void)printf(cp->next == NULL ? "%s" : "%s ",
31910d63b7dSRichard Lowe 					cp->name->string_mb);
32010d63b7dSRichard Lowe 			(void)printf("\n");
32110d63b7dSRichard Lowe 			break;
32210d63b7dSRichard Lowe 		};
32310d63b7dSRichard Lowe }
32410d63b7dSRichard Lowe 
32510d63b7dSRichard Lowe static void
print_rule(Name target)326*e7afc443SToomas Soome print_rule(Name target)
32710d63b7dSRichard Lowe {
328*e7afc443SToomas Soome 	Cmd_line	rule;
329*e7afc443SToomas Soome 	Property	line;
33010d63b7dSRichard Lowe 
33110d63b7dSRichard Lowe 	if (((line= get_prop(target->prop, line_prop)) == NULL) ||
33210d63b7dSRichard Lowe 	    ((line->body.line.command_template == NULL) &&
33310d63b7dSRichard Lowe 	     (line->body.line.dependencies == NULL)))
33410d63b7dSRichard Lowe 		return;
33510d63b7dSRichard Lowe 	print_dependencies(target, line);
33610d63b7dSRichard Lowe 	for (rule= line->body.line.command_template; rule != NULL; rule= rule->next)
33710d63b7dSRichard Lowe 		(void)printf("\t%s\n", rule->command_line->string_mb);
33810d63b7dSRichard Lowe }
33910d63b7dSRichard Lowe 
34010d63b7dSRichard Lowe 
34110d63b7dSRichard Lowe /*
34210d63b7dSRichard Lowe  *  If target is recursive,  print the following to standard out:
34310d63b7dSRichard Lowe  *	.RECURSIVE subdir targ Makefile
34410d63b7dSRichard Lowe  */
34510d63b7dSRichard Lowe static void
print_rec_info(Name target)34610d63b7dSRichard Lowe print_rec_info(Name target)
34710d63b7dSRichard Lowe {
34810d63b7dSRichard Lowe 	Recursive_make	rp;
34910d63b7dSRichard Lowe 	wchar_t		*colon;
35010d63b7dSRichard Lowe 
35110d63b7dSRichard Lowe 	report_recursive_init();
35210d63b7dSRichard Lowe 
35310d63b7dSRichard Lowe 	rp = find_recursive_target(target);
35410d63b7dSRichard Lowe 
35510d63b7dSRichard Lowe 	if (rp) {
35610d63b7dSRichard Lowe 		/*
35710d63b7dSRichard Lowe 		 * if found,  print starting with the space after the ':'
35810d63b7dSRichard Lowe 		 */
35910d63b7dSRichard Lowe 		colon = (wchar_t *) wcschr(rp->oldline, (int) colon_char);
36010d63b7dSRichard Lowe 		(void) printf("%s", colon + 1);
36110d63b7dSRichard Lowe 	}
36210d63b7dSRichard Lowe }
36310d63b7dSRichard Lowe 
364