Developer Interface (API)

Csnake has no user interface or CLI functionality. It’s a code-only package and is meant to be used by developers in their own scripts and programs. The API intended for external use is documented in this file.

File-level code container

This class is intended to be your main way of interacting with csnake. It’s a container allows for easy inclusion of various aspects of C language constructs (i.e. a function’s prototype, a variable’s initialization, …).

Those constructs must previously be declared (instantiated using the provided classes).

Calling the appropriate methods (i.e. CodeWriter.add_variable_initialization()) adds the code to the container sequentially.

class csnake.CodeWriter(lf=None, indent=4)[source]

Bases: csnake.codewriterlite.CodeWriterLite

Container class for C code, with methods to add C constructs.

CodeWriter (abbreviated CW or cw) is a code container that allows you to add code (both manually written and generated), access it as a str, iterate over the lines of code and output the code to a file.

It also helps you to indent and dedent code, open or close code blocks consistently.

CodeWriter is iterable (iterates over lines of code), and also has methods like __contains__() and __len__().

Here’s an overview of abc’s CodeWriter is a virtual subclass of:

>>> from csnake import CodeWriter
>>> from collections.abc import Container, Iterable, Sized, Collection
>>> cwr = CodeWriter()
>>> assert isinstance(cwr, Container)
>>> assert isinstance(cwr, Iterable)
>>> assert isinstance(cwr, Sized)
>>> assert isinstance(cwr, Collection)
Parameters
  • lf (Optional[str]) – linefeed character used to separate lines of code when rendering code with str() or code.

  • indent (Union[int, str]) – indentation unit string or int number of spaces, used to indent code.

lf

linefeed character used to separate lines of code when rendering code with str() or code.

Type

str

lines

lines of code.

Type

list(str)

__contains__(item)

Return whether a str is a substring of the codewriter.

Parameters

item (str) – a potential substring of the codewriter.

Return type

bool

Returns

Whether or not item is a substring of the str() representation of the codewriter.

__getitem__(key)

Return the nth line of code.

Return type

str

__iter__()

Return an iterator that iterates over the lines in the codewriter.

Return type

Iterable[str]

__len__()

Return the number of lines in the codewriter.

__str__()

Return the code joined by lf.

Return type

str

add(text)

Append text to the end of last line.

Parameters

text (str) – str to append to the last line.

Raises

ValueError – if text is not a str.

Return type

None

add_autogen_comment(source_file_name=None)[source]

Add a comment denoting the code was autogenerated by a script.

File name of the script the file is generated from is optional.

Parameters

source_file_name (Optional[str]) – name of the script the code was generated from

Examples

Without a script file name:

>>> from csnake import CodeWriter
>>> cwr1 = CodeWriter()
>>> cwr1.add_autogen_comment()
>>> print(cwr1) 
/*
* This file was automatically generated using csnake v0.2.1.
*
* This file should not be edited directly, any changes will be
* overwritten next time the script is run.
*
* Source code for csnake is available at:
* https://gitlab.com/andrejr/csnake
*/

With a script name:

>>> from csnake import CodeWriter
>>> cwr2 = CodeWriter()
>>> cwr2.add_autogen_comment('test.py')
>>> print(cwr2) 
/*
* This file was automatically generated using csnake v0.2.1.
*
* This file should not be edited directly, any changes will be
* overwritten next time the script is run.
* Make any changes to the file 'test.py', not this file.
*
* Source code for csnake is available at:
* https://gitlab.com/andrejr/csnake
*/
Return type

None

add_define(name, value=None, comment=None)[source]

Add a define directive for macros.

Macros may or may not have a value.

Parameters
  • name (str) – macro name

  • value (Union[CExtendedLiteral, VariableValue, None]) – literal or variable assigned to the macro (optional)

  • comment (Optional[str]) – comment accompanying macro definition

Examples

>>> from csnake import CodeWriter, Variable, Subscript
>>> cwr = CodeWriter()
>>> cwr.add_define('PI', 3.14)
>>> cwr.add_define('LOG')
>>> somearr = Variable('some_array', 'int', value=range(0, 5))
>>> cwr.add_define('DEST', Subscript(somearr, 2))
>>> print(cwr)
#define PI 3.14
#define LOG
#define DEST some_array[2]
Return type

None

add_enum(enum)[source]

Add an enumeration definition.

Parameters

enum (Enum) – enum in question

See also

Enum for details on the enum class

Examples

>>> from csnake import (
...     CodeWriter, Enum, Variable, Dereference, AddressOf
... )
>>> cw = CodeWriter()
>>> name = "somename"
>>> pfx = "pfx"
>>> typedef = False
>>> enum = Enum(name, prefix=pfx, typedef=typedef)
>>> cval1 = Variable("varname", "int")
>>> enum.add_value("val1", 1)
>>> enum.add_value("val2", Dereference(1000))
>>> enum.add_value("val3", cval1)
>>> enum.add_value("val4", AddressOf(cval1), "some comment")
>>> cw.add_enum(enum)
>>> print(cw)
enum somename
{
    pfxval1 = 1,
    pfxval2 = *1000,
    pfxval3 = varname,
    pfxval4 = &varname /* some comment */
};
Return type

None

add_function_call(func, *arg)[source]

Add a call to a function with listed arguments.

Parameters
  • func (Function) – function in question

  • *arg – (rest of the args) function’s args in sequence

See also

Function for details on the Function class

Examples

>>> from csnake import CodeWriter, Variable, Function
>>> cw = CodeWriter()
>>> arg1 = Variable("arg1", "int")
>>> arg2 = Variable("arg2", "int", value=range(10))
>>> arg3 = ("arg3", "int")
>>> arg4 = {"name": "arg4", "primitive": "int"}
>>> fun = Function(
...     "testfunct", "void", arguments=(arg1, arg2, arg3, arg4)
... )
>>> fun.add_code(("code;", "more_code;"))
>>> cw.add_function_call(fun, 1, 2, 3, 4)
>>> print(cw)
testfunct(1, 2, 3, 4);
Return type

