libqmi-qmuxd/build-aux/qmi-codegen/VariableInteger.py

388 lines
16 KiB
Python
Raw Normal View History

#!/usr/bin/env python
# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option) any
# later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Copyright (C) 2012 Lanedo GmbH
#
import string
import utils
from Variable import Variable
"""
Variable type for signed/unsigned Integers
('guint8', 'gint8', 'guint16', 'gint16', 'guint32', 'gint32', 'guint64', 'gint64' 'guint-sized' formats)
"""
class VariableInteger(Variable):
"""
Constructor
"""
def __init__(self, dictionary):
# Call the parent constructor
Variable.__init__(self, dictionary)
self.guint_sized_size = ''
if self.format == "guint-sized":
if 'guint-size' not in dictionary:
raise RuntimeError('Format \'guint-sized\' requires \'guint-size\' parameter')
else:
self.guint_sized_size = dictionary['guint-size']
self.private_format = 'guint64'
self.public_format = 'guint64'
else:
self.private_format = self.format
self.public_format = dictionary['public-format'] if 'public-format' in dictionary else self.private_format
"""
Read a single integer from the raw byte buffer
"""
def emit_buffer_read(self, f, line_prefix, variable_name, buffer_name, buffer_len):
translations = { 'lp' : line_prefix,
'public_format' : self.public_format,
'private_format' : self.private_format,
'len' : self.guint_sized_size,
'variable_name' : variable_name,
'buffer_name' : buffer_name,
'buffer_len' : buffer_len,
'endian' : self.endian }
if self.format == 'guint-sized':
template = (
'${lp}/* Read the ${len}-byte long variable from the buffer */\n'
'${lp}qmi_utils_read_sized_guint_from_buffer (\n'
'${lp} &${buffer_name},\n'
'${lp} &${buffer_len},\n'
'${lp} ${len},\n'
'${lp} ${endian},\n'
'${lp} &(${variable_name}));\n')
elif self.private_format == self.public_format:
template = (
'${lp}/* Read the ${private_format} variable from the buffer */\n'
'${lp}qmi_utils_read_${private_format}_from_buffer (\n'
'${lp} &${buffer_name},\n'
'${lp} &${buffer_len},\n')
if self.private_format != 'guint8' and self.private_format != 'gint8':
template += (
'${lp} ${endian},\n')
template += (
'${lp} &(${variable_name}));\n')
else:
template = (
'${lp}{\n'
'${lp} ${private_format} tmp;\n'
'\n'
'${lp} /* Read the ${private_format} variable from the buffer */\n'
'${lp} qmi_utils_read_${private_format}_from_buffer (\n'
'${lp} &${buffer_name},\n'
'${lp} &${buffer_len},\n')
if self.private_format != 'guint8' and self.private_format != 'gint8':
template += (
'${lp} ${endian},\n')
template += (
'${lp} &tmp);\n'
'${lp} ${variable_name} = (${public_format})tmp;\n'
'${lp}}\n')
f.write(string.Template(template).substitute(translations))
"""
Emits the code involved in computing the size of the variable.
"""
def emit_size_read(self, f, line_prefix, variable_name, buffer_name, buffer_len):
translations = { 'lp' : line_prefix,
'len' : self.guint_sized_size,
'variable_name' : variable_name }
template = ''
if self.format == 'guint-sized':
template += (
'${lp}${variable_name} += ${len};\n')
elif self.private_format == 'guint8' or self.private_format == 'gint8':
template += (
'${lp}${variable_name} += 1;\n')
elif self.private_format == 'guint16' or self.private_format == 'gint16':
template += (
'${lp}${variable_name} += 2;\n')
elif self.private_format == 'guint32' or self.private_format == 'gint32':
template += (
'${lp}${variable_name} += 4;\n')
elif self.private_format == 'guint64' or self.private_format == 'gint64':
template += (
'${lp}${variable_name} += 8;\n')
f.write(string.Template(template).substitute(translations))
"""
Write a single integer to the raw byte buffer
"""
def emit_buffer_write(self, f, line_prefix, variable_name, buffer_name, buffer_len):
translations = { 'lp' : line_prefix,
'private_format' : self.private_format,
'len' : self.guint_sized_size,
'variable_name' : variable_name,
'buffer_name' : buffer_name,
'buffer_len' : buffer_len,
'endian' : self.endian }
if self.format == 'guint-sized':
template = (
'${lp}/* Write the ${len}-byte long variable to the buffer */\n'
'${lp}qmi_utils_write_sized_guint_to_buffer (\n'
'${lp} &${buffer_name},\n'
'${lp} &${buffer_len},\n'
'${lp} ${len},\n'
'${lp} ${endian},\n'
'${lp} &(${variable_name}));\n')
elif self.private_format == self.public_format:
template = (
'${lp}/* Write the ${private_format} variable to the buffer */\n'
'${lp}qmi_utils_write_${private_format}_to_buffer (\n'
'${lp} &${buffer_name},\n'
'${lp} &${buffer_len},\n')
if self.private_format != 'guint8' and self.private_format != 'gint8':
template += (
'${lp} ${endian},\n')
template += (
'${lp} &(${variable_name}));\n')
else:
template = (
'${lp}{\n'
'${lp} ${private_format} tmp;\n'
'\n'
'${lp} tmp = (${private_format})${variable_name};\n'
'${lp} /* Write the ${private_format} variable to the buffer */\n'
'${lp} qmi_utils_write_${private_format}_to_buffer (\n'
'${lp} &${buffer_name},\n'
'${lp} &${buffer_len},\n')
if self.private_format != 'guint8' and self.private_format != 'gint8':
template += (
'${lp} ${endian},\n')
template += (
'${lp} &tmp);\n'
'${lp}}\n')
f.write(string.Template(template).substitute(translations))
"""
Get the integer as a printable string.
"""
def emit_get_printable(self, f, line_prefix, printable, buffer_name, buffer_len):
common_format = ''
common_cast = ''
if self.private_format == 'guint8':
common_format = '%u'
common_cast = '(guint)'
elif self.private_format == 'guint16':
common_format = '%" G_GUINT16_FORMAT "'
elif self.private_format == 'guint32':
common_format = '%" G_GUINT32_FORMAT "'
elif self.private_format == 'guint64':
common_format = '%" G_GUINT64_FORMAT "'
elif self.private_format == 'gint8':
common_format = '%d'
common_cast = '(gint)'
elif self.private_format == 'gint16':
common_format = '%" G_GINT16_FORMAT "'
elif self.private_format == 'gint32':
common_format = '%" G_GINT32_FORMAT "'
elif self.private_format == 'gint64':
common_format = '%" G_GINT64_FORMAT "'
translations = { 'lp' : line_prefix,
'private_format' : self.private_format,
'public_format' : self.public_format,
'len' : self.guint_sized_size,
'printable' : printable,
'buffer_name' : buffer_name,
'buffer_len' : buffer_len,
'common_format' : common_format,
'common_cast' : common_cast,
'endian' : self.endian }
template = (
'\n'
'${lp}{\n'
'${lp} ${private_format} tmp;\n'
'\n')
if self.format == 'guint-sized':
template += (
'${lp} /* Read the ${len}-byte long variable from the buffer */\n'
'${lp} qmi_utils_read_sized_guint_from_buffer (\n'
'${lp} &${buffer_name},\n'
'${lp} &${buffer_len},\n'
'${lp} ${len},\n'
'${lp} ${endian},\n'
'${lp} &tmp);\n'
'\n')
else:
template += (
'${lp} /* Read the ${private_format} variable from the buffer */\n'
'${lp} qmi_utils_read_${private_format}_from_buffer (\n'
'${lp} &${buffer_name},\n'
'${lp} &${buffer_len},\n')
if self.private_format != 'guint8' and self.private_format != 'gint8':
template += (
'${lp} ${endian},\n')
template += (
'${lp} &tmp);\n'
'\n')
if self.public_format == 'gboolean':
template += (
'${lp} g_string_append_printf (${printable}, "%s", tmp ? "yes" : "no");\n')
elif self.public_format != self.private_format:
translations['public_type_underscore'] = utils.build_underscore_name_from_camelcase(self.public_format)
translations['public_type_underscore_upper'] = utils.build_underscore_name_from_camelcase(self.public_format).upper()
template += (
'#if defined __${public_type_underscore_upper}_IS_ENUM__\n'
'${lp} g_string_append_printf (${printable}, "%s", ${public_type_underscore}_get_string ((${public_format})tmp));\n'
'#elif defined __${public_type_underscore_upper}_IS_FLAGS__\n'
'${lp} {\n'
'${lp} gchar *flags_str;\n'
'\n'
'${lp} flags_str = ${public_type_underscore}_build_string_from_mask ((${public_format})tmp);\n'
'${lp} g_string_append_printf (${printable}, "%s", flags_str);\n'
'${lp} g_free (flags_str);\n'
'${lp} }\n'
'#else\n'
'# error unexpected public format: ${public_format}\n'
'#endif\n')
else:
template += (
'${lp} g_string_append_printf (${printable}, "${common_format}", ${common_cast}tmp);\n')
template += (
'${lp}}\n')
f.write(string.Template(template).substitute(translations))
"""
Variable declaration
"""
def build_variable_declaration(self, line_prefix, variable_name):
translations = { 'lp' : line_prefix,
'private_format' : self.private_format,
'name' : variable_name }
template = (
'${lp}${private_format} ${name};\n')
return string.Template(template).substitute(translations)
"""
Getter for the integer type
"""
def build_getter_declaration(self, line_prefix, variable_name):
translations = { 'lp' : line_prefix,
'public_format' : self.public_format,
'name' : variable_name }
template = (
'${lp}${public_format} *${name},\n')
return string.Template(template).substitute(translations)
"""
Documentation for the getter
"""
def build_getter_documentation(self, line_prefix, variable_name):
translations = { 'lp' : line_prefix,
'public_format' : self.public_format,
'name' : variable_name }
template = (
'${lp}@${name}: a placeholder for the output #${public_format}, or %NULL if not required.\n')
return string.Template(template).substitute(translations)
"""
Builds the Integer getter implementation
"""
def build_getter_implementation(self, line_prefix, variable_name_from, variable_name_to, to_is_reference):
needs_cast = True if self.public_format != self.private_format else False
translations = { 'lp' : line_prefix,
'from' : variable_name_from,
'to' : variable_name_to,
'cast_ini' : '(' + self.public_format + ')(' if needs_cast else '',
'cast_end' : ')' if needs_cast else '' }
if to_is_reference:
template = (
'${lp}if (${to})\n'
'${lp} *${to} = ${cast_ini}${from}${cast_end};\n')
return string.Template(template).substitute(translations)
else:
template = (
'${lp}${to} = ${cast_ini}${from}${cast_end};\n')
return string.Template(template).substitute(translations)
"""
Setter for the integer type
"""
def build_setter_declaration(self, line_prefix, variable_name):
translations = { 'lp' : line_prefix,
'public_format' : self.public_format,
'name' : variable_name }
template = (
'${lp}${public_format} ${name},\n')
return string.Template(template).substitute(translations)
"""
Documentation for the setter
"""
def build_setter_documentation(self, line_prefix, variable_name):
translations = { 'lp' : line_prefix,
'public_format' : self.public_format,
'name' : variable_name }
template = (
'${lp}@${name}: a #${public_format}.\n')
return string.Template(template).substitute(translations)
"""
Implementation of the setter
"""
def build_setter_implementation(self, line_prefix, variable_name_from, variable_name_to):
needs_cast = True if self.public_format != self.private_format else False
translations = { 'lp' : line_prefix,
'from' : variable_name_from,
'to' : variable_name_to,
'cast_ini' : '(' + self.private_format + ')(' if needs_cast else '',
'cast_end' : ')' if needs_cast else '' }
template = (
'${lp}${to} = ${cast_ini}${from}${cast_end};\n')
return string.Template(template).substitute(translations)
"""
Documentation for the struct field
"""
def build_struct_field_documentation(self, line_prefix, variable_name):
translations = { 'lp' : line_prefix,
'public_format' : self.public_format,
'name' : variable_name }
template = (
'${lp}@${name}: a #${public_format}.\n')
return string.Template(template).substitute(translations)