Exemplo n.º 1
0
    def get_c_function(self):
        template1A = r"""// Callback function for {packet_comment} callback
"""
        template1B = r"""{override_comment}
"""
        template2 = r"""static void {packet_under}_handler(TF_{device_camel} *device, {parameters}void *user_data) {{
	{unuseds}

{printfs}{extra_message}
}}
"""
        override_comment = self.get_formatted_override_comment(
            '// {0}', None, '\n// ')

        if override_comment == None:
            template1 = template1A
        else:
            template1 = template1B

        parameters = []
        unuseds = ['(void)device;']
        printfs = []

        for parameter in self.get_parameters():
            parameters.append(parameter.get_c_source())
            unuseds += parameter.get_c_unuseds()
            printfs += parameter.get_c_printfs()

        while None in unuseds:
            unuseds.remove(None)

        unuseds.append('(void)user_data;')

        unuseds = common.wrap_non_empty('', '<BP>'.join(unuseds),
                                        ' // avoid unused parameter warning')
        unuseds = common.break_string(unuseds, '').replace('\n', '\n\t')

        while None in printfs:
            printfs.remove(None)

        if len(printfs) > 1:
            printfs.append('\ttf_hal_printf("\\n");')

        extra_message = self.get_formatted_extra_message(
            '\ttf_hal_printf("{0}\\n");').replace('%', '%%')

        if len(extra_message) > 0 and len(printfs) > 0:
            extra_message = '\n' + extra_message

        result = format(template1, None, self, override_comment=override_comment) + \
                 format(template2, self.get_device(), self,
                        parameters=common.wrap_non_empty('', ',<BP>'.join(parameters), ',<BP>'),
                        unuseds=unuseds,
                        printfs='\n'.join(printfs).replace('\r\n\r', '\n\n').strip('\r').replace('\r', '\n'),
                        extra_message=extra_message)

        return common.break_string(result,
                                   '{}_handler('.format(self.get_name().under))
Exemplo n.º 2
0
 def specializer(packet, high_level):
     if packet.get_type() == 'callback':
         return format(
             ':c:func:`{packet_space} <tf_{device_under}_register_{packet_under}_callback>`',
             packet.get_device(), packet, 0)
     else:
         return format(':c:func:`tf_{device_under}_{packet_under}`',
                       packet.get_device(), packet,
                       -2 if high_level else 0)
Exemplo n.º 3
0
    def get_c_source(self):
        template = r"""	// Configure threshold for {packet_comment} "{option_comment}"{declarations}
	tf_{device_under}_set_{packet_under}_callback_threshold(&{device_initial}{arguments}, '{option_char}', {minimum_maximums});
"""
        minimum_maximums = []

        for minimum_maximum in self.get_minimum_maximums():
            minimum_maximums.append(minimum_maximum.get_c_source())

        arg_declarations, arguments = self.get_c_arguments()
        declarations = common.wrap_non_empty(
            '\n', '\n'.join([
                '{global_line_prefix}\t{decl}'.format(
                    global_line_prefix=global_line_prefix, decl=decl)
                for decl in arg_declarations
            ]), '')

        return format(template,
                      self.get_device(),
                      self,
                      declarations=declarations,
                      arguments=common.wrap_non_empty(', ',
                                                      ', '.join(arguments),
                                                      ''),
                      option_char=self.get_option_char(),
                      option_comment=self.get_option_comment(),
                      minimum_maximums=', '.join(minimum_maximums))
Exemplo n.º 4
0
    def get_c_source(self):
        global global_line_prefix

        type_ = self.get_type()

        if type_ == 'empty':
            return ''
        elif type_ == 'debounce_period':
            template = r"""	// Get threshold callbacks with a debounce time of {period_sec} ({period_msec}ms)
	tf_{device_under}_set_debounce_period(&{device_initial}, {period_msec});
"""
            period_msec, period_sec = self.get_formatted_debounce_period()

            return format(template, self.get_device(),
                          period_msec=period_msec,
                          period_sec=period_sec)
        elif type_ == 'sleep':
            template = '{comment1}{global_line_prefix}\ttf_hal_sleep_us(hal, {duration} * 1000);{comment2}\n'

            return template.format(global_line_prefix=global_line_prefix,
                                   duration=self.get_sleep_duration(),
                                   comment1=self.get_formatted_sleep_comment1(global_line_prefix + '\t// {0}\n', '\r', '\n' + global_line_prefix + '\t// '),
                                   comment2=self.get_formatted_sleep_comment2(' // {0}', ''))
        elif type_ == 'wait':
            return None
        elif type_ == 'loop_header':
            template = '{comment}\tint i;\n\tfor(i = 0; i < {limit}; ++i) {{\n'
            global_line_prefix = '\t'

            return template.format(limit=self.get_loop_header_limit(),
                                   comment=self.get_formatted_loop_header_comment('\t// {0}\n', '', '\n\t// '))
        elif type_ == 'loop_footer':
            global_line_prefix = ''

            return '\r\t}\n'