None

add_function_definition(func)[source]

Add a functions’s definition / implementation.

Parameters

func (Function) – function in question

See also

Function for details on the Function class

Examples

>>> from csnake import CodeWriter, Variable, Function
>>> cw = CodeWriter()
>>> arg1 = Variable("arg1", "int")
>>> arg2 = Variable("arg2", "int", value=range(10))
>>> arg3 = ("arg3", "int")
>>> arg4 = {"name": "arg4", "primitive": "int"}
>>> fun = Function(
...     "testfunct", "void", arguments=(arg1, arg2, arg3, arg4)
... )
>>> fun.add_code(("code;", "more_code;"))
>>> cw.add_function_definition(fun)
>>> print(cw)
void testfunct(int arg1, int arg2[10], int arg3, int arg4)
{
    code;
    more_code;
}
Return type

None

add_function_prototype(func, extern=False, comment=None)[source]

Add a functions’s prototype.

Parameters
  • func (Function) – function in question

  • extern (bool) – wheter to add the extern qualifier to the

  • prototype (True) or not (False, default) –

  • comment (Optional[str]) – accompanying inline comment

See also

Function for details on the Function class

Examples

>>> from csnake import CodeWriter, Variable, Function
>>> cw = CodeWriter()
>>> arg1 = Variable("arg1", "int")
>>> arg2 = Variable("arg2", "int", value=range(10))
>>> arg3 = ("arg3", "int")
>>> arg4 = {"name": "arg4", "primitive": "int"}
>>> fun = Function(
...     "testfunct", "void", arguments=(arg1, arg2, arg3, arg4)
... )
>>> fun.add_code(("code;", "more_code;"))
>>> cw.add_function_prototype(fun)
>>> print(cw)
void testfunct(int arg1, int arg2[10], int arg3, int arg4);
Return type

None

add_license_comment(license_, authors=None, intro=None, year=None)[source]

Add a comment with the license and authors.

The comment also adds the year to the copyright.

Parameters
  • license_ (str) – str containing the text of the license

  • authors (Optional[Iterable[Mapping[str, str]]]) – optional iterable containing mappings (dict-likes, one per author) with key-value pairs for keys ‘name’ (author’s name) and email (author’s email, optional)

  • intro (Optional[str]) – introductory text added before the author list, optional

  • year (Optional[int]) – year of the copyright (optional). If it is left out, current year is assumed.

Raises

ValueError – if any of the arguments is of wrong type

Examples

Just license:

>>> from csnake import CodeWriter
>>> license_text = 'license\ntext\nlines'
>>> cw1 = CodeWriter()
>>> cw1.add_license_comment(license_text)
>>> print(cw1)
/*
* license
* text
* lines
*/

With introduction:

>>> intro_text = 'intro\ntext'
>>> cw2 = CodeWriter()
>>> cw2.add_license_comment(license_text, intro=intro_text)
>>> print(cw2)
/*
* intro
* text
*
* license
* text
* lines
*/

With authors (and year; year defaults to current year):

>>> authors = [
...     {'name': 'Author Surname'},
...     {'name': 'Other Surname', 'email': 'test@email'},
... ]
>>> cw3 = CodeWriter()
>>> cw3.add_license_comment(
...     license_text, authors=authors, intro=intro_text, year=2019
... )
>>> print(cw3)
/*
* intro
* text
*
* Copyright © 2019 Author Surname
* Copyright © 2019 Other Surname <test@email>
*
* license
* text
* lines
*/
Return type

None

add_line(text=None, comment=None, ignore_indent=False)

Add a line of text to the container after the last line.

Parameters
  • text (Optional[str]) – str to add

  • comment (Optional[str]) – optional comment

  • ignore_indent (bool) – switch to ignore indentation and insert the code with indentation 0

Raises

ValueError – if text or comment isn’t a str

Return type

None

add_lines(lines, ignore_indent=False)

Append code lines from an iterable or a multi-line str.

If lines is an iterable iterating over str objects, adds the lines to the codewriter in order.

If lines is a multi-line string, adds its lines to the codewriter.

Parameters
  • lines (Union[Iterable[str], str]) – an Iterable of str or a multi-line str to add to codewriter.

  • ignore_indent (bool) – whether to ignore the current indentation level or not. If ignore_indent is true, the lines will be appended without indentation.

Raises

ValueError – if one of the arguments is of the wrong type

Examples

Adding a list of lines:

>>> from csnake import CodeWriter
>>> cwr = CodeWriter()
>>> lol = ['list', 'of', 'lines']
>>> cwr.add_lines(lol)
>>> print(cwr)
list
of
lines
Return type

None

add_struct(struct)[source]

Add a struct declaration.

Parameters

struct (Struct) – struct in question

See also

Struct for details on the Struct class.

Example

>>> from csnake import CodeWriter, Variable, Struct
>>> cw = CodeWriter()
>>> strct = Struct("strname", typedef=False)
>>> var1 = Variable("var1", "int")
>>> var2 = Variable("var2", "int", value=range(10))
>>> strct.add_variable(var1)
>>> strct.add_variable(var2)
>>> strct.add_variable(("var3", "int"))
>>> strct.add_variable({"name": "var4", "primitive": "int"})
>>> cw.add_struct(strct)
>>> print(cw)
struct strname
{
    int var1;
    int var2[10];
    int var3;
    int var4;
};
Return type

None

add_switch_break()[source]

Break a switch case.

Used with start_switch(), end_switch(), add_switch_case(), add_switch_default(), add_switch_return(), to form C switch statements.

Examples

See start_switch().

Return type

None

