Skip to content

Commit 5bc0bbf

Browse files
committed
Add support for glob in file loader and support for absolute paths in metacall.json path field.
1 parent af94689 commit 5bc0bbf

File tree

14 files changed

+369
-10
lines changed

14 files changed

+369
-10
lines changed

source/loader/source/loader.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -426,13 +426,20 @@ int loader_load_from_configuration(const loader_path path, void **handle, void *
426426

427427
size_t str_size = value_type_size(context_path);
428428

429-
loader_path path_base, join_path;
429+
if (portability_path_is_absolute(str, str_size) == 0)
430+
{
431+
context_path_size = portability_path_canonical(str, str_size, context_path_str, LOADER_PATH_SIZE);
432+
}
433+
else
434+
{
435+
loader_path path_base, join_path;
430436

431-
size_t path_base_size = portability_path_get_directory(path, strnlen(path, LOADER_PATH_SIZE) + 1, path_base, LOADER_PATH_SIZE);
437+
size_t path_base_size = portability_path_get_directory(path, strnlen(path, LOADER_PATH_SIZE) + 1, path_base, LOADER_PATH_SIZE);
432438

433-
size_t join_path_size = portability_path_join(path_base, path_base_size, str, str_size, join_path, LOADER_PATH_SIZE);
439+
size_t join_path_size = portability_path_join(path_base, path_base_size, str, str_size, join_path, LOADER_PATH_SIZE);
434440

435-
context_path_size = portability_path_canonical(join_path, join_path_size, context_path_str, LOADER_PATH_SIZE);
441+
context_path_size = portability_path_canonical(join_path, join_path_size, context_path_str, LOADER_PATH_SIZE);
442+
}
436443
}
437444

438445
scripts_array = value_to_array(scripts);

source/loaders/file_loader/source/file_loader_impl.c

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,21 @@ typedef struct stat file_stat_type;
6666

6767
#endif
6868

69+
/* Support for glob, only in POSIX for now */
70+
#if !defined(_WIN32) && \
71+
(defined(unix) || defined(__unix__) || defined(__unix) || \
72+
defined(linux) || defined(__linux__) || defined(__linux) || defined(__gnu_linux) || \
73+
defined(__CYGWIN__) || defined(__CYGWIN32__) || \
74+
(defined(__APPLE__) && defined(__MACH__)) || defined(__MACOSX__))
75+
76+
#include <unistd.h>
77+
78+
#if defined(_POSIX_VERSION)
79+
#define FILE_LOADER_GLOB_SUPPORT 1
80+
#include <glob.h>
81+
#endif
82+
#endif
83+
6984
typedef struct loader_impl_file_descriptor_type
7085
{
7186
loader_path path;
@@ -92,6 +107,7 @@ typedef struct loader_impl_file_function_type
92107
} * loader_impl_file_function;
93108

94109
static int file_loader_impl_load_path(loader_impl_file_handle handle, const loader_path path, size_t path_size);
110+
static int file_loader_impl_load_glob(loader_impl_file_handle handle, const loader_path path, size_t path_size);
95111
static int file_loader_impl_load_execution_path(loader_impl_file file_impl, loader_impl_file_handle handle, const loader_path path);
96112

97113
int function_file_interface_create(function func, function_impl impl)
@@ -253,13 +269,61 @@ int file_loader_impl_load_path(loader_impl_file_handle handle, const loader_path
253269
return 1;
254270
}
255271