Exemplo n.º 5
0
    def get_c_source(self):
        template = '{comment1}{declarations}{global_line_prefix}\tcheck(tf_{device_under}_{packet_under}(&{device_initial}{arguments}), "call {packet_under}");{comment2}\n'

        arg_declarations, arguments = self.get_c_arguments()
        declarations = common.wrap_non_empty(
            '', '\n'.join([
                '{global_line_prefix}\t{decl}'.format(
                    global_line_prefix=global_line_prefix, decl=decl)
                for decl in arg_declarations
            ]), '\n')

        result = format(template,
                        self.get_device(),
                        self,
                        global_line_prefix=global_line_prefix,
                        declarations=declarations,
                        arguments=common.wrap_non_empty(
                            ',<BP>', ',<BP>'.join(arguments), ''),
                        comment1=self.get_formatted_comment1(
                            global_line_prefix + '\t// {0}\n', '\r',
                            '\n' + global_line_prefix + '\t// '),
                        comment2=self.get_formatted_comment2(' // {0}', ''))

        return common.break_string(result,
                                   '_{}('.format(self.get_name().under))
Exemplo n.º 6
0
    def get_c_source(self):
        templateA = r"""	// Set period for {packet_comment} callback to {period_sec_short} ({period_msec}ms){declarations}
	check(tf_{device_under}_set_{packet_under}_period(&{device_initial}{arguments}, {period_msec}), "set {packet_comment} period");
"""
        templateB = r"""	// Set period for {packet_comment} callback to {period_sec_short} ({period_msec}ms)
	// Note: The {packet_comment} callback is only called every {period_sec_long}
	//       if the {packet_comment} has changed since the last call!{declarations}
	check(tf_{device_under}_set_{packet_under}_callback_period(&{device_initial}{arguments}, {period_msec}), "set {packet_comment} callback period");
"""

        if self.get_device().get_name().space.startswith('IMU'):
            template = templateA # FIXME: special hack for IMU Brick (2.0) callback behavior and name mismatch
        else:
            template = templateB

        period_msec, period_sec_short, period_sec_long = self.get_formatted_period()

        arg_declarations, arguments = self.get_c_arguments()
        declarations = common.wrap_non_empty('\n', '\n'.join(['{global_line_prefix}\t{decl}'.format(global_line_prefix=global_line_prefix, decl=decl) for decl in arg_declarations]), '')

        return format(template, self.get_device(), self,
                      declarations=declarations,
                      arguments=common.wrap_non_empty(', ', ', '.join(arguments), ''),
                      period_msec=period_msec,
                      period_sec_short=period_sec_short,
                      period_sec_long=period_sec_long)
Exemplo n.º 7
0
    def get_c_source(self):
        template = 'TF_{device_upper}_{constant_group_upper}_{constant_upper}'

        return format(
            template,
            self.get_device(),
            constant_group_upper=self.get_constant_group().get_name().upper,
            constant_upper=self.get_name().upper)
Exemplo n.º 8
0
    def get_c_source(self):
        template = r"""	// Register {packet_comment}<BP>callback<BP>to<BP>function<BP>{packet_under}_handler
	tf_{device_under}_register_{packet_under}_callback(&{device_initial},
	{spaces}{packet_under}_handler,
	{spaces}NULL);
"""

        result = format(template, self.get_device(), self,
                        spaces=' ' * (len(self.get_device().get_name().under) + len(self.get_name().under) + 23))

        return common.break_string(result, '// ', indent_tail='// ')