add_switch_case(case=typing.Union[csnake.cconstructs.CExtendedLiteral, csnake.cconstructs.VariableValue], comment=None)[source]

Add a switch case statement.

Used with start_switch(), end_switch(), add_switch_default(), add_switch_break(), add_switch_return(), to form C switch statements.

Parameters
  • case – literal or variable representing the current case’s value

  • comment (Optional[str]) – accompanying inline comment

Examples

See start_switch().

Return type

None

add_switch_default(comment=None)[source]

Add a switch default statement.

Used with start_switch(), end_switch(), add_switch_case(), add_switch_break(), add_switch_return(), to form C switch statements.

Switch statements can be nested, so end_switch() closes the innermost switch.

Examples

See start_switch().

Return type

None

add_switch_return(value=None)[source]

Return inside of a switch statement

Used with start_switch(), end_switch(), add_switch_case(), add_switch_default(), add_switch_break(), to form C switch statements.

Parameters

value (Union[CExtendedLiteral, VariableValue, None]) – literal or variable representing the value to return

Examples

See start_switch().

Return type

None

add_variable_declaration(variable, extern=False)[source]

Add a variable’s declaration.

Parameters
  • variable (Variable) – variable in question

  • extern (bool) – wheter to add the extern qualifier to the

  • declaration (True) or not (False, default) –

See also

Variable for details on the Variable class

Examples

>>> import numpy as np
>>> from csnake import CodeWriter, Variable
>>> cw = CodeWriter()
>>> var = Variable(
...     "test",
...     primitive="int",
...     value=np.arange(24).reshape((2, 3, 4))
... )
>>> cw.add_variable_declaration(var)
>>> print(cw)
int test[2][3][4];
Return type

None

add_variable_initialization(variable)[source]

Add a variable’s initialization.

Parameters

variable (Variable) – variable in question

See also

Variable for details on the Variable class

Example

>>> import numpy as np
>>> from csnake import CodeWriter, Variable
>>> cw = CodeWriter()
>>> var = Variable(
...     "test",
...     primitive="int",
...     value=np.arange(24).reshape((2, 3, 4))
... )
>>> cw.add_variable_initialization(var)
>>> print(cw)
int test[2][3][4] = {
    {
        {0, 1, 2, 3},
        {4, 5, 6, 7},
        {8, 9, 10, 11}
    },
    {
        {12, 13, 14, 15},
        {16, 17, 18, 19},
        {20, 21, 22, 23}
    }
};
Return type

None

close_brace()

Add a closed brace and decrease indentation for subsequent lines.

See dedent() for more information on how dedentation is done.

Examples

See open_brace().

Return type

None

property code: str

The contents of the codewriter rendered to a str, using lf as the linebreak.

Type

str

Return type

str

cpp_entry()[source]

Start a conditional extern "C" for use CPP compilers.

Examples

cpp_entry() and cpp_exit() in action:

>>> from csnake import CodeWriter
>>> cwr = CodeWriter()
>>> cwr.cpp_entry()
>>> cwr.add_line('some_code();')
>>> cwr.cpp_exit()
>>> print(cwr)
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
some_code();
#ifdef __cplusplus
}
#endif /* __cplusplus */
Return type

None

cpp_exit()[source]

End a conditional extern "C" for use CPP compilers.

Examples

See cpp_entry().

Return type

None

dedent()

Decrease the indentation level by 1 unit.

Examples

See indent().

Return type

None

end_comment(ignore_indent=False)

End a comment block.

A comment block previously started by start_comment() is ended. The following code is not inside a block comment.

Raises

NoCommentStartError – if you attempt to end a comment block when a comment block hasn’t been started.

Examples

See start_comment().

Return type

None

end_if_def(ignore_ifdef_stack=False)[source]

Insert an #endif to end a #ifdef (preprocessor) block.

#ifdef (or #ifndef) blocks can be nested. #endif always ends the innermost block. endif statements are added by end_if_def().

Parameters

ignore_ifdef_stack (bool) – (optional) don’t throw an exception #endif if is unmatched.

Raises
  • ValueError – if one of the arguments is of the wrong type.

  • DefStackEmptyError – if there isn’t a matching #ifdef and ignore_ifdef_stack isn’t set.

Examples

See start_if_def().

Return type

None

end_switch(ignore_switch_stack=False)[source]

End a switch statement.

Used with start_switch(), add_switch_case(), add_switch_default(), add_switch_break(), add_switch_return(), to form C switch statements.

Switch statements can be nested, so end_switch() closes the innermost switch.

Parameters

ignore_switch_stack (bool) – don’t throw an exception if a switch start is missing

Raises

SwitchStackEmptyError – if end_switch() is called outside of a

:raises switch statement, and ignore_switch_stack is False.:

Examples

See start_switch().

Return type

None

include(name, comment=None)[source]

Add an #include directive.

System headers should be surrounded with brackets (<>), while local headers may or may not be surrounded with quotation marks (“”) (the resulting code will have quotation marks surrounding the header’s name)

Parameters
  • name (str) – name of header to include, with or without brackets/quotes. If no brackets/quotes surround the name, quotes are used by default.

  • comment (Optional[str]) – accompanying inline comment

Examples

All types of includes.

>>> from csnake import CodeWriter
>>> cw = CodeWriter()
>>> cw.include('"some_local_header.h"')
>>> cw.include('other_local_header.h')
>>> cw.include("<string.h>")
>>> print(cw)
#include "some_local_header.h"
#include "other_local_header.h"
#include <string.h>
Return type

None

indent()

Increase the indentation level by 1 unit.

Examples

indent() and dedent() in action:

>>> from csnake import CodeWriter
>>> cwr = CodeWriter()
>>> cwr.add_line('line_1;')
>>> cwr.indent()
>>> cwr.add_line('line_2;')
>>> cwr.add_line('line_3;')
>>> cwr.dedent()
>>> cwr.add_line('line_4;')
>>> print(cwr)
line_1;
    line_2;
    line_3;
line_4;
Return type

None

open_brace()

Add an open brace and increase indentation for subsequent lines.

See indent() for more information on how indentation is done.

Examples

Using open_brace() and close_brace().

>>> from csnake import CodeWriter
>>> cwr = CodeWriter()
>>> cwr.add_line('line_1;')
>>> cwr.open_brace()
>>> cwr.add_line('line_2;')
>>> cwr.add_line('line_3;')
>>> cwr.close_brace()
>>> cwr.add_line('line_4;')
>>> print(cwr)
line_1;
{
    line_2;
    line_3;
}
line_4;
Return type

None

start_comment(ignore_indent=False)

Start a comment block.

All of the lines added after this are in a block comment, until the block is finished by end_comment().

Parameters

ignore_indent (bool) – whether to ignore the indentation and just start the comment from the beginning of the next line.

Raises

NestedCommentError – if you attempt to start a comment block when a comment block has already been started.

Examples

Starting and ending a comment block with start_comment() and end_comment():

>>> from csnake import CodeWriter
>>> cwr = CodeWriter()
>>> cwr.add_line('line_1;')
>>> cwr.start_comment()
>>> cwr.add_line('line_2;')
>>> cwr.add_line('line_3;')
>>> cwr.end_comment()
>>> cwr.add_line('line_4;')
>>> print(cwr)
line_1;
/*
* line_2;
* line_3;
*/
line_4;
Return type

None

start_if_def(define, invert=False, comment=None)[source]

Start an #ifdef or #ifndef (preprocessor) block.

#ifdef (or #ifndef) blocks can be nested. #endif always ends the innermost block. endif statements are added by end_if_def().

Parameters
  • define (str) – name of the macro whose existence we’re checking.

  • invert (bool) – (optional) whether this block is an #ifndef (True) or #ifdef (False, default).

  • comment (Optional[str]) – (optional) comment accompanying the statement.

Raises

ValueError – if one of the arguments is of the wrong type.

Examples

start_if_def() and end_if_def() in action, including nested ifdefs:

>>> from csnake import CodeWriter
>>> cwr = CodeWriter()
>>> cwr.start_if_def('DEBUG')
>>> cwr.start_if_def('ARM', invert=True)
>>> cwr.add_define('LOG')
>>> cwr.end_if_def()
>>> cwr.end_if_def()
>>> print(cwr)
#ifdef DEBUG
#ifndef ARM
#define LOG
#endif /* ARM */
#endif /* DEBUG */
Return type

None

start_switch(switch)[source]

Start a switch statement.

Used with end_switch(), add_switch_case(), add_switch_default(), add_switch_break(), add_switch_return(), to form C switch statements.

Switch statements can be nested, so end_switch() closes the innermost switch.

Parameters

switch (Union[CExtendedLiteral, VariableValue]) – literal or variable the choice depends on.

Examples

Demonstration of switch-related methods:

>>> from csnake import CodeWriter, Variable
>>> cw = CodeWriter()
>>> var = Variable("somevar", "int")
>>> case_var = Variable("case_var", "int")
>>> cw.start_switch(var)
>>> cw.add_switch_case(2)
>>> cw.add_line('do_something();')
>>> cw.add_switch_break()
>>> cw.add_switch_case(case_var)
>>> cw.add_switch_return(5)
>>> cw.add_switch_default()
>>> cw.add_switch_return(8)
>>> cw.end_switch()
>>> print(cw)
switch (somevar)
{
    case 2:
        do_something();
        break;
    case case_var:
        return 5;
    default:
        return 8;
} /* ~switch (somevar) */
Return type

None

write_to_file(filename)[source]

Write code to filename.

Parameters

filename (str) – name of the file to write code into

Return type

None

zero_indent()

Set indentation level to zero.

Return type

None

C language constructs

These classes describe C language constructs such as functions, variables, structs, …

They can be used on their own (by instantiating them and using their str() or other functions such as generate_declaration, generate_definition,… ) or via CodeWriter.

class csnake.Enum(name, prefix=None, typedef=False)[source]

Bases: object

Class describing C enum construct.

Parameters
  • name (str) – name of the enum

  • prefix (Optional[str]) – prefix to add to every enumeration’s name

  • typedef (bool) – whether or not the enum is typedef’d

name

name of the enum

typedef

whether or not the enum is typedef’d

prefix

prefix to add to every enumeration’s name

values

list of Enum.EnumValue

class EnumValue(name, value=None, comment=None)[source]

Bases: object

Singular value of an C-style enumeration.

__str__()[source]

Return the declaration str (with indentation of 4 spaces).

Return type

str

add_value(name, value=None, comment=None)[source]

Add a single name = value pair (or just name).

Return type

None

add_values(values)[source]

Add multiple name = value pairs (or just names).

Values can be one of:

  • a dict with name : value entries

  • a collection of:
    • strs denoting names (no value)

    • dicts with keys [name, value, comment], and optional

      keys [value, comment]

    • collections (list-like) of length 1-3 denoting [name,

      value, comment] respectively

Return type

None

property declaration: str

The declaration str (with indentation of 4 spaces).

See also

generate_declaration() for the underlying method.

Return type

str

generate_declaration(indent=4)[source]

Generate enum declaration code.

Generate a CodeWriterLite instance containing the initialization code for this Enum.

Parameters

indent (Union[int, str]) – indent str or int denoting the number of spaces for indentation

Examples

>>> from csnake import (
...     Enum, Variable, Dereference, AddressOf
... )
>>> name = "somename"
>>> pfx = "pfx"
>>> typedef = False
>>> enum = Enum(name, prefix=pfx, typedef=typedef)
>>> cval1 = Variable("varname", "int")
>>> enum.add_value("val1", 1)
>>> enum.add_value("val2", Dereference(1000))
>>> enum.add_value("val3", cval1)
>>> enum.add_value("val4", AddressOf(cval1), "some comment")
>>> print(enum.generate_declaration())
enum somename
{
    pfxval1 = 1,
    pfxval2 = *1000,
    pfxval3 = varname,
    pfxval4 = &varname /* some comment */
};
Return type

CodeWriterLite

class csnake.Function(name, return_type='void', qualifiers=None, arguments=None)[source]

Bases: object

Class describing C function.

You can generate a function prototype (declaration), a definition or a call. A function’s body is a CodeWriterLite, so You can add lines of code to it (or a whole new CodeWriter instance).

Parameters
  • name (str) – name of the function

  • return_type (str) – str containing function’s return type

  • qualifiers (Union[str, Iterable[str], None]) – str or Sequence of str listing the function’s qualifiers (const, volatile, …)

  • arguments (Optional[Iterable]) –

    an iterable which yields one the following types:

    • a Variable

    • a Collection (tuple/list-like) of 2 strings

      (name, primitive)

    • a Mapping (dict-like) with keys (name,

      primitive)

name

name of the function

return_type

str containing function’s return type

qualifiers

str or Sequence of str listing the function’s qualifiers (const, volatile, …)

arguments

an iterable which yields one the following types:

  • a Variable

  • a Collection (tuple/list-like) of 2 strings

    (name, primitive)

  • a Mapping (dict-like) with keys (name,

    primitive)

codewriter

internal instance of CodeWriterLite that contains

the funtion's body code.
add_argument(arg)[source]

Add an argument to function.

Arguments are added sequentially.

arg: an one the following types:

  • a Variable

  • a Collection (tuple/list-like) of 2 strings

    (name, primitive)

  • a Mapping (dict-like) with keys (name,

    primitive)

Return type

None

add_arguments(args)[source]

Add multiple arguments to function.

Arguments are added sequentially.

args: an iterable which yields one the following types:

  • a Variable

  • a Collection (tuple/list-like) of 2 strings

    (name, primitive)

  • a Mapping (dict-like) with keys (name,

    primitive)

Return type

None

add_code(code)[source]

Add a str or Iterable of strs to function’s body

Since a CodeWriter is an iterable of strs, you can simply add its contents to the function by passing it to this method.

Parameters

code (Union[str, Iterable[str]]) – str or Iterable of strs to be added

Return type

None

property definition: str

Function definition str.

See also

generate_definition() for the underlying method.

Return type

str

generate_call(*arg)[source]

Return function calling code for specific arguments.

Parameters

*arg – argument values for call, in order of appearance.

Doesn’t end with a semicolon (;).

Examples

>>> from csnake import Variable, Function
>>> arg1 = Variable("arg1", "int")
>>> arg2 = Variable("arg2", "int", value=range(10))
>>> arg3 = ("arg3", "int")
>>> arg4 = {"name": "arg4", "primitive": "int"}
>>> fun = Function(
...     "testfunct", "void", arguments=(arg1, arg2, arg3, arg4)
... )
>>> fun.add_code(("code;", "more_code;"))
>>> print(fun.generate_call(1, 2, 3, 4))
testfunct(1, 2, 3, 4)
Return type

str

generate_definition(indent='    ')[source]

Return a CodeWriterLite instance containing the definition code for this Function.

Parameters

indent (Union[int, str]) – indent str or int denoting the number of spaces for indentation

Examples

>>> from csnake import Variable, Function
>>> arg1 = Variable("arg1", "int")
>>> arg2 = Variable("arg2", "int", value=range(10))
>>> arg3 = ("arg3", "int")
>>> arg4 = {"name": "arg4", "primitive": "int"}
>>> fun = Function(
...     "testfunct", "void", arguments=(arg1, arg2, arg3, arg4)
... )
>>> fun.add_code(("code;", "more_code;"))
>>> print(fun.generate_definition())
void testfunct(int arg1, int arg2[10], int arg3, int arg4)
{
    code;
    more_code;
}
Return type

CodeWriterLite

generate_prototype(extern=False)[source]

Generate function prototype code.

Parameters

extern (bool) – whether or not the function is to be declared as extern

Doesn’t end with a semicolon (;).

Examples

>>> from csnake import Variable, Function
>>> arg1 = Variable("arg1", "int")
>>> arg2 = Variable("arg2", "int", value=range(10))
>>> arg3 = ("arg3", "int")
>>> arg4 = {"name": "arg4", "primitive": "int"}
>>> fun = Function(
...     "testfunct", "void", arguments=(arg1, arg2, arg3, arg4)
... )
>>> fun.add_code(("code;", "more_code;"))
>>> print(fun.generate_prototype())
void testfunct(int arg1, int arg2[10], int arg3, int arg4)
Return type

str

init_target_code(formatters=None)[source]

Return code used for variable initialization, formatted with the supplied formatters.

Parameters

formatters (Optional[LiteralFormatters]) – collection of formatters used for formatting the initialization str

Return type

str

property prototype: str

Function prototype (declaration) str.

Ends with a semicolon (;).

See also

generate_prototype() for the underlying method.

Return type

str

class csnake.Struct(name, typedef=False)[source]

Bases: object

Class describing C struct construct.

Parameters
  • name (str) – name of struct

  • typedef (bool) – whether or not the struct is typedef’d

name

name of struct

typedef

whether or not the struct is typedef’d

variables

list of struct’s variables

__str__()[source]

Generate a str instance containing the declaration code for this Struct.

add_variable(variable)[source]

Add a variable to struct.

Variables inside of a Struct are ordered (added sequentially).

Parameters

variable (Union[Variable, Collection, Mapping]) –

variable to add. It can be defined in multiple ways.

