Go to the documentation of this file.00001 """
00002 Created on Nov 22, 2014
00003
00004 Software License Agreement (BSD License)
00005 Copyright (c) 2014, LABUST, UNIZG-FER
00006 All rights reserved.
00007
00008 Redistribution and use in source and binary forms, with or without
00009 modification, are permitted provided that the following conditions
00010 are met:
00011
00012 * Redistributions of source code must retain the above copyright
00013 notice, this list of conditions and the following disclaimer.
00014 * Redistributions in binary form must reproduce the above
00015 copyright notice, this list of conditions and the following
00016 disclaimer in the documentation and/or other materials provided
00017 with the distribution.
00018 * Neither the name of the LABUST nor the names of its
00019 contributors may be used to endorse or promote products derived
00020 from this software without specific prior written permission.
00021
00022 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033 POSSIBILITY OF SUCH DAMAGE.
00034
00035 @author: Dula Nad
00036 """
00037
00038 from .variable import Variable
00039 from .enum import Enum
00040
00041 class Structure:
00042 """
00043 Represents the C++ data structure in the object form.
00044
00045 Class attributes:
00046 _XMLTAG -- constant string with the xml tag description
00047 """
00048 _XMLTAG = 'struct'
00049
00050 class VarGroup:
00051 """
00052 Represents a variable group inside the structure object.
00053
00054 Class attributes:
00055 _XMLTAG -- constant string with the xml tag description
00056 """
00057 _XMLTAG = 'group'
00058
00059 def __init__(self, xmlnode = None):
00060 """
00061 Populates the structure from a XML node info.
00062 When the XML node is not defined, does nothing.
00063
00064 xmlnode -- the XML node with the member definition
00065
00066 Instance attributes:
00067 gvariables -- the member variables list
00068 gcond -- the group conditional
00069 """
00070 self.gcond = None
00071
00072 if xmlnode != None: self.from_xml(xmlnode)
00073
00074 def from_xml(self, xmlnode):
00075 """
00076 Extracts the group attributes from the XML node.
00077 Memeber variables are extracted from the child
00078 nodes as well.
00079
00080 xmlnode -- the XML node with the member definition
00081 """
00082
00083 if xmlnode.tag != self._XMLTAG:
00084 raise NameError(self.__class__.__name__ +
00085 ' expected XML tag: "' +
00086 self._XMLTAG +
00087 '"')
00088
00089 self.gcond = xmlnode.get('if', self.gcond)
00090
00091 for node in xmlnode.findall(Variable._XMLTAG):
00092 self.gvariables.append(Variable(node))
00093
00094
00095 def __init__(self, xmlnode = None):
00096 """
00097 Populates the structure from a XML node info.
00098 When the XML node is not defined, does nothing.
00099
00100 xmlnode -- the XML node with the member definition
00101
00102 Instance attributes:
00103 sname -- name of the structure
00104 sinherit -- the class that is inherited
00105 svariables -- the direct member variables list
00106 sgroups -- the grouped member variables list
00107 smethods -- the member methods list
00108 senums -- the enumerations list
00109 sassert_size -- add size assertion in bytes (useful for bitfields)
00110 sserialization -- the type of serialization (defaults to object serializable)
00111 sid -- the numeric id constant (useful for command structs)
00112 """
00113 self.sname = 'Unnamed'
00114 self.sinherit = None
00115 self.svariables = []
00116 self.sgroups = []
00117 self.smethods = []
00118 self.stypedefs = []
00119 self.senums = []
00120 self.sassert_size = None
00121 self.sserialization = 'object_serializable'
00122
00123 if xmlnode != None: self.from_xml(xmlnode)
00124
00125 def from_xml(self, xmlnode):
00126 """
00127 Extracts the structure attributes from the XML node.
00128 Memeber variables and functions are extracted from the
00129 child nodes as well.
00130
00131 xmlnode -- the XML node with the member definition
00132 """
00133
00134 if xmlnode.tag != self._XMLTAG:
00135 raise NameError(self.__class__.__name__ +
00136 ' expected XML tag: "' +
00137 self._XMLTAG +
00138 '"')
00139
00140 self.sname = xmlnode.get('name', self.sname)
00141 self.sinherit = xmlnode.get('inherit', self.sinherit)
00142 self.sassert_size = xmlnode.get('assert_size', self.sassert_size)
00143 self.sserialization = xmlnode.get('serialization', self.sserialization)
00144
00145 for node in xmlnode.findall('.//'+Variable._XMLTAG):
00146 self.svariables.append(Variable(node))
00147
00148 for node in xmlnode.findall(Enum._XMLTAG):
00149 self.senums.append(Enum(node))
00150
00151 def gen_code(self, bindent = '', indent = ' '):
00152 """
00153 Generates the full structure definition C++ code and
00154 returns it as a string.
00155
00156 bindent -- the current indent in the document
00157 indent -- the usual minimum indentation
00158 """
00159 code = bindent + indent + 'struct ' + self.sname
00160 if self.sinherit != None:
00161 code = code + ': public ' + self.sinherit
00162
00163 code = code + '\n{\n'
00164
00165 for t in self.stypedefs:
00166 code = code + 'typedef ' + t[0] + ' ' + t[1] + ';\n'
00167
00168 for enum in self.senums:
00169 code = code + enum.gen_code() + '\n'
00170
00171 if len(self.senums): code = code + '\n'
00172
00173 for method in self.smethods:
00174 code = code + method.gen_code() + '\n'
00175
00176 for var in self.svariables:
00177 code = code + var.gen_code() + '\n'
00178
00179 code = code + '};\n'
00180
00181 if self.sassert_size != None:
00182 code = code + ('BOOST_STATIC_ASSERT((sizeof(' + self.sname +') == ' +
00183 self.sassert_size + ')' + ' && ("' + self.sname +
00184 ' structure is assumed as size ' + self.sassert_size +
00185 ' bytes."));\n')
00186
00187 return code
00188
00189 def gen_impl(self, bindent = '', indent = ' '):
00190 """
00191 Generates the method implementations in C++ code and
00192 returns it as a string.
00193
00194 bindent -- the current indent in the document
00195 indent -- the usual minimum indentation
00196 """
00197 code = ''
00198 for method in self.smethods:
00199 code = code + method.gen_impl(namespace=self.sname) + '\n'
00200
00201 return code
00202
00203 def __str__(self):
00204 """
00205 Overriden string specifier returns the C++ code snippet
00206 without indentation.
00207 """
00208 return self.gen_code(indent = '')
00209
00210
00211