Exemplo n.º 9
0
    def get_c_source(self):
        template = r"""{global_line_prefix}	// Get current {packet_comment}
{global_line_prefix}{variable_declarations};
{global_line_prefix}	check(tf_{device_under}_{packet_under}(&{device_initial}{arguments}{variable_references}), "get {packet_comment}");

{printfs}
"""
        variable_declarations = []
        variable_references = []
        printfs = []

        for result in self.get_results():
            variable_declarations.append(result.get_c_variable_declaration())
            variable_references.append(result.get_c_variable_reference())
            printfs += result.get_c_printfs()

        arg_declarations, arguments = self.get_c_arguments()
        variable_declarations += arg_declarations

        merged_variable_declarations = []

        for variable_declaration in variable_declarations:
            merged = False

            for merged_variable_declaration in merged_variable_declarations:
                if merged_variable_declaration[0] == variable_declaration[0]:
                    merged_variable_declaration[1].append(variable_declaration[1])
                    merged = True
                    break

            if not merged:
                merged_variable_declarations.append([variable_declaration[0], [variable_declaration[1]]])

        variable_declarations = []

        for merged_variable_declaration in merged_variable_declarations:
            variable_declarations.append('{0} {1}'.format(merged_variable_declaration[0],
                                                          ',<BP>'.join(merged_variable_declaration[1])))

        variable_declarations = common.break_string('\t' + ';<BP>'.join(variable_declarations),
                                                    merged_variable_declarations[0][0] + ' ')
        variable_declarations = re.sub(';\n\t([ ]+)', ';\n\t', variable_declarations, flags=re.MULTILINE)

        while None in printfs:
            printfs.remove(None)

        result = format(template, self.get_device(), self,
                        global_line_prefix=global_line_prefix,
                        variable_declarations=variable_declarations,
                        variable_references=',<BP>' + ',<BP>'.join(variable_references),
                        printfs='\n'.join(printfs).replace('\r\n\r', '\n\n').strip('\r').replace('\r', '\n'),
                        arguments=common.wrap_non_empty(',<BP>', ',<BP>'.join(arguments), ''))

        return common.break_string(result, '_{}('.format(self.get_name().under))
Exemplo n.º 10
0
    def get_c_functions(self, type_):
        functions = []
        template = '.. c:function:: int tf_{device_under}_{packet_under}({params})\n\n{meta_table}{desc}\n'

        for packet in self.get_packets('function'):
            if packet.get_doc_type() != type_:
                continue

            if packet.get_name().under == 'get_api_version':
                continue

            skip = -2 if packet.has_high_level() else 0
            plist = common.wrap_non_empty(
                ', ', packet.get_c_parameters(high_level=True), '')

            meta = packet.get_formatted_element_meta(
                lambda element, cardinality=None: element.get_c_type(
                    'meta', cardinality=cardinality),
                lambda element, index=None: element.get_c_name(index=index),
                output_parameter='always',
                prefix_elements=[
                    (self.get_name().under,
                     'TF_' + self.get_name().camel + ' *', 1, 'in')
                ],
                suffix_elements=[('e_code', 'int', 1, 'return')],
                stream_length_suffix='_length',
                high_level=True)

            functions.append(
                format(template,
                       self,
                       packet,
                       skip,
                       params=format(
                           'TF_{device_camel} *{device_under}{plist}',
                           self,
                           plist=plist),
                       meta_table=common.make_rst_meta_table(meta),
                       desc=packet.get_c_formatted_doc()))

        return ''.join(functions)
Exemplo n.º 11
0
    def get_c_callbacks(self):
        callbacks = []
        template = '.. c:function:: void tf_{device_under}_register_{packet_under}_callback(TF_{device_camel} *{device_under}, TF_{device_camel}{packet_camel}Handler, void *user_data)\n{params}\n{meta_table}\n{desc}\n'
        param_template = {
            'en': """
 .. code-block:: c

  void handler({0})
""",
            'de': """
 .. code-block:: c

  void handler({0})
"""
        }

        for packet in self.get_packets('callback'):
            plist = format('TF_{device_camel} *{device_under}, ',
                           self) + common.wrap_non_empty(
                               '', packet.get_c_parameters(),
                               ', ') + 'void *user_data'

            meta = packet.get_formatted_element_meta(
                lambda element, cardinality=None: element.get_c_type(
                    'meta', cardinality=cardinality),
                lambda element, index=None: element.get_c_name(index=index),
                prefix_elements=[(format('{device_under}', self),
                                  format('TF_{device_camel} *',
                                         self), 1, 'out')],
                suffix_elements=[('user_data', 'void *', 1, 'out')],
                stream_length_suffix='_length')

            callbacks.append(
                format(template,
                       self,
                       packet,
                       params=common.select_lang(param_template).format(plist),
                       meta_table=common.make_rst_meta_table(meta),
                       desc=packet.get_c_formatted_doc()))

        return ''.join(callbacks)
