{"id":15735259,"url":"https://github.com/randoragon/libstaple","last_synced_at":"2026-02-27T17:02:41.089Z","repository":{"id":176069797,"uuid":"398548416","full_name":"randoragon/libstaple","owner":"randoragon","description":"A general-purpose data structure library in pure C89.","archived":false,"fork":false,"pushed_at":"2025-01-07T19:37:37.000Z","size":1090,"stargazers_count":3,"open_issues_count":8,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-18T17:48:47.981Z","etag":null,"topics":["c","c89","data-structures","library"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-2.1","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/randoragon.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,"zenodo":null}},"created_at":"2021-08-21T12:08:48.000Z","updated_at":"2025-01-07T19:37:06.000Z","dependencies_parsed_at":"2024-10-25T00:16:24.278Z","dependency_job_id":"09061780-2a6e-4832-837e-4aa443908771","html_url":"https://github.com/randoragon/libstaple","commit_stats":{"total_commits":292,"total_committers":1,"mean_commits":292.0,"dds":0.0,"last_synced_commit":"e50c11a4983c6a631d31221237ab399760b5a820"},"previous_names":["randoragon/libstaple"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/randoragon/libstaple","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/randoragon%2Flibstaple","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/randoragon%2Flibstaple/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/randoragon%2Flibstaple/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/randoragon%2Flibstaple/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/randoragon","download_url":"https://codeload.github.com/randoragon/libstaple/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/randoragon%2Flibstaple/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269948878,"owners_count":24501826,"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","status":"online","status_checked_at":"2025-08-11T02:00:10.019Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["c","c89","data-structures","library"],"created_at":"2024-10-04T01:11:30.622Z","updated_at":"2026-02-27T17:02:40.998Z","avatar_url":"https://github.com/randoragon.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Staple - easy data structures in C\n\n![build status](https://github.com/Randoragon/libstaple/actions/workflows/main.yaml/badge.svg)\n\nStaple is a general-purpose library implementing common data structures in pure\nC without any external dependencies besides the C standard library.\n\n## Available Modules\n\n- stack\n- queue\n\n## Pending Modules\n\nThe list might grow/shrink and implementations need not follow in any particular\norder. I work on these (among other things) in my spare time, so expect either\nslow development, or sudden bursts of productivity separated by hiatuses.\n\n- deque,\n- bitarray,\n- hashmap,\n- linked list,\n- 2D/3D matrix,\n- priority queue,\n- avl tree,\n- rbtree\n\n## Quick Example\n\nHere's a program that creates a stack of integers, pushes a few numbers, prints\nthe top of the stack, then pops and returns it.\n\n```c\n#include \u003cstdio.h\u003e\n#include \u003cstaple.h\u003e\n\nint main(void)\n{\n\tstruct sp_stack *s;\n\tint ret;\n\ts = sp_stack_create(sizeof(int), 10);\n\n\tsp_stack_pushi(s, 10);\n\tsp_stack_pushi(s, 4);\n\tsp_stack_pushi(s, 8);\n\tprintf(\"top of the stack is %d\\n\", sp_stack_peeki(s));\n\tret = sp_stack_popi(s);\n\n\tsp_stack_destroy(s, NULL);\n\treturn ret;\n}\n```\n\n## Library Design Overview\n\n### Compatibility\n\n- works with any version of C starting from C89\n- fully compliant, compiler-agnostic\n\n### Simplicity\n\n- no magic macros\n- no typedefs\n\n### Convenience\n\n- super easy integration with primitive types\n- man pages for every module and function (integrates nicely with vim's `K`\n  keybinding)\n- built-in print functions for every structure\n\n### Flexibility\n\n- can handle generic data behind void pointers\n- all data structures have implementations for arbitrary insertion/removal\n  get/set functions (if feasible), even if the structure is not optimized for\n  it. Some libraries will implement e.g. the stack with only push/peek/pop\n  operations and not bother with insertion, removal and lookup at arbitrary\n  indices. Staple gives you full control out-of-the-box, because even if in 99%\n  of cases you will only push/pop from the top of the stack, once in a while you\n  need that pinpoint insert, even at the cost of performance.\n- no opaque types - you are free to extend the library, if needed\n\n### Reliability\n\n- complete type safety\n- unit testing with [libcheck](https://libcheck.github.io/check/index.html)\n- runtime errors reported on stderr (can be disabled) and with return codes\n\n## Handling Generic Data vs. Primitives\n\nEvery function that operates on structure elements (e.g. push, pop, insert,\netc.) is available in 2 forms:\n\n- **generic form** for `void*` - allows storing any data (pass-by-reference)\n- **suffixed form** - a faster way to work with primitive types only\n  (pass-by-value)\n\nExamples:\n\n```c\nsp_stack_push(s, \u0026data); /* reads from a (void*) */\nsp_stack_pushi(s, -6);   /* pass-by-value (int) */\nsp_stack_pushus(s, 3);   /* pass-by-value (unsigned short) */\n```\n\nHere's a full table of suffixes, although all you need to remember is to use the\nfirst letters of your target type (except for strings):\n\nsuffix | type\n---: | :---\nnone | any (`void*`)\n`c`, `sc`, `uc` | `char`, `signed char`, `unsigned char`\n`s`, `us` | `short`, `unsigned short`\n`i`, `ui` | `int`, `unsigned int`\n`l`, `ul` | `long`, `unsigned long`\n`f`, `d`, `ld` | `float`, `double`, `long double`\n`str`, `strn` | string (`char*`), substring (`char*`)\n\n`signed char` is the only explicitly signed type available, due to the fact that\nit is not defined by the standard whether or not `char` alone is signed or\nunsigned.\n\nAdditionally, these C99 type suffixes are available when compiling the library\nin C99 (default):\n\nsuffix | type\n---: | :---\n`b` | `_Bool`\n`ll`, `ull` | `long long`, `unsigned long long`\n`i8`, `u8` | `int8_t`, `uint8_t`\n`i16`, `u16` | `int16_t`, `uint16_t`\n`i32`, `u32` | `int32_t`, `uint32_t`\n`i64`, `u64` | `int64_t`, `uint64_t`\n\nThis division into generic and suffixed form without using macro functions\nintroduces a **lot** of redundancy and inflation to the code base and resulting\nlibrary size, which is a conscious choice on my part. **This library does not\naim to be small in size**. It prioritizes simplicity, convenience and\nflexibility.\n\n## Installation\n\nAUR: [libstaple](https://aur.archlinux.org/packages/libstaple/)\n\nOn a Linux system with `make`, simply clone the repo and run the following (if\nnecessary, as root):\n\n\tmake clean install\n\nTo uninstall, run\n\n\tmake uninstall\n\nBy default, the files will be copied to `/usr/local/lib`, `/usr/local/include`\nand `/usr/local/share/man`. If you want them (un)installed directly at `/usr`\n(or somewhere else), override the `PREFIX` variable:\n\n\tmake   install PREFIX=/usr\n\tmake uninstall PREFIX=/usr\n\nThe Makefile produces two library files, `libstaple.so` and `libstaple.a`. The\nformer is a dynamically linked library, the latter is static.\n\nThe library can be compiled with various optional modes (refer to the\n**libstaple**(7) man page for descriptions of each):\n\n\tmake clean install DEBUG=1 QUIET=1 ABORT=1\n\n### Compiling with C89 only\n\nIf your target platform does not have a C99 compiler, the library can be built\nwith just \"ANSI\" C89:\n\n\tmake STDC=c89 clean install\n\nThis option is provided for compatibility purposes only - the library will\nbehave exactly the same, except the C99 functionality will be missing.\n\n## Unit Testing\n\nAll test units are stored in `test/src`. If you wish to run the tests, you will\nneed [libcheck](https://github.com/libcheck/check) and optionally\n[valgrind](https://valgrind.org/). By default, the tests are run with valgrind\nto check for memory-related errors. Valgrind can be disabled by adding\n`VALGRIND=` argument to any make command, e.g. `make VALGRIND= test`.\n\nTesting is divided into modules. To execute tests for a single module \"`XYZ`\", run\n\n\tmake test_XYZ\n\n(for example `make test_stack`). You can also run tests for all the\nmodules with\n\n\tmake test\n\n**NOTE:** Running tests requires that Staple was built with debug mode enabled\nand abort mode disabled. The Makefile is not smart enough to know when that\nisn't the case, but the test executables will notice and exit with an error\nautomatically. If this happens, simply force the library to recompile with `make\nclean` and try running the tests again.\n\nTest executables and object files can be removed with\n\n\tmake test_clean\n\n(this is probably not useful unless you are writing tests).\n\n### Running tests in Docker\n\nThe supplied `Dockerfile` can be used to automatically run tests in a Docker\ncontainer. This includes all the libcheck tests and possibly more - for example\nit ensures the library is compiler-agnostic by testing Staple built with a few\ndifferent C compilers (see `test/docker-entrypoint.sh` for more details).\n\nTo build the Dockerfile and execute all tests in a container, run\n\n\tdocker build -t staple .\n\tdocker run staple\n\n---\n\nIf you notice any test failing on a release commit, please open an issue on\nGitHub or send me an email: \u003crandoragongamedev@gmail.com\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frandoragon%2Flibstaple","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frandoragon%2Flibstaple","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frandoragon%2Flibstaple/lists"}