Path Helpers
#define path_join(...) path_join_(PP_NARG(__VA_ARGS__), __VA_ARGS__)
char* path_join_(size_t nargs, ...)
Joins all the variadic arguments together using path separators if needed. Arguments are not quoted before being concatenated.
char* path_ext(char* path)
Returns a pointer to the first character of the file extension, or to the null terminator if none.
char* path_ext2(char* path, int* end)
Returns a pointer to the first character of the file extension, or to the null terminator if none.
Also provides the length of the preceding path without the period and extension.
char* resolve_path(char* in)
Works like realpath(in, NULL), except also handles ~. The return value is a duped string.
Wrappers around stat()
int is_path_a_dir(char* path)
Returns 0 for false, 1 for true, and 0 on any error. Handles ~ properly.
int is_path_a_dir(char* path)
Returns 0 for false, 1 for true, and 0 on any error. Handles ~ properly.
I/O Helpers
char* read_whole_file(char* path, size_t* srcLen)
Returns a null terminated string. srcLen does NOT include the null terminator. Nulls inside the string are not
escaped or removed; the first null is not necessarily the terminating null.
char* read_whole_file_extra(char* path, size_t extraAlloc, size_t* srcLen)
Reserves extra space in memory just in case you want to append a '\n' or something srcLen reflects the length
of the content, not the allocation.
int write_whole_file(char* path, void* data, size_t len)
Overwrites the file. Returns 0 on success.
Filesystem Searching
Flags used in filesystem functions:
#define FSU_EXCLUDE_HIDDEN (1<<0)
#define FSU_NO_FOLLOW_SYMLINKS (1<<1)
#define FSU_INCLUDE_DIRS (1<<2)
#define FSU_EXCLUDE_FILES (1<<3)
#define FSU_DIRS_ONLY (FSU_EXCLUDE_FILES | FSU_INCLUDE_DIRS)
// returns negative on error, nonzero if scanning was halted by the callback
typedef int (*readDirCallbackFn)(char* fullPath, char* fileName, void* data);
int recurse_dirs(
char* path,
readDirCallbackFn fn,
void* data,
int depth,
unsigned int flags
)
Walk the entire directory tree recursively up to depth, calling the callback on entries as it goes. The callback should
return 0 to continue or nonzero to stop directory scanning.
Returns negative on error, nonzero if scanning was halted by the callback
char** read_whole_dir(char* path, unsigned int flags, size_t* outLen)
Returns a list of the (relative) file names of every file in the immediate directory.
char** read_whole_dir_abs(char* path, unsigned int flags, size_t* outLen)
Returns a list of the absolute paths of every file in the immediate directory.
typedef struct rglob_entry {
char type;
char* full_path;
char* file_name;
// char* dir_name;
} rglob_entry;
typedef struct rglob {
char* pattern;
int len;
int alloc;
rglob_entry* entries;
} rglob;
void recursive_glob(char* base_path, char* pattern, int flags, rglob* results)
Calls recurse_dirs() and filters the results by calling
fnmatch(3)
with attern on each entry before adding it to results->entries if it matches.
char** multi_wordexp_dup(char* input, size_t* out_len)
Works like
wordexp(3), except accepts a list of ;-separated
paths and returns an array of char*'s, all allocated with normal malloc.