1*a3cefe7fSPierre Pronchery /*
2*a3cefe7fSPierre Pronchery * personality.c
3*a3cefe7fSPierre Pronchery * libpkgconf cross-compile personality database
4*a3cefe7fSPierre Pronchery *
5*a3cefe7fSPierre Pronchery * Copyright (c) 2018 pkgconf authors (see AUTHORS).
6*a3cefe7fSPierre Pronchery *
7*a3cefe7fSPierre Pronchery * Permission to use, copy, modify, and/or distribute this software for any
8*a3cefe7fSPierre Pronchery * purpose with or without fee is hereby granted, provided that the above
9*a3cefe7fSPierre Pronchery * copyright notice and this permission notice appear in all copies.
10*a3cefe7fSPierre Pronchery *
11*a3cefe7fSPierre Pronchery * This software is provided 'as is' and without any warranty, express or
12*a3cefe7fSPierre Pronchery * implied. In no event shall the authors be liable for any damages arising
13*a3cefe7fSPierre Pronchery * from the use of this software.
14*a3cefe7fSPierre Pronchery */
15*a3cefe7fSPierre Pronchery
16*a3cefe7fSPierre Pronchery #include <libpkgconf/config.h>
17*a3cefe7fSPierre Pronchery #include <libpkgconf/stdinc.h>
18*a3cefe7fSPierre Pronchery #include <libpkgconf/libpkgconf.h>
19*a3cefe7fSPierre Pronchery
20*a3cefe7fSPierre Pronchery /*
21*a3cefe7fSPierre Pronchery * !doc
22*a3cefe7fSPierre Pronchery *
23*a3cefe7fSPierre Pronchery * libpkgconf `personality` module
24*a3cefe7fSPierre Pronchery * =========================
25*a3cefe7fSPierre Pronchery */
26*a3cefe7fSPierre Pronchery
27*a3cefe7fSPierre Pronchery #ifdef _WIN32
28*a3cefe7fSPierre Pronchery # define strcasecmp _stricmp
29*a3cefe7fSPierre Pronchery #endif
30*a3cefe7fSPierre Pronchery
31*a3cefe7fSPierre Pronchery /*
32*a3cefe7fSPierre Pronchery * Increment each time the default personality is inited, decrement each time
33*a3cefe7fSPierre Pronchery * it's deinited. Whenever it is 0, then the deinit frees the personality. In
34*a3cefe7fSPierre Pronchery * that case an additional call to init will create it anew.
35*a3cefe7fSPierre Pronchery */
36*a3cefe7fSPierre Pronchery static unsigned default_personality_init = 0;
37*a3cefe7fSPierre Pronchery
38*a3cefe7fSPierre Pronchery static pkgconf_cross_personality_t default_personality = {
39*a3cefe7fSPierre Pronchery .name = "default",
40*a3cefe7fSPierre Pronchery };
41*a3cefe7fSPierre Pronchery
42*a3cefe7fSPierre Pronchery static inline void
build_default_search_path(pkgconf_list_t * dirlist)43*a3cefe7fSPierre Pronchery build_default_search_path(pkgconf_list_t* dirlist)
44*a3cefe7fSPierre Pronchery {
45*a3cefe7fSPierre Pronchery #ifdef _WIN32
46*a3cefe7fSPierre Pronchery char namebuf[MAX_PATH];
47*a3cefe7fSPierre Pronchery char outbuf[MAX_PATH];
48*a3cefe7fSPierre Pronchery char *p;
49*a3cefe7fSPierre Pronchery
50*a3cefe7fSPierre Pronchery int sizepath = GetModuleFileName(NULL, namebuf, sizeof namebuf);
51*a3cefe7fSPierre Pronchery char * winslash;
52*a3cefe7fSPierre Pronchery namebuf[sizepath] = '\0';
53*a3cefe7fSPierre Pronchery while ((winslash = strchr (namebuf, '\\')) != NULL)
54*a3cefe7fSPierre Pronchery {
55*a3cefe7fSPierre Pronchery *winslash = '/';
56*a3cefe7fSPierre Pronchery }
57*a3cefe7fSPierre Pronchery p = strrchr(namebuf, '/');
58*a3cefe7fSPierre Pronchery if (p == NULL)
59*a3cefe7fSPierre Pronchery pkgconf_path_split(PKG_DEFAULT_PATH, dirlist, true);
60*a3cefe7fSPierre Pronchery
61*a3cefe7fSPierre Pronchery *p = '\0';
62*a3cefe7fSPierre Pronchery pkgconf_strlcpy(outbuf, namebuf, sizeof outbuf);
63*a3cefe7fSPierre Pronchery pkgconf_strlcat(outbuf, "/", sizeof outbuf);
64*a3cefe7fSPierre Pronchery pkgconf_strlcat(outbuf, "../lib/pkgconfig", sizeof outbuf);
65*a3cefe7fSPierre Pronchery pkgconf_path_add(outbuf, dirlist, true);
66*a3cefe7fSPierre Pronchery pkgconf_strlcpy(outbuf, namebuf, sizeof outbuf);
67*a3cefe7fSPierre Pronchery pkgconf_strlcat(outbuf, "/", sizeof outbuf);
68*a3cefe7fSPierre Pronchery pkgconf_strlcat(outbuf, "../share/pkgconfig", sizeof outbuf);
69*a3cefe7fSPierre Pronchery pkgconf_path_add(outbuf, dirlist, true);
70*a3cefe7fSPierre Pronchery #elif __HAIKU__
71*a3cefe7fSPierre Pronchery char **paths;
72*a3cefe7fSPierre Pronchery size_t count;
73*a3cefe7fSPierre Pronchery if (find_paths(B_FIND_PATH_DEVELOP_LIB_DIRECTORY, "pkgconfig", &paths, &count) == B_OK) {
74*a3cefe7fSPierre Pronchery for (size_t i = 0; i < count; i++)
75*a3cefe7fSPierre Pronchery pkgconf_path_add(paths[i], dirlist, true);
76*a3cefe7fSPierre Pronchery free(paths);
77*a3cefe7fSPierre Pronchery paths = NULL;
78*a3cefe7fSPierre Pronchery }
79*a3cefe7fSPierre Pronchery if (find_paths(B_FIND_PATH_DATA_DIRECTORY, "pkgconfig", &paths, &count) == B_OK) {
80*a3cefe7fSPierre Pronchery for (size_t i = 0; i < count; i++)
81*a3cefe7fSPierre Pronchery pkgconf_path_add(paths[i], dirlist, true);
82*a3cefe7fSPierre Pronchery free(paths);
83*a3cefe7fSPierre Pronchery paths = NULL;
84*a3cefe7fSPierre Pronchery }
85*a3cefe7fSPierre Pronchery #else
86*a3cefe7fSPierre Pronchery pkgconf_path_split(PKG_DEFAULT_PATH, dirlist, true);
87*a3cefe7fSPierre Pronchery #endif
88*a3cefe7fSPierre Pronchery }
89*a3cefe7fSPierre Pronchery
90*a3cefe7fSPierre Pronchery /*
91*a3cefe7fSPierre Pronchery * !doc
92*a3cefe7fSPierre Pronchery *
93*a3cefe7fSPierre Pronchery * .. c:function:: const pkgconf_cross_personality_t *pkgconf_cross_personality_default(void)
94*a3cefe7fSPierre Pronchery *
95*a3cefe7fSPierre Pronchery * Returns the default cross-compile personality.
96*a3cefe7fSPierre Pronchery *
97*a3cefe7fSPierre Pronchery * Not thread safe.
98*a3cefe7fSPierre Pronchery *
99*a3cefe7fSPierre Pronchery * :rtype: pkgconf_cross_personality_t*
100*a3cefe7fSPierre Pronchery * :return: the default cross-compile personality
101*a3cefe7fSPierre Pronchery */
102*a3cefe7fSPierre Pronchery pkgconf_cross_personality_t *
pkgconf_cross_personality_default(void)103*a3cefe7fSPierre Pronchery pkgconf_cross_personality_default(void)
104*a3cefe7fSPierre Pronchery {
105*a3cefe7fSPierre Pronchery if (default_personality_init) {
106*a3cefe7fSPierre Pronchery ++default_personality_init;
107*a3cefe7fSPierre Pronchery return &default_personality;
108*a3cefe7fSPierre Pronchery }
109*a3cefe7fSPierre Pronchery
110*a3cefe7fSPierre Pronchery build_default_search_path(&default_personality.dir_list);
111*a3cefe7fSPierre Pronchery
112*a3cefe7fSPierre Pronchery pkgconf_path_split(SYSTEM_LIBDIR, &default_personality.filter_libdirs, false);
113*a3cefe7fSPierre Pronchery pkgconf_path_split(SYSTEM_INCLUDEDIR, &default_personality.filter_includedirs, false);
114*a3cefe7fSPierre Pronchery
115*a3cefe7fSPierre Pronchery ++default_personality_init;
116*a3cefe7fSPierre Pronchery return &default_personality;
117*a3cefe7fSPierre Pronchery }
118*a3cefe7fSPierre Pronchery
119*a3cefe7fSPierre Pronchery /*
120*a3cefe7fSPierre Pronchery * !doc
121*a3cefe7fSPierre Pronchery *
122*a3cefe7fSPierre Pronchery * .. c:function:: void pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *)
123*a3cefe7fSPierre Pronchery *
124*a3cefe7fSPierre Pronchery * Destroys a cross personality object and/or decreases the reference count on the
125*a3cefe7fSPierre Pronchery * default cross personality object.
126*a3cefe7fSPierre Pronchery *
127*a3cefe7fSPierre Pronchery * Not thread safe.
128*a3cefe7fSPierre Pronchery *
129*a3cefe7fSPierre Pronchery * :rtype: void
130*a3cefe7fSPierre Pronchery */
131*a3cefe7fSPierre Pronchery void
pkgconf_cross_personality_deinit(pkgconf_cross_personality_t * personality)132*a3cefe7fSPierre Pronchery pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *personality)
133*a3cefe7fSPierre Pronchery {
134*a3cefe7fSPierre Pronchery /* allow NULL parameter for API backwards compatibility */
135*a3cefe7fSPierre Pronchery if (personality == NULL)
136*a3cefe7fSPierre Pronchery return;
137*a3cefe7fSPierre Pronchery
138*a3cefe7fSPierre Pronchery /* XXX: this hack is rather ugly, but it works for now... */
139*a3cefe7fSPierre Pronchery if (personality == &default_personality && --default_personality_init > 0)
140*a3cefe7fSPierre Pronchery return;
141*a3cefe7fSPierre Pronchery
142*a3cefe7fSPierre Pronchery pkgconf_path_free(&personality->dir_list);
143*a3cefe7fSPierre Pronchery pkgconf_path_free(&personality->filter_libdirs);
144*a3cefe7fSPierre Pronchery pkgconf_path_free(&personality->filter_includedirs);
145*a3cefe7fSPierre Pronchery
146*a3cefe7fSPierre Pronchery if (personality->sysroot_dir != NULL)
147*a3cefe7fSPierre Pronchery free(personality->sysroot_dir);
148*a3cefe7fSPierre Pronchery
149*a3cefe7fSPierre Pronchery if (personality == &default_personality)
150*a3cefe7fSPierre Pronchery return;
151*a3cefe7fSPierre Pronchery
152*a3cefe7fSPierre Pronchery if (personality->name != NULL)
153*a3cefe7fSPierre Pronchery free(personality->name);
154*a3cefe7fSPierre Pronchery
155*a3cefe7fSPierre Pronchery free(personality);
156*a3cefe7fSPierre Pronchery }
157*a3cefe7fSPierre Pronchery
158*a3cefe7fSPierre Pronchery #ifndef PKGCONF_LITE
159*a3cefe7fSPierre Pronchery static bool
valid_triplet(const char * triplet)160*a3cefe7fSPierre Pronchery valid_triplet(const char *triplet)
161*a3cefe7fSPierre Pronchery {
162*a3cefe7fSPierre Pronchery const char *c = triplet;
163*a3cefe7fSPierre Pronchery
164*a3cefe7fSPierre Pronchery for (; *c; c++)
165*a3cefe7fSPierre Pronchery if (!isalnum((unsigned char)*c) && *c != '-' && *c != '_')
166*a3cefe7fSPierre Pronchery return false;
167*a3cefe7fSPierre Pronchery
168*a3cefe7fSPierre Pronchery return true;
169*a3cefe7fSPierre Pronchery }
170*a3cefe7fSPierre Pronchery
171*a3cefe7fSPierre Pronchery typedef void (*personality_keyword_func_t)(pkgconf_cross_personality_t *p, const char *keyword, const size_t lineno, const ptrdiff_t offset, char *value);
172*a3cefe7fSPierre Pronchery typedef struct {
173*a3cefe7fSPierre Pronchery const char *keyword;
174*a3cefe7fSPierre Pronchery const personality_keyword_func_t func;
175*a3cefe7fSPierre Pronchery const ptrdiff_t offset;
176*a3cefe7fSPierre Pronchery } personality_keyword_pair_t;
177*a3cefe7fSPierre Pronchery
178*a3cefe7fSPierre Pronchery static void
personality_bool_func(pkgconf_cross_personality_t * p,const char * keyword,const size_t lineno,const ptrdiff_t offset,char * value)179*a3cefe7fSPierre Pronchery personality_bool_func(pkgconf_cross_personality_t *p, const char *keyword, const size_t lineno, const ptrdiff_t offset, char *value)
180*a3cefe7fSPierre Pronchery {
181*a3cefe7fSPierre Pronchery (void) keyword;
182*a3cefe7fSPierre Pronchery (void) lineno;
183*a3cefe7fSPierre Pronchery
184*a3cefe7fSPierre Pronchery bool *dest = (bool *)((char *) p + offset);
185*a3cefe7fSPierre Pronchery *dest = strcasecmp(value, "true") || strcasecmp(value, "yes") || *value == '1';
186*a3cefe7fSPierre Pronchery }
187*a3cefe7fSPierre Pronchery
188*a3cefe7fSPierre Pronchery static void
personality_copy_func(pkgconf_cross_personality_t * p,const char * keyword,const size_t lineno,const ptrdiff_t offset,char * value)189*a3cefe7fSPierre Pronchery personality_copy_func(pkgconf_cross_personality_t *p, const char *keyword, const size_t lineno, const ptrdiff_t offset, char *value)
190*a3cefe7fSPierre Pronchery {
191*a3cefe7fSPierre Pronchery (void) keyword;
192*a3cefe7fSPierre Pronchery (void) lineno;
193*a3cefe7fSPierre Pronchery
194*a3cefe7fSPierre Pronchery char **dest = (char **)((char *) p + offset);
195*a3cefe7fSPierre Pronchery *dest = strdup(value);
196*a3cefe7fSPierre Pronchery }
197*a3cefe7fSPierre Pronchery
198*a3cefe7fSPierre Pronchery static void
personality_fragment_func(pkgconf_cross_personality_t * p,const char * keyword,const size_t lineno,const ptrdiff_t offset,char * value)199*a3cefe7fSPierre Pronchery personality_fragment_func(pkgconf_cross_personality_t *p, const char *keyword, const size_t lineno, const ptrdiff_t offset, char *value)
200*a3cefe7fSPierre Pronchery {
201*a3cefe7fSPierre Pronchery (void) keyword;
202*a3cefe7fSPierre Pronchery (void) lineno;
203*a3cefe7fSPierre Pronchery
204*a3cefe7fSPierre Pronchery pkgconf_list_t *dest = (pkgconf_list_t *)((char *) p + offset);
205*a3cefe7fSPierre Pronchery pkgconf_path_split(value, dest, false);
206*a3cefe7fSPierre Pronchery }
207*a3cefe7fSPierre Pronchery
208*a3cefe7fSPierre Pronchery /* keep in alphabetical order! */
209*a3cefe7fSPierre Pronchery static const personality_keyword_pair_t personality_keyword_pairs[] = {
210*a3cefe7fSPierre Pronchery {"DefaultSearchPaths", personality_fragment_func, offsetof(pkgconf_cross_personality_t, dir_list)},
211*a3cefe7fSPierre Pronchery {"SysrootDir", personality_copy_func, offsetof(pkgconf_cross_personality_t, sysroot_dir)},
212*a3cefe7fSPierre Pronchery {"SystemIncludePaths", personality_fragment_func, offsetof(pkgconf_cross_personality_t, filter_includedirs)},
213*a3cefe7fSPierre Pronchery {"SystemLibraryPaths", personality_fragment_func, offsetof(pkgconf_cross_personality_t, filter_libdirs)},
214*a3cefe7fSPierre Pronchery {"Triplet", personality_copy_func, offsetof(pkgconf_cross_personality_t, name)},
215*a3cefe7fSPierre Pronchery {"WantDefaultPure", personality_bool_func, offsetof(pkgconf_cross_personality_t, want_default_pure)},
216*a3cefe7fSPierre Pronchery {"WantDefaultStatic", personality_bool_func, offsetof(pkgconf_cross_personality_t, want_default_static)},
217*a3cefe7fSPierre Pronchery };
218*a3cefe7fSPierre Pronchery
219*a3cefe7fSPierre Pronchery static int
personality_keyword_pair_cmp(const void * key,const void * ptr)220*a3cefe7fSPierre Pronchery personality_keyword_pair_cmp(const void *key, const void *ptr)
221*a3cefe7fSPierre Pronchery {
222*a3cefe7fSPierre Pronchery const personality_keyword_pair_t *pair = ptr;
223*a3cefe7fSPierre Pronchery return strcasecmp(key, pair->keyword);
224*a3cefe7fSPierre Pronchery }
225*a3cefe7fSPierre Pronchery
226*a3cefe7fSPierre Pronchery static void
personality_keyword_set(pkgconf_cross_personality_t * p,const size_t lineno,const char * keyword,char * value)227*a3cefe7fSPierre Pronchery personality_keyword_set(pkgconf_cross_personality_t *p, const size_t lineno, const char *keyword, char *value)
228*a3cefe7fSPierre Pronchery {
229*a3cefe7fSPierre Pronchery const personality_keyword_pair_t *pair = bsearch(keyword,
230*a3cefe7fSPierre Pronchery personality_keyword_pairs, PKGCONF_ARRAY_SIZE(personality_keyword_pairs),
231*a3cefe7fSPierre Pronchery sizeof(personality_keyword_pair_t), personality_keyword_pair_cmp);
232*a3cefe7fSPierre Pronchery
233*a3cefe7fSPierre Pronchery if (pair == NULL || pair->func == NULL)
234*a3cefe7fSPierre Pronchery return;
235*a3cefe7fSPierre Pronchery
236*a3cefe7fSPierre Pronchery pair->func(p, keyword, lineno, pair->offset, value);
237*a3cefe7fSPierre Pronchery }
238*a3cefe7fSPierre Pronchery
239*a3cefe7fSPierre Pronchery static const pkgconf_parser_operand_func_t personality_parser_ops[256] = {
240*a3cefe7fSPierre Pronchery [':'] = (pkgconf_parser_operand_func_t) personality_keyword_set
241*a3cefe7fSPierre Pronchery };
242*a3cefe7fSPierre Pronchery
243*a3cefe7fSPierre Pronchery static void personality_warn_func(void *p, const char *fmt, ...) PRINTFLIKE(2, 3);
244*a3cefe7fSPierre Pronchery
245*a3cefe7fSPierre Pronchery static void
personality_warn_func(void * p,const char * fmt,...)246*a3cefe7fSPierre Pronchery personality_warn_func(void *p, const char *fmt, ...)
247*a3cefe7fSPierre Pronchery {
248*a3cefe7fSPierre Pronchery va_list va;
249*a3cefe7fSPierre Pronchery
250*a3cefe7fSPierre Pronchery (void) p;
251*a3cefe7fSPierre Pronchery
252*a3cefe7fSPierre Pronchery va_start(va, fmt);
253*a3cefe7fSPierre Pronchery vfprintf(stderr, fmt, va);
254*a3cefe7fSPierre Pronchery va_end(va);
255*a3cefe7fSPierre Pronchery }
256*a3cefe7fSPierre Pronchery
257*a3cefe7fSPierre Pronchery static pkgconf_cross_personality_t *
load_personality_with_path(const char * path,const char * triplet,bool datadir)258*a3cefe7fSPierre Pronchery load_personality_with_path(const char *path, const char *triplet, bool datadir)
259*a3cefe7fSPierre Pronchery {
260*a3cefe7fSPierre Pronchery char pathbuf[PKGCONF_ITEM_SIZE];
261*a3cefe7fSPierre Pronchery FILE *f;
262*a3cefe7fSPierre Pronchery pkgconf_cross_personality_t *p;
263*a3cefe7fSPierre Pronchery
264*a3cefe7fSPierre Pronchery /* if triplet is null, assume that path is a direct path to the personality file */
265*a3cefe7fSPierre Pronchery if (triplet == NULL)
266*a3cefe7fSPierre Pronchery pkgconf_strlcpy(pathbuf, path, sizeof pathbuf);
267*a3cefe7fSPierre Pronchery else if (datadir)
268*a3cefe7fSPierre Pronchery snprintf(pathbuf, sizeof pathbuf, "%s/pkgconfig/personality.d/%s.personality", path, triplet);
269*a3cefe7fSPierre Pronchery else
270*a3cefe7fSPierre Pronchery snprintf(pathbuf, sizeof pathbuf, "%s/%s.personality", path, triplet);
271*a3cefe7fSPierre Pronchery
272*a3cefe7fSPierre Pronchery p = calloc(1, sizeof(pkgconf_cross_personality_t));
273*a3cefe7fSPierre Pronchery if (p == NULL)
274*a3cefe7fSPierre Pronchery return NULL;
275*a3cefe7fSPierre Pronchery
276*a3cefe7fSPierre Pronchery if (triplet != NULL)
277*a3cefe7fSPierre Pronchery p->name = strdup(triplet);
278*a3cefe7fSPierre Pronchery
279*a3cefe7fSPierre Pronchery f = fopen(pathbuf, "r");
280*a3cefe7fSPierre Pronchery if (f == NULL) {
281*a3cefe7fSPierre Pronchery pkgconf_cross_personality_deinit(p);
282*a3cefe7fSPierre Pronchery return NULL;
283*a3cefe7fSPierre Pronchery }
284*a3cefe7fSPierre Pronchery
285*a3cefe7fSPierre Pronchery pkgconf_parser_parse(f, p, personality_parser_ops, personality_warn_func, pathbuf);
286*a3cefe7fSPierre Pronchery
287*a3cefe7fSPierre Pronchery return p;
288*a3cefe7fSPierre Pronchery }
289*a3cefe7fSPierre Pronchery
290*a3cefe7fSPierre Pronchery /*
291*a3cefe7fSPierre Pronchery * !doc
292*a3cefe7fSPierre Pronchery *
293*a3cefe7fSPierre Pronchery * .. c:function:: pkgconf_cross_personality_t *pkgconf_cross_personality_find(const char *triplet)
294*a3cefe7fSPierre Pronchery *
295*a3cefe7fSPierre Pronchery * Attempts to find a cross-compile personality given a triplet.
296*a3cefe7fSPierre Pronchery *
297*a3cefe7fSPierre Pronchery * :rtype: pkgconf_cross_personality_t*
298*a3cefe7fSPierre Pronchery * :return: the default cross-compile personality
299*a3cefe7fSPierre Pronchery */
300*a3cefe7fSPierre Pronchery pkgconf_cross_personality_t *
pkgconf_cross_personality_find(const char * triplet)301*a3cefe7fSPierre Pronchery pkgconf_cross_personality_find(const char *triplet)
302*a3cefe7fSPierre Pronchery {
303*a3cefe7fSPierre Pronchery pkgconf_list_t plist = PKGCONF_LIST_INITIALIZER;
304*a3cefe7fSPierre Pronchery pkgconf_node_t *n;
305*a3cefe7fSPierre Pronchery pkgconf_cross_personality_t *out = NULL;
306*a3cefe7fSPierre Pronchery #if ! defined(_WIN32) && ! defined(__HAIKU__)
307*a3cefe7fSPierre Pronchery char pathbuf[PKGCONF_ITEM_SIZE];
308*a3cefe7fSPierre Pronchery const char *envvar;
309*a3cefe7fSPierre Pronchery #endif
310*a3cefe7fSPierre Pronchery
311*a3cefe7fSPierre Pronchery out = load_personality_with_path(triplet, NULL, false);
312*a3cefe7fSPierre Pronchery if (out != NULL)
313*a3cefe7fSPierre Pronchery return out;
314*a3cefe7fSPierre Pronchery
315*a3cefe7fSPierre Pronchery if (!valid_triplet(triplet))
316*a3cefe7fSPierre Pronchery return NULL;
317*a3cefe7fSPierre Pronchery
318*a3cefe7fSPierre Pronchery #if ! defined(_WIN32) && ! defined(__HAIKU__)
319*a3cefe7fSPierre Pronchery envvar = getenv("XDG_DATA_HOME");
320*a3cefe7fSPierre Pronchery if (envvar != NULL)
321*a3cefe7fSPierre Pronchery pkgconf_path_add(envvar, &plist, true);
322*a3cefe7fSPierre Pronchery else {
323*a3cefe7fSPierre Pronchery envvar = getenv("HOME");
324*a3cefe7fSPierre Pronchery if (envvar != NULL) {
325*a3cefe7fSPierre Pronchery pkgconf_strlcpy(pathbuf, envvar, sizeof pathbuf);
326*a3cefe7fSPierre Pronchery pkgconf_strlcat(pathbuf, "/.local/share", sizeof pathbuf);
327*a3cefe7fSPierre Pronchery pkgconf_path_add(pathbuf, &plist, true);
328*a3cefe7fSPierre Pronchery }
329*a3cefe7fSPierre Pronchery }
330*a3cefe7fSPierre Pronchery
331*a3cefe7fSPierre Pronchery pkgconf_path_build_from_environ("XDG_DATA_DIRS", "/usr/local/share" PKG_CONFIG_PATH_SEP_S "/usr/share", &plist, true);
332*a3cefe7fSPierre Pronchery
333*a3cefe7fSPierre Pronchery PKGCONF_FOREACH_LIST_ENTRY(plist.head, n)
334*a3cefe7fSPierre Pronchery {
335*a3cefe7fSPierre Pronchery pkgconf_path_t *pn = n->data;
336*a3cefe7fSPierre Pronchery
337*a3cefe7fSPierre Pronchery out = load_personality_with_path(pn->path, triplet, true);
338*a3cefe7fSPierre Pronchery if (out != NULL)
339*a3cefe7fSPierre Pronchery goto finish;
340*a3cefe7fSPierre Pronchery }
341*a3cefe7fSPierre Pronchery pkgconf_path_free(&plist);
342*a3cefe7fSPierre Pronchery #endif
343*a3cefe7fSPierre Pronchery
344*a3cefe7fSPierre Pronchery pkgconf_path_split(PERSONALITY_PATH, &plist, true);
345*a3cefe7fSPierre Pronchery
346*a3cefe7fSPierre Pronchery PKGCONF_FOREACH_LIST_ENTRY(plist.head, n)
347*a3cefe7fSPierre Pronchery {
348*a3cefe7fSPierre Pronchery pkgconf_path_t *pn = n->data;
349*a3cefe7fSPierre Pronchery
350*a3cefe7fSPierre Pronchery out = load_personality_with_path(pn->path, triplet, false);
351*a3cefe7fSPierre Pronchery if (out != NULL)
352*a3cefe7fSPierre Pronchery goto finish;
353*a3cefe7fSPierre Pronchery }
354*a3cefe7fSPierre Pronchery
355*a3cefe7fSPierre Pronchery finish:
356*a3cefe7fSPierre Pronchery pkgconf_path_free(&plist);
357*a3cefe7fSPierre Pronchery return out != NULL ? out : pkgconf_cross_personality_default();
358*a3cefe7fSPierre Pronchery }
359*a3cefe7fSPierre Pronchery #endif
360