Exemplo n.º 12
0
    def get_c_source(self):
        templateA = r"""	// Set period for {packet_comment} callback to {period_sec_short} ({period_msec}ms){declarations}
	tf_{device_under}_set_{packet_under}_callback_configuration(&{device_initial}{arguments}, {period_msec}{value_has_to_change});
"""
        templateB = r"""	// Set period for {packet_comment} callback to {period_sec_short} ({period_msec}ms) without a threshold{declarations}
	tf_{device_under}_set_{packet_under}_callback_configuration(&{device_initial}{arguments}, {period_msec}{value_has_to_change}, '{option_char}', {minimum_maximums});
"""
        templateC = r"""	// Configure threshold for {packet_comment} "{option_comment}"
	// with a debounce period of {period_sec_short} ({period_msec}ms){declarations}
	tf_{device_under}_set_{packet_under}_callback_configuration(&{device_initial}{arguments}, {period_msec}{value_has_to_change}, '{option_char}', {minimum_maximums});
"""

        if self.get_option_char() == None:
            template = templateA
        elif self.get_option_char() == 'x':
            template = templateB
        else:
            template = templateC

        minimum_maximums = []

        period_msec, period_sec_short, period_sec_long = self.get_formatted_period(
        )

        for minimum_maximum in self.get_minimum_maximums():
            minimum_maximums.append(minimum_maximum.get_c_source())

        arg_declarations, arguments = self.get_c_arguments()
        declarations = common.wrap_non_empty(
            '\n', '\n'.join([
                '{global_line_prefix}\t{decl}'.format(
                    global_line_prefix=global_line_prefix, decl=decl)
                for decl in arg_declarations
            ]), '')

        return format(template,
                      self.get_device(),
                      self,
                      declarations=declarations,
                      arguments=common.wrap_non_empty(', ',
                                                      ', '.join(arguments),
                                                      ''),
                      period_msec=period_msec,
                      period_sec_short=period_sec_short,
                      value_has_to_change=common.wrap_non_empty(
                          ', ',
                          self.get_value_has_to_change('true', 'false', ''),
                          ''),
                      option_char=self.get_option_char(),
                      option_comment=self.get_option_comment(),
                      minimum_maximums=', '.join(minimum_maximums))
