|
1 # Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 # All rights reserved. |
|
3 # This component and the accompanying materials are made available |
|
4 # under the terms of "Eclipse Public License v1.0" |
|
5 # which accompanies this distribution, and is available |
|
6 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 # |
|
8 # Initial Contributors: |
|
9 # Nokia Corporation - initial contribution. |
|
10 # |
|
11 # Contributors: |
|
12 # |
|
13 # Description: |
|
14 # |
|
15 |
|
16 |
|
17 import re |
|
18 import ConfigParser |
|
19 |
|
20 from parameter import Parameter |
|
21 from type import Type |
|
22 |
|
23 # Opens and lexes the type spec file. |
|
24 def getTypes(aTypefile): |
|
25 # Add default types, looked up by 'size' |
|
26 types = {'1' : Type('1', 'TUint8', '', 'TUint8', 1, 'AsTUint8', 'PutByte', 'PutTUint8', '', False, False, False, '0x0', '0xff', '', '', ''), |
|
27 '2' : Type('2', 'TUint16', '', 'TUint16', 2, 'AsTUint16', 'PutBytes16', 'PutTUint16', '', False, False, False, '0x0', '0xffff', '', '', ''), |
|
28 '3' : Type('3', 'TUint32', '', 'TUint32', 3, 'AsTUint32', 'PutBytes32', 'PutTUint32', '', False, False, False, '0x0', '0xffffff', '', '', ''), |
|
29 '4' : Type('4', 'TUint32', '', 'TUint32', 4, 'AsTUint32', 'PutBytes32', 'PutTUint32', '', False, False, False, '0x0', '0xffffffff', '', '', ''), |
|
30 '8' : Type('8', 'TUint64', '', 'TUint64', 8, 'AsTUint64', '', 'PutTUint64', '', False, False, False, '0x0', '0xffffffffffffffff', '', '', '')} |
|
31 |
|
32 cfg = ConfigParser.ConfigParser() |
|
33 cfg.read([aTypefile]) |
|
34 |
|
35 for s in cfg.sections(): |
|
36 t = Type(s, |
|
37 cfg.get(s, 'Type'), |
|
38 cfg.get(s, 'RetType'), |
|
39 cfg.get(s, 'EventRetType'), |
|
40 cfg.getint(s, 'Size'), |
|
41 cfg.get(s, 'Getter'), |
|
42 cfg.get(s, 'Setter'), |
|
43 cfg.get(s, 'EventSetter'), |
|
44 cfg.get(s, 'Maker'), |
|
45 cfg.getboolean(s, 'PassByRef'), |
|
46 cfg.getboolean(s, 'ReturnByRef'), |
|
47 cfg.getboolean(s, 'EventReturnByRef'), |
|
48 cfg.get(s, 'MinValue'), |
|
49 cfg.get(s, 'MaxValue'), |
|
50 cfg.get(s, 'CStringAvoider'), |
|
51 cfg.get(s, 'PckgBufType'), |
|
52 cfg.get(s, 'Cast')) |
|
53 types[t.iName] = t |
|
54 |
|
55 return types |
|
56 |
|
57 def checked_regexop(op, regex, string): |
|
58 if op is None or regex is None or string is None: |
|
59 print "Invalid argument passed to checked_regexop"; |
|
60 sys.exit(0); |
|
61 |
|
62 result = op(regex, string); |
|
63 if result == None: |
|
64 print "Regex operation '" + op.__name__ + "' returned None object" |
|
65 print "with regex '" + regex + "'" |
|
66 print "and string '" + string + "'" |
|
67 import sys; |
|
68 sys.exit(0); |
|
69 |
|
70 return result; |
|
71 |
|
72 # Retrieves one line from the command spec file. |
|
73 # Uses a regexp to split the data. |
|
74 def getLines(aLines): |
|
75 if aLines == []: |
|
76 return [] |
|
77 else: |
|
78 m = checked_regexop(re.match, r'([0-9a-zA-Z_,\(\)]+):(,?)(.*)', aLines[0]) |
|
79 |
|
80 name = checked_regexop(re.match, r'([a-zA-Z_]+)', m.group(1)) |
|
81 # we would check_regexop for the extras, but if we don't have any arguments |
|
82 # to pass then we will get a None back.... so we don't want to exit if |
|
83 # the result is None. |
|
84 # ext = checked_regexop(re.search, r'(\([0-9a-zA-Z_,]+\))', m.group(1)) |
|
85 ext = re.search(r'(\([0-9a-zA-Z_,]+\))', m.group(1)) |
|
86 |
|
87 name = name.group(1) |
|
88 if ext == None: |
|
89 ext = "" |
|
90 else: |
|
91 ext = ext.group(1)[1:-1] |
|
92 |
|
93 m = checked_regexop(re.split, r'[^a-zA-Z_0-9@\*]+', m.group(3)) |
|
94 |
|
95 m = filter(lambda (v): len(v) != 0, |
|
96 map(lambda (v): v.strip(), m)) |
|
97 return [(name, ext, m)] + getLines(aLines[1:]) |
|
98 |
|
99 # Retrieves all entries from the command spec file, ignoring lines starting with a #. |
|
100 def getEntries(aFile): |
|
101 return getLines(filter(lambda(e): e[0] != '#', file(aFile).readlines())) |
|
102 |
|
103 # Calculates the size of all parameters used by a command. |
|
104 def calcArrayBlockSize(aParams): |
|
105 blockSize = 0 |
|
106 |
|
107 for p in aParams: |
|
108 if p.iArray != '': |
|
109 blockSize += p.iType.iSize |
|
110 |
|
111 for p in aParams: |
|
112 p.iBlockSize = blockSize |
|
113 |
|
114 # Retrieves a dictionary of the 'folded' entries from the command file. |
|
115 # A folded entry is a list of parameters indexed in the dictionary by the command name. |
|
116 def getFolded(aEntries, aTypes, aHeaderOffset): |
|
117 folded = {} |
|
118 |
|
119 for e in aEntries: |
|
120 folded[e[0]] = (e[1], getParameters(e[2], aTypes, aHeaderOffset)) |
|
121 calcArrayBlockSize(folded[e[0]][1]) |
|
122 |
|
123 return folded |
|
124 |
|
125 # Builds a list of parameters for a command |
|
126 def getParameters(aParams, aTypes, aOffset): |
|
127 if aParams == []: |
|
128 return [] |
|
129 |
|
130 if aParams[0] in aTypes: |
|
131 t = aTypes[aParams[0]] |
|
132 elif aParams[0][0] == '@' and aParams[0][1:] in aTypes: |
|
133 t = aTypes[aParams[0][1:]] |
|
134 else: # Type not known, assume TDesC8 |
|
135 t = aTypes.get(aParams[1], Type(aParams[0], 'TDesC8', 'TPtrC8', 'TPtrC8', aParams[1], 'AsString', 'PutString', 'PutString', '', True, False, False, '_L8("\\x0")', '_L8("\\xff")', 'UnknownType_instance', '', '')) |
|
136 |
|
137 newOffset = aOffset |
|
138 |
|
139 if t.iSize != 'n': # Not of 'infinite' size |
|
140 newOffset += int(t.iSize) |
|
141 |
|
142 if len(aParams) > 2 and aParams[2] == '*': # Is 'array', delimited by other parameter. |
|
143 return [Parameter(t, aParams[0], aOffset, aParams[3])] + getParameters(aParams[4:], aTypes, newOffset) |
|
144 else: |
|
145 return [Parameter(t, aParams[0], aOffset)] + getParameters(aParams[2:], aTypes, newOffset) |