Browse Source

Add types codegen

zvecr 4 years ago
parent
commit
53052228df
2 changed files with 96 additions and 30 deletions
  1. 56 12
      data/xap/xap_0.0.1.hjson
  2. 40 18
      lib/python/qmk/xap/gen_firmware/header_generator.py

+ 56 - 12
data/xap/xap_0.0.1.hjson

@@ -101,10 +101,6 @@
             '''
             A high-level area of functionality within XAP.
             '''
-        ID:
-            '''
-            A single octet / 8-bit byte.
-            '''
         Route:
             '''
             A sequence of _IDs_ describing the route to invoke a _handler_.
@@ -113,24 +109,72 @@
             '''
             A piece of code that is executed when a specific _route_ is received.
             '''
-        Token:
-            '''
-            A `u16` associated with a specific request as well as its corresponding response.
-            '''
         Response:
             '''
             The data sent back to the host during execution of a _handler_.
             '''
-        "Response Flags":
-            '''
-            An `u8` containing the status of the request.
-            '''
         Payload:
             '''
             Any received data appended to the _route_, which gets delivered to the _handler_ when received.
             '''
     }
 
+    types: {
+        identifier: {
+            name: ID
+            description: Subsystem/Route ID
+            type: u8
+        }
+
+        response_flags: {
+            name: Response Flags
+            description: Contains the status of the request
+            type: u8
+        }
+
+        token: {
+            name: Token
+            description: ID associated with a specific request as well as its corresponding response
+            type: u16
+        }
+
+        request_header: {
+            name: Request Header
+            description: asdf
+            type: struct
+            struct_members: [
+                {
+                    type: token
+                    name: token
+                },
+                {
+                    type: u8
+                    name: length
+                }
+            ]
+        }
+
+        response_header: {
+            name: Response Header
+            description: asdf
+            type: struct
+            struct_members: [
+                {
+                    type: token
+                    name: token
+                },
+                {
+                    type: response_flags
+                    name: flags
+                },
+                {
+                    type: u8
+                    name: length
+                }
+            ]
+        }
+    }
+
     response_flags: {
         define_prefix: XAP_RESPONSE_FLAG
         bits: {

+ 40 - 18
lib/python/qmk/xap/gen_firmware/header_generator.py

@@ -9,6 +9,24 @@ from qmk.constants import GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE
 from qmk.xap.common import latest_xap_defs, route_conditions
 
 
+def _get_c_type(xap_type):
+    if xap_type == 'bool':
+        return 'bool'
+    elif xap_type == 'u8':
+        return 'uint8_t'
+    elif xap_type == 'u16':
+        return 'uint16_t'
+    elif xap_type == 'u32':
+        return 'uint32_t'
+    elif xap_type == 'u64':
+        return 'uint64_t'
+    elif xap_type == 'struct':
+        return 'struct'
+    elif xap_type == 'string':
+        return 'const char *'
+    return 'unknown'
+
+
 def _append_route_defines(lines, container, container_id=None, route_stack=None):
     """Handles building the list of the XAP routes, combining parent and child names together, as well as the route number.
     """
@@ -105,25 +123,29 @@ def _append_types(lines, container):
 
     # Add special
     lines.append(f'#define {prefix}_FAILED 0x00')
+    lines.append('')
 
-    # TODO: define this in xap_*.hjson
-    lines.append(
-        '''
-typedef uint8_t  xap_identifier_t;
-typedef uint8_t  xap_response_flags_t;
-typedef uint16_t xap_token_t;
-
-typedef struct {
-    xap_token_t token;
-    uint8_t     length;
-} xap_request_header_t;
-
-typedef struct {
-    xap_token_t          token;
-    xap_response_flags_t flags;
-    uint8_t              length;
-} xap_response_header_t;'''
-    )
+    additional_types = {}
+    types = container.get('types', {})
+    for key, value in types.items():
+        data_type = _get_c_type(value['type'])
+        additional_types[key] = f'xap_{key}_t'
+
+    for key, value in types.items():
+        data_type = _get_c_type(value['type'])
+        if data_type == 'struct':
+            members = value['struct_members']
+
+            lines.append(f'typedef {data_type} {{')
+            for member in members:
+                member_name = member["name"]
+                member_type = _get_c_type(member["type"])
+                if member_type == 'unknown':
+                    member_type = additional_types[member["type"]]
+                lines.append(f'  {member_type} {member_name};')
+            lines.append(f'}} xap_{key}_t;')
+        else:
+            lines.append(f'typedef {data_type} xap_{key}_t;')
 
 
 def generate_header(output_file, keyboard):