Xiaohan Wang | c51c64b | 2021-12-10 16:08:26 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
Avi Drissman | dfd88085 | 2022-09-15 20:11:09 | [diff] [blame] | 2 | # Copyright 2021 The Chromium Authors |
Xiaohan Wang | c51c64b | 2021-12-10 16:08:26 | [diff] [blame] | 3 | # Use of this source code is governed by a BSD-style license that can be |
| 4 | # found in the LICENSE file. |
| 5 | """Helper for converting Windows HRESULT defines to enums.xml entries. |
| 6 | |
| 7 | It only works with HRESULTs defined using `_HRESULT_TYPEDEF_`, e.g. |
| 8 | #define MF_E_SAMPLE_NOT_WRITABLE _HRESULT_TYPEDEF_(0xC00D36E0L) |
| 9 | will be converted to |
| 10 | <int value="-1072875808" label="MF_E_SAMPLE_NOT_WRITABLE"/> |
| 11 | |
| 12 | Some Windows files may use different or no macros to define HRESULTs, e.g. |
| 13 | #define DRM_E_FILEOPEN ((DRM_RESULT)0x8003006EL) |
| 14 | #define MF_INDEX_SIZE_ERR 0x80700001 |
| 15 | This script will not work in those cases, but is easy to be modified to work. |
| 16 | |
| 17 | Usage: |
| 18 | tools/hresult_to_enum.py -i mferror.h -o mferror.xml |
| 19 | """ |
| 20 | |
| 21 | import argparse |
| 22 | import re |
| 23 | import sys |
| 24 | |
| 25 | _HRESULT_RE = re.compile( |
| 26 | r'^#define\s+([0-9A-Z_]+)\s+.*_HRESULT_TYPEDEF_\((0x[0-9A-F]{8}).*') |
| 27 | |
| 28 | |
| 29 | def _HexToSignedInt(hex_str): |
| 30 | """Converts a hex string to a signed integer string. |
| 31 | |
| 32 | Args: |
| 33 | hex_str: A string representing a hex number. |
| 34 | |
| 35 | Returns: |
| 36 | A string representing the converted signed integer. |
| 37 | """ |
| 38 | int_val = int(hex_str, 16) |
| 39 | if int_val & (1 << 31): |
| 40 | int_val -= 1 << 32 |
| 41 | return str(int_val) |
| 42 | |
| 43 | |
| 44 | def _HresultToEnum(match): |
| 45 | """Converts an HRESULT define to an enums.xml entry. |
| 46 | """ |
| 47 | hresult = match.group(1) |
| 48 | hex_str = match.group(2) |
| 49 | int_str = _HexToSignedInt(hex_str) |
| 50 | return f'<int value="{int_str}" label="{hresult}"/>' |
| 51 | |
| 52 | |
| 53 | def _ConvertAllHresultDefines(source): |
| 54 | """Converts all HRESULT defines to enums.xml entries. |
| 55 | """ |
| 56 | in_lines = source.splitlines() |
| 57 | out_lines = [] |
| 58 | |
| 59 | for in_line in in_lines: |
| 60 | out_line, num_of_subs = _HRESULT_RE.subn(_HresultToEnum, in_line) |
| 61 | assert num_of_subs <= 1 |
| 62 | if num_of_subs == 1: |
| 63 | out_lines.append(out_line) |
| 64 | |
| 65 | return '\n'.join(out_lines) |
| 66 | |
| 67 | |
| 68 | def main(): |
| 69 | parser = argparse.ArgumentParser( |
| 70 | description='Convert HEX HRESULT to signed integer.') |
| 71 | parser.add_argument('-i', |
| 72 | '--input', |
| 73 | help='The input file containing HRESULT defines', |
| 74 | required=True) |
| 75 | parser.add_argument('-o', |
| 76 | '--output', |
| 77 | help='The output file containing enums.xml entries', |
| 78 | required=True) |
| 79 | args = parser.parse_args() |
| 80 | |
| 81 | with open(args.input, 'r') as f: |
| 82 | new_source = _ConvertAllHresultDefines(f.read()) |
| 83 | with open(args.output, 'w', newline='\n') as f: |
| 84 | f.write(new_source) |
| 85 | |
| 86 | |
| 87 | if __name__ == '__main__': |
| 88 | sys.exit(main()) |