xref: /freebsd/contrib/pkgconf/cli/core.c (revision 592efe252472a3385acf36b1f49ecf710a7f3d9c)
1*592efe25SPierre Pronchery /*
2*592efe25SPierre Pronchery  * core.c
3*592efe25SPierre Pronchery  * core, printer functions
4*592efe25SPierre Pronchery  *
5*592efe25SPierre Pronchery  * SPDX-License-Identifier: pkgconf
6*592efe25SPierre Pronchery  *
7*592efe25SPierre Pronchery  * Copyright (c) 2011-2025 pkgconf authors (see AUTHORS).
8*592efe25SPierre Pronchery  *
9*592efe25SPierre Pronchery  * Permission to use, copy, modify, and/or distribute this software for any
10*592efe25SPierre Pronchery  * purpose with or without fee is hereby granted, provided that the above
11*592efe25SPierre Pronchery  * copyright notice and this permission notice appear in all copies.
12*592efe25SPierre Pronchery  *
13*592efe25SPierre Pronchery  * This software is provided 'as is' and without any warranty, express or
14*592efe25SPierre Pronchery  * implied.  In no event shall the authors be liable for any damages arising
15*592efe25SPierre Pronchery  * from the use of this software.
16*592efe25SPierre Pronchery  */
17*592efe25SPierre Pronchery 
18*592efe25SPierre Pronchery #include "libpkgconf/config.h"
19*592efe25SPierre Pronchery #include <libpkgconf/stdinc.h>
20*592efe25SPierre Pronchery #include <libpkgconf/libpkgconf.h>
21*592efe25SPierre Pronchery #include "core.h"
22*592efe25SPierre Pronchery #include "getopt_long.h"
23*592efe25SPierre Pronchery #ifndef PKGCONF_LITE
24*592efe25SPierre Pronchery #include "renderer-msvc.h"
25*592efe25SPierre Pronchery #endif
26*592efe25SPierre Pronchery 
27*592efe25SPierre Pronchery static bool
print_list_entry(const pkgconf_pkg_t * entry,void * data)28*592efe25SPierre Pronchery print_list_entry(const pkgconf_pkg_t *entry, void *data)
29*592efe25SPierre Pronchery {
30*592efe25SPierre Pronchery 	const pkgconf_node_t *n;
31*592efe25SPierre Pronchery 	pkgconf_client_t *client = data;
32*592efe25SPierre Pronchery 
33*592efe25SPierre Pronchery 	if (entry->flags & PKGCONF_PKG_PROPF_UNINSTALLED)
34*592efe25SPierre Pronchery 		return false;
35*592efe25SPierre Pronchery 
36*592efe25SPierre Pronchery 	pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT,
37*592efe25SPierre Pronchery 			"%-30s %s - %s\n", entry->id, entry->realname, entry->description);
38*592efe25SPierre Pronchery 
39*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(entry->provides.head, n)
40*592efe25SPierre Pronchery 	{
41*592efe25SPierre Pronchery 		const pkgconf_dependency_t *dep = n->data;
42*592efe25SPierre Pronchery 
43*592efe25SPierre Pronchery 		if (!strcmp(dep->package, entry->id))
44*592efe25SPierre Pronchery 			continue;
45*592efe25SPierre Pronchery 
46*592efe25SPierre Pronchery 		pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT,
47*592efe25SPierre Pronchery 			"%-30s %s - %s (provided by %s)\n", dep->package, entry->realname, entry->description, entry->id);
48*592efe25SPierre Pronchery 	}
49*592efe25SPierre Pronchery 
50*592efe25SPierre Pronchery 	return false;
51*592efe25SPierre Pronchery }
52*592efe25SPierre Pronchery 
53*592efe25SPierre Pronchery static bool
print_package_entry(const pkgconf_pkg_t * entry,void * data)54*592efe25SPierre Pronchery print_package_entry(const pkgconf_pkg_t *entry, void *data)
55*592efe25SPierre Pronchery {
56*592efe25SPierre Pronchery 	const pkgconf_node_t *n;
57*592efe25SPierre Pronchery 	pkgconf_client_t *client = data;
58*592efe25SPierre Pronchery 
59*592efe25SPierre Pronchery 	if (entry->flags & PKGCONF_PKG_PROPF_UNINSTALLED)
60*592efe25SPierre Pronchery 		return false;
61*592efe25SPierre Pronchery 
62*592efe25SPierre Pronchery 	pkgconf_output_puts(client->output, PKGCONF_OUTPUT_STDOUT, entry->id);
63*592efe25SPierre Pronchery 
64*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(entry->provides.head, n)
65*592efe25SPierre Pronchery 	{
66*592efe25SPierre Pronchery 		const pkgconf_dependency_t *dep = n->data;
67*592efe25SPierre Pronchery 
68*592efe25SPierre Pronchery 		if (!strcmp(dep->package, entry->id))
69*592efe25SPierre Pronchery 			continue;
70*592efe25SPierre Pronchery 
71*592efe25SPierre Pronchery 		pkgconf_output_puts(client->output, PKGCONF_OUTPUT_STDOUT, dep->package);
72*592efe25SPierre Pronchery 	}
73*592efe25SPierre Pronchery 
74*592efe25SPierre Pronchery 	return false;
75*592efe25SPierre Pronchery }
76*592efe25SPierre Pronchery 
77*592efe25SPierre Pronchery static bool
filter_cflags(const pkgconf_client_t * client,const pkgconf_fragment_t * frag,void * data)78*592efe25SPierre Pronchery filter_cflags(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, void *data)
79*592efe25SPierre Pronchery {
80*592efe25SPierre Pronchery 	int got_flags = 0;
81*592efe25SPierre Pronchery 	pkgconf_cli_state_t *state = client->client_data;
82*592efe25SPierre Pronchery 	(void) data;
83*592efe25SPierre Pronchery 
84*592efe25SPierre Pronchery 	if (!(state->want_flags & PKG_KEEP_SYSTEM_CFLAGS) && pkgconf_fragment_has_system_dir(client, frag))
85*592efe25SPierre Pronchery 		return false;
86*592efe25SPierre Pronchery 
87*592efe25SPierre Pronchery 	if (state->want_fragment_filter != NULL && (strchr(state->want_fragment_filter, frag->type) == NULL || !frag->type))
88*592efe25SPierre Pronchery 		return false;
89*592efe25SPierre Pronchery 
90*592efe25SPierre Pronchery 	if (frag->type == 'I')
91*592efe25SPierre Pronchery 		got_flags = PKG_CFLAGS_ONLY_I;
92*592efe25SPierre Pronchery 	else
93*592efe25SPierre Pronchery 		got_flags = PKG_CFLAGS_ONLY_OTHER;
94*592efe25SPierre Pronchery 
95*592efe25SPierre Pronchery 	return (state->want_flags & got_flags) != 0;
96*592efe25SPierre Pronchery }
97*592efe25SPierre Pronchery 
98*592efe25SPierre Pronchery static bool
filter_libs(const pkgconf_client_t * client,const pkgconf_fragment_t * frag,void * data)99*592efe25SPierre Pronchery filter_libs(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, void *data)
100*592efe25SPierre Pronchery {
101*592efe25SPierre Pronchery 	int got_flags = 0;
102*592efe25SPierre Pronchery 	pkgconf_cli_state_t *state = client->client_data;
103*592efe25SPierre Pronchery 	(void) data;
104*592efe25SPierre Pronchery 
105*592efe25SPierre Pronchery 	if (!(state->want_flags & PKG_KEEP_SYSTEM_LIBS) && pkgconf_fragment_has_system_dir(client, frag))
106*592efe25SPierre Pronchery 		return false;
107*592efe25SPierre Pronchery 
108*592efe25SPierre Pronchery 	if (state->want_fragment_filter != NULL && (strchr(state->want_fragment_filter, frag->type) == NULL || !frag->type))
109*592efe25SPierre Pronchery 		return false;
110*592efe25SPierre Pronchery 
111*592efe25SPierre Pronchery 	switch (frag->type)
112*592efe25SPierre Pronchery 	{
113*592efe25SPierre Pronchery 		case 'L': got_flags = PKG_LIBS_ONLY_LDPATH; break;
114*592efe25SPierre Pronchery 		case 'l': got_flags = PKG_LIBS_ONLY_LIBNAME; break;
115*592efe25SPierre Pronchery 		default: got_flags = PKG_LIBS_ONLY_OTHER; break;
116*592efe25SPierre Pronchery 	}
117*592efe25SPierre Pronchery 
118*592efe25SPierre Pronchery 	return (state->want_flags & got_flags) != 0;
119*592efe25SPierre Pronchery }
120*592efe25SPierre Pronchery 
121*592efe25SPierre Pronchery static void
print_variables(pkgconf_output_t * output,pkgconf_pkg_t * pkg)122*592efe25SPierre Pronchery print_variables(pkgconf_output_t *output, pkgconf_pkg_t *pkg)
123*592efe25SPierre Pronchery {
124*592efe25SPierre Pronchery 	pkgconf_node_t *node;
125*592efe25SPierre Pronchery 
126*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(pkg->vars.head, node)
127*592efe25SPierre Pronchery 	{
128*592efe25SPierre Pronchery 		pkgconf_tuple_t *tuple = node->data;
129*592efe25SPierre Pronchery 
130*592efe25SPierre Pronchery 		pkgconf_output_puts(output, PKGCONF_OUTPUT_STDOUT, tuple->key);
131*592efe25SPierre Pronchery 	}
132*592efe25SPierre Pronchery }
133*592efe25SPierre Pronchery 
134*592efe25SPierre Pronchery static void
print_dependency_list(pkgconf_output_t * output,pkgconf_list_t * list)135*592efe25SPierre Pronchery print_dependency_list(pkgconf_output_t *output, pkgconf_list_t *list)
136*592efe25SPierre Pronchery {
137*592efe25SPierre Pronchery 	pkgconf_node_t *node;
138*592efe25SPierre Pronchery 
139*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(list->head, node)
140*592efe25SPierre Pronchery 	{
141*592efe25SPierre Pronchery 		pkgconf_dependency_t *dep = node->data;
142*592efe25SPierre Pronchery 
143*592efe25SPierre Pronchery 		pkgconf_output_fmt(output, PKGCONF_OUTPUT_STDOUT, "%s", dep->package);
144*592efe25SPierre Pronchery 
145*592efe25SPierre Pronchery 		if (dep->version != NULL)
146*592efe25SPierre Pronchery 			pkgconf_output_fmt(output, PKGCONF_OUTPUT_STDOUT, " %s %s",
147*592efe25SPierre Pronchery 				pkgconf_pkg_get_comparator(dep), dep->version);
148*592efe25SPierre Pronchery 
149*592efe25SPierre Pronchery 		pkgconf_output_fmt(output, PKGCONF_OUTPUT_STDOUT, "\n");
150*592efe25SPierre Pronchery 	}
151*592efe25SPierre Pronchery }
152*592efe25SPierre Pronchery 
153*592efe25SPierre Pronchery static bool
apply_provides(pkgconf_client_t * client,pkgconf_pkg_t * world,void * unused,int maxdepth)154*592efe25SPierre Pronchery apply_provides(pkgconf_client_t *client, pkgconf_pkg_t *world, void *unused, int maxdepth)
155*592efe25SPierre Pronchery {
156*592efe25SPierre Pronchery 	pkgconf_node_t *iter;
157*592efe25SPierre Pronchery 	(void) unused;
158*592efe25SPierre Pronchery 	(void) maxdepth;
159*592efe25SPierre Pronchery 
160*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(world->required.head, iter)
161*592efe25SPierre Pronchery 	{
162*592efe25SPierre Pronchery 		pkgconf_dependency_t *dep = iter->data;
163*592efe25SPierre Pronchery 		pkgconf_pkg_t *pkg = dep->match;
164*592efe25SPierre Pronchery 
165*592efe25SPierre Pronchery 		print_dependency_list(client->output, &pkg->provides);
166*592efe25SPierre Pronchery 	}
167*592efe25SPierre Pronchery 
168*592efe25SPierre Pronchery 	return true;
169*592efe25SPierre Pronchery }
170*592efe25SPierre Pronchery 
171*592efe25SPierre Pronchery #ifndef PKGCONF_LITE
172*592efe25SPierre Pronchery static void
print_digraph_node(pkgconf_client_t * client,pkgconf_pkg_t * pkg,void * data)173*592efe25SPierre Pronchery print_digraph_node(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data)
174*592efe25SPierre Pronchery {
175*592efe25SPierre Pronchery 	pkgconf_node_t *node;
176*592efe25SPierre Pronchery 	pkgconf_pkg_t **last_seen = data;
177*592efe25SPierre Pronchery 
178*592efe25SPierre Pronchery 	if (pkg->flags & PKGCONF_PKG_PROPF_VIRTUAL)
179*592efe25SPierre Pronchery 		return;
180*592efe25SPierre Pronchery 
181*592efe25SPierre Pronchery 	pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT, "\"%s\" [fontname=Sans fontsize=8", pkg->id);
182*592efe25SPierre Pronchery 
183*592efe25SPierre Pronchery 	if (pkg->flags & PKGCONF_PKG_PROPF_VISITED_PRIVATE)
184*592efe25SPierre Pronchery 		pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT, " fontcolor=gray color=gray");
185*592efe25SPierre Pronchery 
186*592efe25SPierre Pronchery 	pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT, " label=\"%s@%s\"]\n", pkg->id, pkg->version);
187*592efe25SPierre Pronchery 
188*592efe25SPierre Pronchery 	if (last_seen != NULL)
189*592efe25SPierre Pronchery 	{
190*592efe25SPierre Pronchery 		if (*last_seen != NULL)
191*592efe25SPierre Pronchery 			pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT,
192*592efe25SPierre Pronchery 				"\"%s\" -> \"%s\" [fontname=Sans fontsize=8 color=red]\n", (*last_seen)->id, pkg->id);
193*592efe25SPierre Pronchery 
194*592efe25SPierre Pronchery 		*last_seen = pkg;
195*592efe25SPierre Pronchery 	}
196*592efe25SPierre Pronchery 
197*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(pkg->required.head, node)
198*592efe25SPierre Pronchery 	{
199*592efe25SPierre Pronchery 		pkgconf_dependency_t *dep = node->data;
200*592efe25SPierre Pronchery 		const char *dep_id = (dep->match != NULL) ? dep->match->id : dep->package;
201*592efe25SPierre Pronchery 
202*592efe25SPierre Pronchery 		pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT, "\"%s\" -> \"%s\" [fontname=Sans fontsize=8",
203*592efe25SPierre Pronchery 			pkg->id, dep_id);
204*592efe25SPierre Pronchery 
205*592efe25SPierre Pronchery 		if (dep->flags & PKGCONF_PKG_DEPF_PRIVATE)
206*592efe25SPierre Pronchery 			pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT, " color=gray");
207*592efe25SPierre Pronchery 
208*592efe25SPierre Pronchery 		pkgconf_output_puts(client->output, PKGCONF_OUTPUT_STDOUT, "]");
209*592efe25SPierre Pronchery 	}
210*592efe25SPierre Pronchery 
211*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(pkg->requires_private.head, node)
212*592efe25SPierre Pronchery 	{
213*592efe25SPierre Pronchery 		pkgconf_dependency_t *dep = node->data;
214*592efe25SPierre Pronchery 		const char *dep_id = (dep->match != NULL) ? dep->match->id : dep->package;
215*592efe25SPierre Pronchery 
216*592efe25SPierre Pronchery 		pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT,
217*592efe25SPierre Pronchery 			"\"%s\" -> \"%s\" [fontname=Sans fontsize=8 color=gray]\n", pkg->id, dep_id);
218*592efe25SPierre Pronchery 	}
219*592efe25SPierre Pronchery 
220*592efe25SPierre Pronchery 	if (!(client->flags & PKGCONF_PKG_PKGF_MERGE_PRIVATE_FRAGMENTS))
221*592efe25SPierre Pronchery 	{
222*592efe25SPierre Pronchery 		PKGCONF_FOREACH_LIST_ENTRY(pkg->requires_shared.head, node)
223*592efe25SPierre Pronchery 		{
224*592efe25SPierre Pronchery 			pkgconf_dependency_t *dep = node->data;
225*592efe25SPierre Pronchery 			const char *dep_id = (dep->match != NULL) ? dep->match->id : dep->package;
226*592efe25SPierre Pronchery 			pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT,
227*592efe25SPierre Pronchery 				"\"%s\" -> \"%s\" [fontname=Sans fontsize=8 color=orange]\n", pkg->id, dep_id);
228*592efe25SPierre Pronchery 		}
229*592efe25SPierre Pronchery 	}
230*592efe25SPierre Pronchery }
231*592efe25SPierre Pronchery 
232*592efe25SPierre Pronchery static bool
apply_digraph(pkgconf_client_t * client,pkgconf_pkg_t * world,void * data,int maxdepth)233*592efe25SPierre Pronchery apply_digraph(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth)
234*592efe25SPierre Pronchery {
235*592efe25SPierre Pronchery 	int eflag;
236*592efe25SPierre Pronchery 	pkgconf_cli_state_t *state = client->client_data;
237*592efe25SPierre Pronchery 	pkgconf_list_t *list = data;
238*592efe25SPierre Pronchery 	pkgconf_pkg_t *last_seen = NULL;
239*592efe25SPierre Pronchery 	pkgconf_node_t *iter;
240*592efe25SPierre Pronchery 
241*592efe25SPierre Pronchery 	pkgconf_output_puts(client->output, PKGCONF_OUTPUT_STDOUT,
242*592efe25SPierre Pronchery 		"digraph deptree {\n"
243*592efe25SPierre Pronchery 		"edge [color=blue len=7.5 fontname=Sans fontsize=8]\n"
244*592efe25SPierre Pronchery 		"node [fontname=Sans fontsize=8]\n");
245*592efe25SPierre Pronchery 
246*592efe25SPierre Pronchery 	if (state->want_flags & PKG_PRINT_DIGRAPH_QUERY_NODES)
247*592efe25SPierre Pronchery 	{
248*592efe25SPierre Pronchery 		pkgconf_output_puts(client->output, PKGCONF_OUTPUT_STDOUT,
249*592efe25SPierre Pronchery 			"\"user:request\" [fontname=Sans fontsize=8]\n");
250*592efe25SPierre Pronchery 
251*592efe25SPierre Pronchery 		PKGCONF_FOREACH_LIST_ENTRY(list->head, iter)
252*592efe25SPierre Pronchery 		{
253*592efe25SPierre Pronchery 			pkgconf_queue_t *pkgq = iter->data;
254*592efe25SPierre Pronchery 			pkgconf_pkg_t *pkg = pkgconf_pkg_find(client, pkgq->package);
255*592efe25SPierre Pronchery 
256*592efe25SPierre Pronchery 			pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT,
257*592efe25SPierre Pronchery 				"\"user:request\" -> \"%s\" [fontname=Sans fontsize=8]\n",
258*592efe25SPierre Pronchery 				pkg == NULL ? pkgq->package : pkg->id);
259*592efe25SPierre Pronchery 
260*592efe25SPierre Pronchery 			if (pkg != NULL)
261*592efe25SPierre Pronchery 				pkgconf_pkg_unref(client, pkg);
262*592efe25SPierre Pronchery 		}
263*592efe25SPierre Pronchery 	}
264*592efe25SPierre Pronchery 
265*592efe25SPierre Pronchery 	eflag = pkgconf_pkg_traverse(client, world, print_digraph_node, &last_seen, maxdepth, 0);
266*592efe25SPierre Pronchery 
267*592efe25SPierre Pronchery 	if (eflag != PKGCONF_PKG_ERRF_OK)
268*592efe25SPierre Pronchery 		return false;
269*592efe25SPierre Pronchery 
270*592efe25SPierre Pronchery 	pkgconf_output_puts(client->output, PKGCONF_OUTPUT_STDOUT, "}");
271*592efe25SPierre Pronchery 	return true;
272*592efe25SPierre Pronchery }
273*592efe25SPierre Pronchery 
274*592efe25SPierre Pronchery static void
print_solution_node(pkgconf_client_t * client,pkgconf_pkg_t * pkg,void * unused)275*592efe25SPierre Pronchery print_solution_node(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *unused)
276*592efe25SPierre Pronchery {
277*592efe25SPierre Pronchery 	(void) unused;
278*592efe25SPierre Pronchery 
279*592efe25SPierre Pronchery 	pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT, "%s (%llu)%s\n",
280*592efe25SPierre Pronchery 		pkg->id, (unsigned long long) pkg->identifier,
281*592efe25SPierre Pronchery 		(pkg->flags & PKGCONF_PKG_PROPF_VISITED_PRIVATE) == PKGCONF_PKG_PROPF_VISITED_PRIVATE ? " [private]" : "");
282*592efe25SPierre Pronchery }
283*592efe25SPierre Pronchery 
284*592efe25SPierre Pronchery static bool
apply_print_solution(pkgconf_client_t * client,pkgconf_pkg_t * world,void * unused,int maxdepth)285*592efe25SPierre Pronchery apply_print_solution(pkgconf_client_t *client, pkgconf_pkg_t *world, void *unused, int maxdepth)
286*592efe25SPierre Pronchery {
287*592efe25SPierre Pronchery 	int eflag;
288*592efe25SPierre Pronchery 
289*592efe25SPierre Pronchery 	eflag = pkgconf_pkg_traverse(client, world, print_solution_node, unused, maxdepth, 0);
290*592efe25SPierre Pronchery 
291*592efe25SPierre Pronchery 	return eflag == PKGCONF_PKG_ERRF_OK;
292*592efe25SPierre Pronchery }
293*592efe25SPierre Pronchery #endif
294*592efe25SPierre Pronchery 
295*592efe25SPierre Pronchery static bool
apply_modversion(pkgconf_client_t * client,pkgconf_pkg_t * world,void * data,int maxdepth)296*592efe25SPierre Pronchery apply_modversion(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth)
297*592efe25SPierre Pronchery {
298*592efe25SPierre Pronchery 	pkgconf_cli_state_t *state = client->client_data;
299*592efe25SPierre Pronchery 	pkgconf_node_t *queue_iter;
300*592efe25SPierre Pronchery 	pkgconf_list_t *pkgq = data;
301*592efe25SPierre Pronchery 	(void) maxdepth;
302*592efe25SPierre Pronchery 
303*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(pkgq->head, queue_iter)
304*592efe25SPierre Pronchery 	{
305*592efe25SPierre Pronchery 		pkgconf_node_t *world_iter;
306*592efe25SPierre Pronchery 		pkgconf_queue_t *queue_node = queue_iter->data;
307*592efe25SPierre Pronchery 
308*592efe25SPierre Pronchery 		PKGCONF_FOREACH_LIST_ENTRY(world->required.head, world_iter)
309*592efe25SPierre Pronchery 		{
310*592efe25SPierre Pronchery 			pkgconf_dependency_t *dep = world_iter->data;
311*592efe25SPierre Pronchery 			pkgconf_pkg_t *pkg = dep->match;
312*592efe25SPierre Pronchery 
313*592efe25SPierre Pronchery 			const size_t name_len = strlen(pkg->why);
314*592efe25SPierre Pronchery 			if (name_len > strlen(queue_node->package) ||
315*592efe25SPierre Pronchery 				strncmp(pkg->why, queue_node->package, name_len) ||
316*592efe25SPierre Pronchery 				(queue_node->package[name_len] != 0 &&
317*592efe25SPierre Pronchery 					!isspace((unsigned char)queue_node->package[name_len]) &&
318*592efe25SPierre Pronchery 					!PKGCONF_IS_OPERATOR_CHAR(queue_node->package[name_len])))
319*592efe25SPierre Pronchery 			{
320*592efe25SPierre Pronchery 				continue;
321*592efe25SPierre Pronchery 			}
322*592efe25SPierre Pronchery 
323*592efe25SPierre Pronchery 			if (pkg->version != NULL) {
324*592efe25SPierre Pronchery 				if (state->verbosity)
325*592efe25SPierre Pronchery 					pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT, "%s: ", pkg->id);
326*592efe25SPierre Pronchery 
327*592efe25SPierre Pronchery 				pkgconf_output_puts(client->output, PKGCONF_OUTPUT_STDOUT, pkg->version);
328*592efe25SPierre Pronchery 			}
329*592efe25SPierre Pronchery 
330*592efe25SPierre Pronchery 			break;
331*592efe25SPierre Pronchery 		}
332*592efe25SPierre Pronchery 	}
333*592efe25SPierre Pronchery 
334*592efe25SPierre Pronchery 	return true;
335*592efe25SPierre Pronchery }
336*592efe25SPierre Pronchery 
337*592efe25SPierre Pronchery static bool
apply_variables(pkgconf_client_t * client,pkgconf_pkg_t * world,void * unused,int maxdepth)338*592efe25SPierre Pronchery apply_variables(pkgconf_client_t *client, pkgconf_pkg_t *world, void *unused, int maxdepth)
339*592efe25SPierre Pronchery {
340*592efe25SPierre Pronchery 	pkgconf_node_t *iter;
341*592efe25SPierre Pronchery 	(void) unused;
342*592efe25SPierre Pronchery 	(void) maxdepth;
343*592efe25SPierre Pronchery 
344*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(world->required.head, iter)
345*592efe25SPierre Pronchery 	{
346*592efe25SPierre Pronchery 		pkgconf_dependency_t *dep = iter->data;
347*592efe25SPierre Pronchery 		pkgconf_pkg_t *pkg = dep->match;
348*592efe25SPierre Pronchery 
349*592efe25SPierre Pronchery 		print_variables(client->output, pkg);
350*592efe25SPierre Pronchery 	}
351*592efe25SPierre Pronchery 
352*592efe25SPierre Pronchery 	return true;
353*592efe25SPierre Pronchery }
354*592efe25SPierre Pronchery 
355*592efe25SPierre Pronchery static bool
apply_path(pkgconf_client_t * client,pkgconf_pkg_t * world,void * unused,int maxdepth)356*592efe25SPierre Pronchery apply_path(pkgconf_client_t *client, pkgconf_pkg_t *world, void *unused, int maxdepth)
357*592efe25SPierre Pronchery {
358*592efe25SPierre Pronchery 	pkgconf_node_t *iter;
359*592efe25SPierre Pronchery 	(void) unused;
360*592efe25SPierre Pronchery 	(void) maxdepth;
361*592efe25SPierre Pronchery 
362*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(world->required.head, iter)
363*592efe25SPierre Pronchery 	{
364*592efe25SPierre Pronchery 		pkgconf_dependency_t *dep = iter->data;
365*592efe25SPierre Pronchery 		pkgconf_pkg_t *pkg = dep->match;
366*592efe25SPierre Pronchery 
367*592efe25SPierre Pronchery 		/* a module entry with no filename is either virtual, static (builtin) or synthesized. */
368*592efe25SPierre Pronchery 		if (pkg->filename != NULL)
369*592efe25SPierre Pronchery 			pkgconf_output_puts(client->output, PKGCONF_OUTPUT_STDOUT, pkg->filename);
370*592efe25SPierre Pronchery 	}
371*592efe25SPierre Pronchery 
372*592efe25SPierre Pronchery 	return true;
373*592efe25SPierre Pronchery }
374*592efe25SPierre Pronchery 
375*592efe25SPierre Pronchery static char *
variable_eval(pkgconf_client_t * client,const pkgconf_list_t * vars,const char * varname)376*592efe25SPierre Pronchery variable_eval(pkgconf_client_t *client, const pkgconf_list_t *vars, const char *varname)
377*592efe25SPierre Pronchery {
378*592efe25SPierre Pronchery 	pkgconf_buffer_t varbuf = PKGCONF_BUFFER_INITIALIZER;
379*592efe25SPierre Pronchery 	const pkgconf_buffer_t *sysroot_dir = PKGCONF_BUFFER_FROM_STR(client->sysroot_dir);
380*592efe25SPierre Pronchery 	bool saw_sysroot = false;
381*592efe25SPierre Pronchery 	pkgconf_variable_t *v;
382*592efe25SPierre Pronchery 
383*592efe25SPierre Pronchery 	pkgconf_bytecode_eval_ctx_t ctx = {
384*592efe25SPierre Pronchery 		.client = client,
385*592efe25SPierre Pronchery 		.vars = vars,
386*592efe25SPierre Pronchery 	};
387*592efe25SPierre Pronchery 
388*592efe25SPierre Pronchery 	v = pkgconf_bytecode_eval_lookup_var(&ctx, varname, strlen(varname));
389*592efe25SPierre Pronchery 	(void) pkgconf_variable_eval(client, vars, v, &varbuf, &saw_sysroot);
390*592efe25SPierre Pronchery 
391*592efe25SPierre Pronchery 	if (!saw_sysroot && pkgconf_path_is_plausible(&varbuf))
392*592efe25SPierre Pronchery 	{
393*592efe25SPierre Pronchery 		/* if sysroot is set, and value does not already begin with sysroot */
394*592efe25SPierre Pronchery 		if (!pkgconf_buffer_has_prefix(&varbuf, sysroot_dir))
395*592efe25SPierre Pronchery 			pkgconf_buffer_prepend(&varbuf, pkgconf_buffer_str_or_empty(sysroot_dir));
396*592efe25SPierre Pronchery 	}
397*592efe25SPierre Pronchery 
398*592efe25SPierre Pronchery 	return pkgconf_buffer_freeze(&varbuf);
399*592efe25SPierre Pronchery }
400*592efe25SPierre Pronchery 
401*592efe25SPierre Pronchery static bool
apply_variable(pkgconf_client_t * client,pkgconf_pkg_t * world,const void * variable,int maxdepth)402*592efe25SPierre Pronchery apply_variable(pkgconf_client_t *client, pkgconf_pkg_t *world, const void *variable, int maxdepth)
403*592efe25SPierre Pronchery {
404*592efe25SPierre Pronchery 	pkgconf_node_t *iter;
405*592efe25SPierre Pronchery 	(void) maxdepth;
406*592efe25SPierre Pronchery 
407*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(world->required.head, iter)
408*592efe25SPierre Pronchery 	{
409*592efe25SPierre Pronchery 		pkgconf_dependency_t *dep = iter->data;
410*592efe25SPierre Pronchery 		pkgconf_pkg_t *pkg = dep->match;
411*592efe25SPierre Pronchery 		char *result;
412*592efe25SPierre Pronchery 
413*592efe25SPierre Pronchery 		if (pkg == NULL)
414*592efe25SPierre Pronchery 			continue;
415*592efe25SPierre Pronchery 
416*592efe25SPierre Pronchery 		result = variable_eval(client, &pkg->vars, variable);
417*592efe25SPierre Pronchery 
418*592efe25SPierre Pronchery 		if (result != NULL)
419*592efe25SPierre Pronchery 		{
420*592efe25SPierre Pronchery 			pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT,
421*592efe25SPierre Pronchery 				"%s%s", iter->prev != NULL ? " " : "", result);
422*592efe25SPierre Pronchery 			free(result);
423*592efe25SPierre Pronchery 		}
424*592efe25SPierre Pronchery 	}
425*592efe25SPierre Pronchery 
426*592efe25SPierre Pronchery 	pkgconf_output_puts(client->output, PKGCONF_OUTPUT_STDOUT, "");
427*592efe25SPierre Pronchery 
428*592efe25SPierre Pronchery 	return true;
429*592efe25SPierre Pronchery }
430*592efe25SPierre Pronchery 
431*592efe25SPierre Pronchery static bool
apply_env_var(const char * prefix,pkgconf_client_t * client,pkgconf_pkg_t * world,int maxdepth,unsigned int (* collect_fn)(pkgconf_client_t * client,pkgconf_pkg_t * world,pkgconf_list_t * list,int maxdepth),bool (* filter_fn)(const pkgconf_client_t * client,const pkgconf_fragment_t * frag,void * data),void (* postprocess_fn)(pkgconf_client_t * client,pkgconf_pkg_t * world,pkgconf_list_t * fragment_list))432*592efe25SPierre Pronchery apply_env_var(const char *prefix, pkgconf_client_t *client, pkgconf_pkg_t *world, int maxdepth,
433*592efe25SPierre Pronchery 	unsigned int (*collect_fn)(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *list, int maxdepth),
434*592efe25SPierre Pronchery 	bool (*filter_fn)(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, void *data),
435*592efe25SPierre Pronchery 	void (*postprocess_fn)(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *fragment_list))
436*592efe25SPierre Pronchery {
437*592efe25SPierre Pronchery 	pkgconf_cli_state_t *state = client->client_data;
438*592efe25SPierre Pronchery 	pkgconf_list_t unfiltered_list = PKGCONF_LIST_INITIALIZER;
439*592efe25SPierre Pronchery 	pkgconf_list_t filtered_list = PKGCONF_LIST_INITIALIZER;
440*592efe25SPierre Pronchery 	pkgconf_buffer_t render_buf = PKGCONF_BUFFER_INITIALIZER;
441*592efe25SPierre Pronchery 	unsigned int eflag;
442*592efe25SPierre Pronchery 
443*592efe25SPierre Pronchery 	eflag = collect_fn(client, world, &unfiltered_list, maxdepth);
444*592efe25SPierre Pronchery 	if (eflag != PKGCONF_PKG_ERRF_OK)
445*592efe25SPierre Pronchery 		return false;
446*592efe25SPierre Pronchery 
447*592efe25SPierre Pronchery 	pkgconf_fragment_filter(client, &filtered_list, &unfiltered_list, filter_fn, NULL);
448*592efe25SPierre Pronchery 
449*592efe25SPierre Pronchery 	if (postprocess_fn != NULL)
450*592efe25SPierre Pronchery 		postprocess_fn(client, world, &filtered_list);
451*592efe25SPierre Pronchery 
452*592efe25SPierre Pronchery 	if (filtered_list.head == NULL)
453*592efe25SPierre Pronchery 		goto out;
454*592efe25SPierre Pronchery 
455*592efe25SPierre Pronchery 	pkgconf_fragment_render_buf(&filtered_list, &render_buf, true, state->want_render_ops, (state->want_flags & PKG_NEWLINES) ? '\n' : ' ');
456*592efe25SPierre Pronchery 	pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT, "%s='%s'\n",
457*592efe25SPierre Pronchery 		prefix, pkgconf_buffer_str_or_empty(&render_buf));
458*592efe25SPierre Pronchery 	pkgconf_buffer_finalize(&render_buf);
459*592efe25SPierre Pronchery 
460*592efe25SPierre Pronchery out:
461*592efe25SPierre Pronchery 	pkgconf_fragment_free(&unfiltered_list);
462*592efe25SPierre Pronchery 	pkgconf_fragment_free(&filtered_list);
463*592efe25SPierre Pronchery 
464*592efe25SPierre Pronchery 	return true;
465*592efe25SPierre Pronchery }
466*592efe25SPierre Pronchery 
467*592efe25SPierre Pronchery static void
maybe_add_module_definitions(pkgconf_client_t * client,pkgconf_pkg_t * world,pkgconf_list_t * fragment_list)468*592efe25SPierre Pronchery maybe_add_module_definitions(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *fragment_list)
469*592efe25SPierre Pronchery {
470*592efe25SPierre Pronchery 	pkgconf_node_t *world_iter;
471*592efe25SPierre Pronchery 	pkgconf_cli_state_t *state = client->client_data;
472*592efe25SPierre Pronchery 
473*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_EXISTS_CFLAGS) != PKG_EXISTS_CFLAGS)
474*592efe25SPierre Pronchery 		return;
475*592efe25SPierre Pronchery 
476*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(world->required.head, world_iter)
477*592efe25SPierre Pronchery 	{
478*592efe25SPierre Pronchery 		pkgconf_dependency_t *dep = world_iter->data;
479*592efe25SPierre Pronchery 		char havebuf[PKGCONF_ITEM_SIZE];
480*592efe25SPierre Pronchery 		char *p;
481*592efe25SPierre Pronchery 
482*592efe25SPierre Pronchery 		if ((dep->flags & PKGCONF_PKG_DEPF_QUERY) != PKGCONF_PKG_DEPF_QUERY)
483*592efe25SPierre Pronchery 			continue;
484*592efe25SPierre Pronchery 
485*592efe25SPierre Pronchery 		if (dep->match == NULL)
486*592efe25SPierre Pronchery 			continue;
487*592efe25SPierre Pronchery 
488*592efe25SPierre Pronchery 		snprintf(havebuf, sizeof havebuf, "HAVE_%s", dep->match->id);
489*592efe25SPierre Pronchery 
490*592efe25SPierre Pronchery 		for (p = havebuf; *p; p++)
491*592efe25SPierre Pronchery 		{
492*592efe25SPierre Pronchery 			switch (*p)
493*592efe25SPierre Pronchery 			{
494*592efe25SPierre Pronchery 				case ' ':
495*592efe25SPierre Pronchery 				case '-':
496*592efe25SPierre Pronchery 					*p = '_';
497*592efe25SPierre Pronchery 					break;
498*592efe25SPierre Pronchery 
499*592efe25SPierre Pronchery 				default:
500*592efe25SPierre Pronchery 					*p = (char) toupper((unsigned char) *p);
501*592efe25SPierre Pronchery 			}
502*592efe25SPierre Pronchery 		}
503*592efe25SPierre Pronchery 
504*592efe25SPierre Pronchery 		pkgconf_fragment_insert(client, fragment_list, 'D', havebuf, false);
505*592efe25SPierre Pronchery 	}
506*592efe25SPierre Pronchery }
507*592efe25SPierre Pronchery 
508*592efe25SPierre Pronchery static void
apply_env_variables(pkgconf_client_t * client,pkgconf_pkg_t * world,const char * env_prefix)509*592efe25SPierre Pronchery apply_env_variables(pkgconf_client_t *client, pkgconf_pkg_t *world, const char *env_prefix)
510*592efe25SPierre Pronchery {
511*592efe25SPierre Pronchery 	pkgconf_node_t *world_iter;
512*592efe25SPierre Pronchery 	pkgconf_cli_state_t *state = client->client_data;
513*592efe25SPierre Pronchery 
514*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(world->required.head, world_iter)
515*592efe25SPierre Pronchery 	{
516*592efe25SPierre Pronchery 		pkgconf_dependency_t *dep = world_iter->data;
517*592efe25SPierre Pronchery 		pkgconf_pkg_t *pkg = dep->match;
518*592efe25SPierre Pronchery 		pkgconf_node_t *tuple_iter;
519*592efe25SPierre Pronchery 
520*592efe25SPierre Pronchery 		if ((dep->flags & PKGCONF_PKG_DEPF_QUERY) != PKGCONF_PKG_DEPF_QUERY)
521*592efe25SPierre Pronchery 			continue;
522*592efe25SPierre Pronchery 
523*592efe25SPierre Pronchery 		if (dep->match == NULL)
524*592efe25SPierre Pronchery 			continue;
525*592efe25SPierre Pronchery 
526*592efe25SPierre Pronchery 		PKGCONF_FOREACH_LIST_ENTRY(pkg->vars.head, tuple_iter)
527*592efe25SPierre Pronchery 		{
528*592efe25SPierre Pronchery 			pkgconf_tuple_t *tuple = tuple_iter->data;
529*592efe25SPierre Pronchery 			char havebuf[PKGCONF_ITEM_SIZE];
530*592efe25SPierre Pronchery 			char *p;
531*592efe25SPierre Pronchery 
532*592efe25SPierre Pronchery 			if (state->want_variable != NULL && strcmp(state->want_variable, tuple->key))
533*592efe25SPierre Pronchery 				continue;
534*592efe25SPierre Pronchery 
535*592efe25SPierre Pronchery 			snprintf(havebuf, sizeof havebuf, "%s_%s", env_prefix, tuple->key);
536*592efe25SPierre Pronchery 
537*592efe25SPierre Pronchery 			for (p = havebuf; *p; p++)
538*592efe25SPierre Pronchery 			{
539*592efe25SPierre Pronchery 				switch (*p)
540*592efe25SPierre Pronchery 				{
541*592efe25SPierre Pronchery 					case ' ':
542*592efe25SPierre Pronchery 					case '-':
543*592efe25SPierre Pronchery 						*p = '_';
544*592efe25SPierre Pronchery 						break;
545*592efe25SPierre Pronchery 
546*592efe25SPierre Pronchery 					default:
547*592efe25SPierre Pronchery 						*p = (char) toupper((unsigned char) *p);
548*592efe25SPierre Pronchery 				}
549*592efe25SPierre Pronchery 			}
550*592efe25SPierre Pronchery 
551*592efe25SPierre Pronchery 			char *val = pkgconf_variable_eval_str(client, &pkg->vars, tuple, NULL);
552*592efe25SPierre Pronchery 			pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT,
553*592efe25SPierre Pronchery 				"%s='%s'\n", havebuf, val);
554*592efe25SPierre Pronchery 			free(val);
555*592efe25SPierre Pronchery 		}
556*592efe25SPierre Pronchery 	}
557*592efe25SPierre Pronchery }
558*592efe25SPierre Pronchery 
559*592efe25SPierre Pronchery static bool
apply_env(pkgconf_client_t * client,pkgconf_pkg_t * world,const void * env_prefix_p,int maxdepth)560*592efe25SPierre Pronchery apply_env(pkgconf_client_t *client, pkgconf_pkg_t *world, const void *env_prefix_p, int maxdepth)
561*592efe25SPierre Pronchery {
562*592efe25SPierre Pronchery 	pkgconf_cli_state_t *state = client->client_data;
563*592efe25SPierre Pronchery 	const char *want_env_prefix = env_prefix_p, *it;
564*592efe25SPierre Pronchery 	char workbuf[PKGCONF_ITEM_SIZE];
565*592efe25SPierre Pronchery 
566*592efe25SPierre Pronchery 	for (it = want_env_prefix; *it != '\0'; it++)
567*592efe25SPierre Pronchery 		if (!isalpha((unsigned char)*it) &&
568*592efe25SPierre Pronchery 			!isdigit((unsigned char)*it))
569*592efe25SPierre Pronchery 		{
570*592efe25SPierre Pronchery 			return false;
571*592efe25SPierre Pronchery 		}
572*592efe25SPierre Pronchery 
573*592efe25SPierre Pronchery 	snprintf(workbuf, sizeof workbuf, "%s_CFLAGS", want_env_prefix);
574*592efe25SPierre Pronchery 	if (!apply_env_var(workbuf, client, world, maxdepth, pkgconf_pkg_cflags, filter_cflags, maybe_add_module_definitions))
575*592efe25SPierre Pronchery 		return false;
576*592efe25SPierre Pronchery 
577*592efe25SPierre Pronchery 	snprintf(workbuf, sizeof workbuf, "%s_LIBS", want_env_prefix);
578*592efe25SPierre Pronchery 	if (!apply_env_var(workbuf, client, world, maxdepth, pkgconf_pkg_libs, filter_libs, NULL))
579*592efe25SPierre Pronchery 		return false;
580*592efe25SPierre Pronchery 
581*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_VARIABLES) == PKG_VARIABLES || state->want_variable != NULL)
582*592efe25SPierre Pronchery 		apply_env_variables(client, world, want_env_prefix);
583*592efe25SPierre Pronchery 
584*592efe25SPierre Pronchery 	return true;
585*592efe25SPierre Pronchery }
586*592efe25SPierre Pronchery 
587*592efe25SPierre Pronchery static bool
apply_cflags(pkgconf_client_t * client,pkgconf_pkg_t * world,pkgconf_list_t * target_list,int maxdepth)588*592efe25SPierre Pronchery apply_cflags(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *target_list, int maxdepth)
589*592efe25SPierre Pronchery {
590*592efe25SPierre Pronchery 	pkgconf_list_t unfiltered_list = PKGCONF_LIST_INITIALIZER;
591*592efe25SPierre Pronchery 	pkgconf_list_t filtered_list = PKGCONF_LIST_INITIALIZER;
592*592efe25SPierre Pronchery 	int eflag;
593*592efe25SPierre Pronchery 
594*592efe25SPierre Pronchery 	eflag = pkgconf_pkg_cflags(client, world, &unfiltered_list, maxdepth);
595*592efe25SPierre Pronchery 	if (eflag != PKGCONF_PKG_ERRF_OK)
596*592efe25SPierre Pronchery 		return false;
597*592efe25SPierre Pronchery 
598*592efe25SPierre Pronchery 	pkgconf_fragment_filter(client, &filtered_list, &unfiltered_list, filter_cflags, NULL);
599*592efe25SPierre Pronchery 	maybe_add_module_definitions(client, world, &filtered_list);
600*592efe25SPierre Pronchery 
601*592efe25SPierre Pronchery 	if (filtered_list.head == NULL)
602*592efe25SPierre Pronchery 		goto out;
603*592efe25SPierre Pronchery 
604*592efe25SPierre Pronchery 	pkgconf_fragment_copy_list(client, target_list, &filtered_list);
605*592efe25SPierre Pronchery 
606*592efe25SPierre Pronchery out:
607*592efe25SPierre Pronchery 	pkgconf_fragment_free(&unfiltered_list);
608*592efe25SPierre Pronchery 	pkgconf_fragment_free(&filtered_list);
609*592efe25SPierre Pronchery 
610*592efe25SPierre Pronchery 	return true;
611*592efe25SPierre Pronchery }
612*592efe25SPierre Pronchery 
613*592efe25SPierre Pronchery static bool
apply_libs(pkgconf_client_t * client,pkgconf_pkg_t * world,pkgconf_list_t * target_list,int maxdepth)614*592efe25SPierre Pronchery apply_libs(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *target_list, int maxdepth)
615*592efe25SPierre Pronchery {
616*592efe25SPierre Pronchery 	pkgconf_list_t unfiltered_list = PKGCONF_LIST_INITIALIZER;
617*592efe25SPierre Pronchery 	pkgconf_list_t filtered_list = PKGCONF_LIST_INITIALIZER;
618*592efe25SPierre Pronchery 	int eflag;
619*592efe25SPierre Pronchery 
620*592efe25SPierre Pronchery 	eflag = pkgconf_pkg_libs(client, world, &unfiltered_list, maxdepth);
621*592efe25SPierre Pronchery 	if (eflag != PKGCONF_PKG_ERRF_OK)
622*592efe25SPierre Pronchery 		return false;
623*592efe25SPierre Pronchery 
624*592efe25SPierre Pronchery 	pkgconf_fragment_filter(client, &filtered_list, &unfiltered_list, filter_libs, NULL);
625*592efe25SPierre Pronchery 
626*592efe25SPierre Pronchery 	if (filtered_list.head == NULL)
627*592efe25SPierre Pronchery 		goto out;
628*592efe25SPierre Pronchery 
629*592efe25SPierre Pronchery 	pkgconf_fragment_copy_list(client, target_list, &filtered_list);
630*592efe25SPierre Pronchery 
631*592efe25SPierre Pronchery out:
632*592efe25SPierre Pronchery 	pkgconf_fragment_free(&unfiltered_list);
633*592efe25SPierre Pronchery 	pkgconf_fragment_free(&filtered_list);
634*592efe25SPierre Pronchery 
635*592efe25SPierre Pronchery 	return true;
636*592efe25SPierre Pronchery }
637*592efe25SPierre Pronchery 
638*592efe25SPierre Pronchery static bool
apply_requires(pkgconf_client_t * client,pkgconf_pkg_t * world,void * unused,int maxdepth)639*592efe25SPierre Pronchery apply_requires(pkgconf_client_t *client, pkgconf_pkg_t *world, void *unused, int maxdepth)
640*592efe25SPierre Pronchery {
641*592efe25SPierre Pronchery 	pkgconf_node_t *iter;
642*592efe25SPierre Pronchery 	(void) unused;
643*592efe25SPierre Pronchery 	(void) maxdepth;
644*592efe25SPierre Pronchery 
645*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(world->required.head, iter)
646*592efe25SPierre Pronchery 	{
647*592efe25SPierre Pronchery 		pkgconf_dependency_t *dep = iter->data;
648*592efe25SPierre Pronchery 		pkgconf_pkg_t *pkg = dep->match;
649*592efe25SPierre Pronchery 
650*592efe25SPierre Pronchery 		print_dependency_list(client->output, &pkg->required);
651*592efe25SPierre Pronchery 	}
652*592efe25SPierre Pronchery 
653*592efe25SPierre Pronchery 	return true;
654*592efe25SPierre Pronchery }
655*592efe25SPierre Pronchery 
656*592efe25SPierre Pronchery static bool
apply_requires_private(pkgconf_client_t * client,pkgconf_pkg_t * world,void * unused,int maxdepth)657*592efe25SPierre Pronchery apply_requires_private(pkgconf_client_t *client, pkgconf_pkg_t *world, void *unused, int maxdepth)
658*592efe25SPierre Pronchery {
659*592efe25SPierre Pronchery 	pkgconf_node_t *iter;
660*592efe25SPierre Pronchery 	(void) unused;
661*592efe25SPierre Pronchery 	(void) maxdepth;
662*592efe25SPierre Pronchery 
663*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(world->required.head, iter)
664*592efe25SPierre Pronchery 	{
665*592efe25SPierre Pronchery 		pkgconf_dependency_t *dep = iter->data;
666*592efe25SPierre Pronchery 		pkgconf_pkg_t *pkg = dep->match;
667*592efe25SPierre Pronchery 
668*592efe25SPierre Pronchery 		print_dependency_list(client->output, &pkg->requires_private);
669*592efe25SPierre Pronchery 	}
670*592efe25SPierre Pronchery 	return true;
671*592efe25SPierre Pronchery }
672*592efe25SPierre Pronchery 
673*592efe25SPierre Pronchery static void
check_uninstalled(pkgconf_client_t * client,pkgconf_pkg_t * pkg,void * data)674*592efe25SPierre Pronchery check_uninstalled(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data)
675*592efe25SPierre Pronchery {
676*592efe25SPierre Pronchery 	int *retval = data;
677*592efe25SPierre Pronchery 	(void) client;
678*592efe25SPierre Pronchery 
679*592efe25SPierre Pronchery 	if (pkg->flags & PKGCONF_PKG_PROPF_UNINSTALLED)
680*592efe25SPierre Pronchery 		*retval = EXIT_SUCCESS;
681*592efe25SPierre Pronchery }
682*592efe25SPierre Pronchery 
683*592efe25SPierre Pronchery static bool
apply_uninstalled(pkgconf_client_t * client,pkgconf_pkg_t * world,void * data,int maxdepth)684*592efe25SPierre Pronchery apply_uninstalled(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth)
685*592efe25SPierre Pronchery {
686*592efe25SPierre Pronchery 	int eflag;
687*592efe25SPierre Pronchery 
688*592efe25SPierre Pronchery 	eflag = pkgconf_pkg_traverse(client, world, check_uninstalled, data, maxdepth, 0);
689*592efe25SPierre Pronchery 
690*592efe25SPierre Pronchery 	if (eflag != PKGCONF_PKG_ERRF_OK)
691*592efe25SPierre Pronchery 		return false;
692*592efe25SPierre Pronchery 
693*592efe25SPierre Pronchery 	return true;
694*592efe25SPierre Pronchery }
695*592efe25SPierre Pronchery 
696*592efe25SPierre Pronchery #ifndef PKGCONF_LITE
697*592efe25SPierre Pronchery static void
print_graph_node(pkgconf_client_t * client,pkgconf_pkg_t * pkg,void * data)698*592efe25SPierre Pronchery print_graph_node(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data)
699*592efe25SPierre Pronchery {
700*592efe25SPierre Pronchery 	pkgconf_node_t *n;
701*592efe25SPierre Pronchery 
702*592efe25SPierre Pronchery 	(void) data;
703*592efe25SPierre Pronchery 
704*592efe25SPierre Pronchery 	pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT, "node '%s' {\n", pkg->id);
705*592efe25SPierre Pronchery 
706*592efe25SPierre Pronchery 	if (pkg->version != NULL)
707*592efe25SPierre Pronchery 		pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT, "    version = '%s';\n", pkg->version);
708*592efe25SPierre Pronchery 
709*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(pkg->required.head, n)
710*592efe25SPierre Pronchery 	{
711*592efe25SPierre Pronchery 		pkgconf_dependency_t *dep = n->data;
712*592efe25SPierre Pronchery 
713*592efe25SPierre Pronchery 		pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT, "    dependency '%s'", dep->package);
714*592efe25SPierre Pronchery 
715*592efe25SPierre Pronchery 		if (dep->compare != PKGCONF_CMP_ANY)
716*592efe25SPierre Pronchery 		{
717*592efe25SPierre Pronchery 			pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT,
718*592efe25SPierre Pronchery 				" {\n"
719*592efe25SPierre Pronchery 				"        comparator = '%s';\n"
720*592efe25SPierre Pronchery 				"        version = '%s';\n"
721*592efe25SPierre Pronchery 				"    };\n",
722*592efe25SPierre Pronchery 				pkgconf_pkg_get_comparator(dep), dep->version);
723*592efe25SPierre Pronchery 		}
724*592efe25SPierre Pronchery 		else
725*592efe25SPierre Pronchery 			pkgconf_output_puts(client->output, PKGCONF_OUTPUT_STDOUT, ";");
726*592efe25SPierre Pronchery 	}
727*592efe25SPierre Pronchery 
728*592efe25SPierre Pronchery 	pkgconf_output_puts(client->output, PKGCONF_OUTPUT_STDOUT, "};");
729*592efe25SPierre Pronchery }
730*592efe25SPierre Pronchery 
731*592efe25SPierre Pronchery static bool
apply_simulate(pkgconf_client_t * client,pkgconf_pkg_t * world,void * data,int maxdepth)732*592efe25SPierre Pronchery apply_simulate(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth)
733*592efe25SPierre Pronchery {
734*592efe25SPierre Pronchery 	int eflag;
735*592efe25SPierre Pronchery 
736*592efe25SPierre Pronchery 	eflag = pkgconf_pkg_traverse(client, world, print_graph_node, data, maxdepth, 0);
737*592efe25SPierre Pronchery 
738*592efe25SPierre Pronchery 	if (eflag != PKGCONF_PKG_ERRF_OK)
739*592efe25SPierre Pronchery 		return false;
740*592efe25SPierre Pronchery 
741*592efe25SPierre Pronchery 	return true;
742*592efe25SPierre Pronchery }
743*592efe25SPierre Pronchery #endif
744*592efe25SPierre Pronchery 
745*592efe25SPierre Pronchery static void
print_fragment_tree_branch(pkgconf_output_t * output,pkgconf_list_t * fragment_list,int indent)746*592efe25SPierre Pronchery print_fragment_tree_branch(pkgconf_output_t *output, pkgconf_list_t *fragment_list, int indent)
747*592efe25SPierre Pronchery {
748*592efe25SPierre Pronchery 	pkgconf_node_t *iter;
749*592efe25SPierre Pronchery 
750*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(fragment_list->head, iter)
751*592efe25SPierre Pronchery 	{
752*592efe25SPierre Pronchery 		pkgconf_fragment_t *frag = iter->data;
753*592efe25SPierre Pronchery 
754*592efe25SPierre Pronchery 		if (frag->type)
755*592efe25SPierre Pronchery 			pkgconf_output_fmt(output, PKGCONF_OUTPUT_STDOUT,
756*592efe25SPierre Pronchery 				"%*s'-%c%s' [type %c, " SIZE_FMT_SPECIFIER " children]\n", indent, "", frag->type, frag->data, frag->type, frag->children.length);
757*592efe25SPierre Pronchery 		else
758*592efe25SPierre Pronchery 			pkgconf_output_fmt(output, PKGCONF_OUTPUT_STDOUT,
759*592efe25SPierre Pronchery 				"%*s'%s' [untyped, " SIZE_FMT_SPECIFIER " children]\n", indent, "", frag->data, frag->children.length);
760*592efe25SPierre Pronchery 
761*592efe25SPierre Pronchery 		print_fragment_tree_branch(output, &frag->children, indent + 2);
762*592efe25SPierre Pronchery 	}
763*592efe25SPierre Pronchery 
764*592efe25SPierre Pronchery 	if (fragment_list->head != NULL)
765*592efe25SPierre Pronchery 		pkgconf_output_puts(output, PKGCONF_OUTPUT_STDOUT, "");
766*592efe25SPierre Pronchery }
767*592efe25SPierre Pronchery 
768*592efe25SPierre Pronchery static bool
apply_fragment_tree(pkgconf_client_t * client,pkgconf_pkg_t * world,void * data,int maxdepth)769*592efe25SPierre Pronchery apply_fragment_tree(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth)
770*592efe25SPierre Pronchery {
771*592efe25SPierre Pronchery 	pkgconf_list_t unfiltered_list = PKGCONF_LIST_INITIALIZER;
772*592efe25SPierre Pronchery 	int eflag;
773*592efe25SPierre Pronchery 
774*592efe25SPierre Pronchery 	(void) data;
775*592efe25SPierre Pronchery 
776*592efe25SPierre Pronchery 	eflag = pkgconf_pkg_cflags(client, world, &unfiltered_list, maxdepth);
777*592efe25SPierre Pronchery 	if (eflag != PKGCONF_PKG_ERRF_OK)
778*592efe25SPierre Pronchery 		return false;
779*592efe25SPierre Pronchery 
780*592efe25SPierre Pronchery 	eflag = pkgconf_pkg_libs(client, world, &unfiltered_list, maxdepth);
781*592efe25SPierre Pronchery 	if (eflag != PKGCONF_PKG_ERRF_OK)
782*592efe25SPierre Pronchery 		return false;
783*592efe25SPierre Pronchery 
784*592efe25SPierre Pronchery 	print_fragment_tree_branch(client->output, &unfiltered_list, 0);
785*592efe25SPierre Pronchery 	pkgconf_fragment_free(&unfiltered_list);
786*592efe25SPierre Pronchery 
787*592efe25SPierre Pronchery 	return true;
788*592efe25SPierre Pronchery }
789*592efe25SPierre Pronchery 
790*592efe25SPierre Pronchery static void
print_license(pkgconf_client_t * client,pkgconf_pkg_t * pkg,void * data)791*592efe25SPierre Pronchery print_license(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data)
792*592efe25SPierre Pronchery {
793*592efe25SPierre Pronchery 	pkgconf_buffer_t render_buf = PKGCONF_BUFFER_INITIALIZER;
794*592efe25SPierre Pronchery 	(void) data;
795*592efe25SPierre Pronchery 
796*592efe25SPierre Pronchery 	if (pkg->flags & PKGCONF_PKG_PROPF_VIRTUAL)
797*592efe25SPierre Pronchery 		return;
798*592efe25SPierre Pronchery 
799*592efe25SPierre Pronchery 	if (pkg->license.head == NULL)
800*592efe25SPierre Pronchery 	{
801*592efe25SPierre Pronchery 		pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT,
802*592efe25SPierre Pronchery 				"%s: NOASSERTION\n", pkg->id);
803*592efe25SPierre Pronchery 	}
804*592efe25SPierre Pronchery 	else
805*592efe25SPierre Pronchery 	{
806*592efe25SPierre Pronchery 		/* NOASSERTION is the default when the license is unknown, per SPDX spec § 3.15 */
807*592efe25SPierre Pronchery 		pkgconf_license_render(client, &pkg->license, &render_buf);
808*592efe25SPierre Pronchery 		pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT, "%s: ", pkg->id);
809*592efe25SPierre Pronchery 		pkgconf_output_putbuf(client->output, PKGCONF_OUTPUT_STDOUT, &render_buf, true);
810*592efe25SPierre Pronchery 		pkgconf_buffer_finalize(&render_buf);
811*592efe25SPierre Pronchery 	}
812*592efe25SPierre Pronchery }
813*592efe25SPierre Pronchery 
814*592efe25SPierre Pronchery static bool
apply_license(pkgconf_client_t * client,pkgconf_pkg_t * world,void * data,int maxdepth)815*592efe25SPierre Pronchery apply_license(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth)
816*592efe25SPierre Pronchery {
817*592efe25SPierre Pronchery 	int eflag;
818*592efe25SPierre Pronchery 
819*592efe25SPierre Pronchery 	eflag = pkgconf_pkg_traverse(client, world, print_license, data, maxdepth, 0);
820*592efe25SPierre Pronchery 
821*592efe25SPierre Pronchery 	if (eflag != PKGCONF_PKG_ERRF_OK)
822*592efe25SPierre Pronchery 		return false;
823*592efe25SPierre Pronchery 
824*592efe25SPierre Pronchery 	return true;
825*592efe25SPierre Pronchery }
826*592efe25SPierre Pronchery 
827*592efe25SPierre Pronchery static bool
apply_link_abi(pkgconf_client_t * client,pkgconf_pkg_t * world,void * data,int maxdepth)828*592efe25SPierre Pronchery apply_link_abi(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth)
829*592efe25SPierre Pronchery {
830*592efe25SPierre Pronchery 	pkgconf_list_t abis = PKGCONF_LIST_INITIALIZER;
831*592efe25SPierre Pronchery 	pkgconf_buffer_t render_buf = PKGCONF_BUFFER_INITIALIZER;
832*592efe25SPierre Pronchery 	pkgconf_node_t *node;
833*592efe25SPierre Pronchery 	int *retval = data;
834*592efe25SPierre Pronchery 
835*592efe25SPierre Pronchery 	if (pkgconf_pkg_link_abi(client, world, &abis, maxdepth) != PKGCONF_PKG_ERRF_OK)
836*592efe25SPierre Pronchery 	{
837*592efe25SPierre Pronchery 		pkgconf_bufferset_free(&abis);
838*592efe25SPierre Pronchery 		*retval = EXIT_FAILURE;
839*592efe25SPierre Pronchery 		return false;
840*592efe25SPierre Pronchery 	}
841*592efe25SPierre Pronchery 
842*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(abis.head, node)
843*592efe25SPierre Pronchery 	{
844*592efe25SPierre Pronchery 		pkgconf_bufferset_t *tag = node->data;
845*592efe25SPierre Pronchery 
846*592efe25SPierre Pronchery 		if (pkgconf_buffer_len(&render_buf))
847*592efe25SPierre Pronchery 			pkgconf_buffer_push_byte(&render_buf, ' ');
848*592efe25SPierre Pronchery 
849*592efe25SPierre Pronchery 		pkgconf_buffer_append(&render_buf, pkgconf_buffer_str(&tag->buffer));
850*592efe25SPierre Pronchery 	}
851*592efe25SPierre Pronchery 
852*592efe25SPierre Pronchery 	pkgconf_output_putbuf(client->output, PKGCONF_OUTPUT_STDOUT, &render_buf, true);
853*592efe25SPierre Pronchery 
854*592efe25SPierre Pronchery 	pkgconf_buffer_finalize(&render_buf);
855*592efe25SPierre Pronchery 	pkgconf_bufferset_free(&abis);
856*592efe25SPierre Pronchery 
857*592efe25SPierre Pronchery 	return true;
858*592efe25SPierre Pronchery }
859*592efe25SPierre Pronchery 
860*592efe25SPierre Pronchery static void
print_license_file(pkgconf_client_t * client,pkgconf_pkg_t * pkg,void * data)861*592efe25SPierre Pronchery print_license_file(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data)
862*592efe25SPierre Pronchery {
863*592efe25SPierre Pronchery 	(void) data;
864*592efe25SPierre Pronchery 
865*592efe25SPierre Pronchery 	if (pkg->flags & PKGCONF_PKG_PROPF_VIRTUAL)
866*592efe25SPierre Pronchery 		return;
867*592efe25SPierre Pronchery 
868*592efe25SPierre Pronchery 	/* If license file location is not available then just print empty */
869*592efe25SPierre Pronchery 	pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT, "%s: %s\n",
870*592efe25SPierre Pronchery 		pkg->id, pkg->license_file != NULL ? pkg->license_file : "");
871*592efe25SPierre Pronchery }
872*592efe25SPierre Pronchery 
873*592efe25SPierre Pronchery static bool
apply_license_file(pkgconf_client_t * client,pkgconf_pkg_t * world,void * data,int maxdepth)874*592efe25SPierre Pronchery apply_license_file(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth)
875*592efe25SPierre Pronchery {
876*592efe25SPierre Pronchery 	int eflag;
877*592efe25SPierre Pronchery 
878*592efe25SPierre Pronchery 	eflag = pkgconf_pkg_traverse(client, world, print_license_file, data, maxdepth, 0);
879*592efe25SPierre Pronchery 
880*592efe25SPierre Pronchery 	if (eflag != PKGCONF_PKG_ERRF_OK)
881*592efe25SPierre Pronchery 		return false;
882*592efe25SPierre Pronchery 
883*592efe25SPierre Pronchery 	return true;
884*592efe25SPierre Pronchery }
885*592efe25SPierre Pronchery 
886*592efe25SPierre Pronchery static void
print_source(pkgconf_client_t * client,pkgconf_pkg_t * pkg,void * data)887*592efe25SPierre Pronchery print_source(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data)
888*592efe25SPierre Pronchery {
889*592efe25SPierre Pronchery 	(void) data;
890*592efe25SPierre Pronchery 
891*592efe25SPierre Pronchery 	if (pkg->flags & PKGCONF_PKG_PROPF_VIRTUAL)
892*592efe25SPierre Pronchery 		return;
893*592efe25SPierre Pronchery 
894*592efe25SPierre Pronchery 	/* If source is empty then empty string is printed otherwise URL */
895*592efe25SPierre Pronchery 	pkgconf_output_fmt(client->output, PKGCONF_OUTPUT_STDOUT, "%s: %s\n",
896*592efe25SPierre Pronchery 		pkg->id, pkg->source != NULL ? pkg->source : "");
897*592efe25SPierre Pronchery }
898*592efe25SPierre Pronchery 
899*592efe25SPierre Pronchery static bool
apply_source(pkgconf_client_t * client,pkgconf_pkg_t * world,void * data,int maxdepth)900*592efe25SPierre Pronchery apply_source(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth)
901*592efe25SPierre Pronchery {
902*592efe25SPierre Pronchery 	int eflag;
903*592efe25SPierre Pronchery 
904*592efe25SPierre Pronchery 	eflag = pkgconf_pkg_traverse(client, world, print_source, data, maxdepth, 0);
905*592efe25SPierre Pronchery 
906*592efe25SPierre Pronchery 	if (eflag != PKGCONF_PKG_ERRF_OK)
907*592efe25SPierre Pronchery 		return false;
908*592efe25SPierre Pronchery 
909*592efe25SPierre Pronchery 	return true;
910*592efe25SPierre Pronchery }
911*592efe25SPierre Pronchery 
912*592efe25SPierre Pronchery void
path_list_to_buffer(const pkgconf_list_t * list,pkgconf_buffer_t * buffer,char delim)913*592efe25SPierre Pronchery path_list_to_buffer(const pkgconf_list_t *list, pkgconf_buffer_t *buffer, char delim)
914*592efe25SPierre Pronchery {
915*592efe25SPierre Pronchery 	pkgconf_node_t *n;
916*592efe25SPierre Pronchery 
917*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(list->head, n)
918*592efe25SPierre Pronchery 	{
919*592efe25SPierre Pronchery 		pkgconf_path_t *pn = n->data;
920*592efe25SPierre Pronchery 
921*592efe25SPierre Pronchery 		if (n != list->head)
922*592efe25SPierre Pronchery 			pkgconf_buffer_push_byte(buffer, delim);
923*592efe25SPierre Pronchery 
924*592efe25SPierre Pronchery 		pkgconf_buffer_append(buffer, pn->path);
925*592efe25SPierre Pronchery 	}
926*592efe25SPierre Pronchery }
927*592efe25SPierre Pronchery 
928*592efe25SPierre Pronchery static void
unveil_search_paths(pkgconf_client_t * client,const pkgconf_cross_personality_t * personality)929*592efe25SPierre Pronchery unveil_search_paths(pkgconf_client_t *client, const pkgconf_cross_personality_t *personality)
930*592efe25SPierre Pronchery {
931*592efe25SPierre Pronchery 	pkgconf_node_t *n;
932*592efe25SPierre Pronchery 
933*592efe25SPierre Pronchery 	client->unveil_handler(client, "/dev/null", "rwc");
934*592efe25SPierre Pronchery 
935*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(client->dir_list.head, n)
936*592efe25SPierre Pronchery 	{
937*592efe25SPierre Pronchery 		pkgconf_path_t *pn = n->data;
938*592efe25SPierre Pronchery 
939*592efe25SPierre Pronchery 		client->unveil_handler(client, pn->path, "r");
940*592efe25SPierre Pronchery 	}
941*592efe25SPierre Pronchery 
942*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(personality->dir_list.head, n)
943*592efe25SPierre Pronchery 	{
944*592efe25SPierre Pronchery 		pkgconf_path_t *pn = n->data;
945*592efe25SPierre Pronchery 
946*592efe25SPierre Pronchery 		client->unveil_handler(client, pn->path, "r");
947*592efe25SPierre Pronchery 	}
948*592efe25SPierre Pronchery }
949*592efe25SPierre Pronchery 
950*592efe25SPierre Pronchery /* SAFETY: pkgconf_client_t takes ownership of these package objects */
951*592efe25SPierre Pronchery static void
register_builtins(pkgconf_client_t * client,const pkgconf_cross_personality_t * personality)952*592efe25SPierre Pronchery register_builtins(pkgconf_client_t *client, const pkgconf_cross_personality_t *personality)
953*592efe25SPierre Pronchery {
954*592efe25SPierre Pronchery 	pkgconf_buffer_t pc_path_buf = PKGCONF_BUFFER_INITIALIZER;
955*592efe25SPierre Pronchery 	path_list_to_buffer(&personality->dir_list, &pc_path_buf, ':');
956*592efe25SPierre Pronchery 
957*592efe25SPierre Pronchery 	pkgconf_buffer_t pc_system_libdirs_buf = PKGCONF_BUFFER_INITIALIZER;
958*592efe25SPierre Pronchery 	path_list_to_buffer(&personality->filter_libdirs, &pc_system_libdirs_buf, ':');
959*592efe25SPierre Pronchery 
960*592efe25SPierre Pronchery 	pkgconf_buffer_t pc_system_includedirs_buf = PKGCONF_BUFFER_INITIALIZER;
961*592efe25SPierre Pronchery 	path_list_to_buffer(&personality->filter_includedirs, &pc_system_includedirs_buf, ':');
962*592efe25SPierre Pronchery 
963*592efe25SPierre Pronchery 	pkgconf_pkg_t *pkg_config_virtual = calloc(1, sizeof(pkgconf_pkg_t));
964*592efe25SPierre Pronchery 	if (pkg_config_virtual == NULL)
965*592efe25SPierre Pronchery 	{
966*592efe25SPierre Pronchery 		goto error;
967*592efe25SPierre Pronchery 	}
968*592efe25SPierre Pronchery 
969*592efe25SPierre Pronchery 	pkg_config_virtual->owner = client;
970*592efe25SPierre Pronchery 	pkg_config_virtual->id = strdup("pkg-config");
971*592efe25SPierre Pronchery 	pkg_config_virtual->realname = strdup("pkg-config");
972*592efe25SPierre Pronchery 	pkg_config_virtual->description = strdup("virtual package defining pkgconf API version supported");
973*592efe25SPierre Pronchery 	pkg_config_virtual->url = strdup(PACKAGE_BUGREPORT);
974*592efe25SPierre Pronchery 	pkg_config_virtual->version = strdup(PACKAGE_VERSION);
975*592efe25SPierre Pronchery 
976*592efe25SPierre Pronchery 	pkgconf_tuple_add(client, &pkg_config_virtual->vars, "pc_system_libdirs", pkgconf_buffer_str_or_empty(&pc_system_libdirs_buf), false, 0);
977*592efe25SPierre Pronchery 	pkgconf_tuple_add(client, &pkg_config_virtual->vars, "pc_system_includedirs", pkgconf_buffer_str_or_empty(&pc_system_includedirs_buf), false, 0);
978*592efe25SPierre Pronchery 	pkgconf_tuple_add(client, &pkg_config_virtual->vars, "pc_path", pkgconf_buffer_str_or_empty(&pc_path_buf), false, 0);
979*592efe25SPierre Pronchery 
980*592efe25SPierre Pronchery 	if (!pkgconf_client_preload_one(client, pkg_config_virtual))
981*592efe25SPierre Pronchery 	{
982*592efe25SPierre Pronchery 		goto error;
983*592efe25SPierre Pronchery 	}
984*592efe25SPierre Pronchery 
985*592efe25SPierre Pronchery 	pkgconf_pkg_t *pkgconf_virtual = calloc(1, sizeof(pkgconf_pkg_t));
986*592efe25SPierre Pronchery 	if (pkgconf_virtual == NULL)
987*592efe25SPierre Pronchery 	{
988*592efe25SPierre Pronchery 		goto error;
989*592efe25SPierre Pronchery 	}
990*592efe25SPierre Pronchery 
991*592efe25SPierre Pronchery 	pkgconf_virtual->owner = client;
992*592efe25SPierre Pronchery 	pkgconf_virtual->id = strdup("pkgconf");
993*592efe25SPierre Pronchery 	pkgconf_virtual->realname = strdup("pkgconf");
994*592efe25SPierre Pronchery 	pkgconf_virtual->description = strdup("virtual package defining pkgconf API version supported");
995*592efe25SPierre Pronchery 	pkgconf_virtual->url = strdup(PACKAGE_BUGREPORT);
996*592efe25SPierre Pronchery 	pkgconf_virtual->version = strdup(PACKAGE_VERSION);
997*592efe25SPierre Pronchery 
998*592efe25SPierre Pronchery 	pkgconf_tuple_add(client, &pkgconf_virtual->vars, "pc_system_libdirs", pkgconf_buffer_str_or_empty(&pc_system_libdirs_buf), false, 0);
999*592efe25SPierre Pronchery 	pkgconf_tuple_add(client, &pkgconf_virtual->vars, "pc_system_includedirs", pkgconf_buffer_str_or_empty(&pc_system_includedirs_buf), false, 0);
1000*592efe25SPierre Pronchery 	pkgconf_tuple_add(client, &pkgconf_virtual->vars, "pc_path", pkgconf_buffer_str_or_empty(&pc_path_buf), false, 0);
1001*592efe25SPierre Pronchery 
1002*592efe25SPierre Pronchery 	if (!pkgconf_client_preload_one(client, pkgconf_virtual))
1003*592efe25SPierre Pronchery 	{
1004*592efe25SPierre Pronchery 		goto error;
1005*592efe25SPierre Pronchery 	}
1006*592efe25SPierre Pronchery 
1007*592efe25SPierre Pronchery error:
1008*592efe25SPierre Pronchery 	pkgconf_buffer_finalize(&pc_path_buf);
1009*592efe25SPierre Pronchery 	pkgconf_buffer_finalize(&pc_system_libdirs_buf);
1010*592efe25SPierre Pronchery 	pkgconf_buffer_finalize(&pc_system_includedirs_buf);
1011*592efe25SPierre Pronchery }
1012*592efe25SPierre Pronchery 
1013*592efe25SPierre Pronchery #ifndef PKGCONF_LITE
1014*592efe25SPierre Pronchery static void
dump_personality(pkgconf_output_t * output,const pkgconf_cross_personality_t * p)1015*592efe25SPierre Pronchery dump_personality(pkgconf_output_t *output, const pkgconf_cross_personality_t *p)
1016*592efe25SPierre Pronchery {
1017*592efe25SPierre Pronchery 	pkgconf_buffer_t pc_path_buf = PKGCONF_BUFFER_INITIALIZER;
1018*592efe25SPierre Pronchery 	path_list_to_buffer(&p->dir_list, &pc_path_buf, ':');
1019*592efe25SPierre Pronchery 
1020*592efe25SPierre Pronchery 	pkgconf_buffer_t pc_system_libdirs_buf = PKGCONF_BUFFER_INITIALIZER;
1021*592efe25SPierre Pronchery 	path_list_to_buffer(&p->filter_libdirs, &pc_system_libdirs_buf, ':');
1022*592efe25SPierre Pronchery 
1023*592efe25SPierre Pronchery 	pkgconf_buffer_t pc_system_includedirs_buf = PKGCONF_BUFFER_INITIALIZER;
1024*592efe25SPierre Pronchery 	path_list_to_buffer(&p->filter_includedirs, &pc_system_includedirs_buf, ':');
1025*592efe25SPierre Pronchery 
1026*592efe25SPierre Pronchery 	pkgconf_output_fmt(output, PKGCONF_OUTPUT_STDOUT, "Triplet: %s\n", p->name);
1027*592efe25SPierre Pronchery 
1028*592efe25SPierre Pronchery 	if (p->sysroot_dir)
1029*592efe25SPierre Pronchery 		pkgconf_output_fmt(output, PKGCONF_OUTPUT_STDOUT, "SysrootDir: %s\n", p->sysroot_dir);
1030*592efe25SPierre Pronchery 
1031*592efe25SPierre Pronchery 	pkgconf_output_fmt(output, PKGCONF_OUTPUT_STDOUT, "DefaultSearchPaths: %s\n", pc_path_buf.base);
1032*592efe25SPierre Pronchery 	pkgconf_output_fmt(output, PKGCONF_OUTPUT_STDOUT, "SystemIncludePaths: %s\n", pc_system_includedirs_buf.base);
1033*592efe25SPierre Pronchery 	pkgconf_output_fmt(output, PKGCONF_OUTPUT_STDOUT, "SystemLibraryPaths: %s\n", pc_system_libdirs_buf.base);
1034*592efe25SPierre Pronchery 
1035*592efe25SPierre Pronchery 	if (p->want_default_pure)
1036*592efe25SPierre Pronchery 		pkgconf_output_fmt(output, PKGCONF_OUTPUT_STDOUT, "WantDefaultPure: true\n");
1037*592efe25SPierre Pronchery 
1038*592efe25SPierre Pronchery 	if (p->want_default_static)
1039*592efe25SPierre Pronchery 		pkgconf_output_fmt(output, PKGCONF_OUTPUT_STDOUT, "WantDefaultStatic: true\n");
1040*592efe25SPierre Pronchery 
1041*592efe25SPierre Pronchery 	pkgconf_buffer_finalize(&pc_path_buf);
1042*592efe25SPierre Pronchery 	pkgconf_buffer_finalize(&pc_system_libdirs_buf);
1043*592efe25SPierre Pronchery 	pkgconf_buffer_finalize(&pc_system_includedirs_buf);
1044*592efe25SPierre Pronchery }
1045*592efe25SPierre Pronchery #endif
1046*592efe25SPierre Pronchery 
1047*592efe25SPierre Pronchery int
pkgconf_cli_run(pkgconf_cli_state_t * state,int argc,char * argv[],int last_argc)1048*592efe25SPierre Pronchery pkgconf_cli_run(pkgconf_cli_state_t *state, int argc, char *argv[], int last_argc)
1049*592efe25SPierre Pronchery {
1050*592efe25SPierre Pronchery 	(void) argc;
1051*592efe25SPierre Pronchery 
1052*592efe25SPierre Pronchery 	int ret = EXIT_SUCCESS;
1053*592efe25SPierre Pronchery 	unsigned int want_client_flags = PKGCONF_PKG_PKGF_NONE;
1054*592efe25SPierre Pronchery 	const char *builddir;
1055*592efe25SPierre Pronchery 	const char *sysroot_dir;
1056*592efe25SPierre Pronchery 	pkgconf_list_t pkgq = PKGCONF_LIST_INITIALIZER;
1057*592efe25SPierre Pronchery 	pkgconf_list_t deplist = PKGCONF_LIST_INITIALIZER;
1058*592efe25SPierre Pronchery 	pkgconf_node_t *node;
1059*592efe25SPierre Pronchery 	pkgconf_buffer_t queryparams = PKGCONF_BUFFER_INITIALIZER;
1060*592efe25SPierre Pronchery 	pkgconf_pkg_t world = {
1061*592efe25SPierre Pronchery 		.id = "virtual:world",
1062*592efe25SPierre Pronchery 		.realname = "virtual world package",
1063*592efe25SPierre Pronchery 		.flags = PKGCONF_PKG_PROPF_STATIC | PKGCONF_PKG_PROPF_VIRTUAL,
1064*592efe25SPierre Pronchery 	};
1065*592efe25SPierre Pronchery 
1066*592efe25SPierre Pronchery #ifndef PKGCONF_LITE
1067*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_DUMP_PERSONALITY) == PKG_DUMP_PERSONALITY)
1068*592efe25SPierre Pronchery 	{
1069*592efe25SPierre Pronchery 		dump_personality(state->pkg_client.output, state->pkg_client.personality);
1070*592efe25SPierre Pronchery 
1071*592efe25SPierre Pronchery 		ret = EXIT_SUCCESS;
1072*592efe25SPierre Pronchery 		goto out;
1073*592efe25SPierre Pronchery 	}
1074*592efe25SPierre Pronchery #endif
1075*592efe25SPierre Pronchery 
1076*592efe25SPierre Pronchery #ifndef PKGCONF_LITE
1077*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_MSVC_SYNTAX) == PKG_MSVC_SYNTAX)
1078*592efe25SPierre Pronchery 		state->want_render_ops = msvc_renderer_get();
1079*592efe25SPierre Pronchery #endif
1080*592efe25SPierre Pronchery 
1081*592efe25SPierre Pronchery 	if (pkgconf_client_getenv(&state->pkg_client, "PKG_CONFIG_FDO_SYSROOT_RULES"))
1082*592efe25SPierre Pronchery 		want_client_flags |= PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES;
1083*592efe25SPierre Pronchery 
1084*592efe25SPierre Pronchery 	if (pkgconf_client_getenv(&state->pkg_client, "PKG_CONFIG_PKGCONF1_SYSROOT_RULES"))
1085*592efe25SPierre Pronchery 		want_client_flags |= PKGCONF_PKG_PKGF_PKGCONF1_SYSROOT_RULES;
1086*592efe25SPierre Pronchery 
1087*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_SHORT_ERRORS) == PKG_SHORT_ERRORS)
1088*592efe25SPierre Pronchery 		want_client_flags |= PKGCONF_PKG_PKGF_SIMPLIFY_ERRORS;
1089*592efe25SPierre Pronchery 
1090*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_DONT_RELOCATE_PATHS) == PKG_DONT_RELOCATE_PATHS)
1091*592efe25SPierre Pronchery 		want_client_flags |= PKGCONF_PKG_PKGF_DONT_RELOCATE_PATHS;
1092*592efe25SPierre Pronchery 
1093*592efe25SPierre Pronchery 	state->error_msgout = stderr;
1094*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_ERRORS_ON_STDOUT) == PKG_ERRORS_ON_STDOUT)
1095*592efe25SPierre Pronchery 		state->error_msgout = stdout;
1096*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_SILENCE_ERRORS) == PKG_SILENCE_ERRORS) {
1097*592efe25SPierre Pronchery 		state->error_msgout = fopen(PATH_DEV_NULL, "w");
1098*592efe25SPierre Pronchery 		state->opened_error_msgout = true;
1099*592efe25SPierre Pronchery 	}
1100*592efe25SPierre Pronchery 
1101*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_IGNORE_CONFLICTS) == PKG_IGNORE_CONFLICTS || pkgconf_client_getenv(&state->pkg_client, "PKG_CONFIG_IGNORE_CONFLICTS") != NULL)
1102*592efe25SPierre Pronchery 		want_client_flags |= PKGCONF_PKG_PKGF_SKIP_CONFLICTS;
1103*592efe25SPierre Pronchery 
1104*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_STATIC) == PKG_STATIC || state->pkg_client.personality->want_default_static)
1105*592efe25SPierre Pronchery 		want_client_flags |= (PKGCONF_PKG_PKGF_SEARCH_PRIVATE | PKGCONF_PKG_PKGF_MERGE_PRIVATE_FRAGMENTS);
1106*592efe25SPierre Pronchery 
1107*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_SHARED) == PKG_SHARED)
1108*592efe25SPierre Pronchery 		want_client_flags &= ~(PKGCONF_PKG_PKGF_SEARCH_PRIVATE | PKGCONF_PKG_PKGF_MERGE_PRIVATE_FRAGMENTS);
1109*592efe25SPierre Pronchery 
1110*592efe25SPierre Pronchery 	/* if --static and --pure are both specified, then disable merge-back.
1111*592efe25SPierre Pronchery 	 * this allows for a --static which searches private modules, but has the same fragment behaviour as if
1112*592efe25SPierre Pronchery 	 * --static were disabled.  see <https://github.com/pkgconf/pkgconf/issues/83> for rationale.
1113*592efe25SPierre Pronchery 	 */
1114*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_PURE) == PKG_PURE || pkgconf_client_getenv(&state->pkg_client, "PKG_CONFIG_PURE_DEPGRAPH") != NULL || state->pkg_client.personality->want_default_pure)
1115*592efe25SPierre Pronchery 		want_client_flags &= ~PKGCONF_PKG_PKGF_MERGE_PRIVATE_FRAGMENTS;
1116*592efe25SPierre Pronchery 
1117*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_ENV_ONLY) == PKG_ENV_ONLY)
1118*592efe25SPierre Pronchery 		want_client_flags |= PKGCONF_PKG_PKGF_ENV_ONLY;
1119*592efe25SPierre Pronchery 
1120*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_NO_CACHE) == PKG_NO_CACHE)
1121*592efe25SPierre Pronchery 		want_client_flags |= PKGCONF_PKG_PKGF_NO_CACHE;
1122*592efe25SPierre Pronchery 
1123*592efe25SPierre Pronchery /* On Windows we want to always redefine the prefix by default
1124*592efe25SPierre Pronchery  * but allow that behavior to be manually disabled */
1125*592efe25SPierre Pronchery #if !defined(_WIN32) && !defined(_WIN64)
1126*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_DEFINE_PREFIX) == PKG_DEFINE_PREFIX || pkgconf_client_getenv(&state->pkg_client, "PKG_CONFIG_RELOCATE_PATHS") != NULL)
1127*592efe25SPierre Pronchery #endif
1128*592efe25SPierre Pronchery 		want_client_flags |= PKGCONF_PKG_PKGF_REDEFINE_PREFIX;
1129*592efe25SPierre Pronchery 
1130*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_NO_UNINSTALLED) == PKG_NO_UNINSTALLED || pkgconf_client_getenv(&state->pkg_client, "PKG_CONFIG_DISABLE_UNINSTALLED") != NULL)
1131*592efe25SPierre Pronchery 		want_client_flags |= PKGCONF_PKG_PKGF_NO_UNINSTALLED;
1132*592efe25SPierre Pronchery 
1133*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_NO_PROVIDES) == PKG_NO_PROVIDES)
1134*592efe25SPierre Pronchery 		want_client_flags |= PKGCONF_PKG_PKGF_SKIP_PROVIDES;
1135*592efe25SPierre Pronchery 
1136*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_DONT_DEFINE_PREFIX) == PKG_DONT_DEFINE_PREFIX  || pkgconf_client_getenv(&state->pkg_client, "PKG_CONFIG_DONT_DEFINE_PREFIX") != NULL)
1137*592efe25SPierre Pronchery 		want_client_flags &= ~PKGCONF_PKG_PKGF_REDEFINE_PREFIX;
1138*592efe25SPierre Pronchery 
1139*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_INTERNAL_CFLAGS) == PKG_INTERNAL_CFLAGS)
1140*592efe25SPierre Pronchery 		want_client_flags |= PKGCONF_PKG_PKGF_DONT_FILTER_INTERNAL_CFLAGS;
1141*592efe25SPierre Pronchery 
1142*592efe25SPierre Pronchery 	/* --static --libs, --exists require the full dependency graph to be solved */
1143*592efe25SPierre Pronchery 	if ((state->want_flags & (PKG_STATIC|PKG_LIBS)) == (PKG_STATIC|PKG_LIBS) || (state->want_flags & PKG_EXISTS) == PKG_EXISTS)
1144*592efe25SPierre Pronchery 		want_client_flags |= PKGCONF_PKG_PKGF_REQUIRE_INTERNAL;
1145*592efe25SPierre Pronchery 
1146*592efe25SPierre Pronchery 	/* if these selectors are used, it means that we are querying metadata.
1147*592efe25SPierre Pronchery 	 * so signal to libpkgconf that we only want to walk the flattened dependency set.
1148*592efe25SPierre Pronchery 	 */
1149*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_MODVERSION) == PKG_MODVERSION ||
1150*592efe25SPierre Pronchery 		(state->want_flags & PKG_REQUIRES) == PKG_REQUIRES ||
1151*592efe25SPierre Pronchery 		(state->want_flags & PKG_REQUIRES_PRIVATE) == PKG_REQUIRES_PRIVATE ||
1152*592efe25SPierre Pronchery 		(state->want_flags & PKG_PROVIDES) == PKG_PROVIDES ||
1153*592efe25SPierre Pronchery 		(state->want_flags & PKG_VARIABLES) == PKG_VARIABLES ||
1154*592efe25SPierre Pronchery 		(state->want_flags & PKG_PATH) == PKG_PATH ||
1155*592efe25SPierre Pronchery 		state->want_variable != NULL)
1156*592efe25SPierre Pronchery 		state->maximum_traverse_depth = 1;
1157*592efe25SPierre Pronchery 
1158*592efe25SPierre Pronchery 	/* if we are asking for a variable, path or list of variables, this only makes sense
1159*592efe25SPierre Pronchery 	 * for a single package.
1160*592efe25SPierre Pronchery 	 */
1161*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_VARIABLES) == PKG_VARIABLES ||
1162*592efe25SPierre Pronchery 		(state->want_flags & PKG_PATH) == PKG_PATH ||
1163*592efe25SPierre Pronchery 		state->want_variable != NULL)
1164*592efe25SPierre Pronchery 	{
1165*592efe25SPierre Pronchery 		state->maximum_package_count = 1;
1166*592efe25SPierre Pronchery 	}
1167*592efe25SPierre Pronchery 
1168*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_REQUIRES_PRIVATE) == PKG_REQUIRES_PRIVATE ||
1169*592efe25SPierre Pronchery 		(state->want_flags & PKG_CFLAGS))
1170*592efe25SPierre Pronchery 	{
1171*592efe25SPierre Pronchery 		want_client_flags |= PKGCONF_PKG_PKGF_SEARCH_PRIVATE;
1172*592efe25SPierre Pronchery 	}
1173*592efe25SPierre Pronchery 
1174*592efe25SPierre Pronchery 	if ((builddir = pkgconf_client_getenv(&state->pkg_client, "PKG_CONFIG_TOP_BUILD_DIR")) != NULL)
1175*592efe25SPierre Pronchery 		pkgconf_client_set_buildroot_dir(&state->pkg_client, builddir);
1176*592efe25SPierre Pronchery 
1177*592efe25SPierre Pronchery 	if ((sysroot_dir = pkgconf_client_getenv(&state->pkg_client, "PKG_CONFIG_SYSROOT_DIR")) != NULL)
1178*592efe25SPierre Pronchery 	{
1179*592efe25SPierre Pronchery 		const char *destdir;
1180*592efe25SPierre Pronchery 
1181*592efe25SPierre Pronchery 		pkgconf_client_set_sysroot_dir(&state->pkg_client, sysroot_dir);
1182*592efe25SPierre Pronchery 
1183*592efe25SPierre Pronchery 		if ((destdir = pkgconf_client_getenv(&state->pkg_client, "DESTDIR")) != NULL)
1184*592efe25SPierre Pronchery 		{
1185*592efe25SPierre Pronchery 			if (!strcmp(destdir, sysroot_dir))
1186*592efe25SPierre Pronchery 				want_client_flags |= PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES;
1187*592efe25SPierre Pronchery 		}
1188*592efe25SPierre Pronchery 	}
1189*592efe25SPierre Pronchery 
1190*592efe25SPierre Pronchery 	/* we have determined what features we want most likely.  in some cases, we override later. */
1191*592efe25SPierre Pronchery 	pkgconf_client_set_flags(&state->pkg_client, want_client_flags);
1192*592efe25SPierre Pronchery 
1193*592efe25SPierre Pronchery 	/* at this point, want_client_flags should be set, so build the dir list */
1194*592efe25SPierre Pronchery 	pkgconf_client_dir_list_build(&state->pkg_client, state->pkg_client.personality);
1195*592efe25SPierre Pronchery 
1196*592efe25SPierre Pronchery 	/* unveil the entire search path now that we have loaded the personality data and built the dir list. */
1197*592efe25SPierre Pronchery 	unveil_search_paths(&state->pkg_client, state->pkg_client.personality);
1198*592efe25SPierre Pronchery 
1199*592efe25SPierre Pronchery 	/* register built-in packages */
1200*592efe25SPierre Pronchery 	register_builtins(&state->pkg_client, state->pkg_client.personality);
1201*592efe25SPierre Pronchery 
1202*592efe25SPierre Pronchery 	/* preload any files in PKG_CONFIG_PRELOADED_FILES */
1203*592efe25SPierre Pronchery 	pkgconf_client_preload_from_environ(&state->pkg_client, "PKG_CONFIG_PRELOADED_FILES");
1204*592efe25SPierre Pronchery 
1205*592efe25SPierre Pronchery 	if (state->required_pkgconfig_version != NULL)
1206*592efe25SPierre Pronchery 	{
1207*592efe25SPierre Pronchery 		if (pkgconf_compare_version(PACKAGE_VERSION, state->required_pkgconfig_version) >= 0)
1208*592efe25SPierre Pronchery 			ret = EXIT_SUCCESS;
1209*592efe25SPierre Pronchery 		else
1210*592efe25SPierre Pronchery 			ret = EXIT_FAILURE;
1211*592efe25SPierre Pronchery 
1212*592efe25SPierre Pronchery 		goto out;
1213*592efe25SPierre Pronchery 	}
1214*592efe25SPierre Pronchery 
1215*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_LIST) == PKG_LIST)
1216*592efe25SPierre Pronchery 	{
1217*592efe25SPierre Pronchery 		pkgconf_scan_all(&state->pkg_client, &state->pkg_client, print_list_entry);
1218*592efe25SPierre Pronchery 		ret = EXIT_SUCCESS;
1219*592efe25SPierre Pronchery 		goto out;
1220*592efe25SPierre Pronchery 	}
1221*592efe25SPierre Pronchery 
1222*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_LIST_PACKAGE_NAMES) == PKG_LIST_PACKAGE_NAMES)
1223*592efe25SPierre Pronchery 	{
1224*592efe25SPierre Pronchery 		pkgconf_scan_all(&state->pkg_client, &state->pkg_client, print_package_entry);
1225*592efe25SPierre Pronchery 		ret = EXIT_SUCCESS;
1226*592efe25SPierre Pronchery 		goto out;
1227*592efe25SPierre Pronchery 	}
1228*592efe25SPierre Pronchery 
1229*592efe25SPierre Pronchery 	while (last_argc < argc && argv[last_argc])
1230*592efe25SPierre Pronchery 	{
1231*592efe25SPierre Pronchery 		if (pkgconf_buffer_len(&queryparams) > 0)
1232*592efe25SPierre Pronchery 			pkgconf_buffer_push_byte(&queryparams, ' ');
1233*592efe25SPierre Pronchery 
1234*592efe25SPierre Pronchery 		pkgconf_buffer_append(&queryparams, argv[last_argc]);
1235*592efe25SPierre Pronchery 		last_argc++;
1236*592efe25SPierre Pronchery 	}
1237*592efe25SPierre Pronchery 
1238*592efe25SPierre Pronchery 	pkgconf_dependency_parse_str(&state->pkg_client, &deplist, pkgconf_buffer_str_or_empty(&queryparams), 0);
1239*592efe25SPierre Pronchery 	pkgconf_buffer_finalize(&queryparams);
1240*592efe25SPierre Pronchery 
1241*592efe25SPierre Pronchery 	if (state->required_module_version != NULL || state->required_exact_module_version != NULL || state->required_max_module_version != NULL)
1242*592efe25SPierre Pronchery 	{
1243*592efe25SPierre Pronchery 		const char *target_version = NULL;
1244*592efe25SPierre Pronchery 		pkgconf_pkg_comparator_t compare = PKGCONF_CMP_ANY;
1245*592efe25SPierre Pronchery 
1246*592efe25SPierre Pronchery 		if (state->required_module_version != NULL)
1247*592efe25SPierre Pronchery 		{
1248*592efe25SPierre Pronchery 			target_version = state->required_module_version;
1249*592efe25SPierre Pronchery 			compare = PKGCONF_CMP_GREATER_THAN_EQUAL;
1250*592efe25SPierre Pronchery 		}
1251*592efe25SPierre Pronchery 		else if (state->required_exact_module_version != NULL)
1252*592efe25SPierre Pronchery 		{
1253*592efe25SPierre Pronchery 			target_version = state->required_exact_module_version;
1254*592efe25SPierre Pronchery 			compare = PKGCONF_CMP_EQUAL;
1255*592efe25SPierre Pronchery 		}
1256*592efe25SPierre Pronchery 		else if (state->required_max_module_version != NULL)
1257*592efe25SPierre Pronchery 		{
1258*592efe25SPierre Pronchery 			target_version = state->required_max_module_version;
1259*592efe25SPierre Pronchery 			compare = PKGCONF_CMP_LESS_THAN_EQUAL;
1260*592efe25SPierre Pronchery 		}
1261*592efe25SPierre Pronchery 
1262*592efe25SPierre Pronchery 		PKGCONF_FOREACH_LIST_ENTRY(deplist.head, node)
1263*592efe25SPierre Pronchery 		{
1264*592efe25SPierre Pronchery 			pkgconf_dependency_t *dep = node->data;
1265*592efe25SPierre Pronchery 
1266*592efe25SPierre Pronchery 			/* already constrained at query level */
1267*592efe25SPierre Pronchery 			if (dep->compare != PKGCONF_CMP_ANY)
1268*592efe25SPierre Pronchery 				continue;
1269*592efe25SPierre Pronchery 
1270*592efe25SPierre Pronchery 			dep->compare = compare;
1271*592efe25SPierre Pronchery 			dep->version = strdup(target_version);
1272*592efe25SPierre Pronchery 		}
1273*592efe25SPierre Pronchery 	}
1274*592efe25SPierre Pronchery 
1275*592efe25SPierre Pronchery 	PKGCONF_FOREACH_LIST_ENTRY(deplist.head, node)
1276*592efe25SPierre Pronchery 	{
1277*592efe25SPierre Pronchery 		pkgconf_dependency_t *dep = node->data;
1278*592efe25SPierre Pronchery 		pkgconf_queue_push_dependency(&pkgq, dep);
1279*592efe25SPierre Pronchery 	}
1280*592efe25SPierre Pronchery 
1281*592efe25SPierre Pronchery 	pkgconf_dependency_free(&deplist);
1282*592efe25SPierre Pronchery 
1283*592efe25SPierre Pronchery 	if (pkgq.head == NULL)
1284*592efe25SPierre Pronchery 	{
1285*592efe25SPierre Pronchery 		pkgconf_output_puts(state->pkg_client.output, PKGCONF_OUTPUT_STDERR,
1286*592efe25SPierre Pronchery 			"Please specify at least one package name on the command line.");
1287*592efe25SPierre Pronchery 		ret = EXIT_FAILURE;
1288*592efe25SPierre Pronchery 		goto out;
1289*592efe25SPierre Pronchery 	}
1290*592efe25SPierre Pronchery 
1291*592efe25SPierre Pronchery 	ret = EXIT_SUCCESS;
1292*592efe25SPierre Pronchery 
1293*592efe25SPierre Pronchery 	if (!pkgconf_queue_solve(&state->pkg_client, &pkgq, &world, state->maximum_traverse_depth))
1294*592efe25SPierre Pronchery 	{
1295*592efe25SPierre Pronchery 		ret = EXIT_FAILURE;
1296*592efe25SPierre Pronchery 		goto out;
1297*592efe25SPierre Pronchery 	}
1298*592efe25SPierre Pronchery 
1299*592efe25SPierre Pronchery 	/* we shouldn't need to unveil any more filesystem accesses from this point, so lock it down */
1300*592efe25SPierre Pronchery 	state->pkg_client.unveil_handler(&state->pkg_client, NULL, NULL);
1301*592efe25SPierre Pronchery 
1302*592efe25SPierre Pronchery #ifndef PKGCONF_LITE
1303*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_SIMULATE) == PKG_SIMULATE)
1304*592efe25SPierre Pronchery 	{
1305*592efe25SPierre Pronchery 		state->want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1306*592efe25SPierre Pronchery 
1307*592efe25SPierre Pronchery 		pkgconf_client_set_flags(&state->pkg_client, want_client_flags | PKGCONF_PKG_PKGF_SKIP_ERRORS);
1308*592efe25SPierre Pronchery 		apply_simulate(&state->pkg_client, &world, NULL, -1);
1309*592efe25SPierre Pronchery 	}
1310*592efe25SPierre Pronchery #endif
1311*592efe25SPierre Pronchery 
1312*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_VALIDATE) == PKG_VALIDATE)
1313*592efe25SPierre Pronchery 		goto out;
1314*592efe25SPierre Pronchery 
1315*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_DUMP_LICENSE) == PKG_DUMP_LICENSE)
1316*592efe25SPierre Pronchery 	{
1317*592efe25SPierre Pronchery 		apply_license(&state->pkg_client, &world, &ret, 2);
1318*592efe25SPierre Pronchery 		goto out;
1319*592efe25SPierre Pronchery 	}
1320*592efe25SPierre Pronchery 
1321*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_LINK_ABI) == PKG_LINK_ABI)
1322*592efe25SPierre Pronchery 	{
1323*592efe25SPierre Pronchery 		/* private dependencies only contribute their ABI when statically linked */
1324*592efe25SPierre Pronchery 		if (!(state->want_flags & PKG_STATIC))
1325*592efe25SPierre Pronchery 			pkgconf_client_set_flags(&state->pkg_client, state->pkg_client.flags & ~PKGCONF_PKG_PKGF_SEARCH_PRIVATE);
1326*592efe25SPierre Pronchery 
1327*592efe25SPierre Pronchery 		apply_link_abi(&state->pkg_client, &world, &ret, 2);
1328*592efe25SPierre Pronchery 		goto out;
1329*592efe25SPierre Pronchery 	}
1330*592efe25SPierre Pronchery 
1331*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_DUMP_LICENSE_FILE) == PKG_DUMP_LICENSE_FILE)
1332*592efe25SPierre Pronchery 	{
1333*592efe25SPierre Pronchery 		apply_license_file(&state->pkg_client, &world, &ret, 2);
1334*592efe25SPierre Pronchery 		goto out;
1335*592efe25SPierre Pronchery 	}
1336*592efe25SPierre Pronchery 
1337*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_DUMP_SOURCE) == PKG_DUMP_SOURCE)
1338*592efe25SPierre Pronchery 	{
1339*592efe25SPierre Pronchery 		apply_source(&state->pkg_client, &world, &ret, 2);
1340*592efe25SPierre Pronchery 		goto out;
1341*592efe25SPierre Pronchery 	}
1342*592efe25SPierre Pronchery 
1343*592efe25SPierre Pronchery 
1344*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_UNINSTALLED) == PKG_UNINSTALLED)
1345*592efe25SPierre Pronchery 	{
1346*592efe25SPierre Pronchery 		ret = EXIT_FAILURE;
1347*592efe25SPierre Pronchery 		apply_uninstalled(&state->pkg_client, &world, &ret, 2);
1348*592efe25SPierre Pronchery 		goto out;
1349*592efe25SPierre Pronchery 	}
1350*592efe25SPierre Pronchery 
1351*592efe25SPierre Pronchery 	if (state->want_env_prefix != NULL)
1352*592efe25SPierre Pronchery 	{
1353*592efe25SPierre Pronchery 		apply_env(&state->pkg_client, &world, state->want_env_prefix, 2);
1354*592efe25SPierre Pronchery 		goto out;
1355*592efe25SPierre Pronchery 	}
1356*592efe25SPierre Pronchery 
1357*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_PROVIDES) == PKG_PROVIDES)
1358*592efe25SPierre Pronchery 	{
1359*592efe25SPierre Pronchery 		state->want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1360*592efe25SPierre Pronchery 		apply_provides(&state->pkg_client, &world, NULL, 2);
1361*592efe25SPierre Pronchery 	}
1362*592efe25SPierre Pronchery 
1363*592efe25SPierre Pronchery #ifndef PKGCONF_LITE
1364*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_DIGRAPH) == PKG_DIGRAPH)
1365*592efe25SPierre Pronchery 	{
1366*592efe25SPierre Pronchery 		state->want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1367*592efe25SPierre Pronchery 		apply_digraph(&state->pkg_client, &world, &pkgq, 2);
1368*592efe25SPierre Pronchery 	}
1369*592efe25SPierre Pronchery 
1370*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_SOLUTION) == PKG_SOLUTION)
1371*592efe25SPierre Pronchery 	{
1372*592efe25SPierre Pronchery 		state->want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1373*592efe25SPierre Pronchery 		apply_print_solution(&state->pkg_client, &world, NULL, 2);
1374*592efe25SPierre Pronchery 	}
1375*592efe25SPierre Pronchery #endif
1376*592efe25SPierre Pronchery 
1377*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_MODVERSION) == PKG_MODVERSION)
1378*592efe25SPierre Pronchery 	{
1379*592efe25SPierre Pronchery 		state->want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1380*592efe25SPierre Pronchery 		apply_modversion(&state->pkg_client, &world, &pkgq, 2);
1381*592efe25SPierre Pronchery 	}
1382*592efe25SPierre Pronchery 
1383*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_PATH) == PKG_PATH)
1384*592efe25SPierre Pronchery 	{
1385*592efe25SPierre Pronchery 		state->want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1386*592efe25SPierre Pronchery 
1387*592efe25SPierre Pronchery 		pkgconf_client_set_flags(&state->pkg_client, want_client_flags | PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL);
1388*592efe25SPierre Pronchery 		apply_path(&state->pkg_client, &world, NULL, 2);
1389*592efe25SPierre Pronchery 	}
1390*592efe25SPierre Pronchery 
1391*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_VARIABLES) == PKG_VARIABLES)
1392*592efe25SPierre Pronchery 	{
1393*592efe25SPierre Pronchery 		state->want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1394*592efe25SPierre Pronchery 		apply_variables(&state->pkg_client, &world, NULL, 2);
1395*592efe25SPierre Pronchery 	}
1396*592efe25SPierre Pronchery 
1397*592efe25SPierre Pronchery 	if (state->want_variable != NULL)
1398*592efe25SPierre Pronchery 	{
1399*592efe25SPierre Pronchery 		state->want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1400*592efe25SPierre Pronchery 
1401*592efe25SPierre Pronchery 		pkgconf_client_set_flags(&state->pkg_client, want_client_flags | PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL);
1402*592efe25SPierre Pronchery 		apply_variable(&state->pkg_client, &world, state->want_variable, 2);
1403*592efe25SPierre Pronchery 	}
1404*592efe25SPierre Pronchery 
1405*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_REQUIRES) == PKG_REQUIRES)
1406*592efe25SPierre Pronchery 	{
1407*592efe25SPierre Pronchery 		state->want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1408*592efe25SPierre Pronchery 		apply_requires(&state->pkg_client, &world, NULL, 2);
1409*592efe25SPierre Pronchery 	}
1410*592efe25SPierre Pronchery 
1411*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_REQUIRES_PRIVATE) == PKG_REQUIRES_PRIVATE)
1412*592efe25SPierre Pronchery 	{
1413*592efe25SPierre Pronchery 		state->want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1414*592efe25SPierre Pronchery 
1415*592efe25SPierre Pronchery 		apply_requires_private(&state->pkg_client, &world, NULL, 2);
1416*592efe25SPierre Pronchery 	}
1417*592efe25SPierre Pronchery 
1418*592efe25SPierre Pronchery 	if ((state->want_flags & PKG_FRAGMENT_TREE))
1419*592efe25SPierre Pronchery 	{
1420*592efe25SPierre Pronchery 		state->want_flags &= ~(PKG_CFLAGS|PKG_LIBS);
1421*592efe25SPierre Pronchery 
1422*592efe25SPierre Pronchery 		apply_fragment_tree(&state->pkg_client, &world, NULL, 2);
1423*592efe25SPierre Pronchery 	}
1424*592efe25SPierre Pronchery 
1425*592efe25SPierre Pronchery 	if ((state->want_flags & (PKG_CFLAGS|PKG_LIBS)))
1426*592efe25SPierre Pronchery 	{
1427*592efe25SPierre Pronchery 		pkgconf_list_t target_list = PKGCONF_LIST_INITIALIZER;
1428*592efe25SPierre Pronchery 		pkgconf_buffer_t render_buf = PKGCONF_BUFFER_INITIALIZER;
1429*592efe25SPierre Pronchery 
1430*592efe25SPierre Pronchery 		if ((state->want_flags & PKG_CFLAGS))
1431*592efe25SPierre Pronchery 			apply_cflags(&state->pkg_client, &world, &target_list, 2);
1432*592efe25SPierre Pronchery 
1433*592efe25SPierre Pronchery 		if ((state->want_flags & PKG_LIBS) && !(state->want_flags & PKG_STATIC))
1434*592efe25SPierre Pronchery 			pkgconf_client_set_flags(&state->pkg_client, state->pkg_client.flags & ~PKGCONF_PKG_PKGF_SEARCH_PRIVATE);
1435*592efe25SPierre Pronchery 
1436*592efe25SPierre Pronchery 		if ((state->want_flags & PKG_LIBS))
1437*592efe25SPierre Pronchery 			apply_libs(&state->pkg_client, &world, &target_list, 2);
1438*592efe25SPierre Pronchery 
1439*592efe25SPierre Pronchery 		pkgconf_fragment_render_buf(&target_list, &render_buf, true, state->want_render_ops, (state->want_flags & PKG_NEWLINES) ? '\n' : ' ');
1440*592efe25SPierre Pronchery 		pkgconf_output_putbuf(state->pkg_client.output, PKGCONF_OUTPUT_STDOUT, &render_buf, true);
1441*592efe25SPierre Pronchery 		pkgconf_buffer_finalize(&render_buf);
1442*592efe25SPierre Pronchery 
1443*592efe25SPierre Pronchery 		pkgconf_fragment_free(&target_list);
1444*592efe25SPierre Pronchery 	}
1445*592efe25SPierre Pronchery 
1446*592efe25SPierre Pronchery out:
1447*592efe25SPierre Pronchery 	pkgconf_solution_free(&state->pkg_client, &world);
1448*592efe25SPierre Pronchery 	pkgconf_queue_free(&pkgq);
1449*592efe25SPierre Pronchery 	pkgconf_cli_state_reset(state);
1450*592efe25SPierre Pronchery 
1451*592efe25SPierre Pronchery 	return ret;
1452*592efe25SPierre Pronchery }
1453*592efe25SPierre Pronchery 
1454*592efe25SPierre Pronchery void
pkgconf_cli_state_reset(pkgconf_cli_state_t * state)1455*592efe25SPierre Pronchery pkgconf_cli_state_reset(pkgconf_cli_state_t *state)
1456*592efe25SPierre Pronchery {
1457*592efe25SPierre Pronchery 	pkgconf_cross_personality_deinit((void *) state->pkg_client.personality);
1458*592efe25SPierre Pronchery 	pkgconf_client_deinit(&state->pkg_client);
1459*592efe25SPierre Pronchery 
1460*592efe25SPierre Pronchery 	if (state->logfile_out != NULL)
1461*592efe25SPierre Pronchery 		fclose(state->logfile_out);
1462*592efe25SPierre Pronchery 	if (state->opened_error_msgout)
1463*592efe25SPierre Pronchery 		fclose(state->error_msgout);
1464*592efe25SPierre Pronchery }
1465