{"id":29562290,"url":"https://github.com/apaz-cli/apaz-libc","last_synced_at":"2025-07-18T17:34:15.972Z","repository":{"id":110103774,"uuid":"400940697","full_name":"apaz-cli/apaz-libc","owner":"apaz-cli","description":"My personal C library.","archived":false,"fork":false,"pushed_at":"2025-02-14T05:31:32.000Z","size":135,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-05T16:36:16.441Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apaz-cli.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-08-29T03:23:15.000Z","updated_at":"2025-02-14T05:31:36.000Z","dependencies_parsed_at":"2023-04-13T10:10:16.082Z","dependency_job_id":null,"html_url":"https://github.com/apaz-cli/apaz-libc","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/apaz-cli/apaz-libc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apaz-cli%2Fapaz-libc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apaz-cli%2Fapaz-libc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apaz-cli%2Fapaz-libc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apaz-cli%2Fapaz-libc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apaz-cli","download_url":"https://codeload.github.com/apaz-cli/apaz-libc/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apaz-cli%2Fapaz-libc/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265802001,"owners_count":23830506,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-18T17:34:12.644Z","updated_at":"2025-07-18T17:34:15.953Z","avatar_url":"https://github.com/apaz-cli.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# apaz-libc\n## My personal C library.\n\nThis library is composed of 4 other libraries, with more to come.\n\n\u003cbr\u003e\n\n### Jump to Library Examples:\n\n* [memdebug.h](#memdebug.h)\n* [threadpool.h](#threadpool.h)\n* [list.h](#list.h)\n* [apaz-string.h](#apaz-string.h)\n\n\u003cbr\u003e\n\n# memdebug.h \u003ca name=\"memdebug.h\"\u003e\u003c/a\u003e\nA drop-in replacement for `malloc` that wraps `malloc()`, `realloc()`, and `free()` for the remainder of the translation unit for easy memory debugging.\n\n\n## Example usage: \n```c\n// #define MEMDEBUG to 1 to enable wrapping malloc(), realloc(), and free().\n// Allocations will be tracked, so they can be printed out with print_heap().\n// #define MEMDEBUG to 0, and print_heap() and memory management function \n// wrapping will be defined away and optimized out completely.\n\n// #define PRINT_MEMALLOCS to 1 to print a message on each call to \n// malloc(), realloc(), and free().\n// #define PRINT_MEMALLOCS to 0 if you want to still track allocations for\n// print_heap(), but don't want to spam the terminal with messages.\n\n#define MEMDEBUG 1\n#define PRINT_MEMALLOCS 1\n#include \u003capaz-libc/memdebug.h\u003e\n\nint main() {\n    // Print debug messages on allocation/free\n    void* ptr = malloc(1);\n    ptr = realloc(ptr, 10);\n    free(ptr);\n\n    // Find memory leaks\n    malloc(20);\n    malloc(25);\n    print_heap();\n\n    // Catch out of memory errors\n    // malloc(9223372036854775807);\n\n    // Explode gracefully\n    void* invalid_ref = (void*)0x1;\n    free(invalid_ref);\n}\n```\n\n## Output\n```\napaz@apaz-laptop:~/git/memdebug.h$ gcc test.c\napaz@apaz-laptop:~/git/memdebug.h$ ./a.out\nmalloc(1) -\u003e 0x557d1f5742a0 on line 7 of main() in memdebug_test.c.\nrealloc(0x557d1f5742a0, 10) -\u003e 0x557d1f5742a0 on line 8 of main() in memdebug_test.c.\nfree(0x557d1f5742a0) on line 9 of main() in memdebug_test.c.\nmalloc(20) -\u003e 0x557d1f5742a0 on line 12 of main() in memdebug_test.c.\nmalloc(25) -\u003e 0x557d1f5746d0 on line 13 of main() in memdebug_test.c.\n\n*************\n* HEAP DUMP *\n*************\n1 pointer has been allocated totalling 20 bytes in file: memdebug_test.c in function: main() on line: 12.\n1 pointer has been allocated totalling 25 bytes in file: memdebug_test.c in function: main() on line: 13.\n\nTotal size in bytes: 45\nTotal number of allocations: 2\n\n\n\nMEMORY PANIC: Tried to free() an invalid pointer.\nPointer: 0x1\nOn line: 21\nIn function: main()\nIn file: memdebug_test.c\nAborted.\n```\n\n\u003cbr\u003e\n\n# threadpool.h \u003ca name=\"threadpool.h\"\u003e\u003c/a\u003e\nA minimal threadpool implemented from scratch in C using `pthread`s.\n\n## Example Usage:\n```c\n#include \u003capaz-libc/threadpool.h\u003e\n#include \u003cstdio.h\u003e\n\nvoid say_hello(void* voidptr) {\n    printf(\"Hello from task #%i.\\n\", *((int*)voidptr));\n    free(voidptr);\n}\n\nint main() {\n    Threadpool pool;\n    Threadpool_create(\u0026pool, 8); // 8 tasks to be run at a time\n\n    for (int i = 0; i \u003c 5000; i++) {\n        // Executes a task in the form of a function pointer accepting one\n        // void* argument and returning nothing. You can use this pointer\n        // to provide args, or to return a value, or both.\n        int* intptr = (int*)malloc(sizeof(int));\n        *intptr = i;\n\n        // The reason to malloc() here is to prevent race conditions.\n        // This way each task has its own space for its instructions.\n        // As always, if two threads try to access the same variable\n        // at the same time without a mutex, bad things happen.\n\n        if (!Threadpool_exectask(\u0026pool, say_hello, intptr)) {\n            // If exectask returns 0, the pool rejected the work\n            // because it is already shut down.\n            // It can never happen here, but if it's a possibility\n            // you should check this.\n\n            // The easiest solution is usually to do the task \n            // yourself, like so.\n            say_hello(intptr);\n        }\n    }\n\n    Threadpool_destroy(\u0026pool);\n}\n```\n\n## Output\n```c\n...\nHello from task #7.\nHello from task #6.\nHello from task #5.\nHello from task #4.\nHello from task #3.\nHello from task #2.\nHello from task #1.\nHello from task #273.\nHello from task #335.\nHello from task #616.\nHello from task #102.\nHello from task #318.\nHello from task #201.\nHello from task #317.\n```\n\n\nNote that the pool uses a stack data structure for its tasks, not a queue. This choice was made after some testing. It's less \"fair,\" but it's faster for cache locality reasons. I decided to go the faster route, but it should be noted that should this be undesireable, it can be changed with some very minor modifications to the code.\n\n\u003cbr\u003e\n\n# list.h \u003ca name=\"list.h\"\u003e\u003c/a\u003e\n\nA monadic list library utilizing fat pointers to retain `[]` syntax.\n\n\n## Example Usage:\n```c\n#include \u003capaz-libc/list.h\u003e\n#include \u003cstdio.h\u003e\n#include \u003cstdlib.h\u003e\n\nstatic inline size_t factorial(size_t x) {\n  return x ? x * factorial(x - 1) : 1;\n}\n\nstatic inline void print_size(size_t to_print) {\n  printf(\"%zu\\n\", to_print);\n}\n\n// This macro declares all the functionality of a list of the given type.\nLIST_DEFINE(size_t);\n// You can easily define lists of lists.\nLIST_DEFINE(List_size_t);\n// This is the fun part. (original type, map to type)\nLIST_DEFINE_MONAD(size_t, size_t);\n\nint main() {\n  // The type of the list is List_##type, as provided to LIST_DEFINE. There\n  // are a bunch of ways to define a list, they all have _new in their name.\n  List_size_t list = List_size_t_new_len(10);\n\n  // It's just a size_t*. You can use it as such.\n  for (size_t i = 0; i \u003c List_size_t_len(list); i++)\n    list[i] = i;\n\n  // Add new elements whenever you want, and it will grow to meet demand.\n  // There are two syntaxes for this, whichever you prefer.\n  List_size_t_add(\u0026list, 11);\n  list = List_size_t_addeq(list, 12);\n\n  // You can also peek and pop.\n  size_t peeked = List_size_t_peek(list);\n  List_size_t_pop(list);\n\n  // You can clone lists too.\n  // Lists are heap allocated, so destroy them when you're done with them.\n  // Don't try to use normal free() through. Use List_##type##_destroy()\n  // instead.\n  List_size_t cloned = List_size_t_clone(list);\n  List_size_t_destroy(list);\n\n  // Lists also support operations like map(), filter(), flatmap(), and\n  // foreach().\n  // These operations destroy the list passed to them, and if they return a new\n  // list they re-use the space allocated for the old one where possible.\n  cloned = List_size_t_map_to_size_t(cloned, factorial);\n  List_size_t_foreach(cloned, print_size);\n}\n```\n\n## Output\n```\n1\n1\n2\n6\n24\n120\n720\n5040\n40320\n362880\n39916800\n```\n\n\u003cbr\u003e\n\n# apaz-string.h \u003ca name=\"apaz-string.h\"\u003e\u003c/a\u003e\n\nA string library that utilizes fat pointers to retain the `[]` syntax for accessing characters, but also stores length information.\n\nWhile this isn't any better than ordinary cstrings for optimization, as long as you're not using it with lists, it's great for syntax. For a string implementation with small string optimization, see the one in the [Stilts standard library](https://github.com/apaz-cli/Stilts/blob/master/stdlib/Native/Builtins/StiltsString.h).\n\nWith the \"the syntax sucks for lists\" in mind, check out the example below.\n\n## Example Usage:\n```c\n#define MEMDEBUG 1\n#define PRINT_MEMALLOCS 1\n#include \u003capaz-libc.h\u003e\n\n/* The string module can make use of the list and memdebug modules. */\nvoid String_printAndDestroy(String str) {\n  String_println(str);\n  String_destroy(str);\n}\n\nint main() {\n  /* Basic usage looks great. Just do string stuff. */\n  String s = String_new_of_strlen(\"I can make Strings\");\n  String_println(s);\n  s = String_toUpper(s);\n  assert(String_endsWith(s, \"STRINGS\"));\n  String_println(s);\n\n  /* There's also all the convenience methods you're used to, like split(). */\n  List_String l = String_split(s, \" \");\n  String_destroy(s);\n\n  l = List_String_map_to_String(l, String_toLower);\n\n  /* We can still get its length, add items, and address it like we would a\n   * fixed size array. However, this is all very tedious of course. Also, we\n   * need to pay very careful attention that we free all the memory. */\n  l = List_String_addeq(l, String_new_of_strlen(\"!\"));\n\n  /* Since it returns a list.h list, we can use monads.\n    We can destroy all the strings in the list inside the monad. */\n  List_String_foreach(l, String_printAndDestroy);\n\n  print_heap();\n  puts(\"All memory cleaned up.\");\n}\n```\n\n\n## Output\n```\nmalloc(27) -\u003e 0x55f5bef8f2a0 on line 13 of main() in string_test.c.\nI can make Strings\nI CAN MAKE STRINGS\nmalloc(416) -\u003e 0x55f5bef8f6e0 on line 54 of List_String_new_cap() in /usr/include/apaz-libc.h.\nmalloc(10) -\u003e 0x55f5bef8f890 on line 123 of String_split() in /usr/include/apaz-libc.h.\nmalloc(12) -\u003e 0x55f5bef8f8b0 on line 123 of String_split() in /usr/include/apaz-libc.h.\nmalloc(13) -\u003e 0x55f5bef8f8d0 on line 123 of String_split() in /usr/include/apaz-libc.h.\nmalloc(16) -\u003e 0x55f5bef8f8f0 on line 124 of String_split() in /usr/include/apaz-libc.h.\nfree(0x55f5bef8f2a0) on line 21 of main() in string_test.c.\nmalloc(48) -\u003e 0x55f5bef8f910 on line 54 of List_String_new_len() in /usr/include/apaz-libc.h.\nfree(0x55f5bef8f6e0) on line 54 of List_String_destroy() in /usr/include/apaz-libc.h.\nmalloc(10) -\u003e 0x55f5bef8f950 on line 28 of main() in string_test.c.\nrealloc(0x55f5bef8f910, 192) -\u003e 0x55f5bef8f970 on line 54 of List_String_resize() in /usr/include/apaz-libc.h.\ni\nfree(0x55f5bef8f890) on line 8 of String_printAndDestroy() in string_test.c.\ncan\nfree(0x55f5bef8f8b0) on line 8 of String_printAndDestroy() in string_test.c.\nmake\nfree(0x55f5bef8f8d0) on line 8 of String_printAndDestroy() in string_test.c.\nstrings\nfree(0x55f5bef8f8f0) on line 8 of String_printAndDestroy() in string_test.c.\n!\nfree(0x55f5bef8f950) on line 8 of String_printAndDestroy() in string_test.c.\nfree(0x55f5bef8f970) on line 54 of List_String_destroy() in /usr/include/apaz-libc.h.\napaz@apaz-laptop:~/git/apaz-libc$ sh install.sh \u0026\u0026 gcc string_test.c \u0026\u0026 ./a.out \nmalloc(27) -\u003e 0x5564aac6d2a0 on line 13 of main() in string_test.c.\nI can make Strings\nI CAN MAKE STRINGS\nmalloc(416) -\u003e 0x5564aac6d6e0 on line 54 of List_String_new_cap() in /usr/include/apaz-libc.h.\nmalloc(10) -\u003e 0x5564aac6d890 on line 123 of String_split() in /usr/include/apaz-libc.h.\nmalloc(12) -\u003e 0x5564aac6d8b0 on line 123 of String_split() in /usr/include/apaz-libc.h.\nmalloc(13) -\u003e 0x5564aac6d8d0 on line 123 of String_split() in /usr/include/apaz-libc.h.\nmalloc(16) -\u003e 0x5564aac6d8f0 on line 124 of String_split() in /usr/include/apaz-libc.h.\nfree(0x5564aac6d2a0) on line 21 of main() in string_test.c.\nmalloc(48) -\u003e 0x5564aac6d910 on line 54 of List_String_new_len() in /usr/include/apaz-libc.h.\nfree(0x5564aac6d6e0) on line 54 of List_String_destroy() in /usr/include/apaz-libc.h.\nmalloc(10) -\u003e 0x5564aac6d950 on line 28 of main() in string_test.c.\nrealloc(0x5564aac6d910, 192) -\u003e 0x5564aac6d970 on line 54 of List_String_resize() in /usr/include/apaz-libc.h.\ni\nfree(0x5564aac6d890) on line 8 of String_printAndDestroy() in string_test.c.\ncan\nfree(0x5564aac6d8b0) on line 8 of String_printAndDestroy() in string_test.c.\nmake\nfree(0x5564aac6d8d0) on line 8 of String_printAndDestroy() in string_test.c.\nstrings\nfree(0x5564aac6d8f0) on line 8 of String_printAndDestroy() in string_test.c.\n!\nfree(0x5564aac6d950) on line 8 of String_printAndDestroy() in string_test.c.\nfree(0x5564aac6d970) on line 54 of List_String_destroy() in /usr/include/apaz-libc.h.\n\n*************\n* HEAP DUMP *\n*************\n\nTotal size in bytes: 0\nTotal number of allocations: 0\n\n\nAll memory cleaned up.\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapaz-cli%2Fapaz-libc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapaz-cli%2Fapaz-libc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapaz-cli%2Fapaz-libc/lists"}