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:
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 astr
, 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 withstr()
orcode
.indent (
Union
[int
,str
]) – indentation unit string orint
number of spaces, used to indent code.
- lf¶
linefeed character used to separate lines of code when rendering code with
str()
orcode
.- 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.
- 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 astr
.- 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- Return type:
None
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 */
- 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 namevalue (
Union
[CExtendedLiteral
,VariableValue
,None
]) – literal or variable assigned to the macro (optional)comment (
Optional
[str
]) – comment accompanying macro definition
- Return type:
None
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]
- add_enum(enum)[source]¶
Add an enumeration definition.
- Parameters:
enum (
Enum
) – enum in question- Return type:
None
See also
Enum
for details on the enum classExamples
>>> 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 */ };
- 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
- Return type:
None
See also
Function
for details on the Function classExamples
>>> 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);
- add_function_definition(func)[source]¶
Add a functions’s definition / implementation.
- Parameters:
func (
Function
) – function in question- Return type:
None
See also
Function
for details on the Function classExamples
>>> 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; }
- add_function_prototype(func, extern=False, comment=None)[source]¶
Add a functions’s prototype.
- Parameters:
func (
Function
) – function in questionextern (
bool
) – wheter to add theextern
qualifier to theprototype (True) or not (False, default)
comment (
Optional
[str
]) – accompanying inline comment
- Return type:
None
See also
Function
for details on the Function classExamples
>>> 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);
- 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 licenseauthors (
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, optionalyear (
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
- Return type:
None
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 */
- 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 addcomment (
Optional
[str
]) – optional commentignore_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
]) – anIterable
ofstr
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
- Return type:
None
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
- add_struct(struct)[source]¶
Add a struct declaration.
- Parameters:
struct (
Struct
) – struct in question- Return type:
None
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; };
- 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.- Return type:
None
Examples
See
start_switch()
.
- 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
- Return type:
None
Examples
See
start_switch()
.
- 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.- Return type:
None
Examples
See
start_switch()
.
- 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- Return type:
None
Examples
See
start_switch()
.
- add_variable_declaration(variable, extern=False)[source]¶
Add a variable’s declaration.
- Parameters:
variable (
Variable
) – variable in questionextern (
bool
) – wheter to add theextern
qualifier to thedeclaration (True) or not (False, default)
- Return type:
None
See also
Variable
for details on the Variable classExamples
>>> 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];
- add_variable_initialization(variable)[source]¶
Add a variable’s initialization.
- Parameters:
variable (
Variable
) – variable in question- Return type:
None
See also
Variable
for details on the Variable classExample
>>> 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} } };
- close_brace()¶
Add a closed brace and decrease indentation for subsequent lines.
See
dedent()
for more information on how dedentation is done.- Return type:
None
Examples
See
open_brace()
.
- property code: str¶
The contents of the codewriter rendered to a str, using
lf
as the linebreak.- Type:
str
- cpp_entry()[source]¶
Start a conditional
extern "C"
for use CPP compilers.- Return type:
None
Examples
cpp_entry()
andcpp_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 */
- cpp_exit()[source]¶
End a conditional
extern "C"
for use CPP compilers.- Return type:
None
Examples
See
cpp_entry()
.
- 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
- Return type:
None
See
start_comment()
.
- 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 byend_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
andignore_ifdef_stack
isn’t set.
Examples
- Return type:
None
See
start_if_def()
.
- 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- Return type:
None
- Raises:
SwitchStackEmptyError – if
end_switch()
is called outside of a
:raises switch statement, and
ignore_switch_stack
isFalse
.:Examples
See
start_switch()
.
- 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
- Return type:
None
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>
- indent()¶
Increase the indentation level by 1 unit.
- Return type:
None
Examples
indent()
anddedent()
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;
- open_brace()¶
Add an open brace and increase indentation for subsequent lines.
See
indent()
for more information on how indentation is done.- Return type:
None
Examples
Using
open_brace()
andclose_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;
- 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
- Return type:
None
Starting and ending a comment block with
start_comment()
andend_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;
- 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 byend_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.
- Return type:
None
Examples
start_if_def()
andend_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 */
- 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.- Return type:
None
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) */
- write_to_file(filename)[source]¶
Write code to filename.
- Parameters:
filename (
Union
[str
,Path
]) – 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 enumprefix (
Optional
[str
]) – prefix to add to every enumeration’s nametypedef (
bool
) – whether or not the enum istypedef
’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.
- add_value(name, value=None, comment=None)[source]¶
Add a single
name = value
pair (or justname
).- Return type:
None
- add_values(values)[source]¶
Add multiple
name = value
pairs (or justname
s).Values can be one of: :rtype:
None
a
dict
with name : value entries- a collection of:
str
s denoting names (no value)dict
s with keys [name, value, comment], and optionalkeys [value, comment]
- collections (
list
-like) of length 1-3 denoting [name, value, comment] respectively
- collections (
- property declaration: str¶
The declaration
str
(with indentation of 4 spaces).See also
generate_declaration()
for the underlying method.
- generate_declaration(indent=4)[source]¶
Generate enum declaration code.
Generate a
CodeWriterLite
instance containing the initialization code for thisEnum
.- Parameters:
indent (
Union
[int
,str
]) – indentstr
orint
denoting the number of spaces for indentation- Return type:
CodeWriterLite
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 */ };
- 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 newCodeWriter
instance).- Parameters:
name (
str
) – name of the functionreturn_type (
str
) –str
containing function’s return typequalifiers (
Union
[Iterable
[str
],str
,None
]) –str
orSequence
ofstr
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
- a
Mapping
(dict
-like) with keys (name, primitive)
- a
- name¶
name of the function
- return_type¶
str
containing function’s return type
- qualifiers¶
str
orSequence
ofstr
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
- a
Mapping
(dict
-like) with keys (name, primitive)
- a
- 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: :rtype:
None
a
Variable
- a
Collection
(tuple
/list
-like) of 2 strings (name, primitive)
- a
- a
Mapping
(dict
-like) with keys (name, primitive)
- a
- add_arguments(args)[source]¶
Add multiple arguments to function.
Arguments are added sequentially.
args: an iterable which yields one the following types: :rtype:
None
a
Variable
- a
Collection
(tuple
/list
-like) of 2 strings (name, primitive)
- a
- a
Mapping
(dict
-like) with keys (name, primitive)
- a
- add_code(code)[source]¶
Add a
str
orIterable
ofstr
s to function’s bodySince a
CodeWriter
is an iterable ofstr
s, you can simply add its contents to the function by passing it to this method.- Parameters:
code (
Union
[str
,Iterable
[str
]]) –str
orIterable
ofstr
s to be added- Return type:
None
- property definition: str¶
Function definition
str
.See also
generate_definition()
for the underlying method.
- generate_call(*arg)[source]¶
Return function calling code for specific arguments.
- Parameters:
*arg – argument values for call, in order of appearance.
- Return type:
str
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)
- generate_definition(indent=' ')[source]¶
Return a
CodeWriterLite
instance containing the definition code for thisFunction
.- Parameters:
indent (
Union
[int
,str
]) – indentstr
orint
denoting the number of spaces for indentation- Return type:
CodeWriterLite
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; }
- generate_prototype(extern=False)[source]¶
Generate function prototype code.
- Parameters:
extern (
bool
) – whether or not the function is to be declared asextern
- Return type:
str
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)
- 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 initializationstr
- Return type:
str
- property prototype: str¶
Function prototype (declaration)
str
.Ends with a semicolon (;).
See also
generate_prototype()
for the underlying method.
- class csnake.Struct(name, typedef=False)[source]¶
Bases:
object
Class describing C
struct
construct.- Parameters:
name (
str
) – name of structtypedef (
bool
) – whether or not the struct istypedef
’d
- name¶
name of struct
- typedef¶
whether or not the struct is
typedef
’d
- variables¶
list
ofstruct
’s variables
- add_bit_field(bit_field)[source]¶
Add a bit field to struct.
Bit fields inside of a
Struct
are ordered (added sequentially). The order is synced with theadd_variable()
function.see
BitField
for more information.- Parameters:
bit_field (
BitField
) – bit field to add.
- add_variable(variable)[source]¶
Add a variable to struct.
Variables inside of a
Struct
are ordered (added sequentially). The order is synced with theadd_bit_field()
function.
- property declaration¶
CodeWriterLite
instance containing the declaration code for thisStruct
.See also
generate_declaration()
for the underlying method.
- generate_declaration(indent=4)[source]¶
Generate a
CodeWriterLite
instance containing the initialization code for thisStruct
.- Parameters:
indent (
Union
[int
,str
]) – indentstr
orint
denoting the number of spaces for indentation- Return type:
CodeWriterLite
Example
>>> from csnake import BitField, 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"}) >>> var5 = BitField("int", 2, name="var5") >>> var6 = BitField("int", 3, comment="unused bits") >>> var7 = BitField("int", 1, name="var7") >>> strct.add_bit_field(var5) >>> strct.add_bit_field(var6) >>> strct.add_bit_field(var7) >>> print(strct.generate_declaration()) struct strname { int var1; int var2[10]; int var3; int var4; int var5: 2; int : 3; /* unused bits */ int var7: 1; };
- 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 containstructs
, …).The formatting of initialization
str
s can be altered by encasing some level of the initialization with aFormattedLiteral
.As for function values, the following (Python input → C code) translations are assumed (numpy and scipy ints and floats are considered ints and floats):
dict
→struct
literallist
or tuple → array literalint
→int
literal orint
literalfloat
→float
literal ordouble
literalbool
→bool
literal orint
literalVariable
→ 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 variableprimitive (
Union
[str
,FuncPtr
]) –str
name orFuncPtr
defining the variable’s typequalifiers (
Union
[Iterable
[str
],str
,None
]) –str
orSequence
ofstr
listing the variable’s qualifiers (const
,volatile
, …)array (
Optional
[Iterable
]) –Sequence
ofint
defining the dimensions of a (possibly multidimensional) array. If it’s left out, it’s inferred from value.comment (
Optional
[str
]) – accompanying commentvalue (
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.
- 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 asextern
- Return type:
str
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]
- generate_initialization(indent=4)[source]¶
Return a
CodeWriterLite
instance containing the initialization code for thisVariable
.Ends with a semicolon (;).
- Parameters:
indent (
Union
[int
,str
]) – indentstr
orint
denoting the number of spaces for indentation- Return type:
CodeWriterLite
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} } };
- init_target_code(formatters=None)[source]¶
Return a
str
used for initialization of otherVariable
s- Return type:
str
- property initialization: str¶
Initialization
str
.Ends with a semicolon (;).
See also
generate_initialization()
for the underlying method.
- class csnake.BitField(primitive, width, name=None, comment=None)[source]¶
Bases:
object
Class describing C bit fields.
Bit fields in C are a way of packing variables into bits.
the C syntax is:
type [name] : width ;
- where
type is usually an integer type.
name is optional so we could have unnamed bits for padding..
width is the number of bits.
Note
This class made for declaring bit field specifics for use with
Struct.add_bit_field()
.- Parameters:
name (
Optional
[str
]) – (Optional) name of the bit fieldwidth (
int
) – width of the bit fieldprimitive (
str
) – primitive type of the bit fieldcomment (
Optional
[str
]) – accompanying comment
- property declaration: str¶
Declaration string.
Ends with a semicolon (;). Includes the comment if present.
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.
- class csnake.AddressOf(variable)[source]¶
Bases:
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;
- class csnake.Arrow(variable, item)[source]¶
Bases:
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 accessingmember – 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;
- class csnake.Dereference(value)[source]¶
Bases:
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;
- class csnake.Dot(variable, member)[source]¶
Bases:
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 accessingmember (
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;
- class csnake.GenericModifier(value, function)[source]¶
Bases:
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 functionformat_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");
- class csnake.OffsetOf(struct, member)[source]¶
Bases:
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 usingmember (
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);
- class csnake.Subscript(variable, subscript)[source]¶
Bases:
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 typecastsubscript (
Iterable
) – aVariableValue
orint
orlist
or tuple of them representing the subscript[s].
- variable¶
variable to be typecast
- subscript¶
a
VariableValue
orint
orlist
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];
- class csnake.TextModifier(text)[source]¶
Bases:
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;
- class csnake.Typecast(value, cast)[source]¶
Bases:
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 typecastcast (
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;
- 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:
Variable type declaration helpers¶
These classes help you declare complex types for use as Variable
’s
type.
- class csnake.FuncPtr(return_type, arguments=None)[source]¶
Bases:
object
Class describing function pointer args and return type.
This class made for declaring function pointer type specifics for use with
Variable
s as their type argument.- Parameters:
return_type (
str
) –str
containing the return typearguments (
Optional
[Iterable
]) –an iterable which yields one the following types:
a
Variable
- a
Collection
(tuple
/list
-like) of 2 strings (name, primitive)
- a
- a
Mapping
(dict
-like) with keys (name, primitive)
- a
- 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()
andVariable.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
Image
s 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 PillowImage
to be turned into array.outformat (
str
) – Format of int’s in the output array.
- Return type:
List
[List
[int
]]- Returns:
list
oflist
ofint
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} };