diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2017-02-10 00:17:29 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2017-02-10 18:57:05 +0100 |
commit | 5c3113f099a3c637820f6d6e35a314f1f179bb46 (patch) | |
tree | b90fc74143cd69fc94ced33658a280472a24c6c6 | |
parent | 0e7544ca722078e979b5497f721139dc2bca3e28 (diff) | |
download | external_libqmi-5c3113f099a3c637820f6d6e35a314f1f179bb46.zip external_libqmi-5c3113f099a3c637820f6d6e35a314f1f179bb46.tar.gz external_libqmi-5c3113f099a3c637820f6d6e35a314f1f179bb46.tar.bz2 |
libqmi,codegen: allow specifying 'since' tags for each message and TLV
The 'since' tag specifies in which major stable version the given
message or TLV was introduced.
-rw-r--r-- | build-aux/qmi-codegen/Client.py | 72 | ||||
-rw-r--r-- | build-aux/qmi-codegen/Container.py | 63 | ||||
-rw-r--r-- | build-aux/qmi-codegen/Field.py | 47 | ||||
-rw-r--r-- | build-aux/qmi-codegen/FieldResult.py | 21 | ||||
-rw-r--r-- | build-aux/qmi-codegen/Message.py | 12 |
5 files changed, 133 insertions, 82 deletions
diff --git a/build-aux/qmi-codegen/Client.py b/build-aux/qmi-codegen/Client.py index 32e1e0d..cf957cc 100644 --- a/build-aux/qmi-codegen/Client.py +++ b/build-aux/qmi-codegen/Client.py @@ -40,6 +40,7 @@ class Client: for object_dictionary in objects_dictionary: if object_dictionary['type'] == 'Client': self.name = object_dictionary['name'] + self.since = object_dictionary['since'] if 'since' in object_dictionary else '' elif object_dictionary['type'] == 'Service': self.service = object_dictionary['name'] @@ -49,7 +50,6 @@ class Client: if self.service is None: raise ValueError('Missing Service field') - """ Emits the generic GObject class implementation """ @@ -66,6 +66,7 @@ class Client: '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), + 'since' : self.since, 'service' : self.service.upper() } # Emit class header @@ -85,6 +86,8 @@ class Client: ' *\n' ' * The #${camelcase} structure contains private data and should only be accessed\n' ' * using the provided API.\n' + ' *\n' + ' * Since: ${since}\n' ' */\n' 'struct _${camelcase} {\n' ' /*< private >*/\n' @@ -204,6 +207,7 @@ class Client: translations['signal_name'] = utils.build_dashed_name(message.name) translations['signal_id'] = utils.build_underscore_uppercase_name(message.name) translations['message_name'] = message.name + translations['since'] = message.since inner_template = '' if message.output is not None and message.output.fields is not None: # At least one field in the indication @@ -219,6 +223,8 @@ class Client: ' * @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' + ' * Since: ${since}\n' ' */\n' ' signals[SIGNAL_${signal_id}] =\n' ' g_signal_new ("${signal_name}",\n' @@ -240,6 +246,8 @@ class Client: ' * @object: A #${camelcase}.\n' ' *\n' ' * The ::${signal_name} signal gets emitted when a \'${message_name}\' indication is received.\n' + ' *\n' + ' * Since: ${since}\n' ' */\n' ' signals[SIGNAL_${signal_id}] =\n' ' g_signal_new ("${signal_name}",\n' @@ -285,31 +293,42 @@ class Client: 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: - input_arg_template = 'gpointer unused' + translations['input_arg'] = '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_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' + ' *\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' - ' %s,\n' + ' ${input_arg},\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' @@ -320,7 +339,17 @@ class Client: ' * 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' @@ -433,27 +462,10 @@ class Client: ' 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 += ( + ' ${camelcase} *self,\n' + ' ${input_arg},\n' ' guint timeout,\n' ' GCancellable *cancellable,\n' ' GAsyncReadyCallback callback,\n' diff --git a/build-aux/qmi-codegen/Container.py b/build-aux/qmi-codegen/Container.py index 46e4ddf..d35e236 100644 --- a/build-aux/qmi-codegen/Container.py +++ b/build-aux/qmi-codegen/Container.py @@ -33,7 +33,7 @@ class Container: """ Constructor """ - def __init__(self, prefix, container_type, dictionary, common_objects_dictionary, static): + def __init__(self, prefix, container_type, dictionary, common_objects_dictionary, static, since): # The field container prefix usually contains the name of the Message, # e.g. "Qmi Message Ctl Something" self.prefix = prefix @@ -49,6 +49,7 @@ class Container: self.name = container_type self.static = static + self.since = since # Create the composed full name (prefix + name), # e.g. "Qmi Message Ctl Something Output" @@ -70,6 +71,11 @@ class Container: copy = dict(common) if 'prerequisites' in field_dictionary: copy['prerequisites'] = field_dictionary['prerequisites'] + # Fix 'since' in the copy + if 'since' in field_dictionary: + copy['since'] = field_dictionary['since'] + else: + copy['since'] = self.since new_dict.append(copy) break else: @@ -126,6 +132,8 @@ class Container: ' *\n' ' * The #${camelcase} structure contains private data and should only be accessed\n' ' * using the provided API.\n' + ' *\n' + ' * Since: ${since}\n' ' */\n' 'typedef struct _${camelcase} ${camelcase};\n' '${static}GType ${underscore}_get_type (void) G_GNUC_CONST;\n' @@ -163,10 +171,40 @@ class Container: # Emit container core header template = ( '\n' + '/**\n' + ' * ${underscore}_ref:\n' + ' * @self: a #${camelcase}.\n' + ' *\n' + ' * Atomically increments the reference count of @self by one.\n' + ' *\n' + ' * Returns: the new reference to @self.\n' + ' *\n' + ' * Since: ${since}\n' + ' */\n' '${static}${camelcase} *${underscore}_ref (${camelcase} *self);\n' + '\n' + '/**\n' + ' * ${underscore}_unref:\n' + ' * @self: a #${camelcase}.\n' + ' *\n' + ' * Atomically decrements the reference count of @self by one.\n' + ' * If the reference count drops to 0, @self is completely disposed.\n' + ' *\n' + ' * Since: ${since}\n' + ' */\n' '${static}void ${underscore}_unref (${camelcase} *self);\n') if self.readonly == False: template += ( + '\n' + '/**\n' + ' * ${underscore}_new:\n' + ' *\n' + ' * Allocates a new #${camelcase}.\n' + ' *\n' + ' * Returns: the newly created #${camelcase}. The returned value should be freed with ${underscore}_unref().\n' + ' *\n' + ' * Since: ${since}\n' + ' */\n' '${static}${camelcase} *${underscore}_new (void);\n') if self.static: @@ -194,14 +232,6 @@ class Container: ' return g_define_type_id__volatile;\n' '}\n' '\n' - '/**\n' - ' * ${underscore}_ref:\n' - ' * @self: a #${camelcase}.\n' - ' *\n' - ' * Atomically increments the reference count of @self by one.\n' - ' *\n' - ' * Returns: the new reference to @self.\n' - ' */\n' '${static}${camelcase} *\n' '${underscore}_ref (${camelcase} *self)\n' '{\n' @@ -211,13 +241,6 @@ class Container: ' return self;\n' '}\n' '\n' - '/**\n' - ' * ${underscore}_unref:\n' - ' * @self: a #${camelcase}.\n' - ' *\n' - ' * Atomically decrements the reference count of @self by one.\n' - ' * If the reference count drops to 0, @self is completely disposed.\n' - ' */\n' '${static}void\n' '${underscore}_unref (${camelcase} *self)\n' '{\n' @@ -242,13 +265,6 @@ class Container: template = ( '\n' - '/**\n' - ' * ${underscore}_new:\n' - ' *\n' - ' * Allocates a new #${camelcase}.\n' - ' *\n' - ' * Returns: the newly created #${camelcase}. The returned value should be freed with ${underscore}_unref().\n' - ' */\n' '${static}${camelcase} *\n' '${underscore}_new (void)\n' '{\n' @@ -268,6 +284,7 @@ class Container: translations = { 'name' : self.name, 'camelcase' : utils.build_camelcase_name (self.fullname), 'underscore' : utils.build_underscore_name (self.fullname), + 'since' : self.since, 'static' : 'static ' if self.static else '' } auxfile = cfile if self.static else hfile diff --git a/build-aux/qmi-codegen/Field.py b/build-aux/qmi-codegen/Field.py index 1c4ac90..0f73b06 100644 --- a/build-aux/qmi-codegen/Field.py +++ b/build-aux/qmi-codegen/Field.py @@ -53,6 +53,11 @@ class Field: # e.g. "Qmi Message Ctl Something Output Result" self.fullname = dictionary['fullname'] if 'fullname' in dictionary else self.prefix + ' ' + self.name + # libqmi version where the message was introduced + self.since = dictionary['since'] if 'since' in dictionary else None + if self.since is None: + raise ValueError('TLV ' + self.fullname + ' requires a "since" tag specifying the major version where it was introduced') + # Create our variable object self.variable = VariableFactory.create_variable(dictionary, self.fullname, self.container_type) @@ -108,20 +113,12 @@ class Field: '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' - '${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' @@ -131,7 +128,18 @@ class Field: ' * 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' @@ -172,20 +180,12 @@ class Field: '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' - '${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' @@ -195,7 +195,18 @@ class Field: ' * 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' diff --git a/build-aux/qmi-codegen/FieldResult.py b/build-aux/qmi-codegen/FieldResult.py index 6b7b91e..9b39e82 100644 --- a/build-aux/qmi-codegen/FieldResult.py +++ b/build-aux/qmi-codegen/FieldResult.py @@ -48,19 +48,12 @@ class FieldResult(Field): 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) } + 'prefix_underscore' : utils.build_underscore_name(self.prefix), + 'since' : self.since } # 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' @@ -69,7 +62,17 @@ class FieldResult(Field): ' * Get the result of the QMI operation.\n' ' *\n' ' * Returns: %TRUE if the QMI operation succeeded, %FALSE if @error is set.\n' + ' *\n' + ' * Since: ${since}\n' ' */\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' 'gboolean\n' '${prefix_underscore}_get_result (\n' ' ${prefix_camelcase} *self,\n' diff --git a/build-aux/qmi-codegen/Message.py b/build-aux/qmi-codegen/Message.py index 9c78cf5..3460150 100644 --- a/build-aux/qmi-codegen/Message.py +++ b/build-aux/qmi-codegen/Message.py @@ -38,6 +38,7 @@ class Message: self.name = dictionary['name'] # The specific message ID self.id = dictionary['id'] + # The type, which must always be 'Message' or 'Indication' self.type = dictionary['type'] # The version info, optional @@ -45,6 +46,11 @@ class Message: self.static = True if 'scope' in dictionary and dictionary['scope'] == 'library-only' else False self.abort = True if 'abort' in dictionary and dictionary['abort'] == 'yes' else False + # libqmi version where the message was introduced + self.since = dictionary['since'] if 'since' in dictionary else None + if self.since is None: + raise ValueError('Message ' + self.name + ' requires a "since" tag specifying the major version where it was introduced') + # The vendor id if this command is vendor specific self.vendor = dictionary['vendor'] if 'vendor' in dictionary else None if self.type == 'Indication' and self.vendor is not None: @@ -69,7 +75,8 @@ class Message: 'Output', dictionary['output'] if 'output' in dictionary else None, common_objects_dictionary, - self.static) + self.static, + self.since) self.input = None if self.type == 'Message': @@ -81,7 +88,8 @@ class Message: 'Input', dictionary['input'] if 'input' in dictionary else None, common_objects_dictionary, - self.static) + self.static, + self.since) """ |