1*592efe25SPierre Pronchery /*
2*592efe25SPierre Pronchery * test-path-utils.c
3*592efe25SPierre Pronchery * Tests for libpkgconf internal path utility functions.
4*592efe25SPierre Pronchery *
5*592efe25SPierre Pronchery * SPDX-License-Identifier: pkgconf
6*592efe25SPierre Pronchery *
7*592efe25SPierre Pronchery * Copyright (c) 2025-2026 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/stdinc.h>
19*592efe25SPierre Pronchery #include <libpkgconf/libpkgconf.h>
20*592efe25SPierre Pronchery #include <libpkgconf/path.h>
21*592efe25SPierre Pronchery #include "test-api.h"
22*592efe25SPierre Pronchery
23*592efe25SPierre Pronchery static void
test_path_find_basename(void)24*592efe25SPierre Pronchery test_path_find_basename(void)
25*592efe25SPierre Pronchery {
26*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_path_find_basename("/usr/lib/pkgconfig/foo.pc"), "foo.pc");
27*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_path_find_basename("/usr/lib/pkgconfig"), "pkgconfig");
28*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_path_find_basename("foo.pc"), "foo.pc");
29*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_path_find_basename("/foo.pc"), "foo.pc");
30*592efe25SPierre Pronchery TEST_ASSERT_EMPTY_STRING(pkgconf_path_find_basename("/"));
31*592efe25SPierre Pronchery TEST_ASSERT_EMPTY_STRING(pkgconf_path_find_basename(""));
32*592efe25SPierre Pronchery TEST_ASSERT_EMPTY_STRING(pkgconf_path_find_basename("/usr/"));
33*592efe25SPierre Pronchery TEST_ASSERT_EMPTY_STRING(pkgconf_path_find_basename("usr/"));
34*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_path_find_basename("///usr/lib///pkgconfig///foo.pc"), "foo.pc");
35*592efe25SPierre Pronchery #ifdef _WIN32
36*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_path_find_basename("C:\\lib\\pkgconfig\\foo.pc"), "foo.pc");
37*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_path_find_basename("C:/lib/pkgconfig/foo.pc"), "foo.pc");
38*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_path_find_basename("C:/lib\\pkgconfig/foo.pc"), "foo.pc");
39*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_path_find_basename("C:\\lib/pkgconfig\\foo.pc"), "foo.pc");
40*592efe25SPierre Pronchery #endif
41*592efe25SPierre Pronchery }
42*592efe25SPierre Pronchery
43*592efe25SPierre Pronchery static void
test_path_trim_basename(void)44*592efe25SPierre Pronchery test_path_trim_basename(void)
45*592efe25SPierre Pronchery {
46*592efe25SPierre Pronchery pkgconf_buffer_t buf = PKGCONF_BUFFER_INITIALIZER;
47*592efe25SPierre Pronchery
48*592efe25SPierre Pronchery pkgconf_buffer_append(&buf, "/usr/lib/pkgconfig/foo.pc");
49*592efe25SPierre Pronchery TEST_ASSERT_TRUE(pkgconf_path_trim_basename(&buf));
50*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_buffer_str(&buf), "/usr/lib/pkgconfig");
51*592efe25SPierre Pronchery TEST_ASSERT_TRUE(pkgconf_path_trim_basename(&buf));
52*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_buffer_str(&buf), "/usr/lib");
53*592efe25SPierre Pronchery TEST_ASSERT_TRUE(pkgconf_path_trim_basename(&buf));
54*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_buffer_str(&buf), "/usr");
55*592efe25SPierre Pronchery TEST_ASSERT_TRUE(pkgconf_path_trim_basename(&buf));
56*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_buffer_str(&buf), "");
57*592efe25SPierre Pronchery TEST_ASSERT_FALSE(pkgconf_path_trim_basename(&buf));
58*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_buffer_str(&buf), "");
59*592efe25SPierre Pronchery
60*592efe25SPierre Pronchery pkgconf_buffer_reset(&buf);
61*592efe25SPierre Pronchery pkgconf_buffer_append(&buf, "foo.pc");
62*592efe25SPierre Pronchery TEST_ASSERT_FALSE(pkgconf_path_trim_basename(&buf));
63*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_buffer_str(&buf), "foo.pc");
64*592efe25SPierre Pronchery
65*592efe25SPierre Pronchery pkgconf_buffer_finalize(&buf);
66*592efe25SPierre Pronchery }
67*592efe25SPierre Pronchery
68*592efe25SPierre Pronchery static void
test_determine_prefix_logic(void)69*592efe25SPierre Pronchery test_determine_prefix_logic(void)
70*592efe25SPierre Pronchery {
71*592efe25SPierre Pronchery pkgconf_buffer_t buf = PKGCONF_BUFFER_INITIALIZER;
72*592efe25SPierre Pronchery
73*592efe25SPierre Pronchery // Normal case
74*592efe25SPierre Pronchery pkgconf_buffer_append(&buf, "/opt/foo/lib/pkgconfig/bar.pc");
75*592efe25SPierre Pronchery TEST_ASSERT_TRUE(pkgconf_path_trim_basename(&buf));
76*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_path_find_basename(pkgconf_buffer_str(&buf)), "pkgconfig");
77*592efe25SPierre Pronchery TEST_ASSERT_TRUE(pkgconf_path_trim_basename(&buf));
78*592efe25SPierre Pronchery TEST_ASSERT_TRUE(pkgconf_path_trim_basename(&buf));
79*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_buffer_str(&buf), "/opt/foo");
80*592efe25SPierre Pronchery
81*592efe25SPierre Pronchery // Short path: /pkgconfig/foo.pc
82*592efe25SPierre Pronchery pkgconf_buffer_reset(&buf);
83*592efe25SPierre Pronchery pkgconf_buffer_append(&buf, "/pkgconfig/foo.pc");
84*592efe25SPierre Pronchery TEST_ASSERT_TRUE(pkgconf_path_trim_basename(&buf));
85*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_path_find_basename(pkgconf_buffer_str(&buf)), "pkgconfig");
86*592efe25SPierre Pronchery TEST_ASSERT_TRUE(pkgconf_path_trim_basename(&buf)); // trims pkgconfig, returns true because of /
87*592efe25SPierre Pronchery TEST_ASSERT_FALSE(pkgconf_path_trim_basename(&buf)); // fails to trim further
88*592efe25SPierre Pronchery
89*592efe25SPierre Pronchery // Another short path: lib/pkgconfig/foo.pc
90*592efe25SPierre Pronchery pkgconf_buffer_reset(&buf);
91*592efe25SPierre Pronchery pkgconf_buffer_append(&buf, "lib/pkgconfig/foo.pc");
92*592efe25SPierre Pronchery TEST_ASSERT_TRUE(pkgconf_path_trim_basename(&buf));
93*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_path_find_basename(pkgconf_buffer_str(&buf)), "pkgconfig");
94*592efe25SPierre Pronchery TEST_ASSERT_TRUE(pkgconf_path_trim_basename(&buf));
95*592efe25SPierre Pronchery TEST_ASSERT_FALSE(pkgconf_path_trim_basename(&buf));
96*592efe25SPierre Pronchery
97*592efe25SPierre Pronchery // Trailing slash
98*592efe25SPierre Pronchery pkgconf_buffer_reset(&buf);
99*592efe25SPierre Pronchery pkgconf_buffer_append(&buf, "/usr/lib/pkgconfig/");
100*592efe25SPierre Pronchery TEST_ASSERT_TRUE(pkgconf_path_trim_basename(&buf));
101*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_buffer_str(&buf), "/usr/lib/pkgconfig");
102*592efe25SPierre Pronchery TEST_ASSERT_TRUE(pkgconf_path_trim_basename(&buf));
103*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(pkgconf_buffer_str(&buf), "/usr/lib");
104*592efe25SPierre Pronchery
105*592efe25SPierre Pronchery pkgconf_buffer_finalize(&buf);
106*592efe25SPierre Pronchery }
107*592efe25SPierre Pronchery
108*592efe25SPierre Pronchery static const char *
nth_path(const pkgconf_list_t * list,size_t idx)109*592efe25SPierre Pronchery nth_path(const pkgconf_list_t *list, size_t idx)
110*592efe25SPierre Pronchery {
111*592efe25SPierre Pronchery pkgconf_node_t *n;
112*592efe25SPierre Pronchery size_t i = 0;
113*592efe25SPierre Pronchery
114*592efe25SPierre Pronchery PKGCONF_FOREACH_LIST_ENTRY(list->head, n)
115*592efe25SPierre Pronchery {
116*592efe25SPierre Pronchery const pkgconf_path_t *p = n->data;
117*592efe25SPierre Pronchery
118*592efe25SPierre Pronchery if (i++ == idx)
119*592efe25SPierre Pronchery return p->path;
120*592efe25SPierre Pronchery }
121*592efe25SPierre Pronchery
122*592efe25SPierre Pronchery return NULL;
123*592efe25SPierre Pronchery }
124*592efe25SPierre Pronchery
125*592efe25SPierre Pronchery static void
test_path_prepend(void)126*592efe25SPierre Pronchery test_path_prepend(void)
127*592efe25SPierre Pronchery {
128*592efe25SPierre Pronchery pkgconf_list_t list = PKGCONF_LIST_INITIALIZER;
129*592efe25SPierre Pronchery
130*592efe25SPierre Pronchery pkgconf_path_prepend("/a", &list, false);
131*592efe25SPierre Pronchery pkgconf_path_prepend("/b", &list, false);
132*592efe25SPierre Pronchery pkgconf_path_prepend("/c", &list, false);
133*592efe25SPierre Pronchery
134*592efe25SPierre Pronchery TEST_ASSERT_EQ(list.length, 3);
135*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(nth_path(&list, 0), "/c");
136*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(nth_path(&list, 1), "/b");
137*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(nth_path(&list, 2), "/a");
138*592efe25SPierre Pronchery
139*592efe25SPierre Pronchery pkgconf_path_add("/d", &list, false);
140*592efe25SPierre Pronchery TEST_ASSERT_EQ(list.length, 4);
141*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(nth_path(&list, 0), "/c");
142*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(nth_path(&list, 3), "/d");
143*592efe25SPierre Pronchery
144*592efe25SPierre Pronchery pkgconf_path_prepend("/e//f", &list, false);
145*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(nth_path(&list, 0), "/e/f");
146*592efe25SPierre Pronchery
147*592efe25SPierre Pronchery pkgconf_path_free(&list);
148*592efe25SPierre Pronchery TEST_ASSERT_EQ(list.length, 0);
149*592efe25SPierre Pronchery TEST_ASSERT_NULL(list.head);
150*592efe25SPierre Pronchery TEST_ASSERT_NULL(list.tail);
151*592efe25SPierre Pronchery }
152*592efe25SPierre Pronchery
153*592efe25SPierre Pronchery static void
test_path_prepend_filter(void)154*592efe25SPierre Pronchery test_path_prepend_filter(void)
155*592efe25SPierre Pronchery {
156*592efe25SPierre Pronchery pkgconf_list_t list = PKGCONF_LIST_INITIALIZER;
157*592efe25SPierre Pronchery
158*592efe25SPierre Pronchery pkgconf_path_prepend(".", &list, true);
159*592efe25SPierre Pronchery TEST_ASSERT_EQ(list.length, 1);
160*592efe25SPierre Pronchery
161*592efe25SPierre Pronchery pkgconf_path_prepend(".", &list, true);
162*592efe25SPierre Pronchery TEST_ASSERT_EQ(list.length, 1);
163*592efe25SPierre Pronchery
164*592efe25SPierre Pronchery pkgconf_path_prepend("..", &list, true);
165*592efe25SPierre Pronchery TEST_ASSERT_EQ(list.length, 2);
166*592efe25SPierre Pronchery
167*592efe25SPierre Pronchery pkgconf_path_prepend(".", &list, false);
168*592efe25SPierre Pronchery TEST_ASSERT_EQ(list.length, 3);
169*592efe25SPierre Pronchery
170*592efe25SPierre Pronchery pkgconf_path_free(&list);
171*592efe25SPierre Pronchery }
172*592efe25SPierre Pronchery
173*592efe25SPierre Pronchery static void
test_path_prepend_list(void)174*592efe25SPierre Pronchery test_path_prepend_list(void)
175*592efe25SPierre Pronchery {
176*592efe25SPierre Pronchery pkgconf_list_t src = PKGCONF_LIST_INITIALIZER;
177*592efe25SPierre Pronchery pkgconf_list_t dst = PKGCONF_LIST_INITIALIZER;
178*592efe25SPierre Pronchery
179*592efe25SPierre Pronchery pkgconf_path_add("/s1", &src, false);
180*592efe25SPierre Pronchery pkgconf_path_add("/s2", &src, false);
181*592efe25SPierre Pronchery pkgconf_path_add("/s3", &src, false);
182*592efe25SPierre Pronchery
183*592efe25SPierre Pronchery pkgconf_path_add("/d1", &dst, false);
184*592efe25SPierre Pronchery pkgconf_path_add("/d2", &dst, false);
185*592efe25SPierre Pronchery
186*592efe25SPierre Pronchery pkgconf_path_prepend_list(&dst, &src);
187*592efe25SPierre Pronchery
188*592efe25SPierre Pronchery TEST_ASSERT_EQ(dst.length, 5);
189*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(nth_path(&dst, 0), "/s3");
190*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(nth_path(&dst, 1), "/s2");
191*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(nth_path(&dst, 2), "/s1");
192*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(nth_path(&dst, 3), "/d1");
193*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(nth_path(&dst, 4), "/d2");
194*592efe25SPierre Pronchery
195*592efe25SPierre Pronchery TEST_ASSERT_EQ(src.length, 3);
196*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(nth_path(&src, 0), "/s1");
197*592efe25SPierre Pronchery TEST_ASSERT_TRUE(nth_path(&dst, 2) != nth_path(&src, 0));
198*592efe25SPierre Pronchery
199*592efe25SPierre Pronchery pkgconf_path_free(&dst);
200*592efe25SPierre Pronchery TEST_ASSERT_EQ(dst.length, 0);
201*592efe25SPierre Pronchery
202*592efe25SPierre Pronchery TEST_ASSERT_EQ(src.length, 3);
203*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(nth_path(&src, 2), "/s3");
204*592efe25SPierre Pronchery
205*592efe25SPierre Pronchery pkgconf_path_prepend_list(&dst, &src);
206*592efe25SPierre Pronchery TEST_ASSERT_EQ(dst.length, 3);
207*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(nth_path(&dst, 0), "/s3");
208*592efe25SPierre Pronchery TEST_ASSERT_STRCMP_EQ(nth_path(&dst, 2), "/s1");
209*592efe25SPierre Pronchery
210*592efe25SPierre Pronchery pkgconf_path_free(&src);
211*592efe25SPierre Pronchery pkgconf_path_free(&dst);
212*592efe25SPierre Pronchery }
213*592efe25SPierre Pronchery
214*592efe25SPierre Pronchery static bool
plausible(const char * text)215*592efe25SPierre Pronchery plausible(const char *text)
216*592efe25SPierre Pronchery {
217*592efe25SPierre Pronchery pkgconf_buffer_t buf = PKGCONF_BUFFER_INITIALIZER;
218*592efe25SPierre Pronchery bool result;
219*592efe25SPierre Pronchery
220*592efe25SPierre Pronchery pkgconf_buffer_append(&buf, text);
221*592efe25SPierre Pronchery result = pkgconf_path_is_plausible(&buf);
222*592efe25SPierre Pronchery pkgconf_buffer_finalize(&buf);
223*592efe25SPierre Pronchery
224*592efe25SPierre Pronchery return result;
225*592efe25SPierre Pronchery }
226*592efe25SPierre Pronchery
227*592efe25SPierre Pronchery static void
test_path_is_plausible(void)228*592efe25SPierre Pronchery test_path_is_plausible(void)
229*592efe25SPierre Pronchery {
230*592efe25SPierre Pronchery pkgconf_buffer_t empty = PKGCONF_BUFFER_INITIALIZER;
231*592efe25SPierre Pronchery
232*592efe25SPierre Pronchery TEST_ASSERT_FALSE(pkgconf_path_is_plausible(NULL));
233*592efe25SPierre Pronchery TEST_ASSERT_FALSE(pkgconf_path_is_plausible(&empty));
234*592efe25SPierre Pronchery pkgconf_buffer_finalize(&empty);
235*592efe25SPierre Pronchery
236*592efe25SPierre Pronchery TEST_ASSERT_FALSE(plausible(""));
237*592efe25SPierre Pronchery TEST_ASSERT_FALSE(plausible(" "));
238*592efe25SPierre Pronchery TEST_ASSERT_FALSE(plausible("libfoo"));
239*592efe25SPierre Pronchery TEST_ASSERT_FALSE(plausible("foo bar"));
240*592efe25SPierre Pronchery TEST_ASSERT_FALSE(plausible("."));
241*592efe25SPierre Pronchery TEST_ASSERT_FALSE(plausible(".."));
242*592efe25SPierre Pronchery
243*592efe25SPierre Pronchery TEST_ASSERT_TRUE(plausible("/usr/lib/pkgconfig"));
244*592efe25SPierre Pronchery TEST_ASSERT_TRUE(plausible(" /usr/lib"));
245*592efe25SPierre Pronchery TEST_ASSERT_TRUE(plausible("./foo"));
246*592efe25SPierre Pronchery TEST_ASSERT_TRUE(plausible("../foo"));
247*592efe25SPierre Pronchery TEST_ASSERT_TRUE(plausible(".\\foo"));
248*592efe25SPierre Pronchery TEST_ASSERT_TRUE(plausible("..\\foo"));
249*592efe25SPierre Pronchery TEST_ASSERT_TRUE(plausible("C:/foo"));
250*592efe25SPierre Pronchery TEST_ASSERT_TRUE(plausible("C:\\foo"));
251*592efe25SPierre Pronchery TEST_ASSERT_TRUE(plausible("relative/path"));
252*592efe25SPierre Pronchery TEST_ASSERT_TRUE(plausible("relative\\path"));
253*592efe25SPierre Pronchery TEST_ASSERT_TRUE(plausible("Program Files/MySDK"));
254*592efe25SPierre Pronchery }
255*592efe25SPierre Pronchery
256*592efe25SPierre Pronchery int
main(int argc,char * argv[])257*592efe25SPierre Pronchery main(int argc, char *argv[])
258*592efe25SPierre Pronchery {
259*592efe25SPierre Pronchery (void) argc;
260*592efe25SPierre Pronchery const char *basename = pkgconf_path_find_basename(argv[0]);
261*592efe25SPierre Pronchery
262*592efe25SPierre Pronchery TEST_RUN(basename, test_path_find_basename);
263*592efe25SPierre Pronchery TEST_RUN(basename, test_path_trim_basename);
264*592efe25SPierre Pronchery TEST_RUN(basename, test_determine_prefix_logic);
265*592efe25SPierre Pronchery TEST_RUN(basename, test_path_prepend);
266*592efe25SPierre Pronchery TEST_RUN(basename, test_path_prepend_filter);
267*592efe25SPierre Pronchery TEST_RUN(basename, test_path_prepend_list);
268*592efe25SPierre Pronchery TEST_RUN(basename, test_path_is_plausible);
269*592efe25SPierre Pronchery
270*592efe25SPierre Pronchery return EXIT_SUCCESS;
271*592efe25SPierre Pronchery }
272