Last active
March 18, 2018 03:00
-
-
Save ids1024/9722da9fc3f2beb621f4c9527cf3db70 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
from urllib.request import urlretrieve | |
import tarfile | |
import re | |
import bs4 | |
from pycparser import c_ast, CParser | |
TAR = "susv4tc2.tar.bz2" | |
DLURL = "http://pubs.opengroup.org/onlinepubs/9699919799/download/" + TAR | |
def parseType(node): | |
# XXX handle node.quals | |
if isinstance(node, c_ast.TypeDecl): | |
if isinstance(node.type, c_ast.IdentifierType): | |
return ' '.join(node.quals + node.type.names) | |
else: | |
return None | |
if isinstance(node, c_ast.PtrDecl): | |
ptr = '*' | |
if node.quals: | |
ptr += ' ' + ' '.join(node.quals) | |
if isinstance(node.type, c_ast.FuncDecl): | |
return '(' + parseType(node.type.type) + ')(' + ptr + ')(' + ', '.join(map(parseType, node.type.args.params)) + ')' | |
return parseType(node.type) + ' ' + ptr | |
elif isinstance(node, c_ast.Typename): | |
return parseType(node.type) | |
elif isinstance(node, c_ast.ArrayDecl): | |
return parseType(node.type) + ' [' + node.dim.value + ']' | |
elif isinstance(node, c_ast.Decl): | |
return ' '.join(node.quals + [parseType(node.type)]) | |
else: | |
return None | |
def parse_c(src): | |
ast = cparser.parse(''.join('typedef int '+i+';\n' for i in 'size_t div_t ldiv_t lldiv_t wchar_t locale_t uintptr_t'.split()) + src) | |
fns = {} | |
for _, i in ast.children(): | |
if not isinstance(i, c_ast.Decl): | |
continue | |
if not isinstance(i.type, c_ast.FuncDecl): | |
continue | |
params = i.type.args.params | |
if isinstance(i.type.type, c_ast.PtrDecl): | |
name = i.type.type.type.declname | |
else: | |
name = i.type.type.declname | |
fns[name] = (parseType(i.type.type), list(map(parseType, params))) | |
return fns | |
cparser = CParser() | |
if not os.path.exists(TAR): | |
urlretrieve(DLURL, TAR) | |
os.makedirs("output", exist_ok=True) | |
with tarfile.open(TAR) as tar: | |
for i in tar.getmembers(): | |
m = re.match("susv4tc2/basedefs/(.*\\.h)\\.html", i.name) | |
if not m: | |
continue | |
name = m.group(1) | |
if name != 'string.h': | |
continue | |
html = bs4.BeautifulSoup(tar.extractfile(i), 'lxml') | |
src = '\n'.join(j | |
for i in html.findAll('pre') | |
for j in i.text.splitlines() | |
if not j.startswith('[')) | |
stdfns = parse_c(src) | |
ourfns = parse_c('\n'.join(i for i in open('target/include/' + name).read().splitlines() if not i.strip().startswith('#'))) | |
for i in stdfns: | |
if i in ourfns: | |
std = stdfns[i] | |
our = ourfns[i] | |
if std == our: | |
print("'" + i +"()' definition matches") | |
else: | |
if std[0] != our[0]: | |
print(f"Redox's {i}() returns '{our[0]}', but SUS defines as '{std[0]}'") | |
for x in range(1, min(len(std[1]), len(our[1]))): | |
if std[1][x] != our[1][x]: | |
print(f"Argument {x} of {i}() is type '{our[1][x]}' on Redox, '{std[1][x]}' in SUS") | |
if len(std[1]) != len(our[1]): | |
print(f"Redox's {i}() takes {len(our[1])} arguments, but SUS defines it with {len(std[1])} arguments") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment