source: mainline/tools/xstruct.py@ 81475250

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 81475250 was 6582b36, checked in by Sean Bartell <wingedtachikoma@…>, 13 years ago

Make some scripts work with Python 3.

Arch Linux has already switched so "python" means version 3, so these
scripts don't run otherwise. Only the simplest fixes are made. Note that
automatic int-to-long conversion has existed since at least Python 2.4.

  • Property mode set to 100644
File size: 4.5 KB
RevLine 
[8c25a4a]1#
2# Copyright (c) 2008 Martin Decky
[cc1a727]3# Copyright (c) 2011 Martin Sucha
[8c25a4a]4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9#
10# - Redistributions of source code must retain the above copyright
11# notice, this list of conditions and the following disclaimer.
12# - Redistributions in binary form must reproduce the above copyright
13# notice, this list of conditions and the following disclaimer in the
14# documentation and/or other materials provided with the distribution.
15# - The name of the author may not be used to endorse or promote products
16# derived from this software without specific prior written permission.
17#
18# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28#
29"""
[0516fd7]30Convert descriptive structure definitions to structure object
[8c25a4a]31"""
32
33import struct
[6582b36]34import sys
[cc1a727]35import types
36
[6582b36]37integer_types = (int, long) if sys.version < '3' else (int,)
38
[cc1a727]39ranges = {
[6582b36]40 'B': (integer_types, 0x00, 0xff),
41 'H': (integer_types, 0x0000, 0xffff),
42 'L': (integer_types, 0x00000000, 0xffffffff),
43 'Q': (integer_types, 0x0000000000000000, 0xffffffffffffffff),
44 'b': (integer_types, -0x80, 0x7f),
45 'h': (integer_types, -0x8000, 0x7fff),
46 'l': (integer_types, -0x80000000, 0x7fffffff) ,
47 'q': (integer_types, -0x8000000000000000, 0x7fffffffffffffff),
[cc1a727]48}
49
50def check_range(varname, fmt, value):
51 if value == None:
52 raise ValueError('Variable "%s" not set' % varname)
53 if not fmt in ranges:
54 return
55 vartype, varmin, varmax = ranges[fmt]
56 if not isinstance(value, vartype):
57 raise ValueError('Variable "%s" is %s but should be %s' %
58 (varname, str(type(value)), str(vartype)))
59 if value < varmin or value > varmax:
60 raise ValueError('Variable "%s" value %s out of range %s..%s' %
61 (varname, repr(value), repr(varmin), repr(varmax)))
[8c25a4a]62
[0516fd7]63class Struct:
64 def size(self):
65 return struct.calcsize(self._format_)
66
67 def pack(self):
[5749372]68 args = []
[cc1a727]69 for variable, fmt, length in self._args_:
70 value = self.__dict__[variable]
71 if isinstance(value, list):
72 if length != None and length != len(value):
73 raise ValueError('Variable "%s" length %u does not match %u' %
74 (variable, len(value), length))
75 for index, item in enumerate(value):
76 check_range(variable + '[' + repr(index) + ']', fmt, item)
[5749372]77 args.append(item)
78 else:
[cc1a727]79 check_range(variable, fmt, value)
80 args.append(value)
[5749372]81 return struct.pack(self._format_, *args)
[cc1a727]82
83 def unpack(self, data):
84 values = struct.unpack(self._format_, data)
85 i = 0
86 for variable, fmt, length in self._args_:
87 self.__dict__[variable] = values[i]
88 i += 1
[0516fd7]89
90def create(definition):
91 "Create structure object"
[8c25a4a]92
93 tokens = definition.split(None)
94
95 # Initial byte order tag
[0516fd7]96 format = {
[8c25a4a]97 "little:": lambda: "<",
98 "big:": lambda: ">",
99 "network:": lambda: "!"
100 }[tokens[0]]()
[0516fd7]101 inst = Struct()
[5749372]102 args = []
[b3105ff6]103
[8c25a4a]104 # Member tags
[b3105ff6]105 comment = False
[8f2a852]106 variable = None
[8c25a4a]107 for token in tokens[1:]:
[b3105ff6]108 if (comment):
109 if (token == "*/"):
110 comment = False
111 continue
112
113 if (token == "/*"):
114 comment = True
[8f2a852]115 continue
116
117 if (variable != None):
118 subtokens = token.split("[")
119
[cc1a727]120 length = None
[8f2a852]121 if (len(subtokens) > 1):
[cc1a727]122 length = int(subtokens[1].split("]")[0])
123 format += "%d" % length
[8f2a852]124
125 format += variable
126
127 inst.__dict__[subtokens[0]] = None
[cc1a727]128 args.append((subtokens[0], variable, length))
[8f2a852]129
130 variable = None
131 continue
132
133 if (token[0:8] == "padding["):
[0516fd7]134 size = token[8:].split("]")[0]
135 format += "%dx" % int(size)
[8f2a852]136 continue
137
138 variable = {
139 "char": lambda: "s",
140 "uint8_t": lambda: "B",
141 "uint16_t": lambda: "H",
142 "uint32_t": lambda: "L",
143 "uint64_t": lambda: "Q",
144
145 "int8_t": lambda: "b",
146 "int16_t": lambda: "h",
147 "int32_t": lambda: "l",
148 "int64_t": lambda: "q"
149 }[token]()
[8c25a4a]150
[0516fd7]151 inst.__dict__['_format_'] = format
[5749372]152 inst.__dict__['_args_'] = args
[0516fd7]153 return inst
Note: See TracBrowser for help on using the repository browser.