variable can be:

  • a Variable

  • a Collection (tuple/list-like) of 2

    strs (name, primitive)

  • a Mapping (dict-like) with keys [‘name’,

    ’primitive’]

property declaration

CodeWriterLite instance containing the declaration code for this Struct.

See also

generate_declaration() for the underlying method.

generate_declaration(indent=4)[source]

Generate a CodeWriterLite instance containing the initialization code for this Struct.

Parameters

indent (Union[int, str]) – indent str or int denoting the number of spaces for indentation

Example

>>> from csnake import Variable, Struct
>>> strct = Struct("strname", typedef=False)
>>> var1 = Variable("var1", "int")
>>> var2 = Variable("var2", "int", value=range(10))
>>> strct.add_variable(var1)
>>> strct.add_variable(var2)
>>> strct.add_variable(("var3", "int"))
>>> strct.add_variable({"name": "var4", "primitive": "int"})
>>> print(strct.generate_declaration())
struct strname
{
    int var1;
    int var2[10];
    int var3;
    int var4;
};
Return type

CodeWriterLite

class csnake.Variable(name, primitive, qualifiers=None, array=None, comment=None, value=None)[source]

Bases: object

Class describing C variable contruct.

You can generate declarations and initializations for variables, and variables can be initialized to very complex values (you can init an array variable to an array of struct containing arrays that contain structs, …).

The formatting of initialization strs can be altered by encasing some level of the initialization with a FormattedLiteral.

As for function values, the following (Python input → C code) translations are assumed (numpy and scipy ints and floats are considered ints and floats):

  • dictstruct literal

  • list or tuple → array literal

  • intint literal or int literal

  • floatfloat literal or double literal

  • boolbool literal or int literal

  • Variable → name of the variable

There is no type checking for initializations. That’s what your compiler is for, no sense in replicating such functionality here.

Parameters
  • name (str) – name of the variable

  • primitive (Union[str, FuncPtr]) – str name or FuncPtr defining the variable’s type

  • qualifiers (Union[str, Iterable[str], None]) – str or Sequence of str listing the variable’s qualifiers (const, volatile, …)

  • array (Optional[Iterable]) – Sequence of int defining the dimensions of a (possibly multidimensional) array. If it’s left out, it’s inferred from value.

  • comment (Optional[str]) – accompanying comment

  • value (Optional[CLiteral]) – variable’s value, used for initialization. Explained in detail above

__str__()[source]

Initialization (if value in not None) or declaration str.

Falls back to declaration if value is None.

Ends with a semicolon (;).

See also

generate_initialization() for the initialization method. generate_declaration() for the declaration method.

property declaration: str

Declaration string.

Ends with a semicolon (;).

See also

generate_declaration() for the underlying method.

Return type

str

generate_declaration(extern=False)[source]

Return a declaration str.

Doesn’t end with a semicolon (;).

Parameters

extern (bool) – whether or not the value is to be declared as extern

Examples

>>> import numpy as np
>>> from csnake import Variable
>>> var = Variable(
...     "test",
...     primitive="int",
...     value=np.arange(24).reshape((2, 3, 4))
... )
>>> print(var.generate_declaration())
int test[2][3][4]
Return type

str

generate_initialization(indent=4)[source]

Return a CodeWriterLite instance containing the initialization code for this Variable.

Ends with a semicolon (;).

Parameters

indent (Union[int, str]) – indent str or int denoting the number of spaces for indentation

Example

>>> import numpy as np
>>> from csnake import Variable
>>> var = Variable(
...     "test",
...     primitive="int",
...     value=np.arange(24).reshape((2, 3, 4))
... )
>>> print(var.generate_initialization())
int test[2][3][4] = {
    {
        {0, 1, 2, 3},
        {4, 5, 6, 7},
        {8, 9, 10, 11}
    },
    {
        {12, 13, 14, 15},
        {16, 17, 18, 19},
        {20, 21, 22, 23}
    }
};
Return type

CodeWriterLite

init_target_code(formatters=None)[source]

Return a str used for initialization of other Variables

Return type

str

property initialization: str

Initialization str.

Ends with a semicolon (;).

See also

generate_initialization() for the underlying method.

Return type

str

Variable initialization values

These classes help You modify the literals you’re using to initialize your variables.

class csnake.VariableValue[source]

Bases: object

Abstract base class for any initializer value based on a variable.

Sometimes we want to initialize a value to another variable, but in some more complicated manner: using the address-of operator, dereference operator, subscripting, typecasting… This is an ABC for those modifiers.

abstract __str__()[source]

Return str containing initialization code.

abstract init_target_code(formatters=None)[source]

Return code used for variable initialization, formatted with the supplied formatters.

Parameters

formatters (Optional[LiteralFormatters]) – collection of formatters used for formatting the initialization str

class csnake.AddressOf(variable)[source]

Bases: csnake.cconstructs.VariableValue

Address of (&) VariableValue for variable initialization.

Subclass of VariableValue that returns an initialization string containing the & (address of) used on a value.

Parameters

variable (VariableValue) – variable to return the address of.

variable

variable to return the address of.

Examples

>>> from csnake import Variable, AddressOf
>>> var1 = Variable("var1", "int")
>>> addrof_var1 = AddressOf(var1)
>>> var2 = Variable("var2", "int", value=addrof_var1)
>>> print(var2)
int var2 = &var1;
__str__()[source]

Initialization string.

init_target_code(formatters=None)[source]

Return a str used for initialization of other Variables

Return type

str

class csnake.Arrow(variable, item)[source]

Bases: csnake.cconstructs.VariableValue

Arrow (->) VariableValue for variable initialization.

Subclass of VariableValue that returns an initialization string for accessing a specific member of a struct indirectly (through a pointer).

Parameters
  • variable (Union[CLiteral, VariableValue]) – variable whose member we’re accessing

  • member – name of member we’re accessing

variable

