#ifndef _AKSTDLIB_H_ #define _AKSTDLIB_H_ #include /* * libakerror 1.0.0 is the floor. That release moved the status-name table into a * private registry -- AKERR_MAX_ERR_VALUE and __AKERR_ERROR_NAMES are gone, the * registry entry points raise akerr_ErrorContext * instead of returning int, and * the library gained an soname -- so a translation unit that pairs this header * with a pre-1.0.0 akerror.h is an ABI mismatch, not just a compile problem. * * libakerror publishes no version macro, so this feature-tests on * AKERR_FIRST_CONSUMER_STATUS, which that release introduced, rather than on a * version number that does not exist. Without the guard a stale installed header * fails much further in, as a pile of unrelated errors inside src/stdlib.c. * * See deps/libakerror/UPGRADING.md. */ #ifndef AKERR_FIRST_CONSUMER_STATUS #error "libakstdlib requires libakerror >= 1.0.0: the akerror.h on the include path predates the status registry. Rebuild and reinstall libakerror." #endif /* * AKSL_VERSION_MAJOR/MINOR/PATCH/STRING/NUMBER and AKSL_VERSION_SONAME. * Generated by CMake from include/akstdlib_version.h.in, which is why there is * no such file in the source tree -- it is configured into the build tree and * installed alongside this header. */ #include #include #include #include #include typedef struct aksl_ListNode { void *data; struct aksl_ListNode *next; struct aksl_ListNode *prev; } aksl_ListNode; typedef struct aksl_TreeNode { struct aksl_TreeNode *parent; struct aksl_TreeNode *left; struct aksl_TreeNode *right; void *leaf; } aksl_TreeNode; #define AKSL_TREE_SEARCH_BFS 0 /** Breadth-first search mode for tree nodes. Currently unsupported. */ #define AKSL_TREE_SEARCH_BFS_RIGHT 1 /** Right-hand breadth-first search mode for tree nodes. Currentl unsupported. */ #define AKSL_TREE_SEARCH_DFS 2 /** Alias for AKSL_TREE_SEARCH_DFS_PREORDER */ #define AKSL_TREE_SEARCH_DFS_PREORDER 2 /** Depth first pre-order (root, left, right) search mode for tree nodes */ #define AKSL_TREE_SEARCH_DFS_INORDER 3 /** Depth first in-order (left, root, right) search mode for tree nodes. Currently unsupported. */ #define AKSL_TREE_SEARCH_DFS_POSTORDER 4 /** Depth first post-order (left, right, root) search mode for tree nodes. Currently unsupported. */ #define AKSL_TREE_SEARCH_VISIT 5 /** Used when iterating through a tree structure as a control flag: don't traverse the children, just visit the node */ typedef akerr_ErrorContext AKERR_NOIGNORE *(*aksl_ListNodeIterator)(aksl_ListNode *node, void *data); typedef akerr_ErrorContext AKERR_NOIGNORE *(*aksl_TreeNodeIterator)(aksl_TreeNode *node, void *data); typedef akerr_ErrorContext AKERR_NOIGNORE *(*aksl_AllocFunc)(size_t size, void **dest); typedef akerr_ErrorContext AKERR_NOIGNORE *(*aksl_FreeFunc)(void *ptr); /* * Version of the shared library actually loaded, as opposed to the * AKSL_VERSION_* macros above, which record what the caller was *compiled* * against. The two differ exactly when a stale libakstdlib.so is on the loader * path, which is the failure these entry points exist to name. * * All three pointers are required; this library treats a NULL out-param as a * caller error rather than as "don't care" (so does aksl_free). */ akerr_ErrorContext AKERR_NOIGNORE *aksl_version(int *major, int *minor, int *patch); /* * The loaded library's version as "MAJOR.MINOR.PATCH", and its soname. Neither * can fail -- they return pointers to string literals in the library's own * .rodata -- so they return the string directly rather than an error context, * the same exception akerr_name_for_status() makes for the same reason. */ const char *aksl_version_string(void); const char *aksl_version_soname(void); /* * Compare the caller's compiled-in version against the loaded library's. * Compatibility is defined as "same soname", so pre-1.0 both major and minor * must match and patch is ignored; from 1.0 only major will matter. Raises * AKERR_VALUE naming both versions on a mismatch. * * Call it through AKSL_VERSION_CHECK() below rather than directly. The macro * expands at *your* call site, so it captures the AKSL_VERSION_* the caller was * built with; the function compares them against the values baked into the * library. Passing the numbers by hand defeats the entire mechanism. */ akerr_ErrorContext AKERR_NOIGNORE *aksl_version_check(int major, int minor, int patch); #define AKSL_VERSION_CHECK() \ aksl_version_check(AKSL_VERSION_MAJOR, AKSL_VERSION_MINOR, AKSL_VERSION_PATCH) akerr_ErrorContext AKERR_NOIGNORE *aksl_fopen(char *pathname, char *mode, FILE **fp); akerr_ErrorContext AKERR_NOIGNORE *aksl_fread(void *ptr, size_t size, size_t nmemb, FILE *stream); akerr_ErrorContext AKERR_NOIGNORE *aksl_fwrite(void *ptr, size_t size, size_t nmemb, FILE *fp); akerr_ErrorContext AKERR_NOIGNORE *aksl_fclose(FILE *stream); akerr_ErrorContext AKERR_NOIGNORE *aksl_malloc(size_t size, void **dst); akerr_ErrorContext AKERR_NOIGNORE *aksl_memset(void *s, int c, size_t n); akerr_ErrorContext AKERR_NOIGNORE *aksl_memcpy(void *d, void *s, size_t n); akerr_ErrorContext AKERR_NOIGNORE *aksl_free(void *ptr); akerr_ErrorContext AKERR_NOIGNORE *aksl_printf(int *count, const char *restrict format, ...); akerr_ErrorContext AKERR_NOIGNORE *aksl_fprintf(int *count, FILE *restrict stream, const char *restrict format, ...); akerr_ErrorContext AKERR_NOIGNORE *aksl_sprintf(int *count, char *restrict str, const char *restrict format, ...); akerr_ErrorContext AKERR_NOIGNORE *aksl_atoi(const char *nptr, int *dest); akerr_ErrorContext AKERR_NOIGNORE *aksl_atol(const char *nptr, long *dest); akerr_ErrorContext AKERR_NOIGNORE *aksl_atoll(const char *nptr, long long *dest); akerr_ErrorContext AKERR_NOIGNORE *aksl_atof(const char *nptr, double *dest); akerr_ErrorContext AKERR_NOIGNORE *aksl_realpath(const char *restrict path, char *restrict resolved_path); akerr_ErrorContext AKERR_NOIGNORE *aksl_strhash_djb2(char *str, size_t len, uint32_t *hashval); // Linked list functions akerr_ErrorContext AKERR_NOIGNORE *aksl_list_append(aksl_ListNode *list, aksl_ListNode *obj); akerr_ErrorContext AKERR_NOIGNORE *aksl_list_pop(aksl_ListNode *node); akerr_ErrorContext AKERR_NOIGNORE *aksl_list_iterate(aksl_ListNode *list, aksl_ListNodeIterator iter, void *data); // Tree functions akerr_ErrorContext AKERR_NOIGNORE *aksl_tree_iterate(aksl_TreeNode *root, aksl_TreeNodeIterator iter, aksl_AllocFunc lalloc, aksl_FreeFunc lfree, uint8_t searchmode, void *data, aksl_ListNode *queue); #endif