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