xref: /titanic_51/usr/src/cmd/make/bin/nse_printdep.cc (revision 10d63b7db37a83b39c7f511cf9426c9d03ea0760)
1*10d63b7dSRichard Lowe /*
2*10d63b7dSRichard Lowe  * CDDL HEADER START
3*10d63b7dSRichard Lowe  *
4*10d63b7dSRichard Lowe  * The contents of this file are subject to the terms of the
5*10d63b7dSRichard Lowe  * Common Development and Distribution License (the "License").
6*10d63b7dSRichard Lowe  * You may not use this file except in compliance with the License.
7*10d63b7dSRichard Lowe  *
8*10d63b7dSRichard Lowe  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*10d63b7dSRichard Lowe  * or http://www.opensolaris.org/os/licensing.
10*10d63b7dSRichard Lowe  * See the License for the specific language governing permissions
11*10d63b7dSRichard Lowe  * and limitations under the License.
12*10d63b7dSRichard Lowe  *
13*10d63b7dSRichard Lowe  * When distributing Covered Code, include this CDDL HEADER in each
14*10d63b7dSRichard Lowe  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*10d63b7dSRichard Lowe  * If applicable, add the following below this CDDL HEADER, with the
16*10d63b7dSRichard Lowe  * fields enclosed by brackets "[]" replaced with your own identifying
17*10d63b7dSRichard Lowe  * information: Portions Copyright [yyyy] [name of copyright owner]
18*10d63b7dSRichard Lowe  *
19*10d63b7dSRichard Lowe  * CDDL HEADER END
20*10d63b7dSRichard Lowe  */
21*10d63b7dSRichard Lowe /*
22*10d63b7dSRichard Lowe  * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
23*10d63b7dSRichard Lowe  * Use is subject to license terms.
24*10d63b7dSRichard Lowe  */
25*10d63b7dSRichard Lowe 
26*10d63b7dSRichard Lowe /*
27*10d63b7dSRichard Lowe  * Included files
28*10d63b7dSRichard Lowe  */
29*10d63b7dSRichard Lowe #include <mk/defs.h>
30*10d63b7dSRichard Lowe #include <mksh/misc.h>		/* get_prop() */
31*10d63b7dSRichard Lowe 
32*10d63b7dSRichard Lowe /*
33*10d63b7dSRichard Lowe  * File table of contents
34*10d63b7dSRichard Lowe  */
35*10d63b7dSRichard Lowe void   print_dependencies(register Name target, register Property line);
36*10d63b7dSRichard Lowe static void	print_deps(register Name target, register Property line);
37*10d63b7dSRichard Lowe static void	print_more_deps(Name target, Name name);
38*10d63b7dSRichard Lowe static void	print_filename(Name name);
39*10d63b7dSRichard Lowe static Boolean	should_print_dep(Property line);
40*10d63b7dSRichard Lowe static void	print_forest(Name target);
41*10d63b7dSRichard Lowe static void	print_deplist(Dependency head);
42*10d63b7dSRichard Lowe void		print_value(register Name value, Daemon daemon);
43*10d63b7dSRichard Lowe static void	print_rule(register Name target);
44*10d63b7dSRichard Lowe static	void	print_rec_info(Name target);
45*10d63b7dSRichard Lowe static Boolean	is_out_of_date(Property line);
46*10d63b7dSRichard Lowe extern void depvar_print_results (void);
47*10d63b7dSRichard Lowe 
48*10d63b7dSRichard Lowe /*
49*10d63b7dSRichard Lowe  *	print_dependencies(target, line)
50*10d63b7dSRichard Lowe  *
51*10d63b7dSRichard Lowe  *	Print all the dependencies of a target. First print all the Makefiles.
52*10d63b7dSRichard Lowe  *	Then print all the dependencies. Finally, print all the .INIT
53*10d63b7dSRichard Lowe  *	dependencies.
54*10d63b7dSRichard Lowe  *
55*10d63b7dSRichard Lowe  *	Parameters:
56*10d63b7dSRichard Lowe  *		target		The target we print dependencies for
57*10d63b7dSRichard Lowe  *		line		We get the dependency list from here
58*10d63b7dSRichard Lowe  *
59*10d63b7dSRichard Lowe  *	Global variables used:
60*10d63b7dSRichard Lowe  *		done		The Name ".DONE"
61*10d63b7dSRichard Lowe  *		init		The Name ".INIT"
62*10d63b7dSRichard Lowe  *		makefiles_used	List of all makefiles read
63*10d63b7dSRichard Lowe  */
64*10d63b7dSRichard Lowe void
65*10d63b7dSRichard Lowe print_dependencies(register Name target, register Property line)
66*10d63b7dSRichard Lowe {
67*10d63b7dSRichard Lowe 	Dependency	dp;
68*10d63b7dSRichard Lowe 	static Boolean	makefiles_printed = false;
69*10d63b7dSRichard Lowe 
70*10d63b7dSRichard Lowe 	if (target_variants) {
71*10d63b7dSRichard Lowe 		depvar_print_results();
72*10d63b7dSRichard Lowe 	}
73*10d63b7dSRichard Lowe 
74*10d63b7dSRichard Lowe 	if (!makefiles_printed) {
75*10d63b7dSRichard Lowe 		/*
76*10d63b7dSRichard Lowe 		 * Search the makefile list for the primary makefile,
77*10d63b7dSRichard Lowe 		 * then print it and its inclusions.  After that go back
78*10d63b7dSRichard Lowe 		 * and print the default.mk file and its inclusions.
79*10d63b7dSRichard Lowe 		 */
80*10d63b7dSRichard Lowe 		for (dp = makefiles_used; dp != NULL; dp = dp->next) {
81*10d63b7dSRichard Lowe 			if (dp->name == primary_makefile) {
82*10d63b7dSRichard Lowe 				break;
83*10d63b7dSRichard Lowe 			}
84*10d63b7dSRichard Lowe 		}
85*10d63b7dSRichard Lowe 		if (dp) {
86*10d63b7dSRichard Lowe 			print_deplist(dp);
87*10d63b7dSRichard Lowe 			for (dp = makefiles_used; dp != NULL; dp = dp->next) {
88*10d63b7dSRichard Lowe 				if (dp->name == primary_makefile) {
89*10d63b7dSRichard Lowe 					break;
90*10d63b7dSRichard Lowe 				}
91*10d63b7dSRichard Lowe 				(void)printf(" %s", dp->name->string_mb);
92*10d63b7dSRichard Lowe 			}
93*10d63b7dSRichard Lowe 		}
94*10d63b7dSRichard Lowe 		(void) printf("\n");
95*10d63b7dSRichard Lowe 		makefiles_printed = true;
96*10d63b7dSRichard Lowe 	}
97*10d63b7dSRichard Lowe 	print_deps(target, line);
98*10d63b7dSRichard Lowe /*
99*10d63b7dSRichard Lowe 	print_more_deps(target, init);
100*10d63b7dSRichard Lowe 	print_more_deps(target, done);
101*10d63b7dSRichard Lowe  */
102*10d63b7dSRichard Lowe 	if (target_variants) {
103*10d63b7dSRichard Lowe 		print_forest(target);
104*10d63b7dSRichard Lowe 	}
105*10d63b7dSRichard Lowe }
106*10d63b7dSRichard Lowe 
107*10d63b7dSRichard Lowe /*
108*10d63b7dSRichard Lowe  *	print_more_deps(target, name)
109*10d63b7dSRichard Lowe  *
110*10d63b7dSRichard Lowe  *	Print some special dependencies.
111*10d63b7dSRichard Lowe  *	These are the dependencies for the .INIT and .DONE targets.
112*10d63b7dSRichard Lowe  *
113*10d63b7dSRichard Lowe  *	Parameters:
114*10d63b7dSRichard Lowe  *		target		Target built during make run
115*10d63b7dSRichard Lowe  *		name		Special target to print dependencies for
116*10d63b7dSRichard Lowe  *
117*10d63b7dSRichard Lowe  *	Global variables used:
118*10d63b7dSRichard Lowe  */
119*10d63b7dSRichard Lowe static void
120*10d63b7dSRichard Lowe print_more_deps(Name target, Name name)
121*10d63b7dSRichard Lowe {
122*10d63b7dSRichard Lowe 	Property	line;
123*10d63b7dSRichard Lowe 	register Dependency	dependencies;
124*10d63b7dSRichard Lowe 
125*10d63b7dSRichard Lowe 	line = get_prop(name->prop, line_prop);
126*10d63b7dSRichard Lowe 	if (line != NULL && line->body.line.dependencies != NULL) {
127*10d63b7dSRichard Lowe 		(void) printf("%s:\t", target->string_mb);
128*10d63b7dSRichard Lowe 		print_deplist(line->body.line.dependencies);
129*10d63b7dSRichard Lowe 		(void) printf("\n");
130*10d63b7dSRichard Lowe 		for (dependencies= line->body.line.dependencies;
131*10d63b7dSRichard Lowe 		     dependencies != NULL;
132*10d63b7dSRichard Lowe 		     dependencies= dependencies->next) {
133*10d63b7dSRichard Lowe 	                 print_deps(dependencies->name,
134*10d63b7dSRichard Lowe 				 get_prop(dependencies->name->prop, line_prop));
135*10d63b7dSRichard Lowe 		}
136*10d63b7dSRichard Lowe 	}
137*10d63b7dSRichard Lowe }
138*10d63b7dSRichard Lowe 
139*10d63b7dSRichard Lowe /*
140*10d63b7dSRichard Lowe  *	print_deps(target, line, go_recursive)
141*10d63b7dSRichard Lowe  *
142*10d63b7dSRichard Lowe  *	Print a regular dependency list.  Append to this information which
143*10d63b7dSRichard Lowe  *	indicates whether or not the target is recursive.
144*10d63b7dSRichard Lowe  *
145*10d63b7dSRichard Lowe  *	Parameters:
146*10d63b7dSRichard Lowe  *		target		target to print dependencies for
147*10d63b7dSRichard Lowe  *		line		We get the dependency list from here
148*10d63b7dSRichard Lowe  *		go_recursive	Should we show all dependencies recursively?
149*10d63b7dSRichard Lowe  *
150*10d63b7dSRichard Lowe  *	Global variables used:
151*10d63b7dSRichard Lowe  *		recursive_name	The Name ".RECURSIVE", printed
152*10d63b7dSRichard Lowe  */
153*10d63b7dSRichard Lowe static void
154*10d63b7dSRichard Lowe print_deps(register Name target, register Property line)
155*10d63b7dSRichard Lowe {
156*10d63b7dSRichard Lowe 	register Dependency	dep;
157*10d63b7dSRichard Lowe 
158*10d63b7dSRichard Lowe 	if ((target->dependency_printed) ||
159*10d63b7dSRichard Lowe 	    (target == force)) {
160*10d63b7dSRichard Lowe 		return;
161*10d63b7dSRichard Lowe 	}
162*10d63b7dSRichard Lowe 	target->dependency_printed = true;
163*10d63b7dSRichard Lowe 
164*10d63b7dSRichard Lowe 	/* only print entries that are actually derived and are not leaf
165*10d63b7dSRichard Lowe 	 * files and are not the result of sccs get.
166*10d63b7dSRichard Lowe 	 */
167*10d63b7dSRichard Lowe 	if (should_print_dep(line)) {
168*10d63b7dSRichard Lowe 		if ((report_dependencies_level == 2) ||
169*10d63b7dSRichard Lowe 		    (report_dependencies_level == 4)) {
170*10d63b7dSRichard Lowe 			if (is_out_of_date(line)) {
171*10d63b7dSRichard Lowe 			        (void) printf("1 ");
172*10d63b7dSRichard Lowe 			} else {
173*10d63b7dSRichard Lowe 			        (void) printf("0 ");
174*10d63b7dSRichard Lowe 			}
175*10d63b7dSRichard Lowe 		}
176*10d63b7dSRichard Lowe 		print_filename(target);
177*10d63b7dSRichard Lowe 	    	(void) printf(":\t");
178*10d63b7dSRichard Lowe 	    	print_deplist(line->body.line.dependencies);
179*10d63b7dSRichard Lowe 		print_rec_info(target);
180*10d63b7dSRichard Lowe 	   	(void) printf("\n");
181*10d63b7dSRichard Lowe 	 	for (dep = line->body.line.dependencies;
182*10d63b7dSRichard Lowe 		     dep != NULL;
183*10d63b7dSRichard Lowe 		     dep = dep->next) {
184*10d63b7dSRichard Lowe 			print_deps(dep->name,
185*10d63b7dSRichard Lowe 			           get_prop(dep->name->prop, line_prop));
186*10d63b7dSRichard Lowe 		}
187*10d63b7dSRichard Lowe 	}
188*10d63b7dSRichard Lowe }
189*10d63b7dSRichard Lowe 
190*10d63b7dSRichard Lowe static Boolean
191*10d63b7dSRichard Lowe is_out_of_date(Property line)
192*10d63b7dSRichard Lowe {
193*10d63b7dSRichard Lowe 	Dependency	dep;
194*10d63b7dSRichard Lowe 	Property	line2;
195*10d63b7dSRichard Lowe 
196*10d63b7dSRichard Lowe 	if (line == NULL) {
197*10d63b7dSRichard Lowe 		return false;
198*10d63b7dSRichard Lowe 	}
199*10d63b7dSRichard Lowe 	if (line->body.line.is_out_of_date) {
200*10d63b7dSRichard Lowe 		return true;
201*10d63b7dSRichard Lowe 	}
202*10d63b7dSRichard Lowe 	for (dep = line->body.line.dependencies;
203*10d63b7dSRichard Lowe 	     dep != NULL;
204*10d63b7dSRichard Lowe 	     dep = dep->next) {
205*10d63b7dSRichard Lowe 		line2 = get_prop(dep->name->prop, line_prop);
206*10d63b7dSRichard Lowe 		if (is_out_of_date(line2)) {
207*10d63b7dSRichard Lowe 			line->body.line.is_out_of_date = true;
208*10d63b7dSRichard Lowe 			return true;
209*10d63b7dSRichard Lowe 		}
210*10d63b7dSRichard Lowe 	}
211*10d63b7dSRichard Lowe 	return false;
212*10d63b7dSRichard Lowe }
213*10d63b7dSRichard Lowe 
214*10d63b7dSRichard Lowe /*
215*10d63b7dSRichard Lowe  * Given a dependency print it and all its siblings.
216*10d63b7dSRichard Lowe  */
217*10d63b7dSRichard Lowe static void
218*10d63b7dSRichard Lowe print_deplist(Dependency head)
219*10d63b7dSRichard Lowe {
220*10d63b7dSRichard Lowe 	Dependency	dp;
221*10d63b7dSRichard Lowe 
222*10d63b7dSRichard Lowe 	for (dp = head; dp != NULL; dp = dp->next) {
223*10d63b7dSRichard Lowe 		if ((report_dependencies_level != 2) ||
224*10d63b7dSRichard Lowe 		    ((!dp->automatic) ||
225*10d63b7dSRichard Lowe 		     (dp->name->is_double_colon))) {
226*10d63b7dSRichard Lowe 			if (dp->name != force) {
227*10d63b7dSRichard Lowe 				putwchar(' ');
228*10d63b7dSRichard Lowe 				print_filename(dp->name);
229*10d63b7dSRichard Lowe 			}
230*10d63b7dSRichard Lowe 		}
231*10d63b7dSRichard Lowe 	}
232*10d63b7dSRichard Lowe }
233*10d63b7dSRichard Lowe 
234*10d63b7dSRichard Lowe /*
235*10d63b7dSRichard Lowe  * Print the name of a file for the -P option.
236*10d63b7dSRichard Lowe  * If the file is a directory put on a trailing slash.
237*10d63b7dSRichard Lowe  */
238*10d63b7dSRichard Lowe static void
239*10d63b7dSRichard Lowe print_filename(Name name)
240*10d63b7dSRichard Lowe {
241*10d63b7dSRichard Lowe 	(void) printf("%s", name->string_mb);
242*10d63b7dSRichard Lowe /*
243*10d63b7dSRichard Lowe 	if (name->stat.is_dir) {
244*10d63b7dSRichard Lowe 		putwchar('/');
245*10d63b7dSRichard Lowe 	}
246*10d63b7dSRichard Lowe  */
247*10d63b7dSRichard Lowe }
248*10d63b7dSRichard Lowe 
249*10d63b7dSRichard Lowe /*
250*10d63b7dSRichard Lowe  *	should_print_dep(line)
251*10d63b7dSRichard Lowe  *
252*10d63b7dSRichard Lowe  *	Test if we should print the dependencies of this target.
253*10d63b7dSRichard Lowe  *	The line must exist and either have children dependencies
254*10d63b7dSRichard Lowe  *	or have a command that is not an SCCS command.
255*10d63b7dSRichard Lowe  *
256*10d63b7dSRichard Lowe  *	Return value:
257*10d63b7dSRichard Lowe  *				true if the dependencies should be printed
258*10d63b7dSRichard Lowe  *
259*10d63b7dSRichard Lowe  *	Parameters:
260*10d63b7dSRichard Lowe  *		line		We get the dependency list from here
261*10d63b7dSRichard Lowe  *
262*10d63b7dSRichard Lowe  *	Global variables used:
263*10d63b7dSRichard Lowe  */
264*10d63b7dSRichard Lowe static Boolean
265*10d63b7dSRichard Lowe should_print_dep(Property line)
266*10d63b7dSRichard Lowe {
267*10d63b7dSRichard Lowe 	if (line == NULL) {
268*10d63b7dSRichard Lowe 		return false;
269*10d63b7dSRichard Lowe 	}
270*10d63b7dSRichard Lowe 	if (line->body.line.dependencies != NULL) {
271*10d63b7dSRichard Lowe 		return true;
272*10d63b7dSRichard Lowe 	}
273*10d63b7dSRichard Lowe 	if (line->body.line.sccs_command) {
274*10d63b7dSRichard Lowe 		return false;
275*10d63b7dSRichard Lowe 	}
276*10d63b7dSRichard Lowe 	return true;
277*10d63b7dSRichard Lowe }
278*10d63b7dSRichard Lowe 
279*10d63b7dSRichard Lowe /*
280*10d63b7dSRichard Lowe  * Print out the root nodes of all the dependency trees
281*10d63b7dSRichard Lowe  * in this makefile.
282*10d63b7dSRichard Lowe  */
283*10d63b7dSRichard Lowe static void
284*10d63b7dSRichard Lowe print_forest(Name target)
285*10d63b7dSRichard Lowe {
286*10d63b7dSRichard Lowe 	Name_set::iterator np, e;
287*10d63b7dSRichard Lowe 	Property	line;
288*10d63b7dSRichard Lowe 
289*10d63b7dSRichard Lowe  	for (np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
290*10d63b7dSRichard Lowe 			if (np->is_target && !np->has_parent && np != target) {
291*10d63b7dSRichard Lowe 				(void) doname_check(np, true, false, false);
292*10d63b7dSRichard Lowe 				line = get_prop(np->prop, line_prop);
293*10d63b7dSRichard Lowe 				printf("-\n");
294*10d63b7dSRichard Lowe 				print_deps(np, line);
295*10d63b7dSRichard Lowe 			}
296*10d63b7dSRichard Lowe 	}
297*10d63b7dSRichard Lowe }
298*10d63b7dSRichard Lowe 
299*10d63b7dSRichard Lowe 
300*10d63b7dSRichard Lowe /*
301*10d63b7dSRichard Lowe  *	This is a set  of routines for dumping the internal make state
302*10d63b7dSRichard Lowe  *	Used for the -p option
303*10d63b7dSRichard Lowe  */
304*10d63b7dSRichard Lowe void
305*10d63b7dSRichard Lowe print_value(register Name value, Daemon daemon)
306*10d63b7dSRichard Lowe 
307*10d63b7dSRichard Lowe 
308*10d63b7dSRichard Lowe {
309*10d63b7dSRichard Lowe 	Chain			cp;
310*10d63b7dSRichard Lowe 
311*10d63b7dSRichard Lowe 	if (value == NULL)
312*10d63b7dSRichard Lowe 		(void)printf("=\n");
313*10d63b7dSRichard Lowe 	else
314*10d63b7dSRichard Lowe 		switch (daemon) {
315*10d63b7dSRichard Lowe 		    case no_daemon:
316*10d63b7dSRichard Lowe 			(void)printf("= %s\n", value->string_mb);
317*10d63b7dSRichard Lowe 			break;
318*10d63b7dSRichard Lowe 		    case chain_daemon:
319*10d63b7dSRichard Lowe 			for (cp= (Chain) value; cp != NULL; cp= cp->next)
320*10d63b7dSRichard Lowe 				(void)printf(cp->next == NULL ? "%s" : "%s ",
321*10d63b7dSRichard Lowe 					cp->name->string_mb);
322*10d63b7dSRichard Lowe 			(void)printf("\n");
323*10d63b7dSRichard Lowe 			break;
324*10d63b7dSRichard Lowe 		};
325*10d63b7dSRichard Lowe }
326*10d63b7dSRichard Lowe 
327*10d63b7dSRichard Lowe static void
328*10d63b7dSRichard Lowe print_rule(register Name target)
329*10d63b7dSRichard Lowe {
330*10d63b7dSRichard Lowe 	register Cmd_line	rule;
331*10d63b7dSRichard Lowe 	register Property	line;
332*10d63b7dSRichard Lowe 
333*10d63b7dSRichard Lowe 	if (((line= get_prop(target->prop, line_prop)) == NULL) ||
334*10d63b7dSRichard Lowe 	    ((line->body.line.command_template == NULL) &&
335*10d63b7dSRichard Lowe 	     (line->body.line.dependencies == NULL)))
336*10d63b7dSRichard Lowe 		return;
337*10d63b7dSRichard Lowe 	print_dependencies(target, line);
338*10d63b7dSRichard Lowe 	for (rule= line->body.line.command_template; rule != NULL; rule= rule->next)
339*10d63b7dSRichard Lowe 		(void)printf("\t%s\n", rule->command_line->string_mb);
340*10d63b7dSRichard Lowe }
341*10d63b7dSRichard Lowe 
342*10d63b7dSRichard Lowe 
343*10d63b7dSRichard Lowe /*
344*10d63b7dSRichard Lowe  *  If target is recursive,  print the following to standard out:
345*10d63b7dSRichard Lowe  *	.RECURSIVE subdir targ Makefile
346*10d63b7dSRichard Lowe  */
347*10d63b7dSRichard Lowe static void
348*10d63b7dSRichard Lowe print_rec_info(Name target)
349*10d63b7dSRichard Lowe {
350*10d63b7dSRichard Lowe 	Recursive_make	rp;
351*10d63b7dSRichard Lowe 	wchar_t		*colon;
352*10d63b7dSRichard Lowe 
353*10d63b7dSRichard Lowe 	report_recursive_init();
354*10d63b7dSRichard Lowe 
355*10d63b7dSRichard Lowe 	rp = find_recursive_target(target);
356*10d63b7dSRichard Lowe 
357*10d63b7dSRichard Lowe 	if (rp) {
358*10d63b7dSRichard Lowe 		/*
359*10d63b7dSRichard Lowe 		 * if found,  print starting with the space after the ':'
360*10d63b7dSRichard Lowe 		 */
361*10d63b7dSRichard Lowe 		colon = (wchar_t *) wcschr(rp->oldline, (int) colon_char);
362*10d63b7dSRichard Lowe 		(void) printf("%s", colon + 1);
363*10d63b7dSRichard Lowe 	}
364*10d63b7dSRichard Lowe }
365*10d63b7dSRichard Lowe 
366