Skip to content

serd223/bookkeeper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

124 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bookkeeper

bookkeeper is a single source file C code generation tool that generates boilerplate serialization/deserialization code for your user defined structures.

bookkeeper is heavily inspired by the Rust serde crate and this Tsoding stream.

Quick Start

Here is a simple example that outputs both JSON and Debug output: (quick.c)

#include <stdio.h>

#define BK_IMPLEMENTATION
#define BK_DISABLE_json_PARSE

#include "people.h" // Example file
#include "people.h.bk.h" // Generated file

typedef struct {
    Person friend_info; tag("info")
    int years_known;
} Friend derive_json() derive_debug();
#include "quick.c.bk.h" // Generated file

int main(void) {
    Person p = {.name = "Alice", .age = 30, .married = false};
    Friend f = {.friend_info = p,.years_known = 5};
    printf("JSON:\n");
    dump_json_Friend(&f, stdout);
    printf("\n\nDebug:\n");
    dump_debug_Friend(&f, stdout);
    return 0;
}

Here is its output:

JSON:
{"info":{"name":"Alice","age":30,"married":false},"years_known":5}

Debug:
Friend {
    friend_info: Person {
        (string) name: Alice
        (int) age: 30
        (bool) married: false
    }
    (int) years_known: 5
}

And this is how you can build it:

    $ git clone https://github.com/serd223/bookkeeper.git && cd bookkeeper
    $ mkdir build && mkdir gen
    $ # Uses `clang` by default, set `CC` in the `Makefile` if you prefer another compiler.
    $ make quick
    $ ./build/quick

But why?

As C programmers we find ourselves constantly writing boilerplate code for parsing some config struct, or just simply printing any struct. C lacks the necessary metaprogramming tools to automate the generation of this kind of boilerplate code (unlike more modern languages where you can do #derive(Debug) or deriving Show). So we either write it by hand every single time (too much work), ask LLMs to write the code for us (unreliable and requires code review), or use code generation tools like bookkeeper. bookkeeper aims to be an easy to use, extendible, user friendly, embedded friendly and portable solution to this problem.

Warning

Although bookkeeper aims to be all of those things, it is still somewhat early in development and the tool itself only supports Linux and macOS. The generated code is mostly embedded friendly and portable, though.

Overview

The bk tool requires an output directory and (optional) input file(s). The output directory can be specified with -o. Then you can either supply files one by one with the -i flag (like -i file1 -i file), or you can supply an input directory with -I and the tool will scan that directory for any .c or .h files. bk analyzes the included files and collects all typedef struct { field_type field; } StructName style struct definitions. Each struct can 'derive' functionalities that will be included in the generated code. For instance, if you want your struct to support JSON parsing/dumping you would write:

typedef struct {
    int some_field; tag("SomeField")
    const char* some_other_field;
    /* fields */
} MyStruct derive_json();

(See people.h)

By default, bk places generated files next to their source files (mirroring the original file structure). These generated files have the following naming schema: original_file_name.bk.h.

For further explanation regarding the provided example, check out the Usage section of User Documentation.

Documentation

User Documentation

You can access User Documentation via the docs/index.md file in this repository, this file contains links to other sections of User Documentation.

This documentation contains information about the general usage of bookkeeper, configuration and writing extensions for bookkeeper.

bookkeeper Documentation

bookkeeper Documentation is generated via doxygen. After installing it if you haven't, you can run:

    $ make docs

in the root of the repository to generate the documentation. The generated files are placed inside docs/doxygen and you can open the docs/doxygen/html/index.html file inside your browser to browse the documentation.

This documentation is the general documentation of the internals of bookkeeper. It is meant for those who want to modify bookkeeper, extension authors or those who are just curious.

Build Instructions

Prerequisites

  • git
  • gnu make
  • A C compiler (defaults to clang, change CC in Makefile if you prefer gcc or another)

Instructions

First, you will need to clone this repository and cd into the repository's root directory:

    $ git clone https://github.com/serd223/bookkeeper.git
    $ cd bookkeeper

Then create build and gen folders:

    $ mkdir build
    $ mkdir gen

You can build bk by running:

    $ make
    $ ./build/bk

Building Examples

In order to build the dump_people example, run: (auto-generates necessary files)

    $ make dump
    $ ./build/dump_people

In order to build the parse_people example, run: (auto-generates necessary files)

    $ make parse
    $ ./build/parse_people

In order to build and test the provided extension example, you can run: (auto-generates necessary files)

    $ make schema_ext
    $ ./build/bk_ext -I ./examples -o ./gen -om dir

You can then inspect the generated files inside the gen folder to see the generated example schema functions.

Check out Usage or the examples folder!

Releases

No releases published

Packages

 
 
 

Contributors