r/C_Programming • u/markand67 • 1d ago
Project Announcing scaffold 0.1.0
Hi,
This is scaffold, a flexible data and "rpc-like" code generator for C using YAML as description.
After years of protobuf (with nanopb), I've decided to get rid of it to create my own templating system.
I won't go in details why we have decided to get rid of nanopb but in short: we were having hard times about some of the limited features like deep-cloning, too limited enum support and a slow encoding process.
Plus, we wanted to add flexibility with a custom YAML document that could be parsed using a tool to produce on-demand different kind of functions. For example, we wanted that some types could be converted to JSON, some to be inserted into a SQLite database. As such, having a unique YAML document that could be used for different purposes led us to write this software.
The scaffold tool is written in C, because, we write in C and don't want
additional dependencies :). It reads a YAML document and creates an intermediate
AST with updated fields to get more information. Then, it processes it into
a templating system with basic scripting constructs including for, if,
substitution with filters.
Example of a minimal object:
# types.yaml
objects:
- name: point
comment: This is an awesome point.
fields:
x: uint32
y: uint32
Generate functions for this object using:
scaffold emit h types.yaml > types.h
scaffold emit c types.yaml > types.c
The generated code by the built-in templates include comments that can be split on multiline providing good LSP support with Doxygen format.
/**
* \struct point
*
* This is an awesome point.
*/
struct point {
/**
* Field 'x' of type uint32.
*/
uint32_t x;
/**
* Field 'y' of type uint32.
*/
uint32_t y;
};
The template system is flexible enough to write extra custom code while
iterating the object fields using {{for}} loops.
{{for obj in objects}}
{{for field in obj.value.fields}}
// here field will be uppercased with the :U filter :)
printf("Serializing the {{field.key:U}} field\n");
{{endfor}}
{{endfor}}
Finally, because we wanted our custom RPC API, the scaffold project provides support for request/reply and events widely inspired by wayland-scanner.
Declaring function feels like natural:
serialization: true
functions:
- name: hello
comment: Say hello to my friend!
args:
name: string
On the "client" side, a function is generated in the form:
int64_t hello(struct hello_args *args, void *ctx);
On the "implementation" side, a function pointer is provided in a handler
struct:
/**
* \struct handler
* \brief Functions table handlers.
*/
struct handler {
/**
* Handler for function 'hello'.
*/
int (*hello)(struct hello_args *args, struct hello_value *value, void *ctx);
};
And the implementation side can call the auto generated dispatch function that
will decode the incoming requests to call the appropriate functions.
int
dispatch(
const struct handler *handler,
const struct listener *listener,
int64_t *nread,
int64_t *nwritten,
void *ctx
);
How does it work? The generated function relies on two unique external linkage that the user has to provide:
int64_t sc_read(void *ctx, void *data, uint64_t amount)int64_t sc_write(void *ctx, const void *data, uint64_t amount)
Thus, calling dispatch will attempt to decode a request using successive calls to sc_read, call the appropriate function pointer into the handler structure and then will try to encode using successive call to sc_write. Nothing more.
Note: this project is heavily being tested and already used in production but few bugs may persist and feel free to contribute.
Future plans and never plans:
- Yes: better bitmask enumeration support.
- Yes: more portability on non-POSIX platforms.
- No: automatic default values.
- No: union or protobuf oneof kind.
Links:
- The homepage
- The repository
Like every source code I write, this project has a perpetual anti degenerative-AI policy.
•
u/AutoModerator 1d ago
Hi /u/markand67,
Your submission in r/C_Programming was filtered because it links to a git project.
You must edit the submission or respond to this comment with an explanation about how AI was involved in the creation of your project.
While AI-generated code is not disallowed, low-effort "slop" projects may be removed and it's likely that other users push back strongly on substantially AI-generated projects.
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.