Exemplo n.º 13
0
    def get_c_api(self):
        create_str = {
            'en':
            """
.. c:function:: int tf_{device_under}_create(TF_{device_camel} *{device_under}, const char *uid, TF_HalContext *hal)

{meta_table}

 Creates the device object ``{device_under}`` with the unique device ID ``uid`` and adds
 it to the HAL context ``hal``:

 .. code-block:: c

    TF_{device_camel} {device_under};
    tf_{device_under}_create(&{device_under}, "YOUR_DEVICE_UID", &hal);

 This device object can be used after the HAL has been initialized.
""",
            'de':
            """
.. c:function:: int tf_{device_under}_create(TF_{device_camel} *{device_under}, const char *uid, TF_HalContext *hal)

{meta_table}

 Erzeugt ein Geräteobjekt ``{device_under}`` mit der eindeutigen Geräte ID ``uid`` und
 fügt es dem HAL-Context ``hal`` hinzu:

 .. code-block:: c

    TF_{device_camel} {device_under};
    tf_{device_under}_create(&{device_under}, "YOUR_DEVICE_UID", &ipcon);

 Dieses Geräteobjekt kann benutzt werden, nachdem der HAL initialisiert wurde.
"""
        }

        destroy_str = {
            'en':
            """
.. c:function:: int tf_{device_under}_destroy(TF_{device_camel} *{device_under})

{meta_table}

 Removes the device object ``{device_under}`` from its HAL context and destroys it.
 The device object cannot be used anymore afterwards.
""",
            'de':
            """
.. c:function:: int tf_{device_under}_destroy(TF_{device_camel} *{device_under})

{meta_table}

 Entfernt das Geräteobjekt ``{device_under}`` von dessen HAL-Context und zerstört es.
 Das Geräteobjekt kann hiernach nicht mehr verwendet werden.
"""
        }

        c_str = {
            'en':
            """
.. _{device_doc_rst_ref}_uc_callbacks:

Callbacks
^^^^^^^^^

Callbacks can be registered to receive time critical or recurring data from the
device. The registration is done with the corresponding ``tf_{device_under}_register_*_callback`` function.
The ``user_data``  passed to the registration function as well as the device that triggered the callback are
passed to the registered callback handler.

Only one handler can be registered to a callback at the same time.
To deregister a callback, call the ``tf_{device_under}_register_*_callback`` function
with NULL as handler.

.. note::
 Using callbacks for recurring events is preferred
 compared to using getters. Polling for a callback requires
 writing one byte only. See here :ref:`api_bindings_uc_performance`.

.. warning::
 Calling bindings function from inside a callback handler is not allowed.
 See here :ref:`api_bindings_uc_thread_safety`.

{callbacks}
""",
            'de':
            """
.. _{device_doc_rst_ref}_uc_callbacks:

Callbacks
^^^^^^^^^

Callbacks können registriert werden um zeitkritische oder wiederkehrende Daten
vom Gerät zu erhalten. Die Registrierung kann mit der entsprechenden ``tf_{device_under}_register_*_callback``
Funktion durchgeführt werden. Die ``user_data``, sowie das Gerät, dass das Callback ausgelöst hat, werden
dem registrierten Callback-Handler übergeben.

Nur ein Handler kann gleichzeitig auf das selbe Callback registriert werden.
Um einen Handler zu deregistrieren, kann die ``tf_{device_under}_register_*_callback``-Funktion
mit ``NULL`` als Handler aufgerufen werden.

.. note::
 Callbacks für wiederkehrende Ereignisse zu verwenden ist
 gegenüber der Verwendung von Abfragen zu bevorzugen.
 Es muss nur ein Byte abgefragt werden um zu prüfen ob ein Callback
 vorliegt. Siehe hier :ref:`api_bindings_uc_performance`.

.. warning::
 Aus Callback-Handlern heraus können keine Bindings-Funktionen verwendet werden.
 Siehe hier :ref:`api_bindings_uc_callbacks`.

{callbacks}
"""
        }

        api = {
            'en':
            """
.. _{device_doc_rst_ref}_uc_api:

API
---

Most functions of the C/C++ bindings for microcontrollers return an error code
(``e_code``).

Possible error codes are:

* TF\_\ **E**\\ _OK = 0
* TF\_\ **E**\\ _TIMEOUT = -1
* TF\_\ **E**\\ _INVALID_PARAMETER = -2
* TF\_\ **E**\\ _NOT_SUPPORTED = -3
* TF\_\ **E**\\ _UNKNOWN_ERROR_CODE = -4
* TF\_\ **E**\\ _STREAM_OUT_OF_SYNC = -5
* TF\_\ **E**\\ _INVALID_CHAR_IN_UID = -6
* TF\_\ **E**\\ _UID_TOO_LONG = -7
* TF\_\ **E**\\ _UID_OVERFLOW = -8
* TF\_\ **E**\\ _TOO_MANY_DEVICES = -9
* TF\_\ **E**\\ _DEVICE_NOT_FOUND = -10
* TF\_\ **E**\\ _WRONG_DEVICE_TYPE = -11
* TF\_\ **E**\\ _LOCKED = -12
* TF\_\ **E**\\ _PORT_NOT_FOUND = -13

(as defined in :file:`errors.h`) as well as the errors returned from
the hardware abstraction layer (HAL) that is used.

Use :cpp:func`tf_hal_strerror` (defined in the HAL's header file) to get
an error string for an error code.

Data returned from the device, when a getter is called,
is handled via output parameters. These parameters are labeled with the
``ret_`` prefix. The bindings will not write to an output parameter if NULL or nullptr
is passed. This can be used to ignore outputs that you are not interested in.

**None of the functions listed below are thread-safe.**
See the :ref:`API bindings description <api_bindings_uc>` for details.

{doc_str}

{api_str}
""",
            'de':
            """
.. _{device_doc_rst_ref}_uc_api:

API
---

Die meistens Funktionen der C/C++ Bindings für Mikrocontroller geben einen
Fehlercode (``e_code``) zurück

Mögliche Fehlercodes sind:

* TF\_\ **E**\\ _OK = 0
* TF\_\ **E**\\ _TIMEOUT = -1
* TF\_\ **E**\\ _INVALID_PARAMETER = -2
* TF\_\ **E**\\ _NOT_SUPPORTED = -3
* TF\_\ **E**\\ _UNKNOWN_ERROR_CODE = -4
* TF\_\ **E**\\ _STREAM_OUT_OF_SYNC = -5
* TF\_\ **E**\\ _INVALID_CHAR_IN_UID = -6
* TF\_\ **E**\\ _UID_TOO_LONG = -7
* TF\_\ **E**\\ _UID_OVERFLOW = -8
* TF\_\ **E**\\ _TOO_MANY_DEVICES = -9
* TF\_\ **E**\\ _DEVICE_NOT_FOUND = -10
* TF\_\ **E**\\ _WRONG_DEVICE_TYPE = -11
* TF\_\ **E**\\ _CALLBACK_EXEC = -12
* TF\_\ **E**\\ _PORT_NOT_FOUND = -13

(wie in :file:`errors.h` definiert), sowie die Fehlercodes des verwendeten
Hardware-Abstraction-Layers (HALs). Mit ``tf_hal_strerror`` (im Header das HALs definiert)
kann ein Fehlerstring zu einem Fehlercode abgefragt werden.

Vom Gerät zurückgegebene Daten werden, wenn eine
Abfrage aufgerufen wurde, über Ausgabeparameter gehandhabt. Diese Parameter
sind mit dem ``ret_`` Präfix gekennzeichnet. Die Bindings schreiben einen
Ausgabeparameter nicht, wenn NULL bzw. nullptr übergeben wird. So können
uninteressante Ausgaben ignoriert werden.

**Keine der folgend aufgelisteten Funktionen ist Thread-sicher.**
Details finden sich in der :ref:`Beschreibung der API-Bindings <api_bindings_uc>`.

{doc_str}

{api_str}
"""
        }

        const_str = {
            'en':
            """
.. _{device_doc_rst_ref}_uc_constants:

Constants
^^^^^^^^^

.. c:var:: TF_{device_upper}_DEVICE_IDENTIFIER

 This constant is used to identify a {device_display}.

 The functions :c:func:`tf_{device_under}_get_identity` and :c:func:`tf_hal_get_device_info`
 have a ``device_identifier`` output parameter to specify
 the Brick's or Bricklet's type.

.. c:var:: TF_{device_upper}_DEVICE_DISPLAY_NAME

 This constant represents the human readable name of a {device_display}.
""",
            'de':
            """
.. _{device_doc_rst_ref}_uc_constants:

Konstanten
^^^^^^^^^^

.. c:var:: TF_{device_upper}_DEVICE_IDENTIFIER

 Diese Konstante wird verwendet um {article} {device_display} zu identifizieren.

 Die Funktionen :c:func:`tf_{device_under}_get_identity` und :c:func:`tf_hal_get_device_info`
 haben einen ``device_identifier`` Ausgabe-Parameter um den Typ
 des Bricks oder Bricklets anzugeben.

.. c:var:: TF_{device_upper}_DEVICE_DISPLAY_NAME

 Diese Konstante stellt den Anzeigenamen eines {device_display} dar.
"""
        }

        create_meta = common.format_simple_element_meta([
            (format('{device_under}', self), format('TF_{device_camel} *',
                                                    self), 1, 'in'),
            ('uid', 'const char *', 1, 'in'),
            ('hal', 'TF_HalContext *', 1, 'in')
        ])
        create_meta_table = common.make_rst_meta_table(create_meta)

        cre = format(common.select_lang(create_str),
                     self,
                     meta_table=create_meta_table)

        destroy_meta = common.format_simple_element_meta([
            (format('{device_under}', self), format('TF_{device_camel} *',
                                                    self), 1, 'in')
        ])
        destroy_meta_table = common.make_rst_meta_table(destroy_meta)

        des = format(common.select_lang(destroy_str),
                     self,
                     meta_table=destroy_meta_table)

        bf = self.get_c_functions('bf')
        af = self.get_c_functions('af')
        ccf = self.get_c_functions('ccf')
        c = self.get_c_callbacks()
        vf = self.get_c_functions('vf')
        if_ = self.get_c_functions('if')
        api_str = ''

        if bf:
            api_str += common.select_lang(common.bf_str).format(cre + des, bf)

        if af:
            api_str += common.select_lang(common.af_str).format(af)

        if c:
            api_str += common.select_lang(common.ccf_str).format('', ccf)
            api_str += format(common.select_lang(c_str),
                              self,
                              device_doc_rst_ref=self.get_doc_rst_ref_name(),
                              callbacks=c,
                              padding=' ' * len(self.get_name().under))

        if vf:
            api_str += common.select_lang(common.vf_str).format(vf)

        if if_:
            api_str += common.select_lang(common.if_str).format(if_)

        article = 'ein'

        if self.is_brick():
            article = 'einen'

        api_str += format(common.select_lang(const_str),
                          self,
                          device_doc_rst_ref=self.get_doc_rst_ref_name(),
                          article=article)

        return format(common.select_lang(api),
                      self,
                      device_doc_rst_ref=self.get_doc_rst_ref_name(),
                      doc_str=self.specialize_c_doc_function_links(
                          common.select_lang(self.get_doc())),
                      api_str=api_str)
