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) # doctest: +SKIP
/*
* 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) # doctest: +SKIP
/*
* 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 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:

>>> authors = [
...     {'name': 'Author Surname'},
...     {'name': 'Other Surname', 'email': 'test@email'},
... ]
>>> cw3 = CodeWriter()
>>> cw3.add_license_comment(
...     license_text, authors=authors, intro=intro_text
... )
>>> print(cw3)
/*
* intro
* text
*
* Copyright © 2018 Author Surname
* Copyright © 2018 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
code

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
  • 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
declaration

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[+T_co]]) –

    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

If code is an iterable, it should be one string - one line. Since a CodeWriter is an iterable of strs , you can simply add its contents to the function.

Parameters:code (Union[str, Iterable[str]]) – str or Iterable of strs to be added
Return type:None
definition

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
prototype

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[+T_co], Mapping[~KT, +VT_co]]) –

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’]
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[+T_co]]) – 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 str.

Ends with a semicolon (;).

See also

generate_initialization() for the underlying method.

declaration

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
initialization

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.

__str__()[source]

Return str containing initialization code.

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[+T_co]) – 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).

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. .. autoclass:: FuncPtr

members:
inherited-members:
 
show-inheritance: