2017-11-20 20:03:55 +08:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
#
|
|
|
|
# Copyright (c) 2017 Intel Corporation
|
|
|
|
#
|
|
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
|
|
|
import sys
|
|
|
|
import re
|
|
|
|
import argparse
|
|
|
|
import os
|
|
|
|
import json
|
|
|
|
|
|
|
|
api_regex = re.compile(r'''
|
|
|
|
__syscall\s+ # __syscall attribute, must be first
|
|
|
|
([^(]+) # type and name of system call (split later)
|
|
|
|
[(] # Function opening parenthesis
|
|
|
|
([^)]*) # Arg list (split later)
|
|
|
|
[)] # Closing parenthesis
|
|
|
|
''', re.MULTILINE | re.VERBOSE)
|
|
|
|
|
|
|
|
|
2018-07-02 17:29:19 +08:00
|
|
|
def analyze_headers(multiple_directories):
|
2017-11-20 20:03:55 +08:00
|
|
|
ret = []
|
|
|
|
|
2018-07-02 17:29:19 +08:00
|
|
|
for base_path in multiple_directories:
|
|
|
|
for root, dirs, files in os.walk(base_path):
|
|
|
|
for fn in files:
|
2017-11-20 20:03:55 +08:00
|
|
|
|
2018-07-02 17:29:19 +08:00
|
|
|
# toolchain/common.h has the definition of __syscall which we
|
|
|
|
# don't want to trip over
|
|
|
|
path = os.path.join(root, fn)
|
|
|
|
if not fn.endswith(".h") or path.endswith(os.path.join(os.sep, 'toolchain', 'common.h')):
|
|
|
|
continue
|
2017-11-20 20:03:55 +08:00
|
|
|
|
2018-07-02 17:29:19 +08:00
|
|
|
with open(path, "r", encoding="utf-8") as fp:
|
|
|
|
try:
|
2018-07-24 08:27:57 +08:00
|
|
|
result = [(mo.groups(), fn)
|
2018-07-02 17:29:19 +08:00
|
|
|
for mo in api_regex.finditer(fp.read())]
|
|
|
|
except Exception:
|
|
|
|
sys.stderr.write("While parsing %s\n" % fn)
|
|
|
|
raise
|
2017-11-20 20:03:55 +08:00
|
|
|
|
2018-07-02 17:29:19 +08:00
|
|
|
ret.extend(result)
|
2017-11-20 20:03:55 +08:00
|
|
|
|
|
|
|
return ret
|
|
|
|
|
2017-12-12 21:19:25 +08:00
|
|
|
|
2017-11-20 20:03:55 +08:00
|
|
|
def parse_args():
|
|
|
|
global args
|
2017-12-12 21:19:25 +08:00
|
|
|
parser = argparse.ArgumentParser(
|
|
|
|
description=__doc__,
|
|
|
|
formatter_class=argparse.RawDescriptionHelpFormatter)
|
2017-11-20 20:03:55 +08:00
|
|
|
|
2018-07-02 17:29:19 +08:00
|
|
|
parser.add_argument("-i", "--include", required=True, action='append',
|
2017-12-12 21:19:25 +08:00
|
|
|
help="Base include directory")
|
|
|
|
parser.add_argument(
|
|
|
|
"-j", "--json-file", required=True,
|
|
|
|
help="Write system call prototype information as json to file")
|
2017-11-20 20:03:55 +08:00
|
|
|
args = parser.parse_args()
|
|
|
|
|
2017-12-12 21:19:25 +08:00
|
|
|
|
2017-11-20 20:03:55 +08:00
|
|
|
def main():
|
|
|
|
parse_args()
|
|
|
|
|
|
|
|
syscalls = analyze_headers(args.include)
|
|
|
|
|
|
|
|
syscalls_in_json = json.dumps(
|
|
|
|
syscalls,
|
|
|
|
indent=4,
|
|
|
|
sort_keys=True
|
|
|
|
)
|
|
|
|
|
|
|
|
# Check if the file already exists, and if there are no changes,
|
|
|
|
# don't touch it since that will force an incremental rebuild
|
|
|
|
path = args.json_file
|
|
|
|
new = syscalls_in_json
|
|
|
|
if os.path.exists(path):
|
|
|
|
with open(path, 'r') as fp:
|
|
|
|
old = fp.read()
|
|
|
|
|
|
|
|
if new != old:
|
|
|
|
with open(path, 'w') as fp:
|
|
|
|
fp.write(new)
|
|
|
|
else:
|
|
|
|
with open(path, 'w') as fp:
|
|
|
|
fp.write(new)
|
|
|
|
|
2017-12-12 21:19:25 +08:00
|
|
|
|
2017-11-20 20:03:55 +08:00
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|