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
print_dependencies(register Name target,register Property line)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
print_more_deps(Name target,Name name)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
print_deps(register Name target,register Property line)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
is_out_of_date(Property line)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
print_deplist(Dependency head)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
print_filename(Name name)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
should_print_dep(Property line)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
print_forest(Name target)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
print_value(register Name value,Daemon daemon)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
print_rule(register Name target)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
print_rec_info(Name target)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