Package: calligra
Author:Elie ROUDNINSKIcalligrais 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 doesnot parseC code itself at all.calligrawas first designed to (un)serialize complex (but not too complex …) C structures from JSON.Contents1Installation1.1Requirements1.2From github1.3From pip1.4Tests2Howto2.1Introduction2.2Examples3Modules3.1Conversion3.1.1Jansson3.2Importer1Installation1.1Requirementscalligrarequires 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.Ascalligrais intended to generate code, some external dependencies might be needed to compile the generated code.1.2From githubYou can clone this repository and install it with setuptools directly:$ python3 setup.py install --user1.3From pipAs every pip available package, you can install it easily with the pip package:$ python3 -m pip install --user calligra1.4TestsTests are available in the source distribution (either from github or from pip) and are located in thetests/directory.
You can run them with setuptools:$ python3 setup.py test2Howto2.1IntroductionAs specified before,calligrais 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*)enumstruct, named and anonymousunion, named and anonymousand the following declaration modifiers:pointersarrayNested array of pointers or pointers to array are not supported.At the moment, you have two choices:define everything from Pythonparse C code with the cparser importer moduleIn the future, you will be able to import definitions from:JSON Schema2.2ExamplesLets start with a basic example.
In the following code snippets we will be defining a C structure calledpersonwith 2 members:a stringnamean unsigned integerageAnd then we will generate the associated C code.First import the main modules:importcalligraimportcalligra.stdlibcalligramodule is where the C type/declaration syntax is modelized.calligra.stdlibis where standard C types are defined.Then define the structure:namespace=calligra.stdlib.namespaceperson=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:structperson{char*name;uint8_tage;};More advanced examples are located in theexamples/directory.3Modules3.1ConversionConversion modules are located in thecalligra/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 theJanssonlibrary.3.1.1JanssonIn order to use the jansson conversion module, just import thecalligra.convert.janssonmodule:importcalligra.convert.janssonAfter that, every type should now have ato_jsonand afrom_jsonmethod.
Those are actuallycalligra.functionsobject which you candefineto generate the corresponding C code:print(person.to_json.define())Which should generate something similar to:json_t*person_to_json(structpersonconst*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(structpersonconst*person){json_t*json=json_object(),*child;if(!json){returnNULL;}/*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);returnNULL;}}/*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);returnNULL;}}returnjson;}3.2ImporterImporter modules are located in thecalligra/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 thepycparserpackage.