def emit_sections(self, sfile): translations = { 'underscore': utils.build_underscore_name(self.name), 'no_prefix_underscore_upper': utils.build_underscore_name(self.name[4:]).upper(), 'camelcase': utils.build_camelcase_name(self.name), 'hyphened': utils.build_dashed_name(self.name) } template = ('<SECTION>\n' '<FILE>${hyphened}</FILE>\n' '<TITLE>${camelcase}</TITLE>\n' '${camelcase}\n' '<SUBSECTION Standard>\n' '${camelcase}Class\n' 'QMI_TYPE_${no_prefix_underscore_upper}\n' 'QMI_${no_prefix_underscore_upper}\n' 'QMI_${no_prefix_underscore_upper}_CLASS\n' 'QMI_IS_${no_prefix_underscore_upper}\n' 'QMI_IS_${no_prefix_underscore_upper}_CLASS\n' 'QMI_${no_prefix_underscore_upper}_GET_CLASS\n' '${underscore}_get_type\n' '</SECTION>\n' '\n') sfile.write(string.Template(template).substitute(translations))
def __init__(self, dictionary, struct_type_name, container_type): # Call the parent constructor Variable.__init__(self, dictionary) # The public format of the struct is built directly from the suggested # struct type name self.public_format = utils.build_camelcase_name(struct_type_name) self.private_format = self.public_format self.element_type = self.public_format self.container_type = container_type # Load members of this struct self.members = [] for member_dictionary in dictionary['contents']: member = {} member['name'] = utils.build_underscore_name( member_dictionary['name']) member['object'] = VariableFactory.create_variable( member_dictionary, struct_type_name + ' ' + member['name'], self.container_type) # Specify that the variable will be defined in the public header member['object'].flag_public() self.members.append(member) # We'll need to dispose if at least one of the members needs it for member in self.members: if member['object'].needs_dispose == True: self.needs_dispose = True
def emit(self, hfile, cfile): translations = { 'name' : self.name, 'camelcase' : utils.build_camelcase_name (self.fullname), 'underscore' : utils.build_underscore_name (self.fullname), 'static' : 'static ' if self.static else '' } auxfile = cfile if self.static else hfile if self.fields is None: template = ('\n' '/* Note: no fields in the ${name} container */\n') auxfile.write(string.Template(template).substitute(translations)) cfile.write(string.Template(template).substitute(translations)) return # Emit the container and field types # Emit field getter/setter if self.fields is not None: for field in self.fields: field.emit_types(auxfile, cfile) self.__emit_types(auxfile, cfile, translations) # Emit TLV enums self.__emit_tlv_ids_enum(cfile) # Emit fields if self.fields is not None: for field in self.fields: field.emit_getter(auxfile, cfile) if self.readonly == False: field.emit_setter(auxfile, cfile) # Emit the container core self.__emit_core(auxfile, cfile, translations)
def clear_func_name(self): # element public format might be a base type like 'gchar *' rather # than a structure name like QmiFooBar elt_name = self.array_element.public_format.replace('*', 'pointer') return utils.build_underscore_name(self.name) + \ '_' + \ utils.build_underscore_name_from_camelcase(utils.build_camelcase_name(elt_name))
def add_sections(self, sections): if self.fields is None: return translations = { 'name' : self.name, 'camelcase' : utils.build_camelcase_name (self.fullname), 'underscore' : utils.build_underscore_name (self.fullname), 'type_macro' : 'QMI_TYPE_' + utils.remove_prefix(utils.build_underscore_uppercase_name(self.fullname), 'QMI_') } # Standard template = ( '${underscore}_get_type\n' '${type_macro}\n') sections['standard'] += string.Template(template).substitute(translations) # Public types template = ( '${camelcase}\n') sections['public-types'] += string.Template(template).substitute(translations) # Public methods template = '<SUBSECTION ${camelcase}Methods>\n' if self.readonly == False: template += ( '${underscore}_new\n') template += ( '${underscore}_ref\n' '${underscore}_unref\n') sections['public-methods'] += string.Template(template).substitute(translations) for field in self.fields: field.add_sections(sections)
def __init__(self, dictionary, struct_type_name, container_type): # Call the parent constructor Variable.__init__(self, dictionary) # The public format of the struct is built directly from the suggested # struct type name self.public_format = utils.build_camelcase_name(struct_type_name) self.private_format = self.public_format self.container_type = container_type # Load members of this struct self.members = [] for member_dictionary in dictionary["contents"]: member = {} member["name"] = utils.build_underscore_name(member_dictionary["name"]) member["object"] = VariableFactory.create_variable( member_dictionary, struct_type_name + " " + member["name"], self.container_type ) self.members.append(member) # We'll need to dispose if at least one of the members needs it for member in self.members: if member["object"].needs_dispose == True: self.needs_dispose = True
def emit_sections(self, sfile, message_list): # Do nothing if no supported messages if len(message_list.indication_list) == 0 and len( message_list.request_list) == 0: return translations = { 'underscore': utils.build_underscore_name(self.name), 'no_prefix_underscore_upper': utils.build_underscore_name(self.name[4:]).upper(), 'camelcase': utils.build_camelcase_name(self.name), 'hyphened': utils.build_dashed_name(self.name) } template = ('<SECTION>\n' '<FILE>${hyphened}</FILE>\n' '<TITLE>${camelcase}</TITLE>\n' '${camelcase}\n' '<SUBSECTION Standard>\n' '${camelcase}Class\n' 'QMI_TYPE_${no_prefix_underscore_upper}\n' 'QMI_${no_prefix_underscore_upper}\n' 'QMI_${no_prefix_underscore_upper}_CLASS\n' 'QMI_IS_${no_prefix_underscore_upper}\n' 'QMI_IS_${no_prefix_underscore_upper}_CLASS\n' 'QMI_${no_prefix_underscore_upper}_GET_CLASS\n' '${underscore}_get_type\n' '</SECTION>\n' '\n') sfile.write(string.Template(template).substitute(translations))
def emit_getter(self, hfile, cfile): input_variable_name = utils.build_underscore_name(self.name) variable_getter_dec = self.variable.build_getter_declaration(' ', input_variable_name) variable_getter_doc = self.variable.build_getter_documentation(' * ', input_variable_name) variable_getter_imp = self.variable.build_getter_implementation(' ', 'self->' + self.variable_name, input_variable_name, True) translations = { 'name' : self.name, 'variable_name' : self.variable_name, 'variable_getter_dec' : variable_getter_dec, 'variable_getter_doc' : variable_getter_doc, 'variable_getter_imp' : variable_getter_imp, 'underscore' : utils.build_underscore_name(self.name), 'prefix_camelcase' : utils.build_camelcase_name(self.prefix), 'prefix_underscore' : utils.build_underscore_name(self.prefix), 'static' : 'static ' if self.static else '' } # Emit the getter header template = ( '\n' '${static}gboolean ${prefix_underscore}_get_${underscore} (\n' ' ${prefix_camelcase} *self,\n' '${variable_getter_dec}' ' GError **error);\n') hfile.write(string.Template(template).substitute(translations)) # Emit the getter source template = ( '\n' '/**\n' ' * ${prefix_underscore}_get_${underscore}:\n' ' * @self: a #${prefix_camelcase}.\n' '${variable_getter_doc}' ' * @error: Return location for error or %NULL.\n' ' *\n' ' * Get the \'${name}\' field from @self.\n' ' *\n' ' * Returns: %TRUE if the field is found, %FALSE otherwise.\n' ' */\n' '${static}gboolean\n' '${prefix_underscore}_get_${underscore} (\n' ' ${prefix_camelcase} *self,\n' '${variable_getter_dec}' ' GError **error)\n' '{\n' ' g_return_val_if_fail (self != NULL, FALSE);\n' '\n' ' if (!self->${variable_name}_set) {\n' ' g_set_error (error,\n' ' QMI_CORE_ERROR,\n' ' QMI_CORE_ERROR_TLV_NOT_FOUND,\n' ' "Field \'${name}\' was not found in the message");\n' ' return FALSE;\n' ' }\n' '\n' '${variable_getter_imp}' '\n' ' return TRUE;\n' '}\n') cfile.write(string.Template(template).substitute(translations))
def emit_setter(self, hfile, cfile): input_variable_name = 'value_' + utils.build_underscore_name(self.name) variable_setter_dec = self.variable.build_setter_declaration( ' ', input_variable_name) variable_setter_doc = self.variable.build_setter_documentation( ' * ', input_variable_name) variable_setter_imp = self.variable.build_setter_implementation( ' ', input_variable_name, 'self->' + self.variable_name) translations = { 'name': self.name, 'variable_name': self.variable_name, 'variable_setter_dec': variable_setter_dec, 'variable_setter_doc': variable_setter_doc, 'variable_setter_imp': variable_setter_imp, 'underscore': utils.build_underscore_name(self.name), 'prefix_camelcase': utils.build_camelcase_name(self.prefix), 'prefix_underscore': utils.build_underscore_name(self.prefix), 'since': self.since, 'static': 'static ' if self.static else '' } # Emit the setter header template = ( '\n' '/**\n' ' * ${prefix_underscore}_set_${underscore}:\n' ' * @self: a #${prefix_camelcase}.\n' '${variable_setter_doc}' ' * @error: Return location for error or %NULL.\n' ' *\n' ' * Set the \'${name}\' field in the message.\n' ' *\n' ' * Returns: %TRUE if @value was successfully set, %FALSE otherwise.\n' ' *\n' ' * Since: ${since}\n' ' */\n' '${static}gboolean ${prefix_underscore}_set_${underscore} (\n' ' ${prefix_camelcase} *self,\n' '${variable_setter_dec}' ' GError **error);\n') hfile.write(string.Template(template).substitute(translations)) # Emit the setter source template = ('\n' '${static}gboolean\n' '${prefix_underscore}_set_${underscore} (\n' ' ${prefix_camelcase} *self,\n' '${variable_setter_dec}' ' GError **error)\n' '{\n' ' g_return_val_if_fail (self != NULL, FALSE);\n' '\n' '${variable_setter_imp}' ' self->${variable_name}_set = TRUE;\n' '\n' ' return TRUE;\n' '}\n') cfile.write(string.Template(template).substitute(translations))
def emit_getter(self, hfile, cfile): translations = { 'variable_name': self.variable_name, 'prefix_camelcase': utils.build_camelcase_name(self.prefix), 'prefix_underscore': utils.build_underscore_name(self.prefix) } # Emit the getter header template = ('\n' 'gboolean ${prefix_underscore}_get_result (\n' ' ${prefix_camelcase} *self,\n' ' GError **error);\n') hfile.write(string.Template(template).substitute(translations)) # Emit the getter source template = ( '\n' '/**\n' ' * ${prefix_underscore}_get_result:\n' ' * @self: a ${prefix_camelcase}.\n' ' * @error: Return location for error or %NULL.\n' ' *\n' ' * Get the result of the QMI operation.\n' ' *\n' ' * Returns: %TRUE if the QMI operation succeeded, %FALSE if @error is set.\n' ' */\n' 'gboolean\n' '${prefix_underscore}_get_result (\n' ' ${prefix_camelcase} *self,\n' ' GError **error)\n' '{\n' ' g_return_val_if_fail (self != NULL, FALSE);\n' '\n' ' /* We should always have a result set in the response message */\n' ' if (!self->${variable_name}_set) {\n' ' g_set_error (error,\n' ' QMI_CORE_ERROR,\n' ' QMI_CORE_ERROR_INVALID_MESSAGE,\n' ' "No \'Result\' field given in the message");\n' ' return FALSE;\n' ' }\n' '\n' ' if (self->${variable_name}.error_status == QMI_STATUS_SUCCESS) {\n' ' /* Operation succeeded */\n' ' return TRUE;\n' ' }\n' '\n' ' /* Report a QMI protocol error */\n' ' g_set_error (error,\n' ' QMI_PROTOCOL_ERROR,\n' ' (QmiProtocolError) self->${variable_name}.error_code,\n' ' "QMI protocol error (%u): \'%s\'",\n' ' self->${variable_name}.error_code,\n' ' qmi_protocol_error_get_string ((QmiProtocolError) self->${variable_name}.error_code));\n' ' return FALSE;\n' '}\n') cfile.write(string.Template(template).substitute(translations))
def emit_getter(self, hfile, cfile): translations = { 'variable_name' : self.variable_name, 'prefix_camelcase' : utils.build_camelcase_name(self.prefix), 'prefix_underscore' : utils.build_underscore_name(self.prefix) } # Emit the getter header template = ( '\n' 'gboolean ${prefix_underscore}_get_result (\n' ' ${prefix_camelcase} *self,\n' ' GError **error);\n') hfile.write(string.Template(template).substitute(translations)) # Emit the getter source template = ( '\n' '/**\n' ' * ${prefix_underscore}_get_result:\n' ' * @self: a ${prefix_camelcase}.\n' ' * @error: Return location for error or %NULL.\n' ' *\n' ' * Get the result of the QMI operation.\n' ' *\n' ' * Returns: %TRUE if the QMI operation succeeded, %FALSE if @error is set.\n' ' */\n' 'gboolean\n' '${prefix_underscore}_get_result (\n' ' ${prefix_camelcase} *self,\n' ' GError **error)\n' '{\n' ' g_return_val_if_fail (self != NULL, FALSE);\n' '\n' ' /* We should always have a result set in the response message */\n' ' if (!self->${variable_name}_set) {\n' ' g_set_error (error,\n' ' QMI_CORE_ERROR,\n' ' QMI_CORE_ERROR_INVALID_MESSAGE,\n' ' "No \'Result\' field given in the message");\n' ' return FALSE;\n' ' }\n' '\n' ' if (self->${variable_name}.error_status == QMI_STATUS_SUCCESS) {\n' ' /* Operation succeeded */\n' ' return TRUE;\n' ' }\n' '\n' ' /* Report a QMI protocol error */\n' ' g_set_error (error,\n' ' QMI_PROTOCOL_ERROR,\n' ' (QmiProtocolError) self->${variable_name}.error_code,\n' ' "QMI protocol error (%u): \'%s\'",\n' ' self->${variable_name}.error_code,\n' ' qmi_protocol_error_get_string ((QmiProtocolError) self->${variable_name}.error_code));\n' ' return FALSE;\n' '}\n') cfile.write(string.Template(template).substitute(translations))
def emit_sections(self, sfile): if self.static: return translations = { 'hyphened': utils.build_dashed_name(self.fullname), 'fullname_underscore': utils.build_underscore_name(self.fullname), 'camelcase': utils.build_camelcase_name(self.fullname), 'service': utils.build_underscore_name(self.service), 'name_underscore': utils.build_underscore_name(self.name), 'build_symbol': self.build_symbol, 'fullname': self.service + ' ' + self.name, 'type': 'response' if self.type == 'Message' else 'indication' } sections = { 'public-types': '', 'public-methods': '', 'standard': '', 'private': '' } if self.input: self.input.add_sections(sections) self.output.add_sections(sections) if self.type == 'Message': template = ('<SUBSECTION ${camelcase}ClientMethods>\n' 'qmi_client_${service}_${name_underscore}\n' 'qmi_client_${service}_${name_underscore}_finish\n') sections['public-methods'] += string.Template(template).substitute( translations) translations['message_type'] = 'request' elif self.type == 'Indication': translations['message_type'] = 'indication' translations['public_types'] = sections['public-types'] translations['public_methods'] = sections['public-methods'] translations['standard'] = sections['standard'] translations['private'] = sections['private'] template = ('<SECTION>\n' '<FILE>${hyphened}</FILE>\n' '<TITLE>${fullname} ${message_type}</TITLE>\n' '${public_types}' '${public_methods}' '<SUBSECTION Private>\n' '${build_symbol}\n' '${private}' '<SUBSECTION Standard>\n' '${standard}' '</SECTION>\n' '\n') sfile.write(string.Template(template).substitute(translations))
def add_sections(self, sections): translations = { 'underscore' : utils.build_underscore_name(self.name), 'prefix_camelcase' : utils.build_camelcase_name(self.prefix), 'prefix_underscore' : utils.build_underscore_name(self.prefix) } # Public methods template = ( '${prefix_underscore}_get_${underscore}\n') if self.container_type == 'Input': template += ( '${prefix_underscore}_set_${underscore}\n') sections['public-methods'] += string.Template(template).substitute(translations)
def add_sections(self, sections): translations = { 'underscore': utils.build_underscore_name(self.name), 'prefix_camelcase': utils.build_camelcase_name(self.prefix), 'prefix_underscore': utils.build_underscore_name(self.prefix) } # Public methods template = ('${prefix_underscore}_get_${underscore}\n') if self.container_type == 'Input': template += ('${prefix_underscore}_set_${underscore}\n') sections['public-methods'] += string.Template(template).substitute( translations)
def emit_setter(self, hfile, cfile): input_variable_name = utils.build_underscore_name(self.name) variable_setter_dec = self.variable.build_setter_declaration(' ', input_variable_name) variable_setter_doc = self.variable.build_setter_documentation(' * ', input_variable_name) variable_setter_imp = self.variable.build_setter_implementation(' ', input_variable_name, 'self->' + self.variable_name) translations = { 'name' : self.name, 'variable_name' : self.variable_name, 'variable_setter_dec' : variable_setter_dec, 'variable_setter_doc' : variable_setter_doc, 'variable_setter_imp' : variable_setter_imp, 'underscore' : utils.build_underscore_name(self.name), 'prefix_camelcase' : utils.build_camelcase_name(self.prefix), 'prefix_underscore' : utils.build_underscore_name(self.prefix), 'static' : 'static ' if self.static else '' } # Emit the setter header template = ( '\n' '${static}gboolean ${prefix_underscore}_set_${underscore} (\n' ' ${prefix_camelcase} *self,\n' '${variable_setter_dec}' ' GError **error);\n') hfile.write(string.Template(template).substitute(translations)) # Emit the setter source template = ( '\n' '/**\n' ' * ${prefix_underscore}_set_${underscore}:\n' ' * @self: a #${prefix_camelcase}.\n' '${variable_setter_doc}' ' * @error: Return location for error or %NULL.\n' ' *\n' ' * Set the \'${name}\' field in the message.\n' ' *\n' ' * Returns: %TRUE if @value was successfully set, %FALSE otherwise.\n' ' */\n' '${static}gboolean\n' '${prefix_underscore}_set_${underscore} (\n' ' ${prefix_camelcase} *self,\n' '${variable_setter_dec}' ' GError **error)\n' '{\n' ' g_return_val_if_fail (self != NULL, FALSE);\n' '\n' '${variable_setter_imp}' ' self->${variable_name}_set = TRUE;\n' '\n' ' return TRUE;\n' '}\n') cfile.write(string.Template(template).substitute(translations))
def emit_message_ids_enum(self, f): translations = { 'enum_type': utils.build_camelcase_name(self.message_id_enum_name) } template = ('\n' 'typedef enum {\n') for message in self.list: if message.type == 'Message': translations['enum_name'] = message.id_enum_name translations['enum_value'] = message.id enum_template = (' ${enum_name} = ${enum_value},\n') template += string.Template(enum_template).substitute( translations) template += ('} ${enum_type};\n' '\n') f.write(string.Template(template).substitute(translations))
def add_sections(self, sections): translations = { 'underscore' : utils.build_underscore_name(self.name), 'prefix_camelcase' : utils.build_camelcase_name(self.prefix), 'prefix_underscore' : utils.build_underscore_name(self.prefix) } if TypeFactory.is_section_emitted(self.fullname) is False: TypeFactory.set_section_emitted(self.fullname) self.variable.add_sections(sections) # Public methods template = ( '${prefix_underscore}_get_${underscore}\n') if self.container_type == 'Input': template += ( '${prefix_underscore}_set_${underscore}\n') sections['public-methods'] += string.Template(template).substitute(translations)
def emit_indication_ids_enum(self, f): translations = { 'enum_type' : utils.build_camelcase_name (self.indication_id_enum_name) } template = ( '\n' 'typedef enum {\n') for message in self.list: if message.type == 'Indication': translations['enum_name'] = message.id_enum_name translations['enum_value'] = message.id enum_template = ( ' ${enum_name} = ${enum_value},\n') template += string.Template(enum_template).substitute(translations) template += ( '} ${enum_type};\n' '\n') f.write(string.Template(template).substitute(translations))
def __emit_indication_ids_enum(self, f): # do nothing if nothing in the supported indications list if len(self.indication_list) == 0: return translations = { 'enum_type': utils.build_camelcase_name(self.indication_id_enum_name) } template = ('\n' 'typedef enum {\n') for message in self.indication_list: translations['enum_name'] = message.id_enum_name translations['enum_value'] = message.id enum_template = (' ${enum_name} = ${enum_value},\n') template += string.Template(enum_template).substitute(translations) template += ('} ${enum_type};\n' '\n') f.write(string.Template(template).substitute(translations))
def emit_sections(self, sfile): if self.static: return translations = { 'hyphened' : utils.build_dashed_name (self.fullname), 'fullname_underscore' : utils.build_underscore_name(self.fullname), 'camelcase' : utils.build_camelcase_name (self.fullname), 'service' : utils.build_underscore_name (self.service), 'name_underscore' : utils.build_underscore_name (self.name), 'fullname' : self.service + ' ' + self.name, 'type' : 'response' if self.type == 'Message' else 'indication' } sections = { 'public-types' : '', 'public-methods' : '', 'standard' : '', 'private' : '' } if self.input: self.input.add_sections (sections) self.output.add_sections (sections) if self.type == 'Message': template = ( '<SUBSECTION ${camelcase}ClientMethods>\n' 'qmi_client_${service}_${name_underscore}\n' 'qmi_client_${service}_${name_underscore}_finish\n') sections['public-methods'] += string.Template(template).substitute(translations) translations['public_types'] = sections['public-types'] translations['public_methods'] = sections['public-methods'] translations['standard'] = sections['standard'] translations['private'] = sections['private'] template = ( '<SECTION>\n' '<FILE>${hyphened}</FILE>\n' '<TITLE>${fullname}</TITLE>\n' '${public_types}' '${public_methods}' '<SUBSECTION Private>\n' '${private}' '<SUBSECTION Standard>\n' '${standard}' '</SECTION>\n' '\n') sfile.write(string.Template(template).substitute(translations))
def __emit_response_or_indication_parser(self, hfile, cfile): # If no output fields to parse, don't emit anything if self.output is None or self.output.fields is None: return translations = { 'name' : self.name, 'type' : 'response' if self.type == 'Message' else 'indication', 'container' : utils.build_camelcase_name (self.output.fullname), 'container_underscore' : utils.build_underscore_name (self.output.fullname), 'underscore' : utils.build_underscore_name (self.fullname), 'message_id' : self.id_enum_name } template = ( '\n' 'static ${container} *\n' '__${underscore}_${type}_parse (\n' ' QmiMessage *message,\n' ' GError **error)\n' '{\n' ' ${container} *self;\n' '\n' ' g_assert_cmphex (qmi_message_get_message_id (message), ==, ${message_id});\n' '\n' ' self = g_slice_new0 (${container});\n' ' self->ref_count = 1;\n') cfile.write(string.Template(template).substitute(translations)) for field in self.output.fields: cfile.write( '\n' ' do {\n') field.emit_output_prerequisite_check(cfile, ' ') cfile.write( '\n' ' {\n') field.emit_output_tlv_get(cfile, ' ') cfile.write( '\n' ' }\n') cfile.write( ' } while (0);\n') cfile.write( '\n' ' return self;\n' '}\n')
def __emit_response_or_indication_parser(self, hfile, cfile): # If no output fields to parse, don't emit anything if self.output is None or self.output.fields is None: return translations = { 'name' : self.name, 'type' : 'response' if self.type == 'Message' else 'indication', 'container' : utils.build_camelcase_name (self.output.fullname), 'container_underscore' : utils.build_underscore_name (self.output.fullname), 'underscore' : utils.build_underscore_name (self.fullname), 'message_id' : self.id_enum_name } template = ( '\n' 'static ${container} *\n' '__${underscore}_${type}_parse (\n' ' QmiMessage *message,\n' ' GError **error)\n' '{\n' ' ${container} *self;\n' '\n' ' g_return_val_if_fail (qmi_message_get_message_id (message) == ${message_id}, NULL);\n' '\n' ' self = g_slice_new0 (${container});\n' ' self->ref_count = 1;\n') cfile.write(string.Template(template).substitute(translations)) for field in self.output.fields: cfile.write( '\n' ' do {\n') field.emit_output_prerequisite_check(cfile, ' ') cfile.write( '\n' ' {\n') field.emit_output_tlv_get(cfile, ' ') cfile.write( '\n' ' }\n') cfile.write( ' } while (0);\n') cfile.write( '\n' ' return self;\n' '}\n')
def __emit_message_ids_enum(self, f): # do nothing if nothing in the supported messages list if len(self.request_list) == 0: return translations = { 'enum_type': utils.build_camelcase_name(self.message_id_enum_name) } template = ('\n' 'typedef enum {\n') for message in self.request_list: translations['enum_name'] = message.id_enum_name translations['enum_value'] = message.id if message.vendor is None: enum_template = (' ${enum_name} = ${enum_value},\n') else: translations['vendor'] = message.vendor enum_template = ( ' ${enum_name} = ${enum_value}, /* vendor ${vendor} */\n' ) template += string.Template(enum_template).substitute(translations) template += ('} ${enum_type};\n' '\n') f.write(string.Template(template).substitute(translations))
def emit_sections(self, sfile): translations = { 'underscore' : utils.build_underscore_name(self.name), 'no_prefix_underscore_upper' : utils.build_underscore_name(self.name[4:]).upper(), 'camelcase' : utils.build_camelcase_name (self.name), 'hyphened' : utils.build_dashed_name (self.name) } template = ( '<SECTION>\n' '<FILE>${hyphened}</FILE>\n' '<TITLE>${camelcase}</TITLE>\n' '${camelcase}\n' '<SUBSECTION Standard>\n' '${camelcase}Class\n' 'QMI_TYPE_${no_prefix_underscore_upper}\n' 'QMI_${no_prefix_underscore_upper}\n' 'QMI_${no_prefix_underscore_upper}_CLASS\n' 'QMI_IS_${no_prefix_underscore_upper}\n' 'QMI_IS_${no_prefix_underscore_upper}_CLASS\n' 'QMI_${no_prefix_underscore_upper}_GET_CLASS\n' '${underscore}_get_type\n' '</SECTION>\n' '\n') sfile.write(string.Template(template).substitute(translations))
def __emit_request_creator(self, hfile, cfile): translations = { 'name': self.name, 'service': self.service, 'container': utils.build_camelcase_name(self.input.fullname), 'underscore': utils.build_underscore_name(self.fullname), 'message_id': self.id_enum_name } input_arg_template = 'gpointer unused' if self.input.fields is None else '${container} *input' template = ('\n' 'static QmiMessage *\n' '__${underscore}_request_create (\n' ' guint16 transaction_id,\n' ' guint8 cid,\n' ' %s,\n' ' GError **error)\n' '{\n' ' QmiMessage *self;\n' '\n' ' self = qmi_message_new (QMI_SERVICE_${service},\n' ' cid,\n' ' transaction_id,\n' ' ${message_id});\n' % input_arg_template) cfile.write(string.Template(template).substitute(translations)) if self.input.fields: # Count how many mandatory fields we have n_mandatory = 0 for field in self.input.fields: if field.mandatory: n_mandatory += 1 if n_mandatory == 0: # If we don't have mandatory fields, we do allow to have # a NULL input cfile.write( '\n' ' /* All TLVs are optional, we allow NULL input */\n' ' if (!input)\n' ' return self;\n') else: # If we do have mandatory fields, issue error if no input # given. template = ( '\n' ' /* There is at least one mandatory TLV, don\'t allow NULL input */\n' ' if (!input) {\n' ' g_set_error (error,\n' ' QMI_CORE_ERROR,\n' ' QMI_CORE_ERROR_INVALID_ARGS,\n' ' "Message \'${name}\' has mandatory TLVs");\n' ' goto error_out;\n' ' }\n') cfile.write(string.Template(template).substitute(translations)) # Now iterate fields for field in self.input.fields: translations['tlv_name'] = field.name translations['variable_name'] = field.variable_name template = ('\n' ' /* Try to add the \'${tlv_name}\' TLV */\n' ' if (input->${variable_name}_set) {\n') cfile.write(string.Template(template).substitute(translations)) # Emit the TLV getter field.emit_input_tlv_add(cfile, ' ') if field.mandatory: template = ( ' } else {\n' ' g_set_error (error,\n' ' QMI_CORE_ERROR,\n' ' QMI_CORE_ERROR_INVALID_ARGS,\n' ' "Missing mandatory TLV \'${tlv_name}\' in message \'${name}\'");\n' ' goto error_out;\n') cfile.write( string.Template(template).substitute(translations)) cfile.write(' }\n') cfile.write('\n' ' return self;\n') if self.input.fields: cfile.write('\n' 'error_out:\n' ' qmi_message_unref (self);\n' ' return NULL;\n') cfile.write('}\n')
def __emit_methods(self, hfile, cfile, message_list): translations = { 'underscore': utils.build_underscore_name(self.name), 'camelcase': utils.build_camelcase_name(self.name), 'service_lowercase': self.service.lower(), 'service_uppercase': self.service.upper(), 'service_camelcase': string.capwords(self.service) } for message in message_list.request_list: if message.static: continue translations['message_name'] = message.name translations['message_vendor_id'] = message.vendor translations['message_underscore'] = utils.build_underscore_name( message.name) translations[ 'message_fullname_underscore'] = utils.build_underscore_name( message.fullname) translations['input_camelcase'] = utils.build_camelcase_name( message.input.fullname) translations['output_camelcase'] = utils.build_camelcase_name( message.output.fullname) translations['input_underscore'] = utils.build_underscore_name( message.input.fullname) translations['output_underscore'] = utils.build_underscore_name( message.output.fullname) translations['message_since'] = message.since if message.input.fields is None: translations['input_arg'] = 'gpointer unused' translations['input_var'] = 'NULL' translations[ 'input_doc'] = 'unused: %NULL. This message doesn\'t have any input bundle.' else: translations[ 'input_arg'] = translations['input_camelcase'] + ' *input' translations['input_var'] = 'input' translations['input_doc'] = 'input: a #' + translations[ 'input_camelcase'] + '.' template = ( '\n' '/**\n' ' * ${underscore}_${message_underscore}:\n' ' * @self: a #${camelcase}.\n' ' * @${input_doc}\n' ' * @timeout: maximum time to wait for the method to complete, in seconds.\n' ' * @cancellable: a #GCancellable or %NULL.\n' ' * @callback: a #GAsyncReadyCallback to call when the request is satisfied.\n' ' * @user_data: user data to pass to @callback.\n' ' *\n' ' * Asynchronously sends a ${message_name} request to the device.\n' ) if message.abort: template += ( ' *\n' ' * This message is abortable. If @cancellable is cancelled or if @timeout expires,\n' ' * an abort request will be sent to the device, and the asynchronous operation will\n' ' * not return until the abort response is received. It is not an error if a successful\n' ' * response is returned for the asynchronous operation even after the user has cancelled\n' ' * the cancellable, because it may happen that the response is received before the\n' ' * modem had a chance to run the abort.\n') template += ( ' *\n' ' * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from.\n' ' *\n' ' * You can then call ${underscore}_${message_underscore}_finish() to get the result of the operation.\n' ' *\n' ' * Since: ${message_since}\n' ' */\n' 'void ${underscore}_${message_underscore} (\n' ' ${camelcase} *self,\n' ' ${input_arg},\n' ' guint timeout,\n' ' GCancellable *cancellable,\n' ' GAsyncReadyCallback callback,\n' ' gpointer user_data);\n' '\n' '/**\n' ' * ${underscore}_${message_underscore}_finish:\n' ' * @self: a #${camelcase}.\n' ' * @res: the #GAsyncResult obtained from the #GAsyncReadyCallback passed to ${underscore}_${message_underscore}().\n' ' * @error: Return location for error or %NULL.\n' ' *\n' ' * Finishes an async operation started with ${underscore}_${message_underscore}().\n' ' *\n' ' * Returns: a #${output_camelcase}, or %NULL if @error is set. The returned value should be freed with ${output_underscore}_unref().\n' ' *\n' ' * Since: ${message_since}\n' ' */\n' '${output_camelcase} *${underscore}_${message_underscore}_finish (\n' ' ${camelcase} *self,\n' ' GAsyncResult *res,\n' ' GError **error);\n') hfile.write(string.Template(template).substitute(translations)) template = ( '\n' '${output_camelcase} *\n' '${underscore}_${message_underscore}_finish (\n' ' ${camelcase} *self,\n' ' GAsyncResult *res,\n' ' GError **error)\n' '{\n' ' return g_task_propagate_pointer (G_TASK (res), error);\n' '}\n') if message.abort: template += ( '\n' '#if defined HAVE_QMI_MESSAGE_${service_uppercase}_ABORT\n' '\n' 'static QmiMessage *\n' '__${message_fullname_underscore}_abortable_build_request (\n' ' QmiDevice *self,\n' ' QmiMessage *message,\n' ' QmiClient *client,\n' ' GError **error)\n' '{\n' ' QmiMessage *abort_request;\n' ' guint16 transaction_id;\n' ' g_autoptr(QmiMessage${service_camelcase}AbortInput) input = NULL;\n' '\n' ' transaction_id = qmi_message_get_transaction_id (message);\n' ' g_assert (transaction_id != 0);\n' '\n' ' input = qmi_message_${service_lowercase}_abort_input_new ();\n' ' qmi_message_${service_lowercase}_abort_input_set_transaction_id (\n' ' input,\n' ' transaction_id,\n' ' NULL);\n' ' abort_request = __qmi_message_${service_lowercase}_abort_request_create (\n' ' qmi_client_get_next_transaction_id (client),\n' ' qmi_client_get_cid (client),\n' ' input,\n' ' NULL);\n' ' return abort_request;\n' '}\n' '\n' 'static gboolean\n' '__${message_fullname_underscore}_abortable_parse_response (\n' ' QmiDevice *self,\n' ' QmiMessage *abort_response,\n' ' QmiClient *client,\n' ' GError **error)\n' '{\n' ' g_autoptr(QmiMessage${service_camelcase}AbortOutput) output = NULL;\n' '\n' ' output = __qmi_message_${service_lowercase}_abort_response_parse (\n' ' abort_response,\n' ' error);\n' ' return !!output;\n' '}\n' '\n' '#endif /* HAVE_QMI_MESSAGE_${service_uppercase}_ABORT */\n' '\n') template += ('\n' 'static void\n' '${message_underscore}_ready (\n' ' QmiDevice *device,\n' ' GAsyncResult *res,\n' ' GTask *task)\n' '{\n' ' GError *error = NULL;\n' ' QmiMessage *reply;\n' ' ${output_camelcase} *output;\n' '\n') if message.abort: template += ( ' reply = qmi_device_command_abortable_finish (device, res, &error);\n' ) else: template += ( ' reply = qmi_device_command_full_finish (device, res, &error);\n' ) template += (' if (!reply) {\n') template += ( ' g_task_return_error (task, error);\n' ' g_object_unref (task);\n' ' return;\n' ' }\n' '\n' ' /* Parse reply */\n' ' output = __${message_fullname_underscore}_response_parse (reply, &error);\n' ' if (!output)\n' ' g_task_return_error (task, error);\n' ' else\n' ' g_task_return_pointer (task,\n' ' output,\n' ' (GDestroyNotify)${output_underscore}_unref);\n' ' g_object_unref (task);\n' ' qmi_message_unref (reply);\n' '}\n' '\n' 'void\n' '${underscore}_${message_underscore} (\n' ' ${camelcase} *self,\n' ' ${input_arg},\n' ' guint timeout,\n' ' GCancellable *cancellable,\n' ' GAsyncReadyCallback callback,\n' ' gpointer user_data)\n' '{\n' ' GTask *task;\n' ' GError *error = NULL;\n' ' guint16 transaction_id;\n' ' g_autoptr(QmiMessage) request = NULL;\n') if message.vendor is not None: template += ( ' g_autoptr(QmiMessageContext) context = NULL;\n') template += ( '\n' ' task = g_task_new (self, cancellable, callback, user_data);\n' ' if (!qmi_client_is_valid (QMI_CLIENT (self))) {\n' ' g_task_return_new_error (task, QMI_CORE_ERROR, QMI_CORE_ERROR_WRONG_STATE, "client invalid");\n' ' g_object_unref (task);\n' ' return;\n' ' }\n' '\n' ' transaction_id = qmi_client_get_next_transaction_id (QMI_CLIENT (self));\n' '\n' ' request = __${message_fullname_underscore}_request_create (\n' ' transaction_id,\n' ' qmi_client_get_cid (QMI_CLIENT (self)),\n' ' ${input_var},\n' ' &error);\n' ' if (!request) {\n' ' g_prefix_error (&error, "Couldn\'t create request message: ");\n' ' g_task_return_error (task, error);\n' ' g_object_unref (task);\n' ' return;\n' ' }\n') if message.vendor is not None: template += ( '\n' ' context = qmi_message_context_new ();\n' ' qmi_message_context_set_vendor_id (context, ${message_vendor_id});\n' ) if message.abort: template += ( '\n' ' qmi_device_command_abortable (QMI_DEVICE (qmi_client_peek_device (QMI_CLIENT (self))),\n' ) else: template += ( '\n' ' qmi_device_command_full (QMI_DEVICE (qmi_client_peek_device (QMI_CLIENT (self))),\n' ) template += (' request,\n') if message.vendor is not None: template += (' context,\n') else: template += (' NULL,\n') template += (' timeout,\n') if message.abort: template += ( '#if defined HAVE_QMI_MESSAGE_${service_uppercase}_ABORT\n' ' (QmiDeviceCommandAbortableBuildRequestFn) __${message_fullname_underscore}_abortable_build_request,\n' ' (QmiDeviceCommandAbortableParseResponseFn) __${message_fullname_underscore}_abortable_parse_response,\n' ' g_object_ref (self),\n' ' g_object_unref,\n' '#else\n' ' NULL,\n' ' NULL,\n' ' NULL,\n' ' NULL,\n' '#endif\n') template += ( ' cancellable,\n' ' (GAsyncReadyCallback)${message_underscore}_ready,\n' ' task);\n') template += ('}\n' '\n') cfile.write(string.Template(template).substitute(translations))
def __emit_class(self, hfile, cfile, message_list): # Check if we'll have indications has_indications = False for message in message_list.list: if message.type == 'Indication': has_indications = True break translations = { 'underscore': utils.build_underscore_name(self.name), 'no_prefix_underscore_upper': utils.build_underscore_name(self.name[4:]).upper(), 'camelcase': utils.build_camelcase_name(self.name), 'hyphened': utils.build_dashed_name(self.name), 'service': self.service.upper() } # Emit class header template = ( '#define QMI_TYPE_${no_prefix_underscore_upper} (${underscore}_get_type ())\n' '#define QMI_${no_prefix_underscore_upper}(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), QMI_TYPE_${no_prefix_underscore_upper}, ${camelcase}))\n' '#define QMI_${no_prefix_underscore_upper}_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), QMI_TYPE_${no_prefix_underscore_upper}, ${camelcase}Class))\n' '#define QMI_IS_${no_prefix_underscore_upper}(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), QMI_TYPE_${no_prefix_underscore_upper}))\n' '#define QMI_IS_${no_prefix_underscore_upper}_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), QMI_TYPE_${no_prefix_underscore_upper}))\n' '#define QMI_${no_prefix_underscore_upper}_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), QMI_TYPE_${no_prefix_underscore_upper}, ${camelcase}Class))\n' '\n' 'typedef struct _${camelcase} ${camelcase};\n' 'typedef struct _${camelcase}Class ${camelcase}Class;\n' '\n' '/**\n' ' * ${camelcase}:\n' ' *\n' ' * The #${camelcase} structure contains private data and should only be accessed\n' ' * using the provided API.\n' ' */\n' 'struct _${camelcase} {\n' ' /*< private >*/\n' ' QmiClient parent;\n' ' gpointer priv_unused;\n' '};\n' '\n' 'struct _${camelcase}Class {\n' ' /*< private >*/\n' ' QmiClientClass parent;\n' '};\n' '\n' 'GType ${underscore}_get_type (void);\n' '\n') hfile.write(string.Template(template).substitute(translations)) # Emit class source. Documentation skipped for the CTL service. template = '' if self.service != 'CTL': template += ( '\n' '/**\n' ' * SECTION: ${hyphened}\n' ' * @title: ${camelcase}\n' ' * @short_description: #QmiClient for the ${service} service.\n' ' *\n' ' * #QmiClient which handles operations in the ${service} service.\n' ' */\n' '\n') template += ( 'G_DEFINE_TYPE (${camelcase}, ${underscore}, QMI_TYPE_CLIENT);\n') if has_indications: template += ('\n' 'enum {\n') for message in message_list.list: if message.type == 'Indication': translations[ 'signal_id'] = utils.build_underscore_uppercase_name( message.name) inner_template = (' SIGNAL_${signal_id},\n') template += string.Template(inner_template).substitute( translations) template += (' SIGNAL_LAST\n' '};\n' '\n' 'static guint signals[SIGNAL_LAST] = { 0 };\n') template += ('\n' 'static void\n' 'process_indication (QmiClient *self,\n' ' QmiMessage *message)\n' '{\n' ' switch (qmi_message_get_message_id (message)) {\n') for message in message_list.list: if message.type == 'Indication': translations['enum_name'] = message.id_enum_name translations[ 'message_fullname_underscore'] = utils.build_underscore_name( message.fullname) translations['message_name'] = message.name translations[ 'signal_id'] = utils.build_underscore_uppercase_name( message.name) inner_template = '' if message.output is not None and message.output.fields is not None: # At least one field in the indication translations[ 'output_camelcase'] = utils.build_camelcase_name( message.output.fullname) translations[ 'output_underscore'] = utils.build_underscore_name( message.output.fullname) translations[ 'output_underscore'] = utils.build_underscore_name( message.output.fullname) inner_template += ( ' case ${enum_name}: {\n' ' ${output_camelcase} *output;\n' ' GError *error = NULL;\n' '\n' ' /* Parse indication */\n' ' output = __${message_fullname_underscore}_indication_parse (message, &error);\n' ' if (!output) {\n' ' g_warning ("Couldn\'t parse \'${message_name}\' indication: %s",\n' ' error ? error->message : "Unknown error");\n' ' if (error)\n' ' g_error_free (error);\n' ' } else {\n' ' g_signal_emit (self, signals[SIGNAL_${signal_id}], 0, output);\n' ' ${output_underscore}_unref (output);\n' ' }\n' ' break;\n' ' }\n') else: # No output field in the indication inner_template += ( ' case ${enum_name}: {\n' ' g_signal_emit (self, signals[SIGNAL_${signal_id}], 0, NULL);\n' ' break;\n' ' }\n') template += string.Template(inner_template).substitute( translations) template += ( ' default:\n' ' break;\n' ' }\n' '}\n' '\n' 'static void\n' '${underscore}_init (${camelcase} *self)\n' '{\n' '}\n' '\n' 'static void\n' '${underscore}_class_init (${camelcase}Class *klass)\n' '{\n' ' QmiClientClass *client_class = QMI_CLIENT_CLASS (klass);\n' '\n' ' client_class->process_indication = process_indication;\n') for message in message_list.list: if message.type == 'Indication': translations['signal_name'] = utils.build_dashed_name( message.name) translations[ 'signal_id'] = utils.build_underscore_uppercase_name( message.name) translations['message_name'] = message.name inner_template = '' if message.output is not None and message.output.fields is not None: # At least one field in the indication translations[ 'output_camelcase'] = utils.build_camelcase_name( message.output.fullname) translations[ 'bundle_type'] = 'QMI_TYPE_' + utils.remove_prefix( utils.build_underscore_uppercase_name( message.output.fullname), 'QMI_') translations['service'] = self.service.upper() translations['message_name_dashed'] = message.name.replace( ' ', '-') inner_template += ( '\n' ' /**\n' ' * ${camelcase}::${signal_name}:\n' ' * @object: A #${camelcase}.\n' ' * @output: A #${output_camelcase}.\n' ' *\n' ' * The ::${signal_name} signal gets emitted when a \'<link linkend=\"libqmi-glib-${service}-${message_name_dashed}.top_of_page\">${message_name}</link>\' indication is received.\n' ' */\n' ' signals[SIGNAL_${signal_id}] =\n' ' g_signal_new ("${signal_name}",\n' ' G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),\n' ' G_SIGNAL_RUN_LAST,\n' ' 0,\n' ' NULL,\n' ' NULL,\n' ' NULL,\n' ' G_TYPE_NONE,\n' ' 1,\n' ' ${bundle_type});\n') else: # No output field in the indication inner_template += ( '\n' ' /**\n' ' * ${camelcase}::${signal_name}:\n' ' * @object: A #${camelcase}.\n' ' *\n' ' * The ::${signal_name} signal gets emitted when a \'${message_name}\' indication is received.\n' ' */\n' ' signals[SIGNAL_${signal_id}] =\n' ' g_signal_new ("${signal_name}",\n' ' G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),\n' ' G_SIGNAL_RUN_LAST,\n' ' 0,\n' ' NULL,\n' ' NULL,\n' ' NULL,\n' ' G_TYPE_NONE,\n' ' 0);\n') template += string.Template(inner_template).substitute( translations) template += ('}\n' '\n') cfile.write(string.Template(template).substitute(translations))
def __emit_methods(self, hfile, cfile, message_list): translations = { 'underscore': utils.build_underscore_name(self.name), 'camelcase': utils.build_camelcase_name(self.name), 'service_lowercase': self.service.lower(), 'service_uppercase': self.service.upper(), 'service_camelcase': string.capwords(self.service) } for message in message_list.list: if message.type == 'Indication': continue if message.static: continue translations['message_name'] = message.name translations['message_underscore'] = utils.build_underscore_name( message.name) translations[ 'message_fullname_underscore'] = utils.build_underscore_name( message.fullname) translations['input_camelcase'] = utils.build_camelcase_name( message.input.fullname) translations['output_camelcase'] = utils.build_camelcase_name( message.output.fullname) translations['input_underscore'] = utils.build_underscore_name( message.input.fullname) translations['output_underscore'] = utils.build_underscore_name( message.output.fullname) if message.input.fields is None: input_arg_template = 'gpointer unused' translations['input_var'] = 'NULL' translations[ 'input_doc'] = 'unused: %NULL. This message doesn\'t have any input bundle.' else: input_arg_template = '${input_camelcase} *input' translations['input_var'] = 'input' translations['input_doc'] = 'input: a #' + translations[ 'input_camelcase'] + '.' template = ( '\n' 'void ${underscore}_${message_underscore} (\n' ' ${camelcase} *self,\n' ' %s,\n' ' guint timeout,\n' ' GCancellable *cancellable,\n' ' GAsyncReadyCallback callback,\n' ' gpointer user_data);\n' '${output_camelcase} *${underscore}_${message_underscore}_finish (\n' ' ${camelcase} *self,\n' ' GAsyncResult *res,\n' ' GError **error);\n' % input_arg_template) hfile.write(string.Template(template).substitute(translations)) template = ( '\n' '/**\n' ' * ${underscore}_${message_underscore}_finish:\n' ' * @self: a #${camelcase}.\n' ' * @res: the #GAsyncResult obtained from the #GAsyncReadyCallback passed to ${underscore}_${message_underscore}().\n' ' * @error: Return location for error or %NULL.\n' ' *\n' ' * Finishes an async operation started with ${underscore}_${message_underscore}().\n' ' *\n' ' * Returns: a #${output_camelcase}, or %NULL if @error is set. The returned value should be freed with ${output_underscore}_unref().\n' ' */\n' '${output_camelcase} *\n' '${underscore}_${message_underscore}_finish (\n' ' ${camelcase} *self,\n' ' GAsyncResult *res,\n' ' GError **error)\n' '{\n' ' if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))\n' ' return NULL;\n' '\n' ' return ${output_underscore}_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));\n' '}\n') if message.abort: template += ( '\n' 'static void\n' '${message_underscore}_abort_ready (\n' ' QmiDevice *device,\n' ' GAsyncResult *res)\n' '{\n' ' GError *error = NULL;\n' ' QmiMessage *reply;\n' ' QmiMessage${service_camelcase}AbortOutput *output;\n' '\n' ' reply = qmi_device_command_finish (device, res, &error);\n' ' if (reply) {\n' ' output = __qmi_message_${service_lowercase}_abort_response_parse (reply, &error);\n' ' if (output)\n' ' qmi_message_${service_lowercase}_abort_output_unref (output);\n' ' qmi_message_unref (reply);\n' ' }\n' '\n' ' if (error) {\n' ' g_debug ("Operation to abort \'${message_name}\' failed: %s", error->message);\n' ' g_error_free (error);\n' ' }\n' '}\n') template += ( '\n' 'static void\n' '${message_underscore}_ready (\n' ' QmiDevice *device,\n' ' GAsyncResult *res,\n' ' GSimpleAsyncResult *simple)\n' '{\n' ' GError *error = NULL;\n' ' QmiMessage *reply;\n' ' ${output_camelcase} *output;\n' '\n' ' reply = qmi_device_command_finish (device, res, &error);\n' ' if (!reply) {\n') if message.abort: template += ( ' if (g_error_matches (error, QMI_CORE_ERROR, QMI_CORE_ERROR_TIMEOUT) ||\n' ' g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_ABORTED)) {\n' ' QmiMessage *abort;\n' ' GObject *self;\n' ' guint16 transaction_id;\n' ' QmiMessage${service_camelcase}AbortInput *input;\n' '\n' ' self = g_async_result_get_source_object (G_ASYNC_RESULT (simple));\n' ' g_assert (self != NULL);\n' '\n' ' transaction_id = (guint16) GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (simple),\n' ' "transaction-id"));\n' ' g_assert (transaction_id != 0);\n' '\n' ' input = qmi_message_${service_lowercase}_abort_input_new ();\n' ' qmi_message_${service_lowercase}_abort_input_set_transaction_id (\n' ' input,\n' ' transaction_id,\n' ' NULL);\n' ' abort = __qmi_message_${service_lowercase}_abort_request_create (\n' ' qmi_client_get_next_transaction_id (QMI_CLIENT (self)),\n' ' qmi_client_get_cid (QMI_CLIENT (self)),\n' ' input,\n' ' NULL);\n' ' g_assert (abort != NULL);\n' ' qmi_device_command (device,\n' ' abort,\n' ' 30,\n' ' NULL,\n' ' (GAsyncReadyCallback)${message_underscore}_abort_ready,\n' ' NULL);\n' ' qmi_message_${service_lowercase}_abort_input_unref (input);\n' ' qmi_message_unref (abort);\n' ' g_object_unref (self);\n' ' }\n' '\n') template += ( ' g_simple_async_result_take_error (simple, error);\n' ' g_simple_async_result_complete (simple);\n' ' g_object_unref (simple);\n' ' return;\n' ' }\n' '\n' ' /* Parse reply */\n' ' output = __${message_fullname_underscore}_response_parse (reply, &error);\n' ' if (!output)\n' ' g_simple_async_result_take_error (simple, error);\n' ' else\n' ' g_simple_async_result_set_op_res_gpointer (simple,\n' ' output,\n' ' (GDestroyNotify)${output_underscore}_unref);\n' ' g_simple_async_result_complete (simple);\n' ' g_object_unref (simple);\n' ' qmi_message_unref (reply);\n' '}\n' '\n' '/**\n' ' * ${underscore}_${message_underscore}:\n' ' * @self: a #${camelcase}.\n' ' * @${input_doc}\n' ' * @timeout: maximum time to wait for the method to complete, in seconds.\n' ' * @cancellable: a #GCancellable or %NULL.\n' ' * @callback: a #GAsyncReadyCallback to call when the request is satisfied.\n' ' * @user_data: user data to pass to @callback.\n' ' *\n' ' * Asynchronously sends a ${message_name} request to the device.\n' ' *\n' ' * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from.\n' ' *\n' ' * You can then call ${underscore}_${message_underscore}_finish() to get the result of the operation.\n' ' */\n' 'void\n' '${underscore}_${message_underscore} (\n' ' ${camelcase} *self,\n') template += (' %s,\n' % input_arg_template) template += ( ' guint timeout,\n' ' GCancellable *cancellable,\n' ' GAsyncReadyCallback callback,\n' ' gpointer user_data)\n' '{\n' ' GSimpleAsyncResult *result;\n' ' QmiMessage *request;\n' ' GError *error = NULL;\n' ' guint16 transaction_id;\n' '\n' ' result = g_simple_async_result_new (G_OBJECT (self),\n' ' callback,\n' ' user_data,\n' ' ${underscore}_${message_underscore});\n' '\n' ' transaction_id = qmi_client_get_next_transaction_id (QMI_CLIENT (self));\n' '\n' ' request = __${message_fullname_underscore}_request_create (\n' ' transaction_id,\n' ' qmi_client_get_cid (QMI_CLIENT (self)),\n' ' ${input_var},\n' ' &error);\n' ' if (!request) {\n' ' g_prefix_error (&error, "Couldn\'t create request message: ");\n' ' g_simple_async_result_take_error (result, error);\n' ' g_simple_async_result_complete_in_idle (result);\n' ' g_object_unref (result);\n' ' return;\n' ' }\n') if message.abort: template += ( '\n' ' g_object_set_data (G_OBJECT (result),\n' ' "transaction-id",\n' ' GUINT_TO_POINTER (transaction_id));\n' ) template += ( '\n' ' qmi_device_command (QMI_DEVICE (qmi_client_peek_device (QMI_CLIENT (self))),\n' ' request,\n' ' timeout,\n' ' cancellable,\n' ' (GAsyncReadyCallback)${message_underscore}_ready,\n' ' result);\n' ' qmi_message_unref (request);\n' '}\n' '\n') cfile.write(string.Template(template).substitute(translations))
def __emit_methods(self, hfile, cfile, message_list): translations = { 'underscore' : utils.build_underscore_name(self.name), 'camelcase' : utils.build_camelcase_name (self.name), 'service_lowercase' : self.service.lower(), 'service_uppercase' : self.service.upper(), 'service_camelcase' : string.capwords(self.service) } for message in message_list.list: if message.type == 'Indication': continue if message.static: continue translations['message_name'] = message.name translations['message_underscore'] = utils.build_underscore_name(message.name) translations['message_fullname_underscore'] = utils.build_underscore_name(message.fullname) translations['input_camelcase'] = utils.build_camelcase_name(message.input.fullname) translations['output_camelcase'] = utils.build_camelcase_name(message.output.fullname) translations['input_underscore'] = utils.build_underscore_name(message.input.fullname) translations['output_underscore'] = utils.build_underscore_name(message.output.fullname) if message.input.fields is None: input_arg_template = 'gpointer unused' translations['input_var'] = 'NULL' translations['input_doc'] = 'unused: %NULL. This message doesn\'t have any input bundle.' else: input_arg_template = '${input_camelcase} *input' translations['input_var'] = 'input' translations['input_doc'] = 'input: a #' + translations['input_camelcase'] + '.' template = ( '\n' 'void ${underscore}_${message_underscore} (\n' ' ${camelcase} *self,\n' ' %s,\n' ' guint timeout,\n' ' GCancellable *cancellable,\n' ' GAsyncReadyCallback callback,\n' ' gpointer user_data);\n' '${output_camelcase} *${underscore}_${message_underscore}_finish (\n' ' ${camelcase} *self,\n' ' GAsyncResult *res,\n' ' GError **error);\n' % input_arg_template) hfile.write(string.Template(template).substitute(translations)) template = ( '\n' '/**\n' ' * ${underscore}_${message_underscore}_finish:\n' ' * @self: a #${camelcase}.\n' ' * @res: the #GAsyncResult obtained from the #GAsyncReadyCallback passed to ${underscore}_${message_underscore}().\n' ' * @error: Return location for error or %NULL.\n' ' *\n' ' * Finishes an async operation started with ${underscore}_${message_underscore}().\n' ' *\n' ' * Returns: a #${output_camelcase}, or %NULL if @error is set. The returned value should be freed with ${output_underscore}_unref().\n' ' */\n' '${output_camelcase} *\n' '${underscore}_${message_underscore}_finish (\n' ' ${camelcase} *self,\n' ' GAsyncResult *res,\n' ' GError **error)\n' '{\n' ' if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))\n' ' return NULL;\n' '\n' ' return ${output_underscore}_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));\n' '}\n') if message.abort: template += ( '\n' 'static void\n' '${message_underscore}_abort_ready (\n' ' QmiDevice *device,\n' ' GAsyncResult *res)\n' '{\n' ' GError *error = NULL;\n' ' QmiMessage *reply;\n' ' QmiMessage${service_camelcase}AbortOutput *output;\n' '\n' ' reply = qmi_device_command_finish (device, res, &error);\n' ' if (reply) {\n' ' output = __qmi_message_${service_lowercase}_abort_response_parse (reply, &error);\n' ' if (output)\n' ' qmi_message_${service_lowercase}_abort_output_unref (output);\n' ' qmi_message_unref (reply);\n' ' }\n' '\n' ' if (error) {\n' ' g_debug ("Operation to abort \'${message_name}\' failed: %s", error->message);\n' ' g_error_free (error);\n' ' }\n' '}\n') template += ( '\n' 'static void\n' '${message_underscore}_ready (\n' ' QmiDevice *device,\n' ' GAsyncResult *res,\n' ' GSimpleAsyncResult *simple)\n' '{\n' ' GError *error = NULL;\n' ' QmiMessage *reply;\n' ' ${output_camelcase} *output;\n' '\n' ' reply = qmi_device_command_finish (device, res, &error);\n' ' if (!reply) {\n') if message.abort: template += ( ' if (g_error_matches (error, QMI_CORE_ERROR, QMI_CORE_ERROR_TIMEOUT) ||\n' ' g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_ABORTED)) {\n' ' QmiMessage *abort;\n' ' GObject *self;\n' ' guint16 transaction_id;\n' ' QmiMessage${service_camelcase}AbortInput *input;\n' '\n' ' self = g_async_result_get_source_object (G_ASYNC_RESULT (simple));\n' ' g_assert (self != NULL);\n' '\n' ' transaction_id = (guint16) GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (simple),\n' ' "transaction-id"));\n' ' g_assert (transaction_id != 0);\n' '\n' ' input = qmi_message_${service_lowercase}_abort_input_new ();\n' ' qmi_message_${service_lowercase}_abort_input_set_transaction_id (\n' ' input,\n' ' transaction_id,\n' ' NULL);\n' ' abort = __qmi_message_${service_lowercase}_abort_request_create (\n' ' qmi_client_get_next_transaction_id (QMI_CLIENT (self)),\n' ' qmi_client_get_cid (QMI_CLIENT (self)),\n' ' input,\n' ' NULL);\n' ' g_assert (abort != NULL);\n' ' qmi_device_command (device,\n' ' abort,\n' ' 30,\n' ' NULL,\n' ' (GAsyncReadyCallback)${message_underscore}_abort_ready,\n' ' NULL);\n' ' qmi_message_${service_lowercase}_abort_input_unref (input);\n' ' qmi_message_unref (abort);\n' ' g_object_unref (self);\n' ' }\n' '\n') template += ( ' g_simple_async_result_take_error (simple, error);\n' ' g_simple_async_result_complete (simple);\n' ' g_object_unref (simple);\n' ' return;\n' ' }\n' '\n' ' /* Parse reply */\n' ' output = __${message_fullname_underscore}_response_parse (reply, &error);\n' ' if (!output)\n' ' g_simple_async_result_take_error (simple, error);\n' ' else\n' ' g_simple_async_result_set_op_res_gpointer (simple,\n' ' output,\n' ' (GDestroyNotify)${output_underscore}_unref);\n' ' g_simple_async_result_complete (simple);\n' ' g_object_unref (simple);\n' ' qmi_message_unref (reply);\n' '}\n' '\n' '/**\n' ' * ${underscore}_${message_underscore}:\n' ' * @self: a #${camelcase}.\n' ' * @${input_doc}\n' ' * @timeout: maximum time to wait for the method to complete, in seconds.\n' ' * @cancellable: a #GCancellable or %NULL.\n' ' * @callback: a #GAsyncReadyCallback to call when the request is satisfied.\n' ' * @user_data: user data to pass to @callback.\n' ' *\n' ' * Asynchronously sends a ${message_name} request to the device.\n' ' *\n' ' * When the operation is finished, @callback will be invoked in the thread-default main loop of the thread you are calling this method from.\n' ' *\n' ' * You can then call ${underscore}_${message_underscore}_finish() to get the result of the operation.\n' ' */\n' 'void\n' '${underscore}_${message_underscore} (\n' ' ${camelcase} *self,\n') template += ( ' %s,\n' % input_arg_template) template += ( ' guint timeout,\n' ' GCancellable *cancellable,\n' ' GAsyncReadyCallback callback,\n' ' gpointer user_data)\n' '{\n' ' GSimpleAsyncResult *result;\n' ' QmiMessage *request;\n' ' GError *error = NULL;\n' ' guint16 transaction_id;\n' '\n' ' result = g_simple_async_result_new (G_OBJECT (self),\n' ' callback,\n' ' user_data,\n' ' ${underscore}_${message_underscore});\n' '\n' ' transaction_id = qmi_client_get_next_transaction_id (QMI_CLIENT (self));\n' '\n' ' request = __${message_fullname_underscore}_request_create (\n' ' transaction_id,\n' ' qmi_client_get_cid (QMI_CLIENT (self)),\n' ' ${input_var},\n' ' &error);\n' ' if (!request) {\n' ' g_prefix_error (&error, "Couldn\'t create request message: ");\n' ' g_simple_async_result_take_error (result, error);\n' ' g_simple_async_result_complete_in_idle (result);\n' ' g_object_unref (result);\n' ' return;\n' ' }\n') if message.abort: template += ( '\n' ' g_object_set_data (G_OBJECT (result),\n' ' "transaction-id",\n' ' GUINT_TO_POINTER (transaction_id));\n') template += ( '\n' ' qmi_device_command (QMI_DEVICE (qmi_client_peek_device (QMI_CLIENT (self))),\n' ' request,\n' ' timeout,\n' ' cancellable,\n' ' (GAsyncReadyCallback)${message_underscore}_ready,\n' ' result);\n' ' qmi_message_unref (request);\n' '}\n' '\n') cfile.write(string.Template(template).substitute(translations))
def emit_getter(self, hfile, cfile): input_variable_name = 'value_' + utils.build_underscore_name(self.name) variable_getter_dec = self.variable.build_getter_declaration(' ', input_variable_name) variable_getter_doc = self.variable.build_getter_documentation(' * ', input_variable_name) variable_getter_imp = self.variable.build_getter_implementation(' ', 'self->' + self.variable_name, input_variable_name, True) translations = { 'name' : self.name, 'variable_name' : self.variable_name, 'variable_getter_dec' : variable_getter_dec, 'variable_getter_doc' : variable_getter_doc, 'variable_getter_imp' : variable_getter_imp, 'underscore' : utils.build_underscore_name(self.name), 'prefix_camelcase' : utils.build_camelcase_name(self.prefix), 'prefix_underscore' : utils.build_underscore_name(self.prefix), 'since' : self.since, 'static' : 'static ' if self.static else '' } # Emit the getter header template = ( '\n' '/**\n' ' * ${prefix_underscore}_get_${underscore}:\n' ' * @self: a #${prefix_camelcase}.\n' '${variable_getter_doc}' ' * @error: Return location for error or %NULL.\n' ' *\n' ' * Get the \'${name}\' field from @self.\n' ' *\n' ' * Returns: %TRUE if the field is found, %FALSE otherwise.\n' ' *\n' ' * Since: ${since}\n' ' */\n' '${static}gboolean ${prefix_underscore}_get_${underscore} (\n' ' ${prefix_camelcase} *self,\n' '${variable_getter_dec}' ' GError **error);\n') hfile.write(string.Template(template).substitute(translations)) # Emit the getter source template = ( '\n' '${static}gboolean\n' '${prefix_underscore}_get_${underscore} (\n' ' ${prefix_camelcase} *self,\n' '${variable_getter_dec}' ' GError **error)\n' '{\n' ' g_return_val_if_fail (self != NULL, FALSE);\n' '\n' ' if (!self->${variable_name}_set) {\n' ' g_set_error (error,\n' ' QMI_CORE_ERROR,\n' ' QMI_CORE_ERROR_TLV_NOT_FOUND,\n' ' "Field \'${name}\' was not found in the message");\n' ' return FALSE;\n' ' }\n' '\n' '${variable_getter_imp}' '\n' ' return TRUE;\n' '}\n') cfile.write(string.Template(template).substitute(translations))
def __emit_class(self, hfile, cfile, message_list): # Check if we'll have indications has_indications = False for message in message_list.list: if message.type == 'Indication': has_indications = True break translations = { 'underscore' : utils.build_underscore_name(self.name), 'no_prefix_underscore_upper' : utils.build_underscore_name(self.name[4:]).upper(), 'camelcase' : utils.build_camelcase_name(self.name), 'hyphened' : utils.build_dashed_name(self.name), 'service' : self.service.upper() } # Emit class header template = ( '#define QMI_TYPE_${no_prefix_underscore_upper} (${underscore}_get_type ())\n' '#define QMI_${no_prefix_underscore_upper}(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), QMI_TYPE_${no_prefix_underscore_upper}, ${camelcase}))\n' '#define QMI_${no_prefix_underscore_upper}_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), QMI_TYPE_${no_prefix_underscore_upper}, ${camelcase}Class))\n' '#define QMI_IS_${no_prefix_underscore_upper}(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), QMI_TYPE_${no_prefix_underscore_upper}))\n' '#define QMI_IS_${no_prefix_underscore_upper}_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), QMI_TYPE_${no_prefix_underscore_upper}))\n' '#define QMI_${no_prefix_underscore_upper}_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), QMI_TYPE_${no_prefix_underscore_upper}, ${camelcase}Class))\n' '\n' 'typedef struct _${camelcase} ${camelcase};\n' 'typedef struct _${camelcase}Class ${camelcase}Class;\n' '\n' '/**\n' ' * ${camelcase}:\n' ' *\n' ' * The #${camelcase} structure contains private data and should only be accessed\n' ' * using the provided API.\n' ' */\n' 'struct _${camelcase} {\n' ' /*< private >*/\n' ' QmiClient parent;\n' ' gpointer priv_unused;\n' '};\n' '\n' 'struct _${camelcase}Class {\n' ' /*< private >*/\n' ' QmiClientClass parent;\n' '};\n' '\n' 'GType ${underscore}_get_type (void);\n' '\n') hfile.write(string.Template(template).substitute(translations)) # Emit class source. Documentation skipped for the CTL service. template = '' if self.service != 'CTL': template += ( '\n' '/**\n' ' * SECTION: ${hyphened}\n' ' * @title: ${camelcase}\n' ' * @short_description: #QmiClient for the ${service} service.\n' ' *\n' ' * #QmiClient which handles operations in the ${service} service.\n' ' */\n' '\n') template += ( 'G_DEFINE_TYPE (${camelcase}, ${underscore}, QMI_TYPE_CLIENT);\n') if has_indications: template += ( '\n' 'enum {\n') for message in message_list.list: if message.type == 'Indication': translations['signal_id'] = utils.build_underscore_uppercase_name(message.name) inner_template = ( ' SIGNAL_${signal_id},\n') template += string.Template(inner_template).substitute(translations) template += ( ' SIGNAL_LAST\n' '};\n' '\n' 'static guint signals[SIGNAL_LAST] = { 0 };\n') template += ( '\n' 'static void\n' 'process_indication (QmiClient *self,\n' ' QmiMessage *message)\n' '{\n' ' switch (qmi_message_get_message_id (message)) {\n') for message in message_list.list: if message.type == 'Indication': translations['enum_name'] = message.id_enum_name translations['message_fullname_underscore'] = utils.build_underscore_name(message.fullname) translations['message_name'] = message.name translations['signal_id'] = utils.build_underscore_uppercase_name(message.name) inner_template = '' if message.output is not None and message.output.fields is not None: # At least one field in the indication translations['output_camelcase'] = utils.build_camelcase_name(message.output.fullname) translations['output_underscore'] = utils.build_underscore_name(message.output.fullname) translations['output_underscore'] = utils.build_underscore_name(message.output.fullname) inner_template += ( ' case ${enum_name}: {\n' ' ${output_camelcase} *output;\n' ' GError *error = NULL;\n' '\n' ' /* Parse indication */\n' ' output = __${message_fullname_underscore}_indication_parse (message, &error);\n' ' if (!output) {\n' ' g_warning ("Couldn\'t parse \'${message_name}\' indication: %s",\n' ' error ? error->message : "Unknown error");\n' ' if (error)\n' ' g_error_free (error);\n' ' } else {\n' ' g_signal_emit (self, signals[SIGNAL_${signal_id}], 0, output);\n' ' ${output_underscore}_unref (output);\n' ' }\n' ' break;\n' ' }\n') else: # No output field in the indication inner_template += ( ' case ${enum_name}: {\n' ' g_signal_emit (self, signals[SIGNAL_${signal_id}], 0, NULL);\n' ' break;\n' ' }\n') template += string.Template(inner_template).substitute(translations) template += ( ' default:\n' ' break;\n' ' }\n' '}\n' '\n' 'static void\n' '${underscore}_init (${camelcase} *self)\n' '{\n' '}\n' '\n' 'static void\n' '${underscore}_class_init (${camelcase}Class *klass)\n' '{\n' ' QmiClientClass *client_class = QMI_CLIENT_CLASS (klass);\n' '\n' ' client_class->process_indication = process_indication;\n') for message in message_list.list: if message.type == 'Indication': translations['signal_name'] = utils.build_dashed_name(message.name) translations['signal_id'] = utils.build_underscore_uppercase_name(message.name) translations['message_name'] = message.name inner_template = '' if message.output is not None and message.output.fields is not None: # At least one field in the indication translations['output_camelcase'] = utils.build_camelcase_name(message.output.fullname) translations['bundle_type'] = 'QMI_TYPE_' + utils.remove_prefix(utils.build_underscore_uppercase_name(message.output.fullname), 'QMI_') translations['service'] = self.service.upper() translations['message_name_dashed'] = message.name.replace(' ', '-') inner_template += ( '\n' ' /**\n' ' * ${camelcase}::${signal_name}:\n' ' * @object: A #${camelcase}.\n' ' * @output: A #${output_camelcase}.\n' ' *\n' ' * The ::${signal_name} signal gets emitted when a \'<link linkend=\"libqmi-glib-${service}-${message_name_dashed}.top_of_page\">${message_name}</link>\' indication is received.\n' ' */\n' ' signals[SIGNAL_${signal_id}] =\n' ' g_signal_new ("${signal_name}",\n' ' G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),\n' ' G_SIGNAL_RUN_LAST,\n' ' 0,\n' ' NULL,\n' ' NULL,\n' ' NULL,\n' ' G_TYPE_NONE,\n' ' 1,\n' ' ${bundle_type});\n') else: # No output field in the indication inner_template += ( '\n' ' /**\n' ' * ${camelcase}::${signal_name}:\n' ' * @object: A #${camelcase}.\n' ' *\n' ' * The ::${signal_name} signal gets emitted when a \'${message_name}\' indication is received.\n' ' */\n' ' signals[SIGNAL_${signal_id}] =\n' ' g_signal_new ("${signal_name}",\n' ' G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),\n' ' G_SIGNAL_RUN_LAST,\n' ' 0,\n' ' NULL,\n' ' NULL,\n' ' NULL,\n' ' G_TYPE_NONE,\n' ' 0);\n') template += string.Template(inner_template).substitute(translations) template += ( '}\n' '\n') cfile.write(string.Template(template).substitute(translations))
def __emit_request_creator(self, hfile, cfile): translations = { 'name' : self.name, 'service' : self.service, 'container' : utils.build_camelcase_name (self.input.fullname), 'underscore' : utils.build_underscore_name (self.fullname), 'message_id' : self.id_enum_name } input_arg_template = 'gpointer unused' if self.input.fields is None else '${container} *input' template = ( '\n' 'static QmiMessage *\n' '__${underscore}_request_create (\n' ' guint16 transaction_id,\n' ' guint8 cid,\n' ' %s,\n' ' GError **error)\n' '{\n' ' QmiMessage *self;\n' '\n' ' self = qmi_message_new (QMI_SERVICE_${service},\n' ' cid,\n' ' transaction_id,\n' ' ${message_id});\n' % input_arg_template) cfile.write(string.Template(template).substitute(translations)) if self.input.fields is not None: # Count how many mandatory fields we have n_mandatory = 0 for field in self.input.fields: if field.mandatory == 'yes': n_mandatory += 1 if n_mandatory == 0: # If we don't have mandatory fields, we do allow to have # a NULL input cfile.write( '\n' ' /* All TLVs are optional, we allow NULL input */\n' ' if (!input)\n' ' return self;\n') else: # If we do have mandatory fields, issue error if no input # given. template = ( '\n' ' /* There is at least one mandatory TLV, don\'t allow NULL input */\n' ' if (!input) {\n' ' g_set_error (error,\n' ' QMI_CORE_ERROR,\n' ' QMI_CORE_ERROR_INVALID_ARGS,\n' ' "Message \'${name}\' has mandatory TLVs");\n' ' goto error_out;\n' ' }\n') cfile.write(string.Template(template).substitute(translations)) # Now iterate fields for field in self.input.fields: translations['tlv_name'] = field.name translations['variable_name'] = field.variable_name template = ( '\n' ' /* Try to add the \'${tlv_name}\' TLV */\n' ' if (input->${variable_name}_set) {\n') cfile.write(string.Template(template).substitute(translations)) # Emit the TLV getter field.emit_input_tlv_add(cfile, ' ') if field.mandatory == 'yes': template = ( ' } else {\n' ' g_set_error (error,\n' ' QMI_CORE_ERROR,\n' ' QMI_CORE_ERROR_INVALID_ARGS,\n' ' "Missing mandatory TLV \'${tlv_name}\' in message \'${name}\'");\n' ' goto error_out;\n') cfile.write(string.Template(template).substitute(translations)) cfile.write( ' }\n') cfile.write( '\n' ' return self;\n') if self.input.fields is not None: cfile.write( '\n' 'error_out:\n' ' qmi_message_unref (self);\n' ' return NULL;\n') cfile.write( '}\n')