2 libpsh/path_searcher.c - path searcher
3 Copyright 2020 Zhang Maiyun.
5 This file is part of Psh, P shell.
7 Psh is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 Psh is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <https://www.gnu.org/licenses/>.
24 #include "libpsh/xmalloc.h"
26 /* Call CHK_FUNC on each (substr + TARGET) concatenated string in PATH
27 * separated by SEPARATOR.
28 * Returns the first concatenated string for which CHK_FUNC returns non-zero;
29 * or NULL if none succeeded. Result should be free()d */
30 char *psh_search_path(const char *path
, int separator
, const char *target
,
31 int (*chk_func
)(const char *))
34 size_t len_substr
, len_target
= strlen(target
) + 1,
35 size_allocated
= 2 * len_target
;
36 char *concatenated
= xmalloc(size_allocated
), *occur
= (char *)1;
40 occur
= strchr(path
, separator
);
41 len_substr
= occur
? (size_t)(occur
- path
) : strlen(path
);
43 /* Realloc concatenated if it's too small */
44 if (len_substr
+ len_target
> size_allocated
)
46 size_allocated
= len_target
+ len_substr
;
47 concatenated
= xrealloc(concatenated
, size_allocated
);
51 memcpy(concatenated
, path
, len_substr
);
53 memcpy(concatenated
+ len_substr
, target
, len_target
);
55 *(concatenated
+ len_target
+ len_substr
- 1) = 0;
56 if (chk_func(concatenated
))
58 /* Jump over the substr */
59 path
+= len_substr
+ 1; /* +1 for separator */