source: mainline/tools/autogen.py@ d8bb821

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since d8bb821 was 9827b5b, checked in by Jakub Jermar <jakub@…>, 11 years ago

Generate additional #defines for each autogenerated structure.

For each member, generate a #define describing its size. If the member
is an array (i.e. it has the 'elements' key defined), define also
the size of one item.

  • Property mode set to 100755
File size: 4.8 KB
RevLine 
[0b811da2]1#!/usr/bin/env python
[4be73ba]2#
3# Copyright (c) 2014 Jakub Jermar
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#
[0b811da2]29
30import sys
[6ecc6ba6]31import yaml
[0b811da2]32import re
33
34def usage():
35 print("%s - Automated structure and offsets generator" % sys.argv[0])
36 print("%s file.ag probe|generate struct.ag" % sys.argv[0])
37 sys.exit()
38
39def generate_includes(struct):
40 code = ""
[713b8ce7]41 for include in struct['includes']:
42 if 'guard' in include.keys():
43 code = code + "#ifdef %s\n" % include['guard']
44 if 'negative-guard' in include.keys():
45 code = code + "#ifndef %s\n" % include['negative-guard']
46 code = code + "#include %s\n" % include['include']
47 if 'guard' in include.keys():
48 code = code + "#endif\n"
49 if 'negative-guard' in include.keys():
50 code = code + "#endif\n"
[0b811da2]51 return code.strip()
52
53def generate_struct(struct):
54 code = "typedef struct %s {\n" % struct['name']
55 for i in range(len(struct['members'])):
56 member = struct['members'][i]
[b8f433e]57 if 'elements' in member.keys():
58 code = code + "\t%s %s[%d];\n" % (member['type'], member['name'], member['elements'])
59 else:
60 code = code + "\t%s %s;\n" % (member['type'], member['name'])
[0b811da2]61 code = code + "} %s_t;" % struct['name']
62 return code
63
64def generate_probes(struct):
65 code = ""
66 for i in range(len(struct['members'])):
67 member = struct['members'][i]
[32e3cdf]68 code = code + ("\temit_constant(%s_OFFSET_%s, offsetof(%s_t, %s));\n" %
69 (struct['name'].upper(), member['name'].upper(), struct['name'],
70 member['name']))
[9827b5b]71 code = code + ("\temit_constant(%s_SIZE_%s, sizeof(((%s_t *) 0)->%s));\n" %
72 (struct['name'].upper(), member['name'].upper(), struct['name'],
73 member['name']))
74 if 'elements' in member.keys():
75 code = code + ("\temit_constant(%s_%s_ITEM_SIZE, sizeof(%s));\n" %
76 (struct['name'].upper(), member['name'].upper(), member['type']))
77
[0b811da2]78 return code
79
80def probe(struct):
81 name = struct['name']
82 typename = struct['name'] + "_t"
83
84 code = """
85%s
86
87#define str(s) #s
88#define emit_constant(n, v) \
89 asm volatile ("EMITTED_CONSTANT " str(n) \" = %%0\" :: \"i\" (v))
90#define offsetof(t, m) ((size_t) &(((t *) 0)->m))
91
92%s
93
[81f0940]94int main()
[0b811da2]95{
96%s
97 emit_constant(%s_SIZE, sizeof(%s));
[81f0940]98 return 0;
[0b811da2]99}
100 """ % (generate_includes(struct), generate_struct(struct),
101 generate_probes(struct), name.upper(), typename)
102
103 return code
104
105def generate_defines(pairs):
106 code = ""
107 for pair in pairs:
108 code = code + "#define %s %s\n" % (pair[0], pair[1])
109 return code.strip()
110
111def generate(struct, lines):
112 code = """
113/*****************************************************************************
114 * AUTO-GENERATED FILE, DO NOT EDIT!!!
115 * Generated by: tools/autogen.py
116 * Generated from: %s
117 *****************************************************************************/
118
119#ifndef AUTOGEN_%s_H
120#define AUTOGEN_%s_H
121
122#ifndef __ASM__
123%s
124#endif
125
126%s
127
128#ifndef __ASM__
129%s
130#endif
131
132#endif
133 """ % (sys.argv[2], struct['name'].upper(), struct['name'].upper(),
134 generate_includes(struct), generate_defines(lines),
135 generate_struct(struct))
136
137 return code
138
139def filter_pairs(lines):
[da5ba3a]140 pattern = re.compile("^\tEMITTED_CONSTANT ([A-Z_][A-Z0-9_]*) = (\$|#)?([0-9]+)$");
[0b811da2]141 pairs = []
142 for line in lines:
143 res = pattern.match(line)
144 if res == None:
145 continue
[da5ba3a]146 pairs = pairs + [res.group(1, 3)]
[0b811da2]147 return pairs
148
149
150def run():
151 if len(sys.argv) != 3:
152 usage()
153
154 with open(sys.argv[2], "rb") as fp:
[6ecc6ba6]155 struct = yaml.load(fp)
[0b811da2]156
157 if sys.argv[1] == "probe":
158 code = probe(struct)
159 print(code)
160 elif sys.argv[1] == "generate":
161 lines = sys.stdin.readlines()
162 pairs = filter_pairs(lines)
163 code = generate(struct, pairs)
164 print(code)
165 else:
166 usage()
167
168run()
169
Note: See TracBrowser for help on using the repository browser.