2 # Copyright 2008, Google Inc.
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
9 # * Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # * Redistributions in binary form must reproduce the above
12 # copyright notice, this list of conditions and the following disclaimer
13 # in the documentation and/or other materials provided with the
15 # * Neither the name of Google Inc. nor the names of its
16 # contributors may be used to endorse or promote products derived from
17 # this software without specific prior written permission.
19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 # This script extracts "nacl syscall" prototypes from a c file
33 # given on stdin and then produces wrapped versions of the syscalls.
35 # NOTE: Please use care to maintain python 2.3 compatibility, for
43 AUTOGEN_COMMENT
= """\
45 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
47 * Automatically generated code. See nacl_syscall_handlers_gen.py
49 * NaCl Server Runtime Service Call abstractions
54 TABLE_INITIALIZER
= """\
58 void NaClSyscallTableInit() {
60 for (i = 0; i < NACL_MAX_SYSCALLS; ++i) {
61 nacl_syscall[i].handler = &NotImplementedDecoder;
69 IMPLEMENTATION_SKELETON
= """\
70 /* this function was automagically generated */
71 static int32_t %(name)sDecoder(struct NaClAppThread *natp) {
73 return %(name)s(natp%(arglist)s);
77 def FunctionNameToSyscallDefine(name
):
78 assert name
.startswith("NaClSys")
80 return "NACL_sys_" + name
.lower()
85 return ', ' + ', '.join(alist
)
88 def ExtractVariable(decl
):
89 type_or_idents
= re
.findall(r
'[a-zA-Z][-_a-zA-Z]*', decl
)
90 return type_or_idents
[len(type_or_idents
)-1]
96 # Note: although this return value might be computed more
97 # concisely with a list comprehension, we instead use a
98 # for statement to maintain python 2.3 compatibility.
101 extractedargs
+= ['p.' + ExtractVariable(arg
)]
102 return ', ' + ', '.join(extractedargs
)
105 def MemberList(name
, alist
):
109 # Note: although this return value might be computed more
110 # concisely with a list comprehension, we instead use a
111 # for statement to maintain python 2.3 compatibility.
117 'members' : ';\n'.join(margs
) + ';'
121 struct %(name)sArgs {
123 } p = *(struct %(name)sArgs *) natp->x_esp;
128 def PrintSyscallTableIntializer(protos
, ostr
):
130 for name
, _
in protos
:
131 syscall
= FunctionNameToSyscallDefine(name
)
132 assign
.append(" NaClAddSyscall(%s, &%sDecoder);" % (syscall
, name
))
133 print >>ostr
, TABLE_INITIALIZER
% "\n".join(assign
)
136 def PrintImplSkel(protos
, ostr
):
137 print >>ostr
, AUTOGEN_COMMENT
;
138 for name
, alist
in protos
:
139 values
= { 'name' : name
,
140 'paramlist' : ParamList(alist
[1:]),
141 'arglist' : ArgList(alist
[1:]),
142 'members' : MemberList(name
, alist
[1:]),
144 print >>ostr
, IMPLEMENTATION_SKELETON
% values
147 def GetProtoArgs(s
, fin
):
158 # prune stuff after )
160 args
= [a
.strip() for a
in s
.split(",")]
164 def ParseFileToBeWrapped(fin
, filter_regex
):
167 match
= re
.search(r
"^int32_t (NaClSys[_a-zA-Z0-9]+)[(](.*)$", line
)
170 name
= match
.group(1)
171 args
= GetProtoArgs(match
.group(2), fin
)
172 if filter_regex
and re
.search(filter_regex
, name
):
174 protos
.append( (name
, args
) )
179 usage
='Usage: nacl_syscall_handlers_gen.py [-f regex] [-c] [-d]'
183 opts
, pargs
= getopt
.getopt(argv
[1:], 'hcdf:')
184 except getopt
.error
, e
:
185 print >>sys
.stderr
, 'Illegal option:', str(e
)
186 print >>sys
.stderr
, usage
189 for opt
, val
in opts
:
199 protos
= ParseFileToBeWrapped(sys
.stdin
, filter_regex
)
204 elif mode
== "header":
205 PrintHeaderFile(protos
, sys
.stdout
)
206 elif mode
== "codegen":
207 PrintImplSkel(protos
, sys
.stdout
)
208 PrintSyscallTableIntializer(protos
, sys
.stdout
)
214 if __name__
== '__main__':
215 sys
.exit(main(sys
.argv
))