nunavut.lang.c

Filters for generating C. All filters in this module will be available in the template’s global namespace as c.

class nunavut.lang.c.Language(language_module: module, config: nunavut.lang._config.LanguageConfig, omit_serialization_support: bool, language_options: Optional[Mapping[str, Any]] = None)[source]

Bases: nunavut.lang.Language

Concrete, C-specific nunavut.lang.Language object.

get_includes(dep_types: nunavut.dependencies.Dependencies) → List[str][source]

Get a list of include paths that are specific to this language and the options set for it. :param Dependencies dep_types: A description of the dependencies includes are needed for. :return: A list of include file paths. The list may be empty if no includes were needed.

filter_id(instance: Any, id_type: str = 'any') → str[source]

Produces a valid identifier in the language for a given object. The encoding may not be reversible.

Parameters:
  • instance (any) – Any object or data that either has a name property or can be converted to a string.
  • id_type (str) – A type of identifier. This is different for each language. For example, for C this value can be ‘typedef’, ‘macro’, ‘function’, or ‘enum’. Use ‘any’ to apply stropping rules for all identifier types to the instance.
Returns:

A token that is a valid identifier in the language, is not a reserved keyword, and is transformed in a deterministic manner based on the provided instance.

nunavut.lang.c.filter_id(language: nunavut.lang.c.Language, instance: Any, id_type: str = 'any') → str[source]

Filter that produces a valid C identifier for a given object. The encoding may not be reversible.

# Given
I = 'I ❤ c'

# and
template = '{{ I | id }}'

# then
rendered = 'I_zX2764_c'
# Given
I = 'if'

# and
template = '{{ I | id }}'

# then
rendered = '_if'
# Given
I = '_Reserved'

# and
template = '{{ I | id }}'

# then
rendered = '_reserved'
# Given
I = 'EMACRO_TOKEN'

# and
template = '{{ I | id("macro") }}'

# then
rendered = '_eMACRO_TOKEN'
Parameters:
  • instance (any) – Any object or data that either has a name property or can be converted to a string.
  • id_type (str) – A type of identifier. For C this value can be ‘typedef’, ‘macro’, ‘function’, or ‘enum’. use ‘any’ to apply stropping rules for all identifier types to the instance.
Returns:

A token that is a valid identifier for C, is not a reserved keyword, and is transformed in a deterministic manner based on the provided instance.

nunavut.lang.c.filter_macrofy(language: nunavut.lang.c.Language, value: str) → str[source]

Filter to transform an input into a valid C preprocessor identifier token.

# Given
template = '#ifndef {{ "my full name" | macrofy }}'

# then
rendered = '#ifndef MY_FULL_NAME'

Note that individual tokens are not stropped so the appearance of an identifier in the SCREAMING_SNAKE_CASE output my be different then the token as it appears on its own. For example:

# "register" is reserved so it will be stropped if it appears as an
# identifier...
template = '''#ifndef {{ "namespaced.Type.register" | macrofy }}
{{ "register" | id }}
'''

# ...but it will not be stropped within the macro.
rendered = '''#ifndef NAMESPACED_TYPE_REGISTER
_register
'''

If stropping is enabled, however, the entire token generated by this filter will be stropped:

# Given
template = '#ifndef {{ "_starts_with_underscore" | macrofy }}'

# then
rendered = '#ifndef _sTARTS_WITH_UNDERSCORE'

And again with stropping disabled:

# Given
template = '#ifndef {{ "_starts_with_underscore" | macrofy }}'

# then with stropping disabled
rendered = '#ifndef _STARTS_WITH_UNDERSCORE'
Parameters:value (str) – The value to transform.
Returns:A valid C preprocessor identifier token.
nunavut.lang.c.filter_type_from_primitive(language: nunavut.lang.c.Language, value: pydsdl._serializable._primitive.PrimitiveType) → str[source]

Filter to transform a pydsdl PrimitiveType into a valid C type.

# Given
template = '{{ unsigned_int_32_type | type_from_primitive }}'

# then
rendered = 'uint32_t'
# Given
template = '{{ int_64_type | type_from_primitive }}'

# then
rendered = 'int64_t'
Parameters:value (str) – The dsdl primitive to transform.
Returns:A valid C99 type name.
Raises:RuntimeError

If the primitive cannot be represented as a standard C type.

nunavut.lang.c.filter_to_snake_case(value: str) → str[source]

Filter to transform a string into a snake-case token.

# Given
template = '{{ "scotec.mcu.Timer" | to_snake_case }} a();'

# then
rendered = 'scotec_mcu_timer a();'
# Given
template = '{{ "scotec.mcu.TimerHelper" | to_snake_case }} b();'

# then
rendered = 'scotec_mcu_timer_helper b();'
# and Given
template = '{{ "SCOTEC_MCU_TimerHelper" | to_snake_case }} b();'

# then
rendered = 'scotec_mcu_timer_helper b();'
Parameters:value (str) – The string to transform into C snake-case.
Returns:A valid C99 token using the snake-case convention.
nunavut.lang.c.filter_to_screaming_snake_case(value: str) → str[source]

Filter to transform a string into a SCREAMING_SNAKE_CASE token.

# Given
template = '{{ "scotec.mcu.Timer" | to_screaming_snake_case }} a();'

# then
rendered = 'SCOTEC_MCU_TIMER a();'
nunavut.lang.c.filter_to_template_unique_name(_: Any, base_token: str) → str[source]

Filter that takes a base token and forms a name that is very likely to be unique within the template the filter is invoked. This name is also very likely to be a valid C identifier.

Important

The exact tokens generated may change between major or minor versions of this library. The only guarantee provided is that the tokens will be stable for the same version of this library given the same input.

Also note that name uniqueness is only likely within a given template. Between templates there is no guarantee of uniqueness and, since this library does not lex generated source, there is no guarantee that the generated name does not conflict with a name generated by another means.

# Given
template  = '{{ "foo" | to_template_unique_name }},{{ "Foo" | to_template_unique_name }},'
template += '{{ "fOO" | to_template_unique_name }}'

# then
rendered = '_foo0_,_foo1_,_fOO0_'
# Given
template = '{{ "i like coffee" | to_template_unique_name }}'

# then
rendered = '_i like coffee0_'
Parameters:base_token (str) – A token to include in the base name.
Returns:A name that is likely to be valid C identifier and is likely to be unique within the file generated by the current template.
nunavut.lang.c.filter_short_reference_name(language: nunavut.lang.c.Language, t: pydsdl._serializable._composite.CompositeType) → str[source]

Provides a string that is a shorted version of the full reference name.

# Given a type with illegal C characters
my_type.short_name = '_Foo'
my_type.version.major = 1
my_type.version.minor = 2

# and
template = '{{ my_type | short_reference_name }}'

# then, with stropping enabled
rendered = '_foo_1_2'

With stropping disabled:

rendered = '_Foo_1_2'
Parameters:t (pydsdl.CompositeType) – The DSDL type to get the reference name for.
nunavut.lang.c.filter_includes(language: nunavut.lang.c.Language, t: pydsdl._serializable._composite.CompositeType, sort: bool = True) → List[str][source]

Returns a list of all include paths for a given type.

# Listing the includes for a union with only integer types:
template = '''{% for include in my_type | includes -%}
{{include}}
{% endfor %}'''

# stdint.h will normally be generated
rendered = '''<stdint.h>
<stdlib.h>
'''
# You can suppress std includes by setting use_standard_types to False under
# nunavut.lang.c
rendered = ''
Parameters:
  • t (pydsdl.CompositeType) – The type to scan for dependencies.
  • sort (bool) – If true the returned list will be sorted.
Returns:

a list of include headers needed for a given type.

nunavut.lang.c.filter_to_static_assertion_value(obj: Any) → int[source]

Tries to convert a Python object into a value compatible with static comparisons in C. This allows stable comparison of static values in headers to promote consistency and version compatibility in generated code.

Will raise a ValueError if the object provided does not (yet) have an available conversion in this function.

Currently supported types are string:

 # given
template = '{{ "Any" | to_static_assertion_value }}'

# then
rendered = '1556001108'

int:

 # given
template = '{{ 123 | to_static_assertion_value }}'

# then
rendered = '123'

and bool:

 # given
template = '{{ True | to_static_assertion_value }}'

# then
rendered = '1'
nunavut.lang.c.filter_constant_value(language: nunavut.lang.c.Language, constant: pydsdl._serializable._attribute.Constant) → str[source]

Renders the specified constant as a literal. This is a shorthand for filter_literal().

 # given
template = '{{ my_true_constant | constant_value }}'

# then
rendered = 'true'

Language configuration can control the output of some constant tokens. For example, to use non-standard true and false values in c:

 # given
template = '{{ my_true_constant | constant_value }}'

# then, if true = 'NUNAVUT_TRUE' in the named_values for nunavut.lang.c
rendered = 'NUNAVUT_TRUE'

Floating point values are converted as fractions to ensure no python-specific transformations are applied:

 # given a float value using a fraction of 355/113
template = '{{ almost_pi | constant_value }}'

# ...the rendered value with include that fraction as a division statement.
rendered = '((float) (355.0 / 113.0))'
nunavut.lang.c.filter_literal(language: nunavut.lang.c.Language, value: Union[fractions.Fraction, bool, int], ty: pydsdl._expression._any.Any, cast_format: Optional[str] = None) → str[source]

Renders the specified value of the specified type as a literal.

nunavut.lang.c.filter_full_reference_name(language: nunavut.lang.c.Language, t: pydsdl._serializable._composite.CompositeType) → str[source]

Provides a string that is the full namespace, typename, major, and minor version for a given composite type.

# Given a type with illegal characters for C++
my_obj.full_name = 'any.int.2Foo'
my_obj.full_namespace = 'any.int'
my_obj.version.major = 1
my_obj.version.minor = 2

# and
template = '{{ my_obj | full_reference_name }}'

# then, with stropping enabled
rendered = 'any_int_2Foo_1_2'
Parameters:t (pydsdl.CompositeType) – The DSDL type to get the fully-resolved reference name for.
nunavut.lang.c.filter_to_standard_bit_length(t: pydsdl._serializable._primitive.PrimitiveType) → int[source]

Returns the nearest standard bit length of a type as an int.

# Given
I = pydsdl.UnsignedIntegerType(7, pydsdl.PrimitiveType.CastMode.TRUNCATED)

# and
template = '{{ I | to_standard_bit_length }}'

# then
rendered = '8'
nunavut.lang.c.is_zero_cost_primitive(language: nunavut.lang.c.Language, t: pydsdl._serializable._primitive.PrimitiveType) → bool[source]

Assuming that the target platform is IEEE754-conformant detects whether the native in-memory representation of a value of the supplied primitive type is the same as its on-the-wire representation defined by the DSDL Specification.

For instance; all little-endian, IEEE754-conformant platforms have compatible in-memory representations of int8, int16, int32, int64, uint8, uint16, uint32, uint64, float32, float64. Values of other primitive types typically require some transformations (e.g., float16).

It follows that arrays, certain composite types, and some other entities composed of zero-cost composites are also zero-cost types, but such non-trivial conjectures are not recognized by this function.

Raises a TypeError if the argument is not a value of type pydsdl.PrimitiveType.

# Given
i7  = pydsdl.SignedIntegerType(7, pydsdl.PrimitiveType.CastMode.SATURATED)
u32 = pydsdl.UnsignedIntegerType(32, pydsdl.PrimitiveType.CastMode.TRUNCATED)
f16 = pydsdl.FloatType(16, pydsdl.PrimitiveType.CastMode.TRUNCATED)
f32 = pydsdl.FloatType(32, pydsdl.PrimitiveType.CastMode.SATURATED)
bl = pydsdl.BooleanType(pydsdl.PrimitiveType.CastMode.SATURATED)

# and
template = (
    '{{ i7  is zero_cost_primitive }} '
    '{{ u32 is zero_cost_primitive }} '
    '{{ f16 is zero_cost_primitive }} '
    '{{ f32 is zero_cost_primitive }} '
    '{{ bl is zero_cost_primitive }}'
)

# then
rendered = 'False True False True False'
nunavut.lang.c.filter_is_zero_cost_primitive(language: nunavut.lang.c.Language, t: pydsdl._serializable._primitive.PrimitiveType) → str[source]

Deprecated as a filter. Please use test version.