Exemplo n.º 14
0
    def get_c_source(self):
        template = r"""// This example is not self-contained.
// It requres usage of the example driver specific to your platform.
// See the HAL documentation.

{defines}{includes}{incomplete}{description}

#define UID "{dummy_uid}" // Change {dummy_uid} to the UID of your {device_display}

void check(int rc, const char* msg);

void example_setup(TF_HalContext *hal);
void example_loop(TF_HalContext *hal);

{functions}
static TF_{device_camel} {device_initial};

void example_setup(TF_HalContext *hal) {{
	// Create device object
	check(tf_{device_under}_create(&{device_initial}, UID, hal), "create device object");
{sources}}}

void example_loop(TF_HalContext *hal) {{
	// Poll for callbacks
	tf_hal_callback_tick(hal, 0);
}}
"""

        if self.is_incomplete():
            incomplete = '\n\n// FIXME: This example is incomplete'
        else:
            incomplete = ''

        if self.get_description() != None:
            description = '\n\n// {0}'.format(self.get_description().replace(
                '\n', '\n// '))
        else:
            description = ''

        defines = []
        includes = []
        functions = []
        sources = []
        cleanups = []

        for function in self.get_functions():
            defines += function.get_c_defines()
            includes += function.get_c_includes()
            functions.append(function.get_c_function())
            sources.append(function.get_c_source())

        for cleanup in self.get_cleanups():
            defines += cleanup.get_c_defines()
            includes += cleanup.get_c_includes()
            functions.append(cleanup.get_c_function())
            cleanups.append(cleanup.get_c_source())

        if len(includes) > 0:
            includes += ['']

        includes += [
            '#include "bindings/hal_common.h"',
            format('#include "bindings/{category_under}_{device_under}.h"',
                   self.get_device())
        ]

        unique_includes = []

        for include in includes:
            if include not in unique_includes:
                unique_includes.append(include)

        unique_defines = []

        for define in defines:
            if define not in unique_defines:
                unique_defines.append(define)

        while None in functions:
            functions.remove(None)

        while None in sources:
            sources.remove(None)

        if len(sources) == 0:
            sources = ['\t// TODO: Add example code here\n']

        while None in cleanups:
            cleanups.remove(None)

        return format(
            template,
            self.get_device(),
            defines=common.wrap_non_empty('', '\n'.join(unique_defines),
                                          '\n\n'),
            includes=common.wrap_non_empty('', '\n'.join(unique_includes), ''),
            incomplete=incomplete,
            description=description,
            dummy_uid=self.get_dummy_uid(),
            functions=common.wrap_non_empty('\n', '\n'.join(functions), ''),
            sources='\n' + '\n'.join(sources).replace('\n\r', '').lstrip('\r'))