Automates CBOR serialization/deserialization for C structs
Project description
🐼 Ailuropoda: Automate CBOR for C Structs
✨ Tired of writing tedious, error-prone boilerplate C code for CBOR serialization and deserialization?
Ailuropoda is your solution! This powerful Python tool automatically generates robust C functions to encode and decode your C structs into Concise Binary Object Representation (CBOR), seamlessly integrating with the TinyCBOR library.
🚀 Why Ailuropoda?
Manually handling CBOR for complex C data structures is a time sink. Ailuropoda eliminates this pain, letting you focus on your core logic while it handles the serialization boilerplate.
Key Features:
- Automated Boilerplate: Generates
encode_MyStruct()anddecode_MyStruct()functions for eachstructin your C header files. - TinyCBOR Integration: Produces C code fully compatible with the
CborEncoderandCborValueAPIs from the TinyCBOR library. - Comprehensive Type Support: Handles a wide range of C types:
- Basic integers (
int,uint64_t,char, etc.) - Floating-point numbers (
float,double) - Booleans (
bool) - Fixed-size character arrays (
char name[64]) as CBOR text strings. - Character pointers (
char* email,const char* notes) as CBOR text strings. - Nested structs.
- Fixed-size arrays of primitive types or nested structs.
- Basic integers (
- Ready-to-Use Output: Generates a dedicated output directory containing:
cbor_generated.handcbor_generated.cwith your encode/decode functions.- A
CMakeLists.txtfile to easily compile the generated code and link against TinyCBOR. - Helper functions for
cbor2jsonandjson2cborconversion, simplifying data inspection and interoperability.
- Simplified Development: Define your data structures in C headers, and let
Ailuropodahandle the rest!
🛠️ How It Works
Ailuropoda leverages pycparser to parse your C header file's Abstract Syntax Tree (AST). It identifies struct definitions and their members, then intelligently generates the corresponding C encoding and decoding functions.
📦 Installation & Setup
Ailuropoda is available on PyPI, making installation straightforward with various Python package managers.
Global Installation (Recommended for CLI Tools)
For convenient command-line usage without managing virtual environments manually, pipx is highly recommended:
pip install pipx
pipx install ailuropoda
Virtual Environment Installation
For project-specific dependencies or development:
Using uv (recommended for fast dependency management):
# First, install uv (if you haven't already):
# curl -LsSf https://astral.sh/uv/install.sh | sh
# Create and synchronize the virtual environment
uv venv
uv pip install ailuropoda
# Activate the environment (optional, uv run/exec handle this)
source .venv/bin/activate
Using pip (standard installation):
python -m venv .venv
source .venv/bin/activate
pip install ailuropoda
Using pipenv:
pip install pipenv
pipenv install ailuropoda
pipenv shell
For Development & Testing
If you are contributing to Ailuropoda or running its tests from the source repository:
# Navigate to your project directory
cd /path/to/Ailuropoda
# Create and synchronize the virtual environment with core and development dependencies
uv sync --dev
🚀 Usage
Ailuropoda provides a command-line interface ailuropoda (or ailuropoda.cbor_codegen if running via uv run directly from source).
-
Run the code generator:
# Choose your preferred tool: uvx, pipx, pipenv, or uv run (if developing locally) # Example: Using pipx (recommended if installed globally via pipx install ailuropoda) pipx run ailuropoda <your_header_file.h> --output-dir <output_directory> [--generate-json-helpers] # Example: Using uvx (for ad-hoc execution without global install) uvx ailuropoda <your_header_file.h> --output-dir <output_directory> [--generate-json-helpers] # Example: Using pipenv (if installed in a pipenv project) pipenv run ailuropoda <your_header_file.h> --output-dir <output_directory> [--generate-json-helpers] # Example: If running from source with uv virtual environment uv run ailuropoda <your_header_file.h> --output-dir <output_directory> [--generate-json-helpers]
Concrete Example:
# Generate CBOR code for tests/my_data.h into the 'generated_cbor' directory # Using pipx: pipx run ailuropoda tests/my_data.h --output-dir ./generated_cbor # Using uvx: uvx ailuropoda tests/my_data.h --output-dir ./generated_cbor
This will create a directory (e.g.,
generated_cbor) containingcbor_generated.h,cbor_generated.c, and aCMakeLists.txtfile. -
Integrate with your CMake project: Add the generated directory to your
CMakeLists.txt:add_subdirectory(generated_cbor) target_link_libraries(your_app PRIVATE cbor_generated tinycbor)
⚠️ Assumptions and Limitations
- C Preprocessing: For complex header files with many
#includedirectives or macros, it's recommended to preprocess the header first (e.g., usinggcc -E your_header.h) and then pass the preprocessed output toAiluropoda. - Memory Management for Pointers: For
char*and other pointer types during decoding, the generated C code does not perform dynamic memory allocation (malloc). It assumes that the pointer members in your struct are already pointing to sufficiently large, allocated buffers. You are responsible for managing this memory. - Unsupported C Constructs:
uniontypes are not supported.- Function pointers are detected but skipped.
- Multi-dimensional arrays beyond the first dimension are not fully supported for complex types.
- Flexible array members are not supported.
- Error Handling: The generated C functions return
falseon any CBOR encoding/decoding error. - CBOR Map Keys: Struct member names are used directly as CBOR map keys (text strings).
- Anonymous Structs: Anonymous struct definitions that are not part of a
typedefor a named member are skipped.
💡 Development & Testing Insights
Python Environment and Project Configuration
Ailuropoda follows modern Python packaging and dependency management best practices, leveraging uv and pyproject.toml.
pyproject.toml(PEP 621): This file serves as the single source of truth for project metadata, dependencies, and build system configuration. It adheres to PEP 621, making the project easily discoverable and installable by tools likepip,uv, orrye.uvfor Virtual Environments:uvis used for fast dependency resolution and virtual environment management. Commands likeuv syncensure all project dependencies (and development dependencies with--dev) are installed into an isolated virtual environment.- Running Scripts: Always use
uv run python <script_path>(oruv run <module_name>) to execute project scripts. This automatically activates the virtual environment and ensures the correct Python interpreter and installed packages are used. This approach eliminates the need for manualsource .venv/bin/activateor manipulating thePATHenvironment variable, promoting a cleaner and more reliable development workflow.
C/C++ Integration Testing with Pytest
The project includes robust integration tests (tests/integration/test_full_pipeline.py) to ensure the entire code generation, compilation, and execution pipeline works as expected.
- Pytest Fixtures: Pytest fixtures are extensively used to set up and tear down the testing environment:
tmp_path: Provides a unique, temporary directory for each test, ensuring isolation and preventing test interference. All generated files (C code, build artifacts) are placed here.tinycbor_install_path: This fixture handles the compilation and installation of theTinyCBORC library, whichAiluropoda's generated code depends on. It ensuresTinyCBORis available in a known location for subsequent compilation steps.setup_test_environment: This orchestrates the core integration steps:- It calls
ailuropoda.cbor_codegen.generate_cbor_codeto generate thecbor_generated.h,cbor_generated.c, andCMakeLists.txtfiles into thetmp_path. - It then uses
subprocessto invokecmakeandmakewithin the generated directory to compile the generated C code, linking it against theTinyCBORlibrary. - Finally, it compiles a simple C test harness (e.g.,
c_test_harness_simple_data.c.jinja) that uses the generated CBOR functions, creating an executable binary.
- It calls
subprocessModule: Python'ssubprocessmodule is used to execute external commands, such ascmake,make, and the compiled C test binaries. This allows the Python tests to drive the C build and execution process.- Verification: After execution, the tests can read the output of the C binary (e.g., serialized CBOR data, deserialized values) and compare it against expected results, ensuring correctness of the generated code.
This setup provides a comprehensive way to validate Ailuropoda's output and its compatibility with the target C environment.
🤝 Contributing
We welcome contributions! Feel free to open issues or pull requests on our GitHub repository: jvishnefske/Ailuropoda
📄 License
This project is licensed under the BSD 3-Clause License.
🚧 TODO / Future Enhancements
We're continuously working to improve Ailuropoda. Here are some planned features:
- CBOR to JSON / JSON to CBOR Helpers: Implement optional C helper functions for converting between CBOR and JSON, simplifying debugging and interoperability.
- Dynamic Memory Management for Pointers: Enhance
char*and other pointer decoding to optionally handle dynamic memory allocation (malloc/free) for decoded data, reducing the burden on the user. - Union Type Support: Add support for C
uniontypes. - Enum Type Support: Generate appropriate CBOR representations for C
enumtypes. - Improved Error Handling: Provide more granular error codes and messages in the generated C functions.
- Advanced Array Support: Explore support for multi-dimensional arrays and flexible array members.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ailuropoda-0.2.0.tar.gz.
File metadata
- Download URL: ailuropoda-0.2.0.tar.gz
- Upload date:
- Size: 17.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2ceb6d4b5f0953f9c939709a0db6c398d471102a909f177f2ff1db1044456924
|
|
| MD5 |
43b192d3af46d7f7482b576bd74c53dc
|
|
| BLAKE2b-256 |
69a06dfeac4216a495d8bae8339efd1b8fb4f8364a8f93e41644449258f502a7
|
File details
Details for the file ailuropoda-0.2.0-py3-none-any.whl.
File metadata
- Download URL: ailuropoda-0.2.0-py3-none-any.whl
- Upload date:
- Size: 11.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
db3f2fb4742dd0ac47ad4e9dfc7bfc14a571c37b6c03a1fd5ad084d807cf6599
|
|
| MD5 |
141fc26720c6c421d4dbdcf5377f8272
|
|
| BLAKE2b-256 |
d5ac910ee17974193de516243ef53ef9eebe31ed6884abb73319a1b05529a74d
|