An open API service indexing awesome lists of open source software.

https://github.com/opensourcedoc/c-stack-mustache


https://github.com/opensourcedoc/c-stack-mustache

c generic-programming mustache-templates

Last synced: 6 days ago
JSON representation

Awesome Lists containing this project

README

          

# Generic C Code with Mustache Templates

This project demonstrates how to bring **generic programming** into the C language by using [Mustache](https://mustache.github.io/), a lightweight logic-less template engine.

C lacks native support for generics. Instead of relying on macros or duplicating similar code for each data type, this approach uses Mustache templates to **generate reusable, type-safe stack implementations** in plain C.

The repository includes:

* Mustache templates for `.c` and `.h` files of a stack structure.
* A simple code generation pipeline using `make`.
* Two test cases demonstrating usage with `int` and a custom wrapper type.

This project shows that even in a low-level language like C, **meta-programming techniques** can improve maintainability and reduce boilerplate β€” all without giving up performance or transparency.

---

## Why Mustache?

C macros and conditional compilation can simulate some forms of generic code, but they often come with trade-offs:

* 🧹 **Complex syntax** – Macro logic can quickly become unreadable and hard to debug.
* 🚫 **Limited flexibility** – Features like conditional defaults or type-dependent expansion are hard to express.
* πŸ§ͺ **Poor tooling support** – IDEs and linters usually struggle with macro-heavy code.

Using a template engine like **Mustache** provides a different approach:

* βœ… **Clear separation between code and logic** – Templates stay readable and simple.
* βœ… **Flexible output** – You can generate `.c`/`.h` files for any type combination with consistent formatting.
* βœ… **Static output** – The generated code is plain C, fully transparent to compilers and debuggers.
* βœ… **Easy integration** – Combine with `make` or shell scripts for reproducible, automated generation.

This method doesn’t replace C’s core mechanisms β€” it **augments them** through pre-processing. It’s especially useful when you want to maintain **clean, consistent, reusable data structures** across multiple types without relying on compiler extensions.

---

## Usage Example

The following test demonstrates how to use a generated stack for a user-defined type `int_obj_t`. The type wraps an `int` value, and provides custom `clone` and `free` functions for memory safety.

```c
// int_obj_t is a wrapper around int with malloc/free.
typedef struct {
int data;
} int_obj_t;
```

Here's a minimal usage scenario:

```c
#include "stack_obj.h"

int_obj_t * obj_new(int data);
void * obj_clone(void *obj);
void obj_free(void *obj);

int main(void)
{
stack_t *s = stack_new((stack_params_t){
.clone = obj_clone,
.free = obj_free
});

int data[] = {3, 4, 5, 6};
for (size_t i = 0; i < 4; i++) {
stack_push(s, obj_new(data[i]));
int_obj_t *top = stack_peek(s);
assert(top->data == data[i]);
obj_free(top);
}

// Pops: 6, 5, 4, 3
for (int i = 3; i >= 0; i--) {
int_obj_t *top = stack_pop(s);
assert(top->data == data[i]);
obj_free(top);
}

stack_free(s);
return 0;
}
```

### Build and Run

```bash
make # Generates C code via Mustache and builds the test
./test_obj # Runs the test program
```

This confirms that the generated stack works with non-primitive types and handles memory ownership safely via callbacks.

---

## System Requirements

* A modern C compiler
* GNU Make
* [`mustach`](https://gitlab.com/jobol/mustach) (template processor)

---

## License

Apache License 2.0
Copyright (c) 2019 ByteBard