1 /*
2  * libpkgconf.h
3  * Global include file for everything in libpkgconf.
4  *
5  * Copyright (c) 2011, 2015 pkgconf authors (see AUTHORS).
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * This software is provided 'as is' and without any warranty, express or
12  * implied.  In no event shall the authors be liable for any damages arising
13  * from the use of this software.
14  */
15 
16 #ifndef LIBPKGCONF__LIBPKGCONF_H
17 #define LIBPKGCONF__LIBPKGCONF_H
18 
19 #include <stdio.h>
20 #include <stdarg.h>
21 #include <stddef.h>
22 #include <stdbool.h>
23 #include <libpkgconf/libpkgconf-api.h>
24 #include <libpkgconf/iter.h>
25 #include <libpkgconf/bsdstubs.h>
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 /* pkg-config uses ';' on win32 as ':' is part of path */
32 #ifdef _WIN32
33 #define PKG_CONFIG_PATH_SEP_S   ";"
34 #else
35 #define PKG_CONFIG_PATH_SEP_S   ":"
36 #endif
37 
38 #ifdef _WIN32
39 #define PKG_DIR_SEP_S   '\\'
40 #else
41 #define PKG_DIR_SEP_S   '/'
42 #endif
43 
44 #ifdef _WIN32
45 #define realpath(N,R) _fullpath((R),(N),_MAX_PATH)
46 #endif
47 
48 #define PKGCONF_BUFSIZE	(65535)
49 
50 typedef enum {
51 	PKGCONF_CMP_NOT_EQUAL,
52 	PKGCONF_CMP_ANY,
53 	PKGCONF_CMP_LESS_THAN,
54 	PKGCONF_CMP_LESS_THAN_EQUAL,
55 	PKGCONF_CMP_EQUAL,
56 	PKGCONF_CMP_GREATER_THAN,
57 	PKGCONF_CMP_GREATER_THAN_EQUAL
58 } pkgconf_pkg_comparator_t;
59 
60 #define PKGCONF_CMP_COUNT 7
61 
62 typedef struct pkgconf_pkg_ pkgconf_pkg_t;
63 typedef struct pkgconf_dependency_ pkgconf_dependency_t;
64 typedef struct pkgconf_tuple_ pkgconf_tuple_t;
65 typedef struct pkgconf_fragment_ pkgconf_fragment_t;
66 typedef struct pkgconf_path_ pkgconf_path_t;
67 typedef struct pkgconf_client_ pkgconf_client_t;
68 typedef struct pkgconf_cross_personality_ pkgconf_cross_personality_t;
69 
70 #define PKGCONF_ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
71 
72 #define PKGCONF_FOREACH_LIST_ENTRY(head, value) \
73 	for ((value) = (head); (value) != NULL; (value) = (value)->next)
74 
75 #define PKGCONF_FOREACH_LIST_ENTRY_SAFE(head, nextiter, value) \
76 	for ((value) = (head), (nextiter) = (head) != NULL ? (head)->next : NULL; (value) != NULL; (value) = (nextiter), (nextiter) = (nextiter) != NULL ? (nextiter)->next : NULL)
77 
78 #define PKGCONF_FOREACH_LIST_ENTRY_REVERSE(tail, value) \
79 	for ((value) = (tail); (value) != NULL; (value) = (value)->prev)
80 
81 #define LIBPKGCONF_VERSION	10700
82 #define LIBPKGCONF_VERSION_STR	"1.7.0"
83 
84 struct pkgconf_fragment_ {
85 	pkgconf_node_t iter;
86 
87 	char type;
88 	char *data;
89 
90 	bool merged;
91 };
92 
93 struct pkgconf_dependency_ {
94 	pkgconf_node_t iter;
95 
96 	char *package;
97 	pkgconf_pkg_comparator_t compare;
98 	char *version;
99 	pkgconf_pkg_t *parent;
100 	pkgconf_pkg_t *match;
101 
102 	unsigned int flags;
103 };
104 
105 struct pkgconf_tuple_ {
106 	pkgconf_node_t iter;
107 
108 	char *key;
109 	char *value;
110 };
111 
112 struct pkgconf_path_ {
113 	pkgconf_node_t lnode;
114 
115 	char *path;
116 	void *handle_path;
117 	void *handle_device;
118 };
119 
120 #define PKGCONF_PKG_PROPF_NONE			0x00
121 #define PKGCONF_PKG_PROPF_STATIC		0x01
122 #define PKGCONF_PKG_PROPF_CACHED		0x02
123 #define PKGCONF_PKG_PROPF_SEEN			0x04
124 #define PKGCONF_PKG_PROPF_UNINSTALLED		0x08
125 #define PKGCONF_PKG_PROPF_VIRTUAL		0x10
126 
127 struct pkgconf_pkg_ {
128 	pkgconf_node_t cache_iter;
129 
130 	int refcount;
131 	char *id;
132 	char *filename;
133 	char *realname;
134 	char *version;
135 	char *description;
136 	char *url;
137 	char *pc_filedir;
138 
139 	pkgconf_list_t libs;
140 	pkgconf_list_t libs_private;
141 	pkgconf_list_t cflags;
142 	pkgconf_list_t cflags_private;
143 
144 	pkgconf_list_t required;		/* this used to be requires but that is now a reserved keyword */
145 	pkgconf_list_t requires_private;
146 	pkgconf_list_t conflicts;
147 	pkgconf_list_t provides;
148 
149 	pkgconf_list_t vars;
150 
151 	unsigned int flags;
152 
153 	pkgconf_client_t *owner;
154 
155 	/* these resources are owned by the package and do not need special management,
156 	 * under no circumstance attempt to allocate or free objects belonging to these pointers
157 	 */
158 	pkgconf_tuple_t *orig_prefix;
159 	pkgconf_tuple_t *prefix;
160 };
161 
162 typedef bool (*pkgconf_pkg_iteration_func_t)(const pkgconf_pkg_t *pkg, void *data);
163 typedef void (*pkgconf_pkg_traverse_func_t)(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data);
164 typedef bool (*pkgconf_queue_apply_func_t)(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth);
165 typedef bool (*pkgconf_error_handler_func_t)(const char *msg, const pkgconf_client_t *client, const void *data);
166 
167 struct pkgconf_client_ {
168 	pkgconf_list_t dir_list;
169 	pkgconf_list_t pkg_cache;
170 
171 	pkgconf_list_t filter_libdirs;
172 	pkgconf_list_t filter_includedirs;
173 
174 	pkgconf_list_t global_vars;
175 
176 	void *error_handler_data;
177 	void *warn_handler_data;
178 	void *trace_handler_data;
179 
180 	pkgconf_error_handler_func_t error_handler;
181 	pkgconf_error_handler_func_t warn_handler;
182 	pkgconf_error_handler_func_t trace_handler;
183 
184 	FILE *auditf;
185 
186 	char *sysroot_dir;
187 	char *buildroot_dir;
188 
189 	unsigned int flags;
190 
191 	char *prefix_varname;
192 
193 	bool already_sent_notice;
194 };
195 
196 struct pkgconf_cross_personality_ {
197 	const char *name;
198 
199 	pkgconf_list_t dir_list;
200 
201 	pkgconf_list_t filter_libdirs;
202 	pkgconf_list_t filter_includedirs;
203 
204 	char *sysroot_dir;
205 
206 	bool want_default_static;
207 	bool want_default_pure;
208 };
209 
210 /* client.c */
211 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);
212 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);
213 PKGCONF_API void pkgconf_client_deinit(pkgconf_client_t *client);
214 PKGCONF_API void pkgconf_client_free(pkgconf_client_t *client);
215 PKGCONF_API const char *pkgconf_client_get_sysroot_dir(const pkgconf_client_t *client);
216 PKGCONF_API void pkgconf_client_set_sysroot_dir(pkgconf_client_t *client, const char *sysroot_dir);
217 PKGCONF_API const char *pkgconf_client_get_buildroot_dir(const pkgconf_client_t *client);
218 PKGCONF_API void pkgconf_client_set_buildroot_dir(pkgconf_client_t *client, const char *buildroot_dir);
219 PKGCONF_API unsigned int pkgconf_client_get_flags(const pkgconf_client_t *client);
220 PKGCONF_API void pkgconf_client_set_flags(pkgconf_client_t *client, unsigned int flags);
221 PKGCONF_API const char *pkgconf_client_get_prefix_varname(const pkgconf_client_t *client);
222 PKGCONF_API void pkgconf_client_set_prefix_varname(pkgconf_client_t *client, const char *prefix_varname);
223 PKGCONF_API pkgconf_error_handler_func_t pkgconf_client_get_warn_handler(const pkgconf_client_t *client);
224 PKGCONF_API void pkgconf_client_set_warn_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t warn_handler, void *warn_handler_data);
225 PKGCONF_API pkgconf_error_handler_func_t pkgconf_client_get_error_handler(const pkgconf_client_t *client);
226 PKGCONF_API void pkgconf_client_set_error_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data);
227 PKGCONF_API pkgconf_error_handler_func_t pkgconf_client_get_trace_handler(const pkgconf_client_t *client);
228 PKGCONF_API void pkgconf_client_set_trace_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t trace_handler, void *trace_handler_data);
229 PKGCONF_API void pkgconf_client_dir_list_build(pkgconf_client_t *client, const pkgconf_cross_personality_t *personality);
230 
231 /* personality.c */
232 PKGCONF_API pkgconf_cross_personality_t *pkgconf_cross_personality_default(void);
233 PKGCONF_API pkgconf_cross_personality_t *pkgconf_cross_personality_find(const char *triplet);
234 PKGCONF_API void pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *personality);
235 
236 #define PKGCONF_IS_MODULE_SEPARATOR(c) ((c) == ',' || isspace ((unsigned int)(c)))
237 #define PKGCONF_IS_OPERATOR_CHAR(c) ((c) == '<' || (c) == '>' || (c) == '!' || (c) == '=')
238 
239 #define PKGCONF_PKG_PKGF_NONE				0x0000
240 #define PKGCONF_PKG_PKGF_SEARCH_PRIVATE			0x0001
241 #define PKGCONF_PKG_PKGF_ENV_ONLY			0x0002
242 #define PKGCONF_PKG_PKGF_NO_UNINSTALLED			0x0004
243 #define PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL		0x0008
244 #define PKGCONF_PKG_PKGF_MERGE_PRIVATE_FRAGMENTS	0x0010
245 #define PKGCONF_PKG_PKGF_SKIP_CONFLICTS			0x0020
246 #define PKGCONF_PKG_PKGF_NO_CACHE			0x0040
247 #define PKGCONF_PKG_PKGF_SKIP_ERRORS			0x0080
248 #define PKGCONF_PKG_PKGF_ITER_PKG_IS_PRIVATE		0x0100
249 #define PKGCONF_PKG_PKGF_SKIP_PROVIDES			0x0200
250 #define PKGCONF_PKG_PKGF_REDEFINE_PREFIX		0x0400
251 #define PKGCONF_PKG_PKGF_DONT_RELOCATE_PATHS		0x0800
252 #define PKGCONF_PKG_PKGF_SIMPLIFY_ERRORS		0x1000
253 #define PKGCONF_PKG_PKGF_DONT_FILTER_INTERNAL_CFLAGS	0x2000
254 #define PKGCONF_PKG_PKGF_DONT_MERGE_SPECIAL_FRAGMENTS	0x4000
255 #define PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES		0x8000
256 
257 #define PKGCONF_PKG_DEPF_INTERNAL		0x1
258 
259 #define PKGCONF_PKG_ERRF_OK			0x0
260 #define PKGCONF_PKG_ERRF_PACKAGE_NOT_FOUND	0x1
261 #define PKGCONF_PKG_ERRF_PACKAGE_VER_MISMATCH	0x2
262 #define PKGCONF_PKG_ERRF_PACKAGE_CONFLICT	0x4
263 #define PKGCONF_PKG_ERRF_DEPGRAPH_BREAK		0x8
264 
265 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
266 #define PRINTFLIKE(fmtarg, firstvararg) \
267         __attribute__((__format__ (__printf__, fmtarg, firstvararg)))
268 #define DEPRECATED \
269         __attribute__((deprecated))
270 #else
271 #define PRINTFLIKE(fmtarg, firstvararg)
272 #define DEPRECATED
273 #endif /* defined(__INTEL_COMPILER) || defined(__GNUC__) */
274 
275 /* parser.c */
276 typedef void (*pkgconf_parser_operand_func_t)(void *data, const size_t lineno, const char *key, const char *value);
277 typedef void (*pkgconf_parser_warn_func_t)(void *data, const char *fmt, ...);
278 
279 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);
280 
281 /* pkg.c */
282 PKGCONF_API bool pkgconf_error(const pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3);
283 PKGCONF_API bool pkgconf_warn(const pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3);
284 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);
285 PKGCONF_API bool pkgconf_default_error_handler(const char *msg, const pkgconf_client_t *client, const void *data);
286 
287 #ifndef PKGCONF_LITE
288 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
289 #define PKGCONF_TRACE(client, ...) do { \
290 		pkgconf_trace(client, __FILE__, __LINE__, __PRETTY_FUNCTION__, __VA_ARGS__); \
291 	} while (0);
292 #else
293 #define PKGCONF_TRACE(client, ...) do { \
294 		pkgconf_trace(client, __FILE__, __LINE__, __func__, __VA_ARGS__); \
295 	} while (0);
296 #endif
297 #else
298 #define PKGCONF_TRACE(client, ...)
299 #endif
300 
301 PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_ref(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
302 PKGCONF_API void pkgconf_pkg_unref(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
303 PKGCONF_API void pkgconf_pkg_free(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
304 PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_find(pkgconf_client_t *client, const char *name);
305 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);
306 PKGCONF_API unsigned int pkgconf_pkg_verify_graph(pkgconf_client_t *client, pkgconf_pkg_t *root, int depth);
307 PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_verify_dependency(pkgconf_client_t *client, pkgconf_dependency_t *pkgdep, unsigned int *eflags);
308 PKGCONF_API const char *pkgconf_pkg_get_comparator(const pkgconf_dependency_t *pkgdep);
309 PKGCONF_API unsigned int pkgconf_pkg_cflags(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth);
310 PKGCONF_API unsigned int pkgconf_pkg_libs(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth);
311 PKGCONF_API pkgconf_pkg_comparator_t pkgconf_pkg_comparator_lookup_by_name(const char *name);
312 PKGCONF_API pkgconf_pkg_t *pkgconf_builtin_pkg_get(const char *name);
313 
314 PKGCONF_API int pkgconf_compare_version(const char *a, const char *b);
315 PKGCONF_API pkgconf_pkg_t *pkgconf_scan_all(pkgconf_client_t *client, void *ptr, pkgconf_pkg_iteration_func_t func);
316 
317 /* parse.c */
318 PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *path, FILE *f);
319 PKGCONF_API void pkgconf_dependency_parse_str(const pkgconf_client_t *client, pkgconf_list_t *deplist_head, const char *depends, unsigned int flags);
320 PKGCONF_API void pkgconf_dependency_parse(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist_head, const char *depends, unsigned int flags);
321 PKGCONF_API void pkgconf_dependency_append(pkgconf_list_t *list, pkgconf_dependency_t *tail);
322 PKGCONF_API void pkgconf_dependency_free(pkgconf_list_t *list);
323 PKGCONF_API pkgconf_dependency_t *pkgconf_dependency_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *package, const char *version, pkgconf_pkg_comparator_t compare, unsigned int flags);
324 
325 /* argvsplit.c */
326 PKGCONF_API int pkgconf_argv_split(const char *src, int *argc, char ***argv);
327 PKGCONF_API void pkgconf_argv_free(char **argv);
328 
329 /* fragment.c */
330 typedef struct pkgconf_fragment_render_ops_ {
331 	size_t (*render_len)(const pkgconf_list_t *list, bool escape);
332 	void (*render_buf)(const pkgconf_list_t *list, char *buf, size_t len, bool escape);
333 } pkgconf_fragment_render_ops_t;
334 
335 typedef bool (*pkgconf_fragment_filter_func_t)(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, void *data);
336 PKGCONF_API bool pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value);
337 PKGCONF_API void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string);
338 PKGCONF_API void pkgconf_fragment_copy(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_fragment_t *base, bool is_private);
339 PKGCONF_API void pkgconf_fragment_copy_list(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_list_t *base);
340 PKGCONF_API void pkgconf_fragment_delete(pkgconf_list_t *list, pkgconf_fragment_t *node);
341 PKGCONF_API void pkgconf_fragment_free(pkgconf_list_t *list);
342 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);
343 PKGCONF_API size_t pkgconf_fragment_render_len(const pkgconf_list_t *list, bool escape, const pkgconf_fragment_render_ops_t *ops);
344 PKGCONF_API void pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t len, bool escape, const pkgconf_fragment_render_ops_t *ops);
345 PKGCONF_API char *pkgconf_fragment_render(const pkgconf_list_t *list, bool escape, const pkgconf_fragment_render_ops_t *ops);
346 PKGCONF_API bool pkgconf_fragment_has_system_dir(const pkgconf_client_t *client, const pkgconf_fragment_t *frag);
347 
348 /* fileio.c */
349 PKGCONF_API char *pkgconf_fgetline(char *line, size_t size, FILE *stream);
350 
351 /* tuple.c */
352 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);
353 PKGCONF_API char *pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key);
354 PKGCONF_API char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *list, const char *value);
355 PKGCONF_API void pkgconf_tuple_free(pkgconf_list_t *list);
356 PKGCONF_API void pkgconf_tuple_free_entry(pkgconf_tuple_t *tuple, pkgconf_list_t *list);
357 PKGCONF_API void pkgconf_tuple_add_global(pkgconf_client_t *client, const char *key, const char *value);
358 PKGCONF_API char *pkgconf_tuple_find_global(const pkgconf_client_t *client, const char *key);
359 PKGCONF_API void pkgconf_tuple_free_global(pkgconf_client_t *client);
360 PKGCONF_API void pkgconf_tuple_define_global(pkgconf_client_t *client, const char *kv);
361 
362 /* queue.c */
363 PKGCONF_API void pkgconf_queue_push(pkgconf_list_t *list, const char *package);
364 PKGCONF_API bool pkgconf_queue_compile(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *list);
365 PKGCONF_API void pkgconf_queue_free(pkgconf_list_t *list);
366 PKGCONF_API bool pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, void *data);
367 PKGCONF_API bool pkgconf_queue_validate(pkgconf_client_t *client, pkgconf_list_t *list, int maxdepth);
368 
369 /* cache.c */
370 PKGCONF_API pkgconf_pkg_t *pkgconf_cache_lookup(pkgconf_client_t *client, const char *id);
371 PKGCONF_API void pkgconf_cache_add(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
372 PKGCONF_API void pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg);
373 PKGCONF_API void pkgconf_cache_free(pkgconf_client_t *client);
374 
375 /* audit.c */
376 PKGCONF_API void pkgconf_audit_set_log(pkgconf_client_t *client, FILE *auditf);
377 PKGCONF_API void pkgconf_audit_log(pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3);
378 PKGCONF_API void pkgconf_audit_log_dependency(pkgconf_client_t *client, const pkgconf_pkg_t *dep, const pkgconf_dependency_t *depnode);
379 
380 /* path.c */
381 PKGCONF_API void pkgconf_path_add(const char *text, pkgconf_list_t *dirlist, bool filter);
382 PKGCONF_API size_t pkgconf_path_split(const char *text, pkgconf_list_t *dirlist, bool filter);
383 PKGCONF_API size_t pkgconf_path_build_from_environ(const char *envvarname, const char *fallback, pkgconf_list_t *dirlist, bool filter);
384 PKGCONF_API bool pkgconf_path_match_list(const char *path, const pkgconf_list_t *dirlist);
385 PKGCONF_API void pkgconf_path_free(pkgconf_list_t *dirlist);
386 PKGCONF_API bool pkgconf_path_relocate(char *buf, size_t buflen);
387 PKGCONF_API void pkgconf_path_copy_list(pkgconf_list_t *dst, const pkgconf_list_t *src);
388 
389 #ifdef __cplusplus
390 }
391 #endif
392 
393 #endif
394