variable whose member we’re accessing

member

name of member we’re accessing

Examples

>>> from csnake import Variable, Arrow
>>> var1 = Variable("var1", "struct somestr")
>>> arrvar = Arrow(var1, 'some_member')
>>> var2 = Variable("var2", "int", value=arrvar)
>>> print(var2)
int var2 = var1->some_member;
__str__()[source]

Initialization string.

init_target_code(formatters=None)[source]

Return a str used for initialization of other Variables

Return type

str

class csnake.Dereference(value)[source]

Bases: csnake.cconstructs.VariableValue

Dereference (*) modifier for variable initialization.

Subclass of VariableValue that returns an initialization string containing the * (dereference) used on a value.

Parameters

value (Union[CExtendedLiteral, VariableValue]) – value to dereference.

value

value to dereference.

Examples

>>> from csnake import Variable, Dereference
>>> var1 = Variable("var1", "int")
>>> derefd_var1 = Dereference(var1)
>>> var2 = Variable("var2", "int", value=derefd_var1)
>>> print(var2)
int var2 = *var1;
>>> derefd_number = Dereference(16)
>>> var3 = Variable("var3", "int", value=derefd_number)
>>> print(var3)
int var3 = *16;
__str__()[source]

Initialization string.

init_target_code(formatters=None)[source]

Return a str used for initialization of other values

Return type

str

class csnake.Dot(variable, member)[source]

Bases: csnake.cconstructs.VariableValue

Dot (.) VariableValue for variable initialization.

Subclass of VariableValue that returns an initialization string for accessing a specific member of a struct.

Parameters
  • variable (Union[CLiteral, VariableValue]) – variable whose member we’re accessing

  • member (str) – name of member we’re accessing

variable

variable whose member we’re accessing

member

name of member we’re accessing

Examples

>>> from csnake import Variable, Dot
>>> var1 = Variable("var1", "struct somestr")
>>> dotvar = Dot(var1, 'some_member')
>>> var2 = Variable("var2", "int", value=dotvar)
>>> print(var2)
int var2 = var1.some_member;
__str__()[source]

Initialization string.

init_target_code(formatters=None)[source]

Return a str used for initialization of other Variables

Return type

str

class csnake.GenericModifier(value, function)[source]

Bases: csnake.cconstructs.VariableValue

VariableValue generated by applying a function to a value.

A value’s initializer string is passed through the supplied function, which should return a str.

Parameters
  • value (Union[CExtendedLiteral, VariableValue]) – value whose initializer we’re passing through a function

  • format_function – function used for modifying a value’s initializer

value

value whose initializer we’re passing through a function

format_function

function used for modifying a value’s initializer

Examples

>>> from csnake import Variable, GenericModifier
>>> var1 = Variable("var1", "int")
>>> genmod_var1 = GenericModifier(var1, lambda l: f'TRANSLATE({l})')
>>> var2 = Variable("var2", "int", value=genmod_var1)
>>> print(var2)
int var2 = TRANSLATE(var1);
>>> genmod_var2 = GenericModifier('test', lambda l: f'do_whatever({l})')
>>> var3 = Variable("var3", "int", value=genmod_var2)
>>> print(var3)
int var3 = do_whatever("test");
__str__()[source]

Initialization string.

init_target_code(formatters=None)[source]

Return a str used for initialization of other Variables

Return type

str

class csnake.OffsetOf(struct, member)[source]

Bases: csnake.cconstructs.VariableValue

offsetof VariableValue modifier for initializing to offsets of struct members.

Subclass of VariableValue that returns an initialization string containing the offset of a specific member of a struct.

Parameters
  • struct (Union[Struct, str]) – struct whose member’s offset we’re using

  • member (Union[VariableValue, str]) – struct member whose offset we’re using

struct

struct whose member’s offset we’re using

member

struct member whose offset we’re using

Examples

>>> from csnake import Variable, OffsetOf, Struct
>>> offs_val1 = OffsetOf('struct some', 'some_member')
>>> var2 = Variable("var2", "int", value=offs_val1 )
>>> print(var2)
int var2 = offsetof(struct some, some_member);
>>> test_struct = Struct('other')
>>> offs_val2 = OffsetOf(test_struct, 'other_member')
>>> var3 = Variable("var3", "int", value=offs_val2 )
>>> print(var3)
int var3 = offsetof(struct other, other_member);
__str__()[source]

Initialization string.

init_target_code(formatters=None)[source]

Return a str used for initialization of other Variables

Return type

str

class csnake.Subscript(variable, subscript)[source]

Bases: csnake.cconstructs.VariableValue

Subscript ([]) modifier for variable initialization.

Subclass of VariableValue that returns an initialization string with a subscripted value.

Parameters
  • variable (Union[CLiteral, VariableValue]) – variable to be typecast

  • subscript (Iterable) – a VariableValue or int or list or tuple of them representing the subscript[s].

variable

variable to be typecast

subscript

a VariableValue or int or list or tuple of them representing the subscript[s].

Examples

>>> from csnake import Variable, Subscript
>>> var1 = Variable("var1", "int")
>>> subscr1_var1 = Subscript(var1, 3)
>>> var2 = Variable("var2", "int", value=subscr1_var1)
>>> print(var2)
int var2 = var1[3];
>>> subscr2_var1 = Subscript(var1, (3, 2))
>>> var3 = Variable("var3", "int", value=subscr2_var1)
>>> print(var3)
int var3 = var1[3][2];
>>> subscr2_var1 = Subscript(var1, (var3, 2))
>>> var4 = Variable("var4", "int", value=subscr2_var1)
>>> print(var4)
int var4 = var1[var3][2];
__str__()[source]

Initialization string.

init_target_code(formatters=None)[source]

Return a str used for initialization of other Variables

Return type

str

class csnake.TextModifier(text)[source]

