_CCodeGenerator.generate_header(): use Jinja 2 templates
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Thu, 27 Aug 2020 19:51:52 +0000 (15:51 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Fri, 28 Aug 2020 14:44:19 +0000 (10:44 -0400)
This patch makes _CCodeGenerator.generate_header() generate the main
barectf header file using Jinja 2 templates.

The master template, `barectf.h.j2`, includes:

`c-common.j2`:
    Common macros for C templates.

`c-ctx-init-func-proto.j2`:
    Context initialization function prototype.

`c-open-func-proto.j2`:
    Packet opening function prototype.

`c-close-func-proto.j2`:
    Packet closing function prototype.

`c-trace-func-proto.j2`:
    Tracing function prototype.

This patch removes a lot of code from `gen.py` and `templates.py` which
now has its equivalent in Jinja 2 templates.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
barectf/gen.py
barectf/templates.py
barectf/templates/barectf.h.j2 [new file with mode: 0644]
barectf/templates/c-close-func-proto.j2 [new file with mode: 0644]
barectf/templates/c-common.j2 [new file with mode: 0644]
barectf/templates/c-ctx-init-func-proto.j2 [new file with mode: 0644]
barectf/templates/c-open-func-proto.j2 [new file with mode: 0644]
barectf/templates/c-trace-func-proto.j2 [new file with mode: 0644]
barectf/templates/common.j2
barectf/templates/metadata.j2

index fb413cb9318d602177cdd013902c5c5b25335484..4745f54ad8f00804c6c05d95fdb7f02218f4edcd 100644 (file)
@@ -74,7 +74,6 @@ class CodeGenerator:
 
     def generate_c_sources(self):
         if self._c_sources is None:
-            bitfield_header_name = f'{self._file_name_prefix}-bitfield.h'
             self._c_sources = [
                 _GeneratedFile(f'{self._file_name_prefix}.c',
                                self._ccode_gen.generate_c_src(self._barectf_header_name,
@@ -207,19 +206,22 @@ class _SerializationActions:
         self._actions.append(_SerializeSerializationAction(offset_in_byte, ft, self._names))
 
 
-_PREFIX_TPH = 'tph_'
-_PREFIX_SPC = 'spc_'
-_PREFIX_SEH = 'seh_'
-_PREFIX_SEC = 'sec_'
-_PREFIX_EC = 'ec_'
-_PREFIX_EP = 'ep_'
-_PREFIX_TO_NAME = {
-    _PREFIX_TPH: 'trace packet header',
-    _PREFIX_SPC: 'stream packet context',
-    _PREFIX_SEH: 'stream event header',
-    _PREFIX_SEC: 'stream event context',
-    _PREFIX_EC: 'event context',
-    _PREFIX_EP: 'event payload',
+class _RootFtPrefixes:
+    TPH = 'tph_'
+    SPC = 'spc_'
+    SEH = 'seh_'
+    SEC = 'sec_'
+    EC = 'ec_'
+    EP = 'ep_'
+
+
+_ROOT_FT_PREFIX_TO_NAME = {
+    _RootFtPrefixes.TPH: 'trace packet header',
+    _RootFtPrefixes.SPC: 'stream packet context',
+    _RootFtPrefixes.SEH: 'stream event header',
+    _RootFtPrefixes.SEC: 'stream event context',
+    _RootFtPrefixes.EC: 'event context',
+    _RootFtPrefixes.EP: 'event payload',
 }
 
 
@@ -231,11 +233,17 @@ class _CCodeGenerator:
         self._cg = barectf_codegen._CodeGenerator('\t')
         self._saved_serialization_actions = {}
 
+    @property
+    def _template_filters(self):
+        return {
+            'ft_c_type': self._get_ft_c_type,
+        }
+
     def _create_template(self, name: str) -> barectf_template._Template:
-        return barectf_template._Template(name, cfg=self._cfg)
+        return barectf_template._Template(name, False, self._cfg, self._template_filters)
 
     def _create_file_template(self, name: str) -> barectf_template._Template:
-        return barectf_template._Template(name, True, self._cfg)
+        return barectf_template._Template(name, True, self._cfg, self._template_filters)
 
     @property
     def _trace_type(self):
@@ -244,58 +252,6 @@ class _CCodeGenerator:
     def _clk_type_c_type(self, clk_type):
         return self._cfg.options.code_generation_options.clock_type_c_types[clk_type]
 
-    def _generate_ctx_parent(self):
-        tmpl = barectf_templates._CTX_PARENT
-        self._cg.add_lines(tmpl.format(prefix=self._iden_prefix))
-
-    def _generate_ctx(self, stream_type):
-        tmpl = barectf_templates._CTX_BEGIN
-        self._cg.add_lines(tmpl.format(prefix=self._iden_prefix, sname=stream_type.name))
-        self._cg.indent()
-        pkt_header_ft = self._trace_type._pkt_header_ft
-
-        if pkt_header_ft is not None:
-            for member_name in pkt_header_ft.members:
-                self._cg.add_lines(f'uint32_t off_tph_{member_name};')
-
-        for member_name in stream_type._pkt_ctx_ft.members:
-            self._cg.add_lines(f'uint32_t off_spc_{member_name};')
-
-        if stream_type.default_clock_type is not None:
-            self._cg.add_line(f'{self._clk_type_c_type(stream_type.default_clock_type)} cur_last_event_ts;')
-
-        self._cg.unindent()
-        tmpl = barectf_templates._CTX_END
-        self._cg.add_lines(tmpl)
-
-    def _generate_ctxs(self):
-        for stream_type in self._trace_type.stream_types:
-            self._generate_ctx(stream_type)
-
-    def _generate_clock_cb(self, clk_type):
-        tmpl = barectf_templates._CLOCK_CB
-        self._cg.add_lines(tmpl.format(return_ctype=self._clk_type_c_type(clk_type),
-                                       cname=clk_type.name))
-
-    def _generate_clock_cbs(self):
-        clk_names = set()
-
-        for stream_type in self._trace_type.stream_types:
-            def_clk_type = stream_type.default_clock_type
-
-            if def_clk_type is not None and def_clk_type not in clk_names:
-                self._generate_clock_cb(def_clk_type)
-                clk_names.add(def_clk_type)
-
-    def _generate_platform_callbacks(self):
-        tmpl = barectf_templates._PLATFORM_CALLBACKS_BEGIN
-        self._cg.add_lines(tmpl.format(prefix=self._iden_prefix))
-        self._cg.indent()
-        self._generate_clock_cbs()
-        self._cg.unindent()
-        tmpl = barectf_templates._PLATFORM_CALLBACKS_END
-        self._cg.add_lines(tmpl)
-
     def generate_bitfield_header(self):
         return self._create_file_template('bitfield.h.j2').render()
 
@@ -359,7 +315,7 @@ class _CCodeGenerator:
         self._cg.add_lines(tmpl.format(prefix=self._iden_prefix, sname=stream_type.name))
 
         if self._trace_type._pkt_header_ft is not None:
-            self._generate_proto_params(self._trace_type._pkt_header_ft, _PREFIX_TPH,
+            self._generate_proto_params(self._trace_type._pkt_header_ft, _RootFtPrefixes.TPH,
                                         {'magic', 'stream_id', 'uuid'})
 
         exclude_set = {
@@ -369,7 +325,7 @@ class _CCodeGenerator:
             'content_size',
             'events_discarded',
         }
-        self._generate_proto_params(stream_type._pkt_ctx_ft, _PREFIX_SPC, exclude_set)
+        self._generate_proto_params(stream_type._pkt_ctx_ft, _RootFtPrefixes.SPC, exclude_set)
         tmpl = barectf_templates._FUNC_OPEN_PROTO_END
         self._cg.add_lines(tmpl)
 
@@ -379,16 +335,18 @@ class _CCodeGenerator:
 
     def _generate_func_trace_proto_params(self, stream_type, ev_type):
         if stream_type._ev_header_ft is not None:
-            self._generate_proto_params(stream_type._ev_header_ft, _PREFIX_SEH, {'id', 'timestamp'})
+            self._generate_proto_params(stream_type._ev_header_ft,
+                                        _RootFtPrefixes.SEH, {'id', 'timestamp'})
 
         if stream_type.event_common_context_field_type is not None:
-            self._generate_proto_params(stream_type.event_common_context_field_type, _PREFIX_SEC)
+            self._generate_proto_params(stream_type.event_common_context_field_type,
+                                        _RootFtPrefixes.SEC)
 
         if ev_type.specific_context_field_type is not None:
-            self._generate_proto_params(ev_type.specific_context_field_type, _PREFIX_EC)
+            self._generate_proto_params(ev_type.specific_context_field_type, _RootFtPrefixes.EC)
 
         if ev_type.payload_field_type is not None:
-            self._generate_proto_params(ev_type.payload_field_type, _PREFIX_EP)
+            self._generate_proto_params(ev_type.payload_field_type, _RootFtPrefixes.EP)
 
     def _generate_func_trace_proto(self, stream_type, ev_type):
         tmpl = barectf_templates._FUNC_TRACE_PROTO_BEGIN
@@ -398,80 +356,8 @@ class _CCodeGenerator:
         tmpl = barectf_templates._FUNC_TRACE_PROTO_END
         self._cg.add_lines(tmpl)
 
-    def _punctuate_proto(self):
-        self._cg.append_to_last_line(';')
-
     def generate_header(self):
-        self._cg.reset()
-        dt = datetime.datetime.now().isoformat()
-        prefix_def = ''
-        def_stream_type_name_def = ''
-        cg_opts = self._cfg.options.code_generation_options
-        header_opts = cg_opts.header_options
-
-        if header_opts.identifier_prefix_definition:
-            prefix_def = f'#define _BARECTF_PREFIX {self._iden_prefix}'
-
-        def_stream_type = cg_opts.default_stream_type
-
-        if header_opts.default_stream_type_name_definition and def_stream_type is not None:
-            def_stream_type_name_def = f'#define _BARECTF_DEFAULT_STREAM {def_stream_type.name}'
-
-        def_stream_type_trace_defs = ''
-
-        if def_stream_type is not None:
-            lines = []
-
-            for ev_type in def_stream_type.event_types:
-                tmpl = barectf_templates._DEFINE_DEFAULT_STREAM_TRACE
-                define = tmpl.format(prefix=self._iden_prefix, sname=def_stream_type.name,
-                                     evname=ev_type.name)
-                lines.append(define)
-
-            def_stream_type_trace_defs = '\n'.join(lines)
-
-        tmpl = barectf_templates._HEADER_BEGIN
-        self._cg.add_lines(tmpl.format(prefix=self._iden_prefix,
-                                       ucprefix=self._iden_prefix.upper(),
-                                       version=barectf_version.__version__, date=dt,
-                                       prefix_def=prefix_def,
-                                       default_stream_def=def_stream_type_name_def,
-                                       default_stream_trace_defs=def_stream_type_trace_defs))
-        self._cg.add_empty_line()
-
-        # platform callbacks structure
-        self._generate_platform_callbacks()
-        self._cg.add_empty_line()
-
-        # context parent
-        self._generate_ctx_parent()
-        self._cg.add_empty_line()
-
-        # stream contexts
-        self._generate_ctxs()
-        self._cg.add_empty_line()
-
-        # initialization function prototype
-        self._generate_func_init_proto()
-        self._punctuate_proto()
-        self._cg.add_empty_line()
-
-        for stream_type in self._trace_type.stream_types:
-            self._generate_func_open_proto(stream_type)
-            self._punctuate_proto()
-            self._cg.add_empty_line()
-            self._generate_func_close_proto(stream_type)
-            self._punctuate_proto()
-            self._cg.add_empty_line()
-
-            for ev_type in stream_type.event_types:
-                self._generate_func_trace_proto(stream_type, ev_type)
-                self._punctuate_proto()
-                self._cg.add_empty_line()
-
-        tmpl = barectf_templates._HEADER_END
-        self._cg.add_lines(tmpl.format(ucprefix=self._iden_prefix.upper()))
-        return self._cg.code
+        return self._create_file_template('barectf.h.j2').render(root_ft_prefixes=_RootFtPrefixes)
 
     def _get_call_event_param_list_from_struct_ft(self, ft, prefix, exclude_set=None):
         if exclude_set is None:
@@ -492,19 +378,19 @@ class _CCodeGenerator:
 
         if stream_type._ev_header_ft is not None:
             lst += self._get_call_event_param_list_from_struct_ft(stream_type._ev_header_ft,
-                                                                  _PREFIX_SEH, {'id', 'timestamp'})
+                                                                  _RootFtPrefixes.SEH, {'id', 'timestamp'})
 
         if stream_type.event_common_context_field_type is not None:
             lst += self._get_call_event_param_list_from_struct_ft(stream_type.event_common_context_field_type,
-                                                                  _PREFIX_SEC)
+                                                                  _RootFtPrefixes.SEC)
 
         if ev_type.specific_context_field_type is not None:
             lst += self._get_call_event_param_list_from_struct_ft(ev_type.specific_context_field_type,
-                                                                  _PREFIX_EC)
+                                                                  _RootFtPrefixes.EC)
 
         if ev_type.payload_field_type is not None:
             lst += self._get_call_event_param_list_from_struct_ft(ev_type.payload_field_type,
-                                                                  _PREFIX_EP)
+                                                                  _RootFtPrefixes.EP)
 
         return lst
 
@@ -533,18 +419,19 @@ class _CCodeGenerator:
         self._cg.add_empty_line()
         self._cg.indent()
         ser_actions = _SerializationActions()
-        ser_actions.append_root_scope_ft(stream_type._ev_header_ft, _PREFIX_SEH)
-        ser_actions.append_root_scope_ft(stream_type.event_common_context_field_type, _PREFIX_SEC)
-        ser_actions.append_root_scope_ft(ev_type.specific_context_field_type, _PREFIX_EC)
-        ser_actions.append_root_scope_ft(ev_type.payload_field_type, _PREFIX_EP)
+        ser_actions.append_root_scope_ft(stream_type._ev_header_ft, _RootFtPrefixes.SEH)
+        ser_actions.append_root_scope_ft(stream_type.event_common_context_field_type,
+                                         _RootFtPrefixes.SEC)
+        ser_actions.append_root_scope_ft(ev_type.specific_context_field_type, _RootFtPrefixes.EC)
+        ser_actions.append_root_scope_ft(ev_type.payload_field_type, _RootFtPrefixes.EP)
 
         for action in ser_actions.actions:
             if type(action) is _AlignSerializationAction:
                 if action.names:
                     if len(action.names) == 1:
-                        line = f'align {_PREFIX_TO_NAME[action.names[0]]} structure'
+                        line = f'align {_ROOT_FT_PREFIX_TO_NAME[action.names[0]]} structure'
                     else:
-                        line = f'align field `{action.names[-1]}` ({_PREFIX_TO_NAME[action.names[0]]})'
+                        line = f'align field `{action.names[-1]}` ({_ROOT_FT_PREFIX_TO_NAME[action.names[0]]})'
 
                     self._cg.add_cc_line(line)
 
@@ -553,7 +440,7 @@ class _CCodeGenerator:
             else:
                 assert type(action) is _SerializeSerializationAction
                 assert(len(action.names) >= 2)
-                line = f'add size of field `{action.names[-1]}` ({_PREFIX_TO_NAME[action.names[0]]})'
+                line = f'add size of field `{action.names[-1]}` ({_ROOT_FT_PREFIX_TO_NAME[action.names[0]]})'
                 self._cg.add_cc_line(line)
 
                 if type(action.ft) is barectf_config.StringFieldType:
@@ -642,9 +529,9 @@ class _CCodeGenerator:
             if type(action) is _AlignSerializationAction:
                 if action.names:
                     if len(action.names) == 1:
-                        line = f'align {_PREFIX_TO_NAME[action.names[0]]} structure'
+                        line = f'align {_ROOT_FT_PREFIX_TO_NAME[action.names[0]]} structure'
                     else:
-                        line = f'align field `{action.names[-1]}` ({_PREFIX_TO_NAME[action.names[0]]})'
+                        line = f'align field `{action.names[-1]}` ({_ROOT_FT_PREFIX_TO_NAME[action.names[0]]})'
 
                     self._cg.add_cc_line(line)
 
@@ -654,7 +541,7 @@ class _CCodeGenerator:
                 assert type(action) is _SerializeSerializationAction
                 assert(len(action.names) >= 2)
                 member_name = action.names[-1]
-                line = f'serialize field `{member_name}` ({_PREFIX_TO_NAME[action.names[0]]})'
+                line = f'serialize field `{member_name}` ({_ROOT_FT_PREFIX_TO_NAME[action.names[0]]})'
                 self._cg.add_cc_line(line)
                 src = prefix + member_name
 
@@ -674,7 +561,7 @@ class _CCodeGenerator:
 
         if stream_type._ev_header_ft is not None:
             params = self._get_call_event_param_list_from_struct_ft(stream_type._ev_header_ft,
-                                                                    _PREFIX_SEH,
+                                                                    _RootFtPrefixes.SEH,
                                                                     {'timestamp', 'id'})
             self._cg.add_cc_line('stream event header')
             line = f'_serialize_stream_event_header_{stream_type.name}(ctx, {ev_type.id}{params});'
@@ -683,7 +570,7 @@ class _CCodeGenerator:
 
         if stream_type.event_common_context_field_type is not None:
             params = self._get_call_event_param_list_from_struct_ft(stream_type.event_common_context_field_type,
-                                                                    _PREFIX_SEC)
+                                                                    _RootFtPrefixes.SEC)
             self._cg.add_cc_line('stream event context')
             line = f'_serialize_stream_event_context_{stream_type.name}(ctx{params});'
             self._cg.add_line(line)
@@ -694,15 +581,15 @@ class _CCodeGenerator:
 
         if ev_type.specific_context_field_type is not None:
             ser_action_index = len(ser_actions.actions)
-            ser_actions.append_root_scope_ft(ev_type.specific_context_field_type, _PREFIX_EC)
+            ser_actions.append_root_scope_ft(ev_type.specific_context_field_type, _RootFtPrefixes.EC)
             ser_action_iter = itertools.islice(ser_actions.actions, ser_action_index, None)
-            self._generate_serialize_statements_from_actions(_PREFIX_EC, ser_action_iter)
+            self._generate_serialize_statements_from_actions(_RootFtPrefixes.EC, ser_action_iter)
 
         if ev_type.payload_field_type is not None:
             ser_action_index = len(ser_actions.actions)
-            ser_actions.append_root_scope_ft(ev_type.payload_field_type, _PREFIX_EP)
+            ser_actions.append_root_scope_ft(ev_type.payload_field_type, _RootFtPrefixes.EP)
             ser_action_iter = itertools.islice(ser_actions.actions, ser_action_index, None)
-            self._generate_serialize_statements_from_actions(_PREFIX_EP, ser_action_iter)
+            self._generate_serialize_statements_from_actions(_RootFtPrefixes.EP, ser_action_iter)
 
         self._cg.unindent()
         tmpl = barectf_templates._FUNC_SERIALIZE_EVENT_BODY_END
@@ -713,7 +600,7 @@ class _CCodeGenerator:
         self._cg.add_lines(tmpl.format(prefix=self._iden_prefix, sname=stream_type.name))
 
         if stream_type._ev_header_ft is not None:
-            self._generate_proto_params(stream_type._ev_header_ft, _PREFIX_SEH,
+            self._generate_proto_params(stream_type._ev_header_ft, _RootFtPrefixes.SEH,
                                         {'id', 'timestamp'})
 
         tmpl = barectf_templates._FUNC_SERIALIZE_STREAM_EVENT_HEADER_PROTO_END
@@ -724,7 +611,7 @@ class _CCodeGenerator:
         self._cg.add_lines(tmpl.format(prefix=self._iden_prefix, sname=stream_type.name))
 
         if stream_type.event_common_context_field_type is not None:
-            self._generate_proto_params(stream_type.event_common_context_field_type, _PREFIX_SEC)
+            self._generate_proto_params(stream_type.event_common_context_field_type, _RootFtPrefixes.SEC)
 
         tmpl = barectf_templates._FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_PROTO_END
         self._cg.add_lines(tmpl)
@@ -758,7 +645,7 @@ class _CCodeGenerator:
             if member is not None:
                 spec_src[member_name] = f'({self._get_ft_c_type(member.field_type)}) ts'
 
-            self._generate_serialize_statements_from_actions(_PREFIX_SEH, ser_action_iter,
+            self._generate_serialize_statements_from_actions(_RootFtPrefixes.SEH, ser_action_iter,
                                                              spec_src)
 
         self._cg.unindent()
@@ -773,7 +660,7 @@ class _CCodeGenerator:
         self._cg.indent()
 
         if stream_type.event_common_context_field_type is not None:
-            self._generate_serialize_statements_from_actions(_PREFIX_SEC, ser_action_iter)
+            self._generate_serialize_statements_from_actions(_RootFtPrefixes.SEC, ser_action_iter)
 
         self._cg.unindent()
         tmpl = barectf_templates._FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_BODY_END
@@ -842,7 +729,7 @@ class _CCodeGenerator:
             self._cg.add_cc_line('trace packet header')
             self._cg.add_line('{')
             self._cg.indent()
-            ser_actions.append_root_scope_ft(pkt_header_ft, _PREFIX_TPH)
+            ser_actions.append_root_scope_ft(pkt_header_ft, _RootFtPrefixes.TPH)
 
             for action in ser_actions.actions:
                 if type(action) is _AlignSerializationAction:
@@ -862,7 +749,7 @@ class _CCodeGenerator:
                     member_name = action.names[-1]
                     line = f'serialize field `{member_name}`'
                     self._cg.add_cc_line(line)
-                    src = _PREFIX_TPH + member_name
+                    src = _RootFtPrefixes.TPH + member_name
 
                     if member_name == 'magic':
                         src = '0xc1fc1fc1UL'
@@ -900,7 +787,7 @@ class _CCodeGenerator:
         self._cg.add_cc_line('stream packet context')
         self._cg.add_line('{')
         self._cg.indent()
-        ser_actions.append_root_scope_ft(pkt_ctx_ft, _PREFIX_SPC)
+        ser_actions.append_root_scope_ft(pkt_ctx_ft, _RootFtPrefixes.SPC)
 
         for action in itertools.islice(ser_actions.actions, spc_action_index, None):
             if type(action) is _AlignSerializationAction:
@@ -920,7 +807,7 @@ class _CCodeGenerator:
                 member_name = action.names[-1]
                 line = f'serialize field `{member_name}`'
                 self._cg.add_cc_line(line)
-                src = _PREFIX_SPC + member_name
+                src = _RootFtPrefixes.SPC + member_name
                 skip_int = False
 
                 if member_name == 'timestamp_begin':
@@ -1025,14 +912,14 @@ class _CCodeGenerator:
             ser_actions = _SerializationActions()
 
             if stream_type._ev_header_ft is not None:
-                ser_actions.append_root_scope_ft(stream_type._ev_header_ft, _PREFIX_SEH)
+                ser_actions.append_root_scope_ft(stream_type._ev_header_ft, _RootFtPrefixes.SEH)
                 self._generate_func_serialize_event_header(stream_type, iter(ser_actions.actions))
                 self._cg.add_empty_line()
 
             if stream_type.event_common_context_field_type is not None:
                 ser_action_index = len(ser_actions.actions)
                 ser_actions.append_root_scope_ft(stream_type.event_common_context_field_type,
-                                                 _PREFIX_SEC)
+                                                 _RootFtPrefixes.SEC)
                 ser_action_iter = itertools.islice(ser_actions.actions, ser_action_index, None)
                 self._generate_func_serialize_event_common_context(stream_type, ser_action_iter)
                 self._cg.add_empty_line()
index 8b38f184cecb34d2a5e334950d9d7aa66ff7e30b..047b7b42e68d232af608efe6c275ce0a2d25dcf0 100644 (file)
 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-_CLOCK_CB = '{return_ctype} (*{cname}_clock_get_value)(void *);'
-
-
-_PLATFORM_CALLBACKS_BEGIN = '''/* barectf platform callbacks */
-struct {prefix}platform_callbacks {{
-       /* clock callbacks */'''
-
-
-_PLATFORM_CALLBACKS_END = '''
-       /* is back-end full? */
-       int (*is_backend_full)(void *);
-
-       /* open packet */
-       void (*open_packet)(void *);
-
-       /* close packet */
-       void (*close_packet)(void *);
-};'''
-
-
-_CTX_PARENT = '''/* common barectf context */
-struct {prefix}ctx {{
-       /* platform callbacks */
-       struct {prefix}platform_callbacks cbs;
-
-       /* platform data (passed to callbacks) */
-       void *data;
-
-       /* output buffer (will contain a CTF binary packet) */
-       uint8_t *buf;
-
-       /* packet size in bits */
-       uint32_t packet_size;
-
-       /* content size in bits */
-       uint32_t content_size;
-
-       /* current position from beginning of packet in bits */
-       uint32_t at;
-
-       /* packet header + context size (content offset) */
-       uint32_t off_content;
-
-       /* events discarded */
-       uint32_t events_discarded;
-
-       /* current packet is opened */
-       int packet_is_open;
-
-       /* in tracing code */
-       volatile int in_tracing_section;
-
-       /* tracing is enabled */
-       volatile int is_tracing_enabled;
-
-       /* use current/last event timestamp when opening/closing packets */
-       int use_cur_last_event_ts;
-}};'''
-
-
-_CTX_BEGIN = '''/* context for stream `{sname}` */
-struct {prefix}{sname}_ctx {{
-       /* parent */
-       struct {prefix}ctx parent;
-
-       /* config-specific members follow */'''
-
-
-_CTX_END = '};'
-
-
 _FUNC_INIT_PROTO = '''/* initialize context */
 void {prefix}init(
        void *vctx,
@@ -211,9 +140,6 @@ _FUNC_CLOSE_BODY_END = '''
 }'''
 
 
-_DEFINE_DEFAULT_STREAM_TRACE = '#define {prefix}trace_{evname} {prefix}{sname}_trace_{evname}'
-
-
 _FUNC_TRACE_PROTO_BEGIN = '''/* trace (stream `{sname}`, event `{evname}`) */
 void {prefix}{sname}_trace_{evname}(
        struct {prefix}{sname}_ctx *ctx'''
@@ -315,77 +241,6 @@ _FUNC_SERIALIZE_EVENT_BODY_BEGIN = '''{{
 _FUNC_SERIALIZE_EVENT_BODY_END = '}'
 
 
-_HEADER_BEGIN = '''#ifndef _{ucprefix}H
-#define _{ucprefix}H
-
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2015-2020 Philippe Proulx <pproulx@efficios.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- *
- * The following C code was generated by barectf {version}
- * on {date}.
- *
- * For more details, see <http://barectf.org>.
- */
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {{
-#endif
-
-{prefix_def}
-{default_stream_def}
-
-{default_stream_trace_defs}
-
-struct {prefix}ctx;
-
-uint32_t {prefix}packet_size(void *ctx);
-int {prefix}packet_is_full(void *ctx);
-int {prefix}packet_is_empty(void *ctx);
-uint32_t {prefix}packet_events_discarded(void *ctx);
-uint8_t *{prefix}packet_buf(void *ctx);
-void {prefix}packet_set_buf(void *ctx, uint8_t *buf, uint32_t buf_size);
-uint32_t {prefix}packet_buf_size(void *ctx);
-int {prefix}packet_is_open(void *ctx);
-int {prefix}is_in_tracing_section(void *ctx);
-volatile const int *{prefix}is_in_tracing_section_ptr(void *ctx);
-int {prefix}is_tracing_enabled(void *ctx);
-void {prefix}enable_tracing(void *ctx, int enable);'''
-
-
-_HEADER_END = '''#ifdef __cplusplus
-}}
-#endif
-
-#endif /* _{ucprefix}H */
-'''
-
-
 _C_SRC = '''/*
  * The MIT License (MIT)
  *
diff --git a/barectf/templates/barectf.h.j2 b/barectf/templates/barectf.h.j2
new file mode 100644 (file)
index 0000000..f19b74d
--- /dev/null
@@ -0,0 +1,175 @@
+{% import 'common.j2' as common %}
+{% import 'c-common.j2' as c_common %}
+{% set prefix = common.prefix %}
+{% set ucprefix = common.ucprefix %}
+{% set trace_type = cfg.trace.type %}
+{% set cg_opts = cfg.options.code_generation_options %}
+{% set def_stream_type = cg_opts.default_stream_type %}
+{% set header_opts = cg_opts.header_options %}
+#ifndef _{{ ucprefix }}H
+#define _{{ ucprefix }}H
+
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015-2020 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ *
+ * The following C code was generated by barectf v{{ barectf_version.__version__ }}
+ * on {{ common.gen_date }}.
+ *
+ * For more details, see <https://barectf.org/>.
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+{% if header_opts.identifier_prefix_definition %}
+#define _BARECTF_PREFIX {{ prefix }}
+{% endif %}
+{% if def_stream_type and header_opts.default_stream_type_name_definition %}
+#define _BARECTF_DEFAULT_STREAM {{ def_stream_type.name }}
+{% endif %}
+{% if def_stream_type %}
+
+{% for ev_type in def_stream_type.event_types | sort %}
+#define {{ prefix }}trace_{{ ev_type.name }} {{ c_common.trace_func_name(def_stream_type, ev_type) }}
+{% endfor %}
+{% endif %}
+
+struct {{ prefix }}ctx;
+
+uint32_t {{ prefix }}packet_size(void *ctx);
+int {{ prefix }}packet_is_full(void *ctx);
+int {{ prefix }}packet_is_empty(void *ctx);
+uint32_t {{ prefix }}packet_events_discarded(void *ctx);
+uint8_t *{{ prefix }}packet_buf(void *ctx);
+void {{ prefix }}packet_set_buf(void *ctx, uint8_t *buf, uint32_t buf_size);
+uint32_t {{ prefix }}packet_buf_size(void *ctx);
+int {{ prefix }}packet_is_open(void *ctx);
+int {{ prefix }}is_in_tracing_section(void *ctx);
+volatile const int *{{ prefix }}is_in_tracing_section_ptr(void *ctx);
+int {{ prefix }}is_tracing_enabled(void *ctx);
+void {{ prefix }}enable_tracing(void *ctx, int enable);
+
+/* barectf platform callbacks */
+struct {{ prefix }}platform_callbacks {
+{% set clk_types = trace_type.clock_types %}
+{% if clk_types %}
+       /* clock callbacks */
+{% for clk_type in clk_types | sort %}
+       {{ cg_opts.clock_type_c_types[clk_type] }} (*{{ clk_type.name }}_clock_get_value)(void *);
+{% endfor %}
+
+{% endif %}
+       /* is back-end full? */
+       int (*is_backend_full)(void *);
+
+       /* open packet */
+       void (*open_packet)(void *);
+
+       /* close packet */
+       void (*close_packet)(void *);
+};
+
+/* common barectf context */
+struct {{ prefix }}ctx {
+       /* platform callbacks */
+       struct {{ prefix }}platform_callbacks cbs;
+
+       /* platform data (passed to callbacks) */
+       void *data;
+
+       /* output buffer (will contain a CTF binary packet) */
+       uint8_t *buf;
+
+       /* packet's total size (bits) */
+       uint32_t packet_size;
+
+       /* packet's content size (bits) */
+       uint32_t content_size;
+
+       /* current position from beginning of packet (bits) */
+       uint32_t at;
+
+       /* size of packet header + context fields (content offset) */
+       uint32_t off_content;
+
+       /* discarded event counter */
+       uint32_t events_discarded;
+
+       /* current packet is open? */
+       int packet_is_open;
+
+       /* in tracing code? */
+       volatile int in_tracing_section;
+
+       /* tracing is enabled? */
+       volatile int is_tracing_enabled;
+
+       /* use current/last event time when opening/closing packets */
+       int use_cur_last_event_ts;
+};
+
+{% for stream_type in trace_type.stream_types | sort %}
+/* context for stream type `{{ stream_type.name }}` */
+struct {{ prefix }}{{ stream_type.name }}_ctx {
+       /* parent */
+       struct {{ prefix }}ctx parent;
+
+       /* config-specific members follow */
+{% if trace_type._pkt_header_ft %}
+{% for member_name in trace_type._pkt_header_ft.members %}
+       uint32_t off_tph_{{ member_name }};
+{% endfor %}
+{% endif %}
+{% for member_name in stream_type._pkt_ctx_ft.members %}
+       uint32_t off_spc_{{ member_name }};
+{% endfor %}
+{% if stream_type.default_clock_type %}
+       {{ cg_opts.clock_type_c_types[stream_type.default_clock_type] }} cur_last_event_ts;
+{% endif %}
+};
+
+{% endfor %}
+{% include 'c-ctx-init-func-proto.j2' %};
+
+{% for stream_type in trace_type.stream_types | sort %}
+{% include 'c-open-func-proto.j2' %};
+
+{% include 'c-close-func-proto.j2' %};
+{% for ev_type in stream_type.event_types | sort %}
+
+{% include 'c-trace-func-proto.j2' %};
+{% endfor %}
+{% endfor %}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _{{ ucprefix }}H */
diff --git a/barectf/templates/c-close-func-proto.j2 b/barectf/templates/c-close-func-proto.j2
new file mode 100644 (file)
index 0000000..848ad86
--- /dev/null
@@ -0,0 +1,2 @@
+/* close packet for stream type `{{ stream_type.name }}` */
+void {{ prefix }}{{ stream_type.name }}_close_packet(struct {{ prefix }}{{ stream_type.name }}_ctx *ctx)
diff --git a/barectf/templates/c-common.j2 b/barectf/templates/c-common.j2
new file mode 100644 (file)
index 0000000..9f79229
--- /dev/null
@@ -0,0 +1,42 @@
+{#
+ # Common variables and macros (for C templates).
+ #}
+
+{% import 'common.j2' as common %}
+
+{#
+ # Generates the name of a tracing function for the stream type
+ # `stream_type` and the event type `ev_type`.
+ #}
+{% macro trace_func_name(stream_type, ev_type) -%}
+{{ common.prefix }}{{ stream_type.name }}_trace_{{ ev_type.name }}
+{%- endmacro %}
+
+{#
+ # Generates the name of a single function parameter named `name` for
+ # the field type `ft`.
+ #}
+{% macro func_param(name, ft) -%}
+{{ ft | ft_c_type }} {{ name }}
+{%- endmacro %}
+
+{#
+ # Generates a list of parameters for the members of a given structure
+ # field type `struct_ft`.
+ #
+ # Each parameter has the prefix `name_prefix` and starts with an
+ # immediate comma followed with a newline and a tab. For example:
+ #
+ #     ,
+ #             const char * msg,
+ #             uint32_t msg_id
+ #
+ # This macro does not generate a parameter line for a member name which
+ # is part of `exclude_list`.
+ #}
+{% macro func_params(struct_ft, name_prefix, exclude_list) -%}
+{% for name, member in struct_ft.members.items() if name not in exclude_list -%}
+,
+       {{ func_param(name_prefix + name, member.field_type) }}
+{%- endfor %}
+{%- endmacro %}
diff --git a/barectf/templates/c-ctx-init-func-proto.j2 b/barectf/templates/c-ctx-init-func-proto.j2
new file mode 100644 (file)
index 0000000..225e2f1
--- /dev/null
@@ -0,0 +1,7 @@
+/* initialize context */
+void {{ prefix }}init(
+    void *vctx,
+    uint8_t *buf,
+    uint32_t buf_size,
+    struct {{ prefix }}platform_callbacks cbs,
+    void *data)
diff --git a/barectf/templates/c-open-func-proto.j2 b/barectf/templates/c-open-func-proto.j2
new file mode 100644 (file)
index 0000000..630707f
--- /dev/null
@@ -0,0 +1,16 @@
+{% set pkt_header_exclude_list = ['magic', 'stream_id', 'uuid'] %}
+{% set pkt_ctx_exclude_list = [
+       'timestamp_begin',
+       'timestamp_end',
+       'packet_size',
+       'content_size',
+       'events_discarded'
+] %}
+/* open packet for stream type `{{ stream_type.name }}` */
+void {{ prefix }}{{ stream_type.name }}_open_packet(
+       struct {{ prefix }}{{ stream_type.name }}_ctx *ctx
+       {%- if trace_type._pkt_header_ft -%}
+               {{ c_common.func_params(trace_type._pkt_header_ft,
+                       root_ft_prefixes.TPH, pkt_header_exclude_list) }}
+       {%- endif -%}
+    {{ c_common.func_params(stream_type._pkt_ctx_ft, root_ft_prefixes.SPC, pkt_ctx_exclude_list) }})
diff --git a/barectf/templates/c-trace-func-proto.j2 b/barectf/templates/c-trace-func-proto.j2
new file mode 100644 (file)
index 0000000..b1bc696
--- /dev/null
@@ -0,0 +1,18 @@
+{% set ev_header_exclude_list = ['id', 'timestamp'] %}
+/* trace (stream type `{{ stream_type.name }}`, event type `{{ ev_type.name }}`) */
+void {{ prefix }}{{ stream_type.name }}_trace_{{ ev_type.name }}(
+       struct {{ prefix }}{{ stream_type.name }}_ctx *ctx
+       {%- if stream_type._ev_header_ft -%}
+               {{ c_common.func_params(stream_type._ev_header_ft,
+                       root_ft_prefixes.SEH, ev_header_exclude_list) }}
+       {%- endif -%}
+       {%- if stream_type.event_common_context_field_type -%}
+               {{ c_common.func_params(stream_type.event_common_context_field_type,
+                       root_ft_prefixes.SEC, []) }}
+       {%- endif -%}
+       {%- if ev_type.specific_context_field_type -%}
+               {{ c_common.func_params(ev_type.specific_context_field_type, root_ft_prefixes.EC, []) }}
+       {%- endif -%}
+       {%- if ev_type.payload_field_type -%}
+               {{ c_common.func_params(ev_type.payload_field_type, root_ft_prefixes.EP, []) }}
+       {%- endif -%})
index c346ffa9136443949c2bf08d8aff5d30f0db7236..4a05f97ca0046ce7276a6b528d180f8d588300d5 100644 (file)
@@ -1,7 +1,10 @@
 {#
- # Common variables and macros.
+ # Common variables and macros (for any template).
  #}
 
 {# identifier prefix and its uppercase equivalent #}
 {% set prefix = cfg.options.code_generation_options.identifier_prefix %}
 {% set ucprefix = prefix | upper %}
+
+{# generation date #}
+{% set gen_date = cfg.trace.environment['barectf_gen_date'] %}
index ad46b626a88839e7964ce2f6bcb63f203a9bfec2..f3abe749476fe897b583e45b80c9ccfb7e32a930 100644 (file)
@@ -1,3 +1,4 @@
+{% import 'common.j2' as common %}
 /* CTF 1.8 */
 
 /*
@@ -26,7 +27,7 @@
  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  *
  * The following TSDL code was generated by barectf v{{ barectf_version.__version__ }}
- * on {{ cfg.trace.environment['barectf_gen_date'] }}.
+ * on {{ common.gen_date }}.
  *
  * For more details, see <https://barectf.org/>.
  */
This page took 0.035314 seconds and 4 git commands to generate.