OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # | 2 # |
3 # Copyright (c) 2009 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2009 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 """Creates windows and posix stub files for a given set of signatures. | 7 """Creates windows and posix stub files for a given set of signatures. |
8 | 8 |
9 For libraries that need to be loaded outside of the standard executable startup | 9 For libraries that need to be loaded outside of the standard executable startup |
10 path mechanism, stub files need to be generated for the wanted functions. In | 10 path mechanism, stub files need to be generated for the wanted functions. In |
(...skipping 26 matching lines...) Expand all Loading... |
37 class SubprocessError(Error): | 37 class SubprocessError(Error): |
38 def __init__(self, message, error_code): | 38 def __init__(self, message, error_code): |
39 Error.__init__(self) | 39 Error.__init__(self) |
40 self.message = message | 40 self.message = message |
41 self.error_code = error_code | 41 self.error_code = error_code |
42 | 42 |
43 def __str__(self): | 43 def __str__(self): |
44 return 'Failed with code %s: %s' % (self.message, repr(self.error_code)) | 44 return 'Failed with code %s: %s' % (self.message, repr(self.error_code)) |
45 | 45 |
46 | 46 |
47 # Regular expression used to parse signatures in the input files. The regex | 47 # Regular expression used to parse function signatures in the input files. |
48 # is built around identifying the "identifier" for the function name. We | 48 # The regex is built around identifying the "identifier" for the function name. |
49 # consider the identifier to be the string that follows these constraints: | 49 # We consider the identifier to be the string that follows these constraints: |
50 # | 50 # |
51 # 1) Starts with [_a-ZA-Z] (C++ spec 2.10). | 51 # 1) Starts with [_a-ZA-Z] (C++ spec 2.10). |
52 # 2) Continues with [_a-ZA-Z0-9] (C++ spec 2.10). | 52 # 2) Continues with [_a-ZA-Z0-9] (C++ spec 2.10). |
53 # 3) Preceeds an opening parenthesis by 0 or more whitespace chars. | 53 # 3) Preceeds an opening parenthesis by 0 or more whitespace chars. |
54 # | 54 # |
55 # From that, all preceeding characters are considered the return value. | 55 # From that, all preceeding characters are considered the return value. |
56 # Trailing characters should have a substring matching the form (.*). That | 56 # Trailing characters should have a substring matching the form (.*). That |
57 # is considered the arguments. | 57 # is considered the arguments. |
58 SIGNATURE_REGEX = re.compile('(?P<return_type>.+?)' | 58 SIGNATURE_REGEX = re.compile('(?P<return_type>.+?)' |
59 '(?P<name>[_a-zA-Z][_a-zA-Z0-9]+)\s*' | 59 '(?P<name>[_a-zA-Z][_a-zA-Z0-9]+)\s*' |
(...skipping 13 matching lines...) Expand all Loading... |
73 # name: The name of the function. | 73 # name: The name of the function. |
74 # params: The parameters to the function. | 74 # params: The parameters to the function. |
75 # return_prefix: 'return ' if this function is not void. '' otherwise. | 75 # return_prefix: 'return ' if this function is not void. '' otherwise. |
76 # arg_list: The arguments used to call the stub function. | 76 # arg_list: The arguments used to call the stub function. |
77 STUB_FUNCTION_DEFINITION = ( | 77 STUB_FUNCTION_DEFINITION = ( |
78 """extern %(return_type)s %(name)s(%(params)s) __attribute__((weak)); | 78 """extern %(return_type)s %(name)s(%(params)s) __attribute__((weak)); |
79 %(return_type)s %(name)s(%(params)s) { | 79 %(return_type)s %(name)s(%(params)s) { |
80 %(return_prefix)s%(name)s_ptr(%(arg_list)s); | 80 %(return_prefix)s%(name)s_ptr(%(arg_list)s); |
81 }""") | 81 }""") |
82 | 82 |
| 83 # Template for generating a variadic stub function definition with return |
| 84 # value. |
| 85 # Includes a forward declaration marking the symbol as weak. |
| 86 # This template takes the following named parameters. |
| 87 # return_type: The return type. |
| 88 # name: The name of the function. |
| 89 # params: The parameters to the function. |
| 90 # arg_list: The arguments used to call the stub function without the |
| 91 # variadic argument. |
| 92 # last_named_arg: Name of the last named argument before the variadic |
| 93 # argument. |
| 94 VARIADIC_STUB_FUNCTION_DEFINITION = ( |
| 95 """extern %(return_type)s %(name)s(%(params)s) __attribute__((weak)); |
| 96 %(return_type)s %(name)s(%(params)s) { |
| 97 va_list args___; |
| 98 va_start(args___, %(last_named_arg)s); |
| 99 %(return_type)s ret___ = %(name)s_ptr(%(arg_list)s, args___); |
| 100 va_end(args___); |
| 101 return ret___; |
| 102 }""") |
| 103 |
| 104 # Template for generating a variadic stub function definition without |
| 105 # return value. |
| 106 # Includes a forward declaration marking the symbol as weak. |
| 107 # This template takes the following named parameters. |
| 108 # name: The name of the function. |
| 109 # params: The parameters to the function. |
| 110 # arg_list: The arguments used to call the stub function without the |
| 111 # variadic argument. |
| 112 # last_named_arg: Name of the last named argument before the variadic |
| 113 # argument. |
| 114 VOID_VARIADIC_STUB_FUNCTION_DEFINITION = ( |
| 115 """extern void %(name)s(%(params)s) __attribute__((weak)); |
| 116 void %(name)s(%(params)s) { |
| 117 va_list args___; |
| 118 va_start(args___, %(last_named_arg)s); |
| 119 %(name)s_ptr(%(arg_list)s, args___); |
| 120 va_end(args___); |
| 121 }""") |
| 122 |
83 # Template for the preamble for the stub header file with the header guards, | 123 # Template for the preamble for the stub header file with the header guards, |
84 # standard set of includes, and namespace opener. This template takes the | 124 # standard set of includes, and namespace opener. This template takes the |
85 # following named parameters: | 125 # following named parameters: |
86 # guard_name: The macro to use as the header guard. | 126 # guard_name: The macro to use as the header guard. |
87 # namespace: The namespace for the stub functions. | 127 # namespace: The namespace for the stub functions. |
88 STUB_HEADER_PREAMBLE = """// This is generated file. Do not modify directly. | 128 STUB_HEADER_PREAMBLE = """// This is generated file. Do not modify directly. |
89 | 129 |
90 #ifndef %(guard_name)s | 130 #ifndef %(guard_name)s |
91 #define %(guard_name)s | 131 #define %(guard_name)s |
92 | 132 |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 if signature['return_type'] != 'void': | 593 if signature['return_type'] != 'void': |
554 return_prefix = 'return ' | 594 return_prefix = 'return ' |
555 | 595 |
556 # Generate the argument list. | 596 # Generate the argument list. |
557 arguments = [re.split('[\*& ]', arg)[-1].strip() for arg in | 597 arguments = [re.split('[\*& ]', arg)[-1].strip() for arg in |
558 signature['params']] | 598 signature['params']] |
559 arg_list = ', '.join(arguments) | 599 arg_list = ', '.join(arguments) |
560 if arg_list == 'void': | 600 if arg_list == 'void': |
561 arg_list = '' | 601 arg_list = '' |
562 | 602 |
563 return STUB_FUNCTION_DEFINITION % { | 603 if arg_list != '' and len(arguments) > 1 and arguments[-1] == '...': |
564 'return_type': signature['return_type'], | 604 # If the last argment is ... then this is a variadic function. |
565 'name': signature['name'], | 605 if return_prefix != '': |
566 'params': ', '.join(signature['params']), | 606 return VARIADIC_STUB_FUNCTION_DEFINITION % { |
567 'return_prefix': return_prefix, | 607 'return_type': signature['return_type'], |
568 'arg_list': arg_list} | 608 'name': signature['name'], |
| 609 'params': ', '.join(signature['params']), |
| 610 'arg_list': ', '.join(arguments[0:-1]), |
| 611 'last_named_arg': arguments[-2]} |
| 612 else: |
| 613 return VOID_VARIADIC_STUB_FUNCTION_DEFINITION % { |
| 614 'name': signature['name'], |
| 615 'params': ', '.join(signature['params']), |
| 616 'arg_list': ', '.join(arguments[0:-1]), |
| 617 'last_named_arg': arguments[-2]} |
| 618 else: |
| 619 # This is a regular function. |
| 620 return STUB_FUNCTION_DEFINITION % { |
| 621 'return_type': signature['return_type'], |
| 622 'name': signature['name'], |
| 623 'params': ', '.join(signature['params']), |
| 624 'return_prefix': return_prefix, |
| 625 'arg_list': arg_list} |
569 | 626 |
570 @classmethod | 627 @classmethod |
571 def WriteImplementationPreamble(cls, header_path, outfile): | 628 def WriteImplementationPreamble(cls, header_path, outfile): |
572 """Write the necessary includes for the implementation file. | 629 """Write the necessary includes for the implementation file. |
573 | 630 |
574 Args: | 631 Args: |
575 header_path: The path to the header file. | 632 header_path: The path to the header file. |
576 outfile: The file handle to populate. | 633 outfile: The file handle to populate. |
577 """ | 634 """ |
578 outfile.write(IMPLEMENTATION_PREAMBLE % header_path) | 635 outfile.write(IMPLEMENTATION_PREAMBLE % header_path) |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
959 if options.type == FILE_TYPE_WIN: | 1016 if options.type == FILE_TYPE_WIN: |
960 CreateWindowsLibForSigFiles(args, out_dir, intermediate_dir) | 1017 CreateWindowsLibForSigFiles(args, out_dir, intermediate_dir) |
961 elif options.type == FILE_TYPE_POSIX_STUB: | 1018 elif options.type == FILE_TYPE_POSIX_STUB: |
962 CreatePosixStubsForSigFiles(args, options.stubfile_name, out_dir, | 1019 CreatePosixStubsForSigFiles(args, options.stubfile_name, out_dir, |
963 intermediate_dir, options.path_from_source, | 1020 intermediate_dir, options.path_from_source, |
964 options.extra_stub_header) | 1021 options.extra_stub_header) |
965 | 1022 |
966 | 1023 |
967 if __name__ == '__main__': | 1024 if __name__ == '__main__': |
968 main() | 1025 main() |
OLD | NEW |