Bases: csnake.cconstructs.VariableValue

Generic textual VariableValue for initializing to an arbitrary str.

The str supplied as the argument is output verbatim as the Initialization string.

Parameters

text (str) – initialization string

text

initialization string

Examples

>>> from csnake import Variable, TextModifier
>>> textmod1 = TextModifier('whatever + you + want')
>>> var2 = Variable("var2", "int", value=textmod1)
>>> print(var2)
int var2 = whatever + you + want;
>>> textmod2 = TextModifier(f'you_can_do_this_too + {var2.name}')
>>> var3 = Variable("var3", "int", value=textmod2)
>>> print(var3)
int var3 = you_can_do_this_too + var2;
__str__()[source]

Initialization string.

init_target_code(formatters=None)[source]

Return a str used for initialization of other Variables

Return type

str

class csnake.Typecast(value, cast)[source]

Bases: csnake.cconstructs.VariableValue

Typecast modifier for variable initialization.

Subclass of VariableValue that returns an initialization string containing the typecast to type used on a value.

Parameters
  • value (Union[CExtendedLiteral, VariableValue]) – value to be typecast

  • cast (str) – type to cast to

value

value to be typecast

cast

type to cast to

Examples

>>> from csnake import Variable, Typecast
>>> var1 = Variable("var1", "int")
>>> cast_var1 = Typecast(var1, 'long')
>>> var2 = Variable("var2", "int", value=cast_var1)
>>> print(var2)
int var2 = (long) var1;
>>> cast_number = Typecast(16, 'long')
>>> var3 = Variable("var3", "int", value=cast_number)
>>> print(var3)
int var3 = (long) 16;
__str__()[source]

Initialization string.

init_target_code(formatters=None)[source]

Return a str used for initialization of other values

Return type

str

class csnake.FormattedLiteral(value, *args, **kwargs)[source]

Bases: object

A C literal with its formatter collection altered.

The accompanying literal formatter collection will be used when generating the initialization str.

Parameters

**kwargs – keyword arguments for each of the formatters in [‘int_formatter’, ‘float_formatter’, ‘bool_formatter’, ‘string_formatter’] we want to change for this literal. Every missing formatter is inherited from the literal (or default).

value

value of literal

formatter

collection of literal formatters

Variable value literal formatters

You can specify formatters which are used to modify the way literals are printed by encasing your Variable’s value with a FormattedLiteral with the some formatters given by keyword arguments (see FormattedLiteral for details).

These are some format functions used by default by csnake:

csnake.simple_bool_formatter(value)[source]

Simple formatter that turns a bool into ‘true’ or ‘false’.

Parameters

value (bool) – boolean to format

Return type

str

Returns

str’s ‘true’ or ‘false’

csnake.simple_str_formatter(value)[source]

Simple formatter that surrounds a str with quotes.

Parameters

value (str) – string to format

Return type

str

Returns

str that’s the input string surrounded with double quotes

Variable type declaration helpers

These classes help you declare complex types for use as Variable’s type.

class csnake.FuncPtr(return_type, arguments=None, comment=None)[source]

Bases: object

Class describing function pointer args and return type.

This class made for declaring function pointer type specifics for use with Variables as their type argument.

Parameters
  • return_type (str) – str containing the return type

  • arguments (Optional[Iterable]) –

    an iterable which yields one the following types:

    • a Variable

    • a Collection (tuple/list-like) of 2 strings

      (name, primitive)

    • a Mapping (dict-like) with keys (name,

      primitive)

get_declaration(name, qualifiers=None, array=None)[source]

Generate the whole declaration str according to parameters.

This method is meant to be called from Variable.generate_declaration() and Variable.generate_initialization() function and is probably useless to You elsewhere.

Return type

str

Extra variable value conversion modules

These submodules contain functions to convert more complicated types (like PIL Images, for instance) to types that can be used as initializers.

Module pil_converter

Module for conversion of PIL images to lists for variable initialization.

csnake.pil_converter.pil_image_to_list(image, outformat='ARGB8888')[source]

Convert a PIL image into an a list of ints.

Conversion is done from the Image.tobytes() to list of int, based on the format given by the argument format.

The main purpose of this is to turn Images into nested lists, which can be used as array initialization values by :class: csnake.variable.

image’s format is extracted from the image itself and there is only a limited number of conversions available. While the input format is fixed, the output format is supplied by outformat.

Here are the supported mappings of formats (PIL Image.mode → output format):

  • RGB → RGB888

  • RGB → RGB565

  • RGBA → ARGB888

  • L → A8

Parameters
  • image (Image) – PIL or Pillow Image to be turned into array.

  • outformat (str) – Format of int’s in the output array.

Return type

List[List[int]]

Returns

list of list of int for pixels of the image

Raises
  • TypeError – If the image arg passed isn’t a PIL Image.

  • ValueError – If the conversion between the listed formats isn’t possible.

Examples

>>> from csnake.pil_converter import pil_image_to_list
>>> from csnake import CodeWriter, Variable, FormattedLiteral
>>> from PIL import Image, ImageDraw
>>> im = Image.new('RGB', (3, 3))
>>> dr = ImageDraw.Draw(im)
>>> dr.line((0,0) + im.size, fill = '#8CAFAF')
>>> im_ls = pil_image_to_list(im, "RGB888")
>>> print(im_ls)
[[9220015, 0, 0], [0, 9220015, 0], [0, 0, 9220015]]
>>> var = Variable(
...     "pic",
...     primitive="int",
...     value=FormattedLiteral(im_ls, int_formatter=hex),
... )
>>> cw = CodeWriter()
>>> cw.add_variable_initialization(var)
>>> print(cw)
int pic[3][3] = {
    {0x8cafaf, 0x0, 0x0},
    {0x0, 0x8cafaf, 0x0},
    {0x0, 0x0, 0x8cafaf}
};