272+
int file_loader_impl_load_glob(loader_impl_file_handle handle, const loader_path path, size_t path_size)
273+
{
274+
glob_t glob_result;
275+
276+
(void)path_size;
277+
278+
memset(&glob_result, 0, sizeof(glob_result));
279+
280+
if (glob(path, GLOB_TILDE, NULL, &glob_result) != 0)
281+
{
282+
globfree(&glob_result);
283+
return 1;
284+
}
285+
286+
size_t i, loaded_files = 0;
287+
288+
for (i = 0; i < glob_result.gl_pathc; ++i)
289+
{
290+
loader_path glob_path;
291+
size_t length = strnlen(glob_result.gl_pathv[i], LOADER_PATH_SIZE);
292+
293+
strncpy(glob_path, glob_result.gl_pathv[i], length);
294+
295+
glob_path[length] = '\0';
296+
297+
if (file_loader_impl_load_path(handle, glob_path, length + 1) == 0)
298+
{
299+
++loaded_files;
300+
}
301+
}
302+
303+
globfree(&glob_result);
304+
305+
return (loaded_files == 0);
306+
}
307+
256308
int file_loader_impl_load_execution_path(loader_impl_file file_impl, loader_impl_file_handle handle, const loader_path path)
257309
{
258310
size_t path_size = strnlen(path, LOADER_PATH_SIZE) + 1;
311+
int (*impl_load_path)(loader_impl_file_handle, const loader_path, size_t);
312+
313+
#if defined(FILE_LOADER_GLOB_SUPPORT)
314+
if (portability_path_is_pattern(path, path_size) == 0)
315+
{
316+
impl_load_path = &file_loader_impl_load_glob;
317+
}
318+
else
319+
#endif
320+
{
321+
impl_load_path = &file_loader_impl_load_path;
322+
}
259323

260324
if (portability_path_is_absolute(path, path_size) == 0)
261325
{
262-
return file_loader_impl_load_path(handle, path, path_size);
326+
return impl_load_path(handle, path, path_size);
263327
}
264328
else
265329
{
@@ -271,7 +335,7 @@ int file_loader_impl_load_execution_path(loader_impl_file file_impl, loader_impl
271335
loader_path absolute_path;
272336
size_t absolute_path_size = portability_path_join(*execution_path, strnlen(*execution_path, LOADER_PATH_SIZE) + 1, path, path_size, absolute_path, LOADER_PATH_SIZE);
273337

274-
if (file_loader_impl_load_path(handle, absolute_path, absolute_path_size) == 0)
338+
if (impl_load_path(handle, absolute_path, absolute_path_size) == 0)
275339
{
276340
return 0;
277341
}

source/portability/include/portability/portability_path.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,14 +125,16 @@ PORTABILITY_API size_t portability_path_get_relative(const char *base, size_t ba
125125

126126
PORTABILITY_API int portability_path_is_subpath(const char *parent, size_t parent_size, const char *child, size_t child_size);
127127

128-
PORTABILITY_API int portability_path_is_absolute(const char *path, size_t path_size);
128+
PORTABILITY_API int portability_path_is_absolute(const char *path, size_t size);
129129

130130
PORTABILITY_API size_t portability_path_join(const char *left_path, size_t left_path_size, const char *right_path, size_t right_path_size, char *join_path, size_t join_size);
131131

132132
PORTABILITY_API size_t portability_path_canonical(const char *path, size_t path_size, char *canonical, size_t canonical_size);
133133

134134
PORTABILITY_API int portability_path_compare(const char *left_path, const char *right_path);
135135

136+
PORTABILITY_API int portability_path_is_pattern(const char *path, size_t size);
137+
136138
#ifdef __cplusplus
137139
}
138140
#endif

source/portability/source/portability_path.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,15 +231,15 @@ int portability_path_is_subpath(const char *parent, size_t parent_size, const ch
231231
return !(strncmp(parent, child, parent_size) == 0);
232232
}
233233

234-
int portability_path_is_absolute(const char *path, size_t path_size)
234+
int portability_path_is_absolute(const char *path, size_t size)
235235
{
236236
if (path == NULL)
237237
{
238238
return 1;
239239
}
240240

241241
#if defined(WIN32) || defined(_WIN32)
242-
if (path_size < 3)
242+
if (size < 3)
243243
{
244244
return 1;
245245
}
@@ -253,7 +253,7 @@ int portability_path_is_absolute(const char *path, size_t path_size)
253253
(defined(__APPLE__) && defined(__MACH__)) || defined(__MACOSX__) || \
254254
defined(__HAIKU__) || defined(__BEOS__)
255255

256-
if (path_size < 1)
256+
if (size < 1)
257257
{
258258
return 1;
259259
}
@@ -462,3 +462,23 @@ int portability_path_compare(const char *left_path, const char *right_path)
462462

463463
return (strncmp(left_path, right_path, left_length) != 0);
464464
}
465+
466+
int portability_path_is_pattern(const char *path, size_t size)
467+
{
468+
if (path == NULL || size == 0)
469+
{
470+
return 1;
471+
}
472+
473+
size_t i;
474+
475+
for (i = 0; path[i] != '\0' && i < size; ++i)
476+
{
477+
if (path[i] == '*')
478+
{
479+
return 0;
480+
}
481+
}
482+
483+
return 1;
484+
}

source/scripts/file/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ include(FileProject)
1515

1616
add_subdirectory(static)
1717
add_subdirectory(favicon)
18+
add_subdirectory(glob)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#
2+
# Configure file project
3+
#
4+
5+
file_project(glob 0.1.0)

source/scripts/file/glob/source/glob/a.txt

Whitespace-only changes.

source/scripts/file/glob/source/glob/b.txt

Whitespace-only changes.

source/scripts/file/glob/source/glob/c.json

Whitespace-only changes.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"language_id": "file",
3+
"path": ".",
4+
"scripts": [
5+
"./glob/*.txt"
6+
]
7+
}

0 commit comments

Comments
 (0)