xref: /freebsd/contrib/pkgconf/libpkgconf/libpkgconf.h (revision 592efe252472a3385acf36b1f49ecf710a7f3d9c)
1 /*
2  * libpkgconf.h
3  * Global include file for everything in libpkgconf.
4  *
5  * SPDX-License-Identifier: pkgconf
6  *
7  * Copyright (c) 2011, 2015 pkgconf authors (see AUTHORS).
8  *
9  * Permission to use, copy, modify, and/or distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * This software is provided 'as is' and without any warranty, express or
14  * implied.  In no event shall the authors be liable for any damages arising
15  * from the use of this software.
16  */
17 
18 #ifndef LIBPKGCONF__LIBPKGCONF_H
19 #define LIBPKGCONF__LIBPKGCONF_H
20 
21 #include <inttypes.h>
22 #include <stdio.h>
23 #include <stdarg.h>
24 #include <stddef.h>
25 #include <stdbool.h>
26 #include <stdint.h>
27 #include <string.h>
28 #include <libpkgconf/libpkgconf-api.h>
29 #include <libpkgconf/iter.h>
30 #include <libpkgconf/bsdstubs.h>
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 #define PKGCONF_BUFSIZE	(65535)
37 
38 typedef enum {
39 	PKGCONF_CMP_NOT_EQUAL,
40 	PKGCONF_CMP_ANY,
41 	PKGCONF_CMP_LESS_THAN,
42 	PKGCONF_CMP_LESS_THAN_EQUAL,
43 	PKGCONF_CMP_EQUAL,
44 	PKGCONF_CMP_GREATER_THAN,
45 	PKGCONF_CMP_GREATER_THAN_EQUAL
46 } pkgconf_pkg_comparator_t;
47 
48 #define PKGCONF_CMP_COUNT 7
49 
50 typedef struct pkgconf_pkg_ pkgconf_pkg_t;
51 typedef struct pkgconf_dependency_ pkgconf_dependency_t;
52 typedef struct pkgconf_buffer_ pkgconf_buffer_t;
53 typedef struct pkgconf_bufferset_ pkgconf_bufferset_t;
54 typedef struct pkgconf_span_ pkgconf_span_t;
55 typedef struct pkgconf_fragment_ pkgconf_fragment_t;
56 typedef struct pkgconf_path_ pkgconf_path_t;
57 typedef struct pkgconf_client_ pkgconf_client_t;
58 typedef struct pkgconf_cross_personality_ pkgconf_cross_personality_t;
59 typedef struct pkgconf_queue_ pkgconf_queue_t;
60 typedef struct pkgconf_output_ pkgconf_output_t;
61 typedef struct pkgconf_license_ pkgconf_license_t;
62 
63 #define PKGCONF_ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
64 
65 #define PKGCONF_FOREACH_LIST_ENTRY(head, value) \
66 	for ((value) = (head); (value) != NULL; (value) = (value)->next)
67 
68 #define PKGCONF_FOREACH_LIST_ENTRY_SAFE(head, nextiter, value) \
69 	for ((value) = (head), (nextiter) = (head) != NULL ? (head)->next : NULL; (value) != NULL; (value) = (nextiter), (nextiter) = (nextiter) != NULL ? (nextiter)->next : NULL)
70 
71 #define PKGCONF_FOREACH_LIST_ENTRY_REVERSE(tail, value) \
72 	for ((value) = (tail); (value) != NULL; (value) = (value)->prev)
73 
74 #define LIBPKGCONF_VERSION	20993
75 #define LIBPKGCONF_VERSION_STR	"2.9.93"
76 
77 struct pkgconf_queue_ {
78 	pkgconf_node_t iter;
79 	char *package;
80 
81 	unsigned int flags;
82 };
83 
84 struct pkgconf_fragment_ {
85 	pkgconf_node_t iter;
86 
87 	char type;
88 	char *data;
89 
90 	pkgconf_list_t children;
91 	unsigned int flags;
92 };
93 
94 #define PKGCONF_PKG_FRAGF_TERMINATED		0x1
95 
96 struct pkgconf_dependency_ {
97 	pkgconf_node_t iter;
98 
99 	char *package;
100 	pkgconf_pkg_comparator_t compare;
101 	char *version;
102 	pkgconf_pkg_t *parent;
103 	pkgconf_pkg_t *match;
104 
105 	unsigned int flags;
106 
107 	int refcount;
108 	pkgconf_client_t *owner;
109 
110 	char *why;
111 };
112 
113 struct pkgconf_buffer_ {
114 	char *base;
115 	char *end;
116 };
117 
118 struct pkgconf_bufferset_ {
119 	pkgconf_node_t node;
120 	pkgconf_buffer_t buffer;
121 };
122 
123 #if defined(_MSC_VER) && !defined(__clang__)
124 # define PKGCONF_PACKED_STRUCT(name) __pragma(pack(push, 1)) struct name __pragma(pack(pop))
125 #else
126 # define PKGCONF_PACKED_STRUCT(name) struct __attribute__((__packed__)) name
127 #endif
128 
129 enum pkgconf_bytecode_op {
130 	PKGCONF_BYTECODE_OP_TEXT = 1,
131 	PKGCONF_BYTECODE_OP_VAR = 2,
132 	PKGCONF_BYTECODE_OP_SYSROOT = 3,
133 };
134 
135 typedef PKGCONF_PACKED_STRUCT(pkgconf_bytecode_op_) {
136 	enum pkgconf_bytecode_op tag;
137 	uint32_t size;
138 	char data[];
139 } pkgconf_bytecode_op_t;
140 
141 typedef struct {
142 	const uint8_t *base;
143 	size_t len;
144 } pkgconf_bytecode_t;
145 
146 typedef struct pkgconf_variable_ {
147 	pkgconf_node_t iter;
148 
149 	char *key;
150 
151 	pkgconf_buffer_t bcbuf;
152 	pkgconf_bytecode_t bc;
153 
154 	unsigned int flags;
155 
156 	bool expanding;
157 } pkgconf_variable_t;
158 
159 #define PKGCONF_VARIABLEF_OVERRIDE		0x1
160 
161 typedef pkgconf_variable_t pkgconf_tuple_t;
162 
163 #define PKGCONF_PKG_TUPLEF_OVERRIDE		PKGCONF_VARIABLEF_OVERRIDE
164 
165 struct pkgconf_tuple_ {
166 	pkgconf_node_t iter;
167 
168 	char *key;
169 	char *value;
170 
171 	unsigned int flags;
172 };
173 
174 struct pkgconf_path_ {
175 	pkgconf_node_t lnode;
176 
177 	char *path;
178 	void *handle_path;
179 	void *handle_device;
180 
181 	unsigned int flags;
182 };
183 
184 typedef enum {
185 	PKGCONF_LICENSE_UNKNOWN = 0,
186 	PKGCONF_LICENSE_EXPRESSION = 1,
187 	PKGCONF_LICENSE_AND = 10,
188 	PKGCONF_LICENSE_OR = 11,
189 	PKGCONF_LICENSE_WITH = 12,
190 	PKGCONF_LICENSE_BRACKET_OPEN = 20,
191 	PKGCONF_LICENSE_BRACKET_CLOSE = 21,
192 } pkgconf_license_types_t;
193 
194 struct pkgconf_license_ {
195 	pkgconf_node_t iter;
196 
197 	unsigned char type;
198 	char *data;
199 };
200 
201 #define PKGCONF_PKG_PROPF_NONE			0x00
202 #define PKGCONF_PKG_PROPF_STATIC		0x01
203 #define PKGCONF_PKG_PROPF_CACHED		0x02
204 #define PKGCONF_PKG_PROPF_UNINSTALLED		0x08
205 #define PKGCONF_PKG_PROPF_VIRTUAL		0x10
206 #define PKGCONF_PKG_PROPF_ANCESTOR		0x20
207 #define PKGCONF_PKG_PROPF_VISITED_PRIVATE	0x40
208 #define PKGCONF_PKG_PROPF_PRELOADED		0x80
209 
210 struct pkgconf_pkg_ {
211 	int refcount;
212 	char *id;
213 	char *filename;
214 	char *realname;
215 	char *version;
216 	char *description;
217 	char *url;
218 	char *pc_filedir;
219 	char *maintainer;
220 	char *source;
221 	char *license_file;
222 	char *why;
223 
224 	pkgconf_list_t copyright;
225 
226 	pkgconf_list_t license;
227 
228 	pkgconf_list_t link_abi;
229 
230 	pkgconf_list_t libs;
231 	pkgconf_list_t libs_private;
232 	pkgconf_list_t libs_shared;
233 	pkgconf_list_t cflags;
234 	pkgconf_list_t cflags_private;
235 	pkgconf_list_t cflags_shared;
236 
237 	pkgconf_list_t required;		/* this used to be requires but that is now a reserved keyword */
238 	pkgconf_list_t requires_private;
239 	pkgconf_list_t requires_shared;
240 	pkgconf_list_t conflicts;
241 	pkgconf_list_t provides;
242 
243 	pkgconf_list_t vars;
244 
245 	unsigned int flags;
246 
247 	pkgconf_client_t *owner;
248 
249 	pkgconf_buffer_t orig_prefix;
250 	pkgconf_buffer_t calculated_prefix;
251 
252 	uint64_t serial;
253 	uint64_t identifier;
254 
255 	pkgconf_node_t preload_node;
256 };
257 
258 typedef bool (*pkgconf_pkg_iteration_func_t)(const pkgconf_pkg_t *pkg, void *data);
259 typedef void (*pkgconf_pkg_traverse_func_t)(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data);
260 typedef bool (*pkgconf_queue_apply_func_t)(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth);
261 typedef bool (*pkgconf_error_handler_func_t)(const char *msg, const pkgconf_client_t *client, void *data);
262 typedef void (*pkgconf_unveil_handler_func_t)(const pkgconf_client_t *client, const char *path, const char *permissions);
263 typedef const char *(*pkgconf_environ_lookup_handler_func_t)(const pkgconf_client_t *client, const char *variable);
264 
265 struct pkgconf_client_ {
266 	pkgconf_list_t dir_list;
267 
268 	pkgconf_list_t filter_libdirs;
269 	pkgconf_list_t filter_includedirs;
270 
271 	pkgconf_list_t global_vars;
272 
273 	void *client_data;
274 	void *error_handler_data;
275 	void *warn_handler_data;
276 	void *trace_handler_data;
277 
278 	pkgconf_error_handler_func_t error_handler;
279 	pkgconf_error_handler_func_t warn_handler;
280 	pkgconf_error_handler_func_t trace_handler;
281 
282 	pkgconf_environ_lookup_handler_func_t environ_lookup_handler;
283 
284 	FILE *auditf;
285 
286 	char *sysroot_dir;
287 	char *buildroot_dir;
288 
289 	unsigned int flags;
290 
291 	char *prefix_varname;
292 
293 	bool already_sent_notice;
294 
295 	uint64_t serial;
296 	uint64_t identifier;
297 
298 	pkgconf_pkg_t **cache_table;
299 	size_t cache_count;
300 
301 	pkgconf_unveil_handler_func_t unveil_handler;
302 
303 	pkgconf_list_t preloaded_pkgs;
304 
305 	pkgconf_output_t *output;
306 
307 	const pkgconf_cross_personality_t *personality;
308 
309 	pkgconf_buffer_t _scratch_buffer;
310 };
311 
312 struct pkgconf_cross_personality_ {
313 	char *name;
314 
315 	pkgconf_list_t dir_list;
316 
317 	pkgconf_list_t filter_libdirs;
318 	pkgconf_list_t filter_includedirs;
319 
320 	char *sysroot_dir;
321 
322 	bool want_default_static;
323 	bool want_default_pure;
324 };
325 
326 /* bytecode.c */
327 static inline const pkgconf_bytecode_op_t *
pkgconf_bytecode_op_next(const pkgconf_bytecode_op_t * op)328 pkgconf_bytecode_op_next(const pkgconf_bytecode_op_t *op)
329 {
330 	return (const pkgconf_bytecode_op_t *)
331 		((const uint8_t *)op + sizeof(*op) + op->size);
332 }
333 
334 typedef struct pkgconf_bytecode_eval_ctx_ {
335 	const pkgconf_client_t *client;
336 	const pkgconf_list_t *vars;
337 
338 	pkgconf_buffer_t sysroot;
339 
340 	size_t expansions;
341 } pkgconf_bytecode_eval_ctx_t;
342 
343 PKGCONF_API bool pkgconf_bytecode_eval(const pkgconf_client_t *client, const pkgconf_list_t *tuples, const pkgconf_bytecode_t *bc, pkgconf_buffer_t *out, bool *saw_sysroot);
344 PKGCONF_API bool pkgconf_bytecode_emit(pkgconf_buffer_t *buf, enum pkgconf_bytecode_op tag, const void *data, uint32_t size);
345 PKGCONF_API bool pkgconf_bytecode_emit_text(pkgconf_buffer_t *buf, const char *p, size_t n);
346 PKGCONF_API bool pkgconf_bytecode_emit_var(pkgconf_buffer_t *buf, const char *name, size_t nlen);
347 PKGCONF_API bool pkgconf_bytecode_emit_sysroot(pkgconf_buffer_t *buf);
348 PKGCONF_API void pkgconf_bytecode_from_buffer(pkgconf_bytecode_t *bc, const pkgconf_buffer_t *buf);
349 PKGCONF_API bool pkgconf_bytecode_compile(pkgconf_buffer_t *out, const char *value);
350 PKGCONF_API bool pkgconf_bytecode_eval_str_to_buf(const pkgconf_client_t *client, const pkgconf_list_t *vars, const char *input, bool *saw_sysroot, pkgconf_buffer_t *out);
351 PKGCONF_API char *pkgconf_bytecode_eval_str(const pkgconf_client_t *client, const pkgconf_list_t *vars, const char *input, bool *saw_sysroot);
352 PKGCONF_API pkgconf_variable_t *pkgconf_bytecode_eval_lookup_var(pkgconf_bytecode_eval_ctx_t *ctx, const char *name, size_t nlen);
353 PKGCONF_API bool pkgconf_bytecode_references_var(const pkgconf_buffer_t *buf, const char *key);
354 PKGCONF_API bool pkgconf_bytecode_rewrite_selfrefs(pkgconf_buffer_t *out, const pkgconf_buffer_t *rhs, const char *key, const pkgconf_buffer_t *prev);
355 
356 /* variable.c */
357 PKGCONF_API pkgconf_variable_t *pkgconf_variable_new(const char *key);
358 PKGCONF_API void pkgconf_variable_free(pkgconf_variable_t *v);
359 PKGCONF_API pkgconf_variable_t *pkgconf_variable_find(const pkgconf_list_t *vars, const char *key);
360 PKGCONF_API pkgconf_variable_t *pkgconf_variable_get_or_create(pkgconf_list_t *vars, const char *key);
361 PKGCONF_API void pkgconf_variable_delete(pkgconf_list_t *vars, pkgconf_variable_t *v);
362 PKGCONF_API void pkgconf_variable_list_free(pkgconf_list_t *vars);
363 PKGCONF_API bool pkgconf_variable_eval(pkgconf_client_t *client, const pkgconf_list_t *tuples, const pkgconf_variable_t *v, pkgconf_buffer_t *out, bool *saw_sysroot);
364 PKGCONF_API char *pkgconf_variable_eval_str(pkgconf_client_t *client, const pkgconf_list_t *tuples, const pkgconf_variable_t *v, bool *saw_sysroot);
365 
366 /* client.c */
367 PKGCONF_API void pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data, const pkgconf_cross_personality_t *personality, void *client_data, pkgconf_environ_lookup_handler_func_t environ_lookup_handler);
368 PKGCONF_API pkgconf_client_t * pkgconf_client_new(pkgconf_error_handler_func_t error_handler, void *error_handler_data, const pkgconf_cross_personality_t *personality, void *client_data, pkgconf_environ_lookup_handler_func_t environ_lookup_handler);
369 PKGCONF_API void pkgconf_client_deinit(pkgconf_client_t *client);
370 PKGCONF_API void pkgconf_client_free(pkgconf_client_t *client);
371 PKGCONF_API const char *pkgconf_client_get_sysroot_dir(const pkgconf_client_t *client);
372 PKGCONF_API void pkgconf_client_set_sysroot_dir(pkgconf_client_t *client, const char *sysroot_dir);
373 PKGCONF_API const char *pkgconf_client_get_buildroot_dir(const pkgconf_client_t *client);
374 PKGCONF_API void pkgconf_client_set_buildroot_dir(pkgconf_client_t *client, const char *buildroot_dir);
375 PKGCONF_API unsigned int pkgconf_client_get_flags(const pkgconf_client_t *client);
376 PKGCONF_API void pkgconf_client_set_flags(pkgconf_client_t *client, unsigned int flags);
377 PKGCONF_API const char *pkgconf_client_get_prefix_varname(const pkgconf_client_t *client);
378 PKGCONF_API void pkgconf_client_set_prefix_varname(pkgconf_client_t *client, const char *prefix_varname);
379 PKGCONF_API pkgconf_error_handler_func_t pkgconf_client_get_warn_handler(const pkgconf_client_t *client);
380 PKGCONF_API void pkgconf_client_set_warn_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t warn_handler, void *warn_handler_data);
381 PKGCONF_API pkgconf_error_handler_func_t pkgconf_client_get_error_handler(const pkgconf_client_t *client);
382 PKGCONF_API void pkgconf_client_set_error_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data);
383 PKGCONF_API pkgconf_error_handler_func_t pkgconf_client_get_trace_handler(const pkgconf_client_t *client);
384 PKGCONF_API void pkgconf_client_set_trace_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t trace_handler, void *trace_handler_data);
385 PKGCONF_API pkgconf_unveil_handler_func_t pkgconf_client_get_unveil_handler(const pkgconf_client_t *client);
386 PKGCONF_API void pkgconf_client_set_unveil_handler(pkgconf_client_t *client, pkgconf_unveil_handler_func_t unveil_handler);
387 PKGCONF_API void pkgconf_client_dir_list_build(pkgconf_client_t *client, const pkgconf_cross_personality_t *personality);
388 PKGCONF_API bool pkgconf_client_preload_one(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
389 PKGCONF_API bool pkgconf_client_preload_path(pkgconf_client_t *client, const char *path);
390 PKGCONF_API bool pkgconf_client_preload_from_environ(pkgconf_client_t *client, const char *env);
391 PKGCONF_API void pkgconf_client_set_output(pkgconf_client_t *client, pkgconf_output_t *output);
392 PKGCONF_API const char *pkgconf_client_getenv(const pkgconf_client_t *client, const char *key);
393 
394 /* personality.c */
395 PKGCONF_API pkgconf_cross_personality_t *pkgconf_cross_personality_default(void);
396 PKGCONF_API pkgconf_cross_personality_t *pkgconf_cross_personality_find(const char *triplet);
397 PKGCONF_API void pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *personality);
398 
399 #define PKGCONF_IS_MODULE_SEPARATOR(c) ((c) == ',' || isspace ((unsigned char)(c)))
400 #define PKGCONF_IS_OPERATOR_CHAR(c) ((c) == '<' || (c) == '>' || (c) == '!' || (c) == '=')
401 
402 #define PKGCONF_PKG_PKGF_NONE				0x0000
403 #define PKGCONF_PKG_PKGF_SEARCH_PRIVATE			0x0001
404 #define PKGCONF_PKG_PKGF_ENV_ONLY			0x0002
405 #define PKGCONF_PKG_PKGF_NO_UNINSTALLED			0x0004
406 #define PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL		0x0008
407 #define PKGCONF_PKG_PKGF_MERGE_PRIVATE_FRAGMENTS	0x0010
408 #define PKGCONF_PKG_PKGF_SKIP_CONFLICTS			0x0020
409 #define PKGCONF_PKG_PKGF_NO_CACHE			0x0040
410 #define PKGCONF_PKG_PKGF_SKIP_ERRORS			0x0080
411 #define PKGCONF_PKG_PKGF_ITER_PKG_IS_PRIVATE		0x0100
412 #define PKGCONF_PKG_PKGF_SKIP_PROVIDES			0x0200
413 #define PKGCONF_PKG_PKGF_REDEFINE_PREFIX		0x0400
414 #define PKGCONF_PKG_PKGF_DONT_RELOCATE_PATHS		0x0800
415 #define PKGCONF_PKG_PKGF_SIMPLIFY_ERRORS		0x1000
416 #define PKGCONF_PKG_PKGF_DONT_FILTER_INTERNAL_CFLAGS	0x2000
417 #define PKGCONF_PKG_PKGF_DONT_MERGE_SPECIAL_FRAGMENTS	0x4000
418 #define PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES		0x8000
419 #define PKGCONF_PKG_PKGF_PKGCONF1_SYSROOT_RULES         0x10000
420 #define PKGCONF_PKG_PKGF_REQUIRE_INTERNAL		0x20000
421 
422 #define PKGCONF_PKG_DEPF_INTERNAL		0x1
423 #define PKGCONF_PKG_DEPF_PRIVATE		0x2
424 #define PKGCONF_PKG_DEPF_QUERY			0x4
425 #define PKGCONF_PKG_DEPF_SHARED			0x8
426 
427 #define PKGCONF_PKG_ERRF_OK			0x0
428 #define PKGCONF_PKG_ERRF_PACKAGE_NOT_FOUND	0x1
429 #define PKGCONF_PKG_ERRF_PACKAGE_VER_MISMATCH	0x2
430 #define PKGCONF_PKG_ERRF_PACKAGE_CONFLICT	0x4
431 #define PKGCONF_PKG_ERRF_DEPGRAPH_BREAK		0x8
432 
433 #if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
434 # define PRINTFLIKE(fmtarg, firstvararg) \
435          __attribute__((__format__ (gnu_printf, fmtarg, firstvararg)))
436 #elif defined(__clang__) || defined(__INTEL_COMPILER) || __GNUC__ > 2 || (_GNUC__ == 2 && __GNUC_MINOR__ >= 5)
437 # define PRINTFLIKE(fmtarg, firstvararg) \
438          __attribute__((__format__ (__printf__, fmtarg, firstvararg)))
439 #else
440 # define PRINTFLIKE(fmtarg, firstvararg)
441 #endif
442 
443 #if defined(__clang__) || defined(__INTEL_COMPILER) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
444 # define DEPRECATED __attribute__((deprecated))
445 #elif defined(_MSC_VER)
446 # define DEPRECATED __declspec(deprecated)
447 #else
448 # define DEPRECATED
449 #endif
450 
451 /* pkg.c */
452 PKGCONF_API bool pkgconf_error(const pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3);
453 PKGCONF_API bool pkgconf_warn(const pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3);
454 PKGCONF_API bool pkgconf_trace(const pkgconf_client_t *client, const char *filename, size_t lineno, const char *funcname, const char *format, ...) PRINTFLIKE(5, 6);
455 PKGCONF_API bool pkgconf_default_error_handler(const char *msg, const pkgconf_client_t *client, void *data);
456 
457 #ifndef PKGCONF_LITE
458 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
459 #define PKGCONF_TRACE(client, ...) do { \
460 		pkgconf_trace(client, __FILE__, __LINE__, __PRETTY_FUNCTION__, __VA_ARGS__); \
461 	} while (0)
462 #else
463 #define PKGCONF_TRACE(client, ...) do { \
464 		pkgconf_trace(client, __FILE__, __LINE__, __func__, __VA_ARGS__); \
465 	} while (0)
466 #endif
467 #else
468 #define PKGCONF_TRACE(client, ...)
469 #endif
470 
471 PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_ref(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
472 PKGCONF_API void pkgconf_pkg_unref(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
473 PKGCONF_API void pkgconf_pkg_free(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
474 PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_find(pkgconf_client_t *client, const char *name);
475 PKGCONF_API unsigned int pkgconf_pkg_traverse(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_pkg_traverse_func_t func, void *data, int maxdepth, unsigned int skip_flags);
476 PKGCONF_API unsigned int pkgconf_pkg_walk_conflicts_list(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *deplist);
477 PKGCONF_API unsigned int pkgconf_pkg_verify_graph(pkgconf_client_t *client, pkgconf_pkg_t *root, int depth);
478 PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_verify_dependency(pkgconf_client_t *client, pkgconf_dependency_t *pkgdep, unsigned int *eflags);
479 PKGCONF_API const char *pkgconf_pkg_get_comparator(const pkgconf_dependency_t *pkgdep);
480 PKGCONF_API unsigned int pkgconf_pkg_cflags(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth);
481 PKGCONF_API unsigned int pkgconf_pkg_libs(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth);
482 PKGCONF_API unsigned int pkgconf_pkg_link_abi(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth);
483 PKGCONF_API pkgconf_pkg_comparator_t pkgconf_pkg_comparator_lookup_by_name(const char *name);
484 
485 PKGCONF_API int pkgconf_compare_version(const char *a, const char *b);
486 PKGCONF_API pkgconf_pkg_t *pkgconf_scan_all(pkgconf_client_t *client, void *ptr, pkgconf_pkg_iteration_func_t func);
487 
488 /* parse.c */
489 PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_new_from_path(pkgconf_client_t *client, const char *path, unsigned int flags);
490 PKGCONF_API void pkgconf_dependency_parse_str(pkgconf_client_t *client, pkgconf_list_t *deplist_head, const char *depends, unsigned int flags);
491 PKGCONF_API void pkgconf_dependency_parse(pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist_head, const char *depends, unsigned int flags);
492 PKGCONF_API void pkgconf_dependency_append(pkgconf_list_t *list, pkgconf_dependency_t *tail);
493 PKGCONF_API void pkgconf_dependency_free(pkgconf_list_t *list);
494 PKGCONF_API void pkgconf_dependency_free_one(pkgconf_dependency_t *dep);
495 PKGCONF_API pkgconf_dependency_t *pkgconf_dependency_add(pkgconf_client_t *client, pkgconf_list_t *list, const char *package, const char *version, pkgconf_pkg_comparator_t compare, unsigned int flags);
496 PKGCONF_API pkgconf_dependency_t *pkgconf_dependency_ref(pkgconf_client_t *client, pkgconf_dependency_t *dep);
497 PKGCONF_API void pkgconf_dependency_unref(pkgconf_client_t *client, pkgconf_dependency_t *dep);
498 PKGCONF_API pkgconf_dependency_t *pkgconf_dependency_copy(pkgconf_client_t *client, const pkgconf_dependency_t *dep);
499 
500 /* argvsplit.c */
501 PKGCONF_API int pkgconf_argv_split(const char *src, int *argc, char ***argv);
502 PKGCONF_API void pkgconf_argv_free(char **argv);
503 
504 /* fragment.c */
505 typedef struct pkgconf_fragment_render_ctx_ {
506 	const bool escape;
507 	const char delim;
508 } pkgconf_fragment_render_ctx_t;
509 
510 typedef struct pkgconf_fragment_render_ops_ {
511 	void (*render)(const pkgconf_fragment_render_ctx_t *ctx, const pkgconf_fragment_t *frag, pkgconf_buffer_t *buf);
512 } pkgconf_fragment_render_ops_t;
513 
514 typedef bool (*pkgconf_fragment_filter_func_t)(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, void *data);
515 PKGCONF_API bool pkgconf_fragment_parse(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value, unsigned int flags);
516 PKGCONF_API void pkgconf_fragment_insert(pkgconf_client_t *client, pkgconf_list_t *list, char type, const char *data, bool tail);
517 PKGCONF_API void pkgconf_fragment_add(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *string, unsigned int flags);
518 PKGCONF_API void pkgconf_fragment_copy(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_fragment_t *base, bool is_private);
519 PKGCONF_API void pkgconf_fragment_copy_list(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_list_t *base);
520 PKGCONF_API void pkgconf_fragment_delete(pkgconf_list_t *list, pkgconf_fragment_t *node);
521 PKGCONF_API void pkgconf_fragment_free(pkgconf_list_t *list);
522 PKGCONF_API void pkgconf_fragment_filter(const pkgconf_client_t *client, pkgconf_list_t *dest, pkgconf_list_t *src, pkgconf_fragment_filter_func_t filter_func, void *data);
523 PKGCONF_API void pkgconf_fragment_render_buf(const pkgconf_list_t *list, pkgconf_buffer_t *buf, bool escape, const pkgconf_fragment_render_ops_t *ops, char delim);
524 PKGCONF_API bool pkgconf_fragment_has_system_dir(const pkgconf_client_t *client, const pkgconf_fragment_t *frag);
525 PKGCONF_API bool pkgconf_is_locale_utf8(void);
526 
527 /* license.c */
528 PKGCONF_API void pkgconf_license_copy_list(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_list_t *base);
529 PKGCONF_API void pkgconf_license_evaluate_str(pkgconf_client_t *client, pkgconf_list_t *deplist_head, const char *expression, unsigned int flags);
530 PKGCONF_API void pkgconf_license_evaluate(pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist, const char *depends, unsigned int flags);
531 PKGCONF_API void pkgconf_license_free(pkgconf_list_t *list);
532 PKGCONF_API void pkgconf_license_insert(pkgconf_client_t *client, pkgconf_list_t *list, unsigned char type, const char *data);
533 PKGCONF_API void pkgconf_license_render(pkgconf_client_t *client, const pkgconf_list_t *list, pkgconf_buffer_t *buf);
534 
535 /* tuple.c */
536 PKGCONF_API pkgconf_tuple_t *pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *parent, const char *key, const char *value, bool parse, unsigned int flags);
537 PKGCONF_API const char *pkgconf_tuple_find(pkgconf_client_t *client, pkgconf_list_t *list, const char *key);
538 PKGCONF_API void pkgconf_tuple_free(pkgconf_list_t *list);
539 PKGCONF_API void pkgconf_tuple_free_entry(pkgconf_tuple_t *tuple, pkgconf_list_t *list);
540 PKGCONF_API void pkgconf_tuple_add_global(pkgconf_client_t *client, const char *key, const char *value);
541 PKGCONF_API const char *pkgconf_tuple_find_global(pkgconf_client_t *client, const char *key);
542 PKGCONF_API void pkgconf_tuple_free_global(pkgconf_client_t *client);
543 PKGCONF_API void pkgconf_tuple_define_global(pkgconf_client_t *client, const char *kv);
544 
545 /* queue.c */
546 PKGCONF_API void pkgconf_queue_push(pkgconf_list_t *list, const char *package);
547 PKGCONF_API void pkgconf_queue_push_dependency(pkgconf_list_t *list, const pkgconf_dependency_t *dep);
548 PKGCONF_API bool pkgconf_queue_compile(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *list);
549 PKGCONF_API bool pkgconf_queue_solve(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_pkg_t *world, int maxdepth);
550 PKGCONF_API void pkgconf_queue_free(pkgconf_list_t *list);
551 PKGCONF_API bool pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, void *data);
552 PKGCONF_API bool pkgconf_queue_validate(pkgconf_client_t *client, pkgconf_list_t *list, int maxdepth);
553 PKGCONF_API void pkgconf_solution_free(pkgconf_client_t *client, pkgconf_pkg_t *world);
554 
555 /* cache.c */
556 PKGCONF_API pkgconf_pkg_t *pkgconf_cache_lookup(pkgconf_client_t *client, const char *id);
557 PKGCONF_API void pkgconf_cache_add(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
558 PKGCONF_API void pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
559 PKGCONF_API void pkgconf_cache_free(pkgconf_client_t *client);
560 
561 /* audit.c */
562 PKGCONF_API void pkgconf_audit_set_log(pkgconf_client_t *client, FILE *auditf);
563 PKGCONF_API void pkgconf_audit_log(pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3);
564 PKGCONF_API void pkgconf_audit_log_dependency(pkgconf_client_t *client, const pkgconf_pkg_t *dep, const pkgconf_dependency_t *depnode);
565 
566 /* path.c */
567 PKGCONF_API void pkgconf_path_add(const char *text, pkgconf_list_t *dirlist, bool filter);
568 PKGCONF_API void pkgconf_path_prepend(const char *text, pkgconf_list_t *dirlist, bool filter);
569 PKGCONF_API size_t pkgconf_path_split(const char *text, pkgconf_list_t *dirlist, bool filter);
570 PKGCONF_API size_t pkgconf_path_build_from_environ(const pkgconf_client_t *client, const char *envvarname, const char *fallback, pkgconf_list_t *dirlist, bool filter);
571 #ifdef _WIN32
572 PKGCONF_API size_t pkgconf_path_build_from_registry(pkgconf_client_t *client, /* HKEY -> HANDLE -> PVOID */ void *hKey, pkgconf_list_t *dirlist, bool filter);
573 #endif
574 PKGCONF_API bool pkgconf_path_match_list(const char *path, const pkgconf_list_t *dirlist);
575 PKGCONF_API void pkgconf_path_free(pkgconf_list_t *dirlist);
576 PKGCONF_API bool pkgconf_path_relocate(pkgconf_buffer_t *buf);
577 PKGCONF_API void pkgconf_path_copy_list(pkgconf_list_t *dst, const pkgconf_list_t *src);
578 PKGCONF_API void pkgconf_path_prepend_list(pkgconf_list_t *dst, const pkgconf_list_t *src);
579 PKGCONF_API bool pkgconf_path_is_plausible(const pkgconf_buffer_t *buf);
580 
581 /* buffer.c */
582 struct pkgconf_span_ {
583 	unsigned char lo;
584 	unsigned char hi;	/* inclusive */
585 };
586 
pkgconf_span_contains(unsigned char c,const pkgconf_span_t * spans,size_t nspans)587 static inline bool pkgconf_span_contains(unsigned char c, const pkgconf_span_t *spans, size_t nspans) {
588 	for (size_t i = 0; i < nspans; i++)
589 		if (c >= spans[i].lo && c <= spans[i].hi)
590 			return true;
591 
592 	return false;
593 }
594 
595 PKGCONF_API bool pkgconf_buffer_append(pkgconf_buffer_t *buffer, const char *text);
596 PKGCONF_API bool pkgconf_buffer_append_slice(pkgconf_buffer_t *buf, const char *p, size_t n);
597 PKGCONF_API bool pkgconf_buffer_append_fmt(pkgconf_buffer_t *buffer, const char *fmt, ...) PRINTFLIKE(2, 3);
598 PKGCONF_API bool pkgconf_buffer_append_vfmt(pkgconf_buffer_t *buffer, const char *fmt, va_list va) PRINTFLIKE(2, 0);
599 PKGCONF_API bool pkgconf_buffer_prepend(pkgconf_buffer_t *buffer, const char *text);
600 PKGCONF_API bool pkgconf_buffer_push_byte(pkgconf_buffer_t *buffer, char byte);
601 PKGCONF_API bool pkgconf_buffer_trim_byte(pkgconf_buffer_t *buffer);
602 PKGCONF_API void pkgconf_buffer_finalize(pkgconf_buffer_t *buffer);
603 PKGCONF_API bool pkgconf_buffer_fputs(pkgconf_buffer_t *buffer, FILE *out);
604 PKGCONF_API bool pkgconf_buffer_vjoin(pkgconf_buffer_t *buffer, char delim, va_list va);
605 PKGCONF_API bool pkgconf_buffer_join(pkgconf_buffer_t *buffer, int delim, ...);
606 PKGCONF_API bool pkgconf_buffer_has_prefix(const pkgconf_buffer_t *haystack, const pkgconf_buffer_t *prefix);
607 PKGCONF_API bool pkgconf_buffer_contains(const pkgconf_buffer_t *haystack, const pkgconf_buffer_t *needle);
608 PKGCONF_API bool pkgconf_buffer_contains_byte(const pkgconf_buffer_t *haystack, char needle);
609 PKGCONF_API bool pkgconf_buffer_match(const pkgconf_buffer_t *haystack, const pkgconf_buffer_t *needle);
610 PKGCONF_API bool pkgconf_buffer_subst(pkgconf_buffer_t *dest, const pkgconf_buffer_t *src, const char *pattern, const char *value);
611 PKGCONF_API bool pkgconf_buffer_escape(pkgconf_buffer_t *dest, const pkgconf_buffer_t *src, const pkgconf_span_t *spans, size_t nspans);
612 
613 /*
614  * !doc
615  *
616  * .. c:function:: static inline const char *pkgconf_buffer_str(const pkgconf_buffer_t *buffer)
617  *
618  *    Get the underlying string from the buffer. This may return :code:`NULL`.
619  *
620  *    :param const pkgconf_buffer_t *buffer: The buffer to get the string from.
621  *    :return: The underlying string.
622  */
pkgconf_buffer_str(const pkgconf_buffer_t * buffer)623 static inline const char *pkgconf_buffer_str(const pkgconf_buffer_t *buffer)
624 {
625 	return buffer->base;
626 }
627 
628 /*
629  * !doc
630  *
631  * .. c:function:: static inline const char *pkgconf_buffer_str_or_empty(const pkgconf_buffer_t *buffer)
632  *
633  *    Get the underlying string from the buffer, or the empty string if :code:`NULL`.
634  *
635  *    :param const pkgconf_buffer_t *buffer: The buffer to get the string from.
636  *    :return: The underlying string, or the empty string.
637  */
pkgconf_buffer_str_or_empty(const pkgconf_buffer_t * buffer)638 static inline const char *pkgconf_buffer_str_or_empty(const pkgconf_buffer_t *buffer)
639 {
640 	return buffer->base != NULL ? buffer->base : "";
641 }
642 
643 /*
644  * !doc
645  *
646  * .. c:function:: static inline size_t *pkgconf_buffer_len(const pkgconf_buffer_t *buffer)
647  *
648  *    Get the underlying raw buffer length.
649  *
650  *    :param const pkgconf_buffer_t *buffer: The buffer to check the length of.
651  *    :return: The size of the underlying buffer.
652  */
pkgconf_buffer_len(const pkgconf_buffer_t * buffer)653 static inline size_t pkgconf_buffer_len(const pkgconf_buffer_t *buffer)
654 {
655 	return (size_t)(ptrdiff_t)(buffer->end - buffer->base);
656 }
657 
658 /*
659  * !doc
660  *
661  * .. c:function:: static inline const char *pkgconf_buffer_lastc(const pkgconf_buffer_t *buffer)
662  *
663  *    Get the last character from the buffer. If the buffer is empty, return :code:`'\0'`.
664  *
665  *    :param pkgconf_buffer_t *buffer: The buffer to get the last character from.
666  *    :return: The last character, or '\0' if the string is empty.
667  */
pkgconf_buffer_lastc(const pkgconf_buffer_t * buffer)668 static inline char pkgconf_buffer_lastc(const pkgconf_buffer_t *buffer)
669 {
670 	if (buffer->base == buffer->end)
671 		return '\0';
672 
673 	return *(buffer->end - 1);
674 }
675 
676 #define PKGCONF_BUFFER_INITIALIZER { NULL, NULL }
677 #define PKGCONF_BUFFER_FROM_STR(str) &(const pkgconf_buffer_t){ .base = str, .end = ((str) ? &(str)[strlen(str)] : (str)) }
678 #define PKGCONF_BUFFER_FROM_STR_NONNULL(str) &(const pkgconf_buffer_t){ .base = str, .end = &(str)[strlen(str)] }
679 
680 /*
681  * !doc
682  *
683  * .. c:function:: static inline void pkgconf_buffer_reset(const pkgconf_buffer_t *buffer)
684  *
685  *    Reset the underlying buffer, freeing any existing string.
686  *
687  *    :param pkgconf_buffer_t *buffer: The buffer to reset.
688  *    :return: nothing
689  */
pkgconf_buffer_reset(pkgconf_buffer_t * buffer)690 static inline void pkgconf_buffer_reset(pkgconf_buffer_t *buffer)
691 {
692 	pkgconf_buffer_finalize(buffer);
693 	buffer->base = buffer->end = NULL;
694 }
695 
696 /*
697  * !doc
698  *
699  * .. c:function:: static inline char *pkgconf_buffer_freeze(pkgconf_buffer_t *buffer)
700  *
701  *    Free the underlying buffer, copying the underlying string.
702  *    The string must be freed by the caller.
703  *
704  *    :param pkgconf_buffer_t *buffer: The buffer to freeze.
705  *    :return: The underlying string, copied.
706  */
pkgconf_buffer_freeze(pkgconf_buffer_t * buffer)707 static inline char *pkgconf_buffer_freeze(pkgconf_buffer_t *buffer)
708 {
709 	if (buffer->base == NULL)
710 		return NULL;
711 
712 	char *out = pkgconf_strndup(pkgconf_buffer_str(buffer), pkgconf_buffer_len(buffer));
713 	pkgconf_buffer_reset(buffer);
714 	return out;
715 }
716 
717 /*
718  * !doc
719  *
720  * .. c:function:: static inline bool pkgconf_buffer_copy(pkgconf_buffer_t *buffer, pkgconf_buffer_t *newptr)
721  *
722  *    Copy the contents of one buffer to another, erasing the contents of the buffer in :code:`newptr`.
723  *
724  *    :param pkgconf_buffer_t *buffer: The buffer to copy from.
725  *    :param pkgconf_buffer_t *buffer: The buffer to copy to.
726  *    :return: :code:`true` on success, :code:`false` on failure.
727  */
pkgconf_buffer_copy(pkgconf_buffer_t * buffer,pkgconf_buffer_t * newptr)728 static inline bool pkgconf_buffer_copy(pkgconf_buffer_t *buffer, pkgconf_buffer_t *newptr)
729 {
730 	pkgconf_buffer_reset(newptr);
731 	return pkgconf_buffer_append_slice(newptr, pkgconf_buffer_str(buffer), pkgconf_buffer_len(buffer));
732 }
733 
734 /*
735  * !doc
736  *
737  * .. c:function:: static inline bool pkgconf_str_eq_slice(const char *s, const char *p, size_t n)
738  *
739  *    Compare :code:`s` to :code:`p`, which must be :code:`n` size long.
740  *
741  *    :param const char *s: string to search
742  *    :param const char *p: string to search for
743  *    :param size_t n: length of :code:`s`
744  *    :return: :code:`true` if equal, :code:`false` if not.
745  */
pkgconf_str_eq_slice(const char * s,const char * p,size_t n)746 static inline bool pkgconf_str_eq_slice(const char *s, const char *p, size_t n)
747 {
748 	return s != NULL &&
749 		strncmp(s, p, n) == 0 &&
750 		s[n] == '\0';
751 }
752 
753 /* bufferset.c */
754 PKGCONF_API pkgconf_bufferset_t *pkgconf_bufferset_extend(pkgconf_list_t *list, pkgconf_buffer_t *buffer);
755 PKGCONF_API void pkgconf_bufferset_free(pkgconf_list_t *list);
756 
757 /* fileio.c */
758 PKGCONF_API bool pkgconf_fgetline(pkgconf_buffer_t *buffer, FILE *stream);
759 
760 /* parser.c */
761 typedef void (*pkgconf_parser_operand_func_t)(void *data, const char *warnprefix, const char *key, const char *value);
762 typedef void (*pkgconf_parser_warn_func_t)(void *data, const char *fmt, ...);
763 
764 PKGCONF_API void pkgconf_parser_parse_buffer(void *data, const pkgconf_parser_operand_func_t *ops, const pkgconf_parser_warn_func_t warnfunc, pkgconf_buffer_t *buffer, const char *warnprefix);
765 PKGCONF_API void pkgconf_parser_parse(FILE *f, void *data, const pkgconf_parser_operand_func_t *ops, const pkgconf_parser_warn_func_t warnfunc, const char *filename);
766 
767 /* output.c */
768 typedef enum {
769 	PKGCONF_OUTPUT_STDOUT,
770 	PKGCONF_OUTPUT_STDERR,
771 } pkgconf_output_stream_t;
772 
773 struct pkgconf_output_ {
774 	void *privdata;
775 
776 	bool (*write)(pkgconf_output_t *output, pkgconf_output_stream_t stream, const pkgconf_buffer_t *buffer);
777 };
778 
779 PKGCONF_API bool pkgconf_output_putbuf(pkgconf_output_t *output, pkgconf_output_stream_t stream, const pkgconf_buffer_t *buffer, bool newline);
780 PKGCONF_API bool pkgconf_output_puts(pkgconf_output_t *output, pkgconf_output_stream_t stream, const char *str);
781 PKGCONF_API bool pkgconf_output_fmt(pkgconf_output_t *output, pkgconf_output_stream_t stream, const char *fmt, ...) PRINTFLIKE(3,4);
782 PKGCONF_API bool pkgconf_output_vfmt(pkgconf_output_t *output, pkgconf_output_stream_t stream, const char *fmt, va_list va_src) PRINTFLIKE(3,0);
783 PKGCONF_API pkgconf_output_t *pkgconf_output_default(void);
784 
785 PKGCONF_API bool pkgconf_output_file_vfmt(FILE *f, const char *fmt, va_list va) PRINTFLIKE(2,0);
786 PKGCONF_API bool pkgconf_output_file_fmt(FILE *f, const char *fmt, ...) PRINTFLIKE(2,3);
787 
788 #ifdef __cplusplus
789 }
790 #endif
791 
792 #endif
793