Commit d27bb543 authored by Tomas Popela's avatar Tomas Popela Committed by Commit Bot

Add support for variadic arguments in generated stubs

Previously we were using va_list for variadic arguments. The downside
for this was that only the first value from the variadic argument was
passed to the original function.

To make it work properly we have to use the __VA_ARGS__ variadic macro
that was introduces in C99 and is available in all major C/C++
compilers.

Change-Id: I50652f7348a16214811aaab8af116d78cdb70444
Reviewed-on: https://chromium-review.googlesource.com/c/1323089Reviewed-by: default avatarPatrik Höglund <phoglund@chromium.org>
Reviewed-by: default avatarDirk Pranke <dpranke@chromium.org>
Commit-Queue: Tomáš Popela <tomas.popela@gmail.com>
Cr-Commit-Position: refs/heads/master@{#606588}
parent bd3fd842
...@@ -17,16 +17,6 @@ or a header + implementation file of stubs suitable for use in a POSIX system. ...@@ -17,16 +17,6 @@ or a header + implementation file of stubs suitable for use in a POSIX system.
This script also handles variadic functions, e.g. This script also handles variadic functions, e.g.
void printf(const char* s, ...); void printf(const char* s, ...);
TODO(hclam): Fix the situation for variadic functions.
Stub for the above function will be generated and inside the stub function it
is translated to:
void printf(const char* s, ...) {
printf_ptr(s, (void*)arg1);
}
Only one argument from the variadic arguments is used and it will be used as
type void*.
""" """
__author__ = 'ajwong@chromium.org (Albert J. Wong)' __author__ = 'ajwong@chromium.org (Albert J. Wong)'
...@@ -111,11 +101,9 @@ STUB_FUNCTION_DEFINITION = ( ...@@ -111,11 +101,9 @@ STUB_FUNCTION_DEFINITION = (
VARIADIC_STUB_FUNCTION_DEFINITION = ( VARIADIC_STUB_FUNCTION_DEFINITION = (
"""extern %(return_type)s %(name)s(%(params)s) __attribute__((weak)); """extern %(return_type)s %(name)s(%(params)s) __attribute__((weak));
%(return_type)s %(export)s %(name)s(%(params)s) { %(return_type)s %(export)s %(name)s(%(params)s) {
va_list args___; #define %(name)s_ptr_variadic(%(arg_list)s, ...) \
va_start(args___, %(last_named_arg)s); %(name)s_ptr(%(arg_list)s, ##__VA_ARGS__)
%(return_type)s ret___ = %(name)s_ptr(%(arg_list)s, va_arg(args___, void*)); return %(name)s_ptr_variadic(%(arg_list)s);
va_end(args___);
return ret___;
}""") }""")
# Template for generating a variadic stub function definition without # Template for generating a variadic stub function definition without
...@@ -132,10 +120,9 @@ VARIADIC_STUB_FUNCTION_DEFINITION = ( ...@@ -132,10 +120,9 @@ VARIADIC_STUB_FUNCTION_DEFINITION = (
VOID_VARIADIC_STUB_FUNCTION_DEFINITION = ( VOID_VARIADIC_STUB_FUNCTION_DEFINITION = (
"""extern void %(name)s(%(params)s) __attribute__((weak)); """extern void %(name)s(%(params)s) __attribute__((weak));
void %(export)s %(name)s(%(params)s) { void %(export)s %(name)s(%(params)s) {
va_list args___; #define %(name)s_ptr_variadic(%(arg_list)s, ...) \
va_start(args___, %(last_named_arg)s); %(name)s_ptr(%(arg_list)s, ##__VA_ARGS__)
%(name)s_ptr(%(arg_list)s, va_arg(args___, void*)); %(name)s_ptr_variadic(%(arg_list)s);
va_end(args___);
}""") }""")
# Template for the preamble for the stub header file with the header guards, # Template for the preamble for the stub header file with the header guards,
......
...@@ -42,6 +42,8 @@ SIMPLE_SIGNATURES = [ ...@@ -42,6 +42,8 @@ SIMPLE_SIGNATURES = [
('int corge(void);', _MakeSignature('int', 'corge', ['void'])), ('int corge(void);', _MakeSignature('int', 'corge', ['void'])),
('int ferda(char **argv[]);', ('int ferda(char **argv[]);',
_MakeSignature('int', 'ferda', ['char **argv[]'])), _MakeSignature('int', 'ferda', ['char **argv[]'])),
('void brouk(char *pytlik, ...);',
_MakeSignature('void', 'brouk', ['char *pytlik', '...'])),
] ]
TRICKY_SIGNATURES = [ TRICKY_SIGNATURES = [
...@@ -221,6 +223,14 @@ int ferda(char **argv[]) { ...@@ -221,6 +223,14 @@ int ferda(char **argv[]) {
return ferda_ptr(argv); return ferda_ptr(argv);
}""", gs.PosixStubWriter.StubFunction(SIMPLE_SIGNATURES[6][1])) }""", gs.PosixStubWriter.StubFunction(SIMPLE_SIGNATURES[6][1]))
# Test variadic argument
self.assertEqual("""extern void brouk(char *pytlik, ...) \
__attribute__((weak));
void brouk(char *pytlik, ...) {
#define brouk_ptr_variadic(pytlik, ...) brouk_ptr(pytlik, ##__VA_ARGS__)
brouk_ptr_variadic(pytlik);
}""", gs.PosixStubWriter.StubFunction(SIMPLE_SIGNATURES[7][1]))
def testWriteImplemenationContents(self): def testWriteImplemenationContents(self):
outfile = StringIO.StringIO() outfile = StringIO.StringIO()
self.writer.WriteImplementationContents('my_namespace', outfile) self.writer.WriteImplementationContents('my_namespace', outfile)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment