Skip to main content

1 calligra

Author:

Elie ROUDNINSKI

calligra is a pure Python package that tries to modelize a subset of the C langage syntax in order to reason about C types, from Python scripts. Its main goals are to do metaprogrammation and code generation. It does not parse C code itself at all.

calligra was first designed to (un)serialize complex (but not too complex …) C structures from JSON.

1.1 Installation

1.1.1 Requirements

calligra requires Python 3. It has been tested on Python 3.6 on Linux but it should work on 3.4 and 3.6 and on Windows also. At the moment, it does not require any external Python modules/packages, but this might change in the future.

As calligra is intended to generate code, some external dependencies might be needed to compile the generated code.

1.1.2 From github

You can clone this repository and install it with setuptools directly:

$ python3 setup.py install --user

1.1.3 From pip

As every pip available package, you can install it easily with the pip package:

$ python3 -m pip install --user calligra

1.1.4 Tests

Tests are available in the source distribution (either from github or from pip) and are located in the tests/ directory. You can run them with setuptools:

$ python3 setup.py test

1.2 Howto

1.2.1 Introduction

As specified before, calligra is intended to reason about C types at a Python level.

Currently, you can modelize the following types:

  • primary types like char, int, float, double etc.

  • C strings (char*)

  • enum

  • struct, named and anonymous

  • union, named and anonymous

and the following declaration modifiers:

  • pointers

  • array

Nested array of pointers or pointers to array are not supported.

At the moment, you have two choices:

  • define everything from Python

  • parse C code with the cparser importer module

In the future, you will be able to import definitions from:

  • JSON Schema

1.2.2 Examples

Lets start with a basic example. In the following code snippets we will be defining a C structure called person with 2 members:

  • a string name

  • an unsigned integer age

And then we will generate the associated C code.

First import the main modules:

import calligra
import calligra.stdlib

calligra module is where the C type/declaration syntax is modelized. calligra.stdlib is where standard C types are defined.

Then define the structure:

namespace = calligra.stdlib.namespace
person = calligra.struct(namespace, 'person')
person.add(
    calligra.declaration(
        namespace, namespace.get('char'), 'name', pointer = True
    )
)
person.add(
    calligra.declaration(
        namespace, namespace.get('uint8_t'), 'age'
    )
)

Finally, generate the C code:

print(person.define())

This should generate something similar to:

struct person {
    char *name;
    uint8_t age;
};

More advanced examples are located in the examples/ directory.

1.3 Modules

1.3.1 Conversion

Conversion modules are located in the calligra/convert/ directory and are meant to (un)serialize C types to and from another format (like JSON).

Currently available conversion modules are:

  • calligra.convert.jansson: to convert C types to and from JSON using the Jansson library.

1.3.1.1 Jansson

In order to use the jansson conversion module, just import the calligra.convert.jansson module:

import calligra.convert.jansson

After that, every type should now have a to_json and a from_json method. Those are actually calligra.functions object which you can define to generate the corresponding C code:

print(person.to_json.define())

Which should generate something similar to:

json_t *person_to_json(struct person const *person);

And for the function body:

print(person.to_json.code(body = True))

Which should generate something similar to (non-contractual code):

json_t *person_to_json(struct person const *person) {
    json_t *json = json_object(), *child;
    if(!json) {
        return NULL;
    }
    /*name*/
    if((person != NULL) && ((*person).name != NULL) && (*(*person).name != 0)) {
        child = json_string((*person).name);
        if(!child || json_object_set_new_nocheck(json, "name", child) != 0) {
            if(child) {
                json_decref(child);
            }
            json_decref(json);
            return NULL;
        }
    }
    /*age*/
    if(person != NULL) {
        child = json_integer((*person).age);
        if(!child || json_object_set_new_nocheck(json, "age", child) != 0) {
            if(child) {
                json_decref(child);
            }
            json_decref(json);
            return NULL;
        }
    }
    return json;
}

1.3.2 Importer

Importer modules are located in the calligra/importer/ directory and are meant to import C types from another format (like C).

Currently available importer modules are:

  • calligra.importer.cparser: to import C types directly from C code using the pycparser package.

Metadata

Release files for calligra 0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for calligra 0.3
File Size Uploaded Provenance Actions
calligra-0.3.tar.gz 16.9 kB Without provenance Details for calligra-0.3.tar.gz

Release files / calligra-0.3.tar.gz

Download URL calligra-0.3.tar.gz
Size 16.9 kB
Tags Source
SHA-256 checksum
How to use checksums
691ee91430c54a11dc5edf9ee696be813041739c929675488ebb9da45d81df7e
BLAKE2b-256 checksum
How to use checksums
5a4b62794f4c5f460def18ceb35f212939d7508496cdbe28641a2113080d61dc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Security for calligra 0.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.3 This release

1 release file No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page