Hackfix and re-enable strtoull and wcstoull, see bug #3798.
[sdcc.git] / sdcc / support / scripts / as2gbmap.py
blobea17f0787505190c97b5d275c0a650c69c23c17e
1 #!/usr/bin/env python3
3 # as2gbmap - asxxxx to gb map file converter
5 # Copyright (c) 2010 Borut Razem
7 # This file is part of sdcc.
9 # This software is provided 'as-is', without any express or implied
10 # warranty. In no event will the authors be held liable for any damages
11 # arising from the use of this software.
13 # Permission is granted to anyone to use this software for any purpose,
14 # including commercial applications, and to alter it and redistribute it
15 # freely, subject to the following restrictions:
17 # 1. The origin of this software must not be misrepresented; you must not
18 # claim that you wrote the original software. If you use this software
19 # in a product, an acknowledgment in the product documentation would be
20 # appreciated but is not required.
21 # 2. Altered source versions must be plainly marked as such, and must not be
22 # misrepresented as being the original software.
23 # 3. This notice may not be removed or altered from any source distribution.
25 # Borut Razem
26 # borut.razem@siol.net
28 import sys
29 import os
30 import re
31 from optparse import OptionParser
32 import operator
34 def main():
35 '''asxxxx to gb map file converter'''
36 usage = "usage: %prog [options] [<input_asxxxx_map_file> [<output_gb_file>]]"
37 parser = OptionParser(usage = usage, version = "1.0")
38 parser.set_defaults(no_gmb = False)
39 parser.add_option("-j", "--no$gmb", action = "store_true", dest = "no_gmb", help = "generate no$gmb symbol file (default: rrgb)")
40 (options, args) = parser.parse_args()
42 if len(args) > 0 and args[0] != "-":
43 try:
44 fin = open(args[0], "r")
45 except IOError as xxx_todo_changeme:
46 (errno, strerror) = xxx_todo_changeme.args
47 print("%s: can't open %s: %s" % (os.path.basename(sys.argv[0]), args[0], strerror), file=sys.stderr)
48 return 1
49 else:
50 fin = sys.stdin
52 if len(args) > 1 and args[1] != "-":
53 try:
54 fout = open(args[1], "w")
55 except IOError as xxx_todo_changeme1:
56 (errno, strerror) = xxx_todo_changeme1.args
57 print("%s: can't create %s: %s" % (os.path.basename(sys.argv[1]), args[1], strerror), file=sys.stderr)
58 return 1
59 else:
60 fout = sys.stdout
62 areas = []
63 modules = []
64 libraries = []
65 ubads = []
67 radix = 'HEX'
68 state = None
69 area = None
71 # process asxxxx map file
72 for line in fin:
73 if re.match(r"^Hexadecimal$", line):
74 radix = 'HEX';
75 continue
77 if re.match(r"^Area +Addr +Size +Decimal +Bytes +\(Attributes\)$", line):
78 line = next(fin)
79 if re.match(r"^[- ]+$", line):
80 line = next(fin)
81 m = re.match(r"^([^ ]+) +([0-9A-Fa-f]{4}) +([0-9A-Fa-f]{4}) += +\d+\. +\w+ +\(([^\)]+)\)$", line)
82 if m:
83 if area:
84 if m.group(1) != area['area']:
85 areas.append(area)
86 area = {'area': m.group(1), 'radix': radix, 'base': int(m.group(2), 16), 'size': int(m.group(3), 16), 'attrib': m.group(4).replace(',', ' '), 'globals': []}
87 else:
88 area = {'area': m.group(1), 'radix': radix, 'base': int(m.group(2), 16), 'size': int(m.group(3), 16), 'attrib': m.group(4).replace(',', ' '), 'globals': []}
89 state = 'IN_AREA'
90 continue
92 m = re.match(r"^ +([0-9A-Fa-f]{4}) +([^ ]+) +$", line)
93 if state == 'IN_AREA' and m:
94 area['globals'].append({'value': int(m.group(1), 16), 'global': m.group(2)})
95 continue
97 m = re.match(r"Files Linked +\[ module\(s\) \]$", line)
98 if m:
99 state = 'IN_MODULES'
100 continue
102 m = re.match(r"Libraries Linked +\[ object file \]$", line)
103 if m:
104 state = 'IN_LIBRARIES'
105 continue
107 m = re.match(r"User Base Address Definitions$", line)
108 if m:
109 state = 'IN_UBAD'
110 continue
112 m = re.match(r"^([^ ]+) +\[ ([^ ]*) \]$", line)
113 if m:
114 if state == 'IN_MODULES':
115 modules.append({'file': m.group(1), 'name': m.group(2)})
116 continue
118 if state == 'IN_LIBRARIES':
119 libraries.append({'library': m.group(1), 'module': m.group(2)})
120 continue
122 m = re.match(r"^([^ ]+) += +0x([0-9A-Fa-f]{4})$", line)
123 if state == 'IN_UBAD' and m:
124 ubads.append({'symbol': m.group(1), 'value': m.group(2)})
125 continue
127 if area:
128 areas.append(area)
131 if options.no_gmb:
132 # generate no$gmp map file
133 print('; no$gmb format .sym file', file=fout)
134 print('; Generated automagically by %s' % os.path.basename(sys.argv[0]), file=fout)
135 for e in areas:
136 print('; Area: %s' % e['area'], file=fout)
137 if e['globals']:
138 e['globals'].sort(key = operator.itemgetter('value'))
139 for g in e['globals']:
140 if g['global'][0:3] != 'l__':
141 if g['value'] > 0x7FFF:
142 print('00:%04X %s' % (g['value'], g['global']), file=fout)
143 else:
144 print('%02X:%04X %s' % (g['value'] // 16384, g['value'], g['global']), file=fout)
145 else:
146 # generate rrgb map file
147 for e in areas:
148 print('AREA %s' % e['area'], file=fout)
149 print('\tRADIX %s' % e['radix'], file=fout)
150 print('\tBASE %04X' % e['base'], file=fout)
151 print('\tSIZE %04X' % e['size'], file=fout)
152 print('\tATTRIB %s' % e['attrib'], file=fout)
153 if e['globals']:
154 e['globals'].sort(key = operator.itemgetter('value'))
155 print('\tGLOBALS', file=fout)
156 for g in e['globals']:
157 print('\t\t%s\t%04X' % (g['global'], g['value']), file=fout)
159 if modules:
160 print('MODULES', file=fout)
161 for m in modules:
162 print('\tFILE %s' % m['file'], file=fout)
163 if m['name']:
164 print('\t\tNAME %s' % m['name'], file=fout)
166 if libraries:
167 print('LIBRARIES', file=fout)
168 for m in libraries:
169 print('\tLIBRARY %s' % m['library'], file=fout)
170 print('\t\tMODULE %s' % m['module'], file=fout)
172 if ubads:
173 print('USERBASEDEF', file=fout)
174 for m in ubads:
175 print('\t%s = 0x%04X' % (m['symbol'], int(m['value'], 16)), file=fout)
176 return 0
178 if __name__ == '__main__':
179 sys.exit(main())