Home Rumble Youtube Twitter/X Kofi Contact / Crypto

Filesystem Helpers

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.