3 # Copyright (c) 2014 Jakub Jermar
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
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.
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.
35 print("%s - Automated structure and offsets generator" % sys
.argv
[0])
36 print("%s file.ag depend|probe|generate struct.ag" % sys
.argv
[0])
41 for include
in struct
['includes']:
42 if 'depends' in include
.keys():
43 deps
= deps
+ include
['depends'] + "\n"
46 def generate_includes(struct
):
48 for include
in struct
['includes']:
49 if 'guard' in include
.keys():
50 code
= code
+ "#ifdef %s\n" % include
['guard']
51 if 'negative-guard' in include
.keys():
52 code
= code
+ "#ifndef %s\n" % include
['negative-guard']
53 code
= code
+ "#include %s\n" % include
['include']
54 if 'guard' in include
.keys():
55 code
= code
+ "#endif\n"
56 if 'negative-guard' in include
.keys():
57 code
= code
+ "#endif\n"
60 def generate_struct(struct
):
62 if ('packed' in struct
.keys() and struct
['packed']):
63 packed
= "__attribute__ ((packed)) "
64 code
= "typedef struct %s {\n" % struct
['name']
65 for i
in range(len(struct
['members'])):
66 member
= struct
['members'][i
]
67 if 'elements' in member
.keys():
68 code
= code
+ "\t%s %s[%d];\n" % (member
['type'], member
['name'], member
['elements'])
70 code
= code
+ "\t%s %s;\n" % (member
['type'], member
['name'])
71 code
= code
+ "} %s%s_t;" % (packed
, struct
['name'])
74 def generate_probes(struct
):
76 for i
in range(len(struct
['members'])):
77 member
= struct
['members'][i
]
78 code
= code
+ ("\temit_constant(%s_OFFSET_%s, offsetof(%s_t, %s));\n" %
79 (struct
['name'].upper(), member
['name'].upper(), struct
['name'],
81 code
= code
+ ("\temit_constant(%s_SIZE_%s, sizeof(((%s_t *) 0)->%s));\n" %
82 (struct
['name'].upper(), member
['name'].upper(), struct
['name'],
84 if 'elements' in member
.keys():
85 code
= code
+ ("\temit_constant(%s_%s_ITEM_SIZE, sizeof(%s));\n" %
86 (struct
['name'].upper(), member
['name'].upper(), member
['type']))
92 typename
= struct
['name'] + "_t"
98 #define emit_constant(n, v) \
99 asm volatile ("EMITTED_CONSTANT " str(n) \" = %%0\" :: \"i\" (v))
101 #define offsetof(t, m) ((size_t) &(((t *) 0)->m))
105 extern int main(int, char *[]);
107 int main(int argc, char *argv[])
110 emit_constant(%s_SIZE, sizeof(%s));
113 """ % (generate_includes(struct
), generate_struct(struct
),
114 generate_probes(struct
), name
.upper(), typename
)
118 def generate_defines(pairs
):
121 code
= code
+ "#define %s %s\n" % (pair
[0], pair
[1])
124 def generate(struct
, lines
):
126 /*****************************************************************************
127 * AUTO-GENERATED FILE, DO NOT EDIT!!!
128 * Generated by: tools/autogen.py
130 *****************************************************************************/
146 """ % (sys
.argv
[2], struct
['name'].upper(), struct
['name'].upper(),
147 generate_includes(struct
), generate_defines(lines
),
148 generate_struct(struct
))
152 def filter_pairs(lines
):
153 pattern
= re
.compile("^\tEMITTED_CONSTANT ([A-Z_][A-Z0-9_]*) = (\$|#)?([0-9]+)$");
156 res
= pattern
.match(line
)
159 pairs
= pairs
+ [res
.group(1, 3)]
164 if len(sys
.argv
) != 3:
167 with
open(sys
.argv
[2], "rb") as fp
:
168 struct
= yaml
.load(fp
)
170 if sys
.argv
[1] == "depend":
171 deps
= depend(struct
)
173 elif sys
.argv
[1] == "probe":
176 elif sys
.argv
[1] == "generate":
177 lines
= sys
.stdin
.readlines()
178 pairs
= filter_pairs(lines
)
179 code
= generate(struct
, pairs
)