import re
import sys
pointer_whitelist = set([
'use_rle_for_non_zero',
'use_rle_for_zero',
'self',
'total',
])
p = re.compile("""fn[^(]+[(]((([^),]*),)*)(([^),]*)[)])""")
VARIABLE_TO_DEREFERENCE="""[A-Za-z0-9_.]+""" NOT_ISIZE = """([^(]|\n|(\([^i])|(\(i[^s])|(\(is[^i]))+"""
TRAILING_PARENS = """[ \t\n\)\]\}]*"""
offset_pat = VARIABLE_TO_DEREFERENCE + """[.]offset\(""" + NOT_ISIZE + """\(isize\)[ \n\t]*\)""" + TRAILING_PARENS
o2 = """\*""" + offset_pat
p2 = re.compile(o2)
pointer_cast = re.compile("""as \(\*[^\)]+\)""")
psubarray = re.compile(offset_pat)
elite_something = """if[\n ]+1337i?3?2?[\n ]*!=[\n ]*0[\n ]*({[\n ]*(SOMETHING([\n ]+'[a-zA-Z0-9_]+)?(\n )*;)[\n ]*})"""
elite_break = re.compile(elite_something.replace("SOMETHING", "break"))
elite_continue = re.compile(elite_something.replace("SOMETHING", "continue"))
def subbreak(match):
return match.group(1)
def subfun(match):
all_items = match.group()
each_arg = all_items.split(',')
out_arg = []
for index in range(len(each_arg)):
v = each_arg[index]
out_arg.append(v)
is_single = False
for item in pointer_whitelist:
if item in v:
is_single = True
where = v.find('*mut')
if where != -1:
if is_single:
v= v.replace('*mut', '&mut', 1)
else:
v= v.replace('*mut', '&mut [', 1).replace('[ ','[') + ']'
where = v.find('*const')
if where != -1:
if is_single:
v= v.replace('*const', '&', 1)
else:
v= v.replace('*const', '& [', 1).replace('[ ','[')+']'
if v.endswith(')]'):
v = v[:-2] + '])'
out_arg[index] = v
return balance(','.join(out_arg))
def recursive_offset_match(data):
if data.find('.offset') != -1:
data = p2.sub(dereffun, data)
data = psubarray.sub(desubarrayfun, data)
return data
def zerofirstoffset(data):
where = data.find('.offset')
if where == -1:
assert False
return data[0:where] + '.\xff' + data[where + 2:]
def cut_out_both_offset(data):
split_loc = data.find('.offset') + 1
ret = data[split_loc:]
ret = p2.sub(dereffun, ret)
ret = psubarray.sub(desubarrayfun, ret)
return data[:split_loc] + ret
def dereffun(match):
data = match.group()
if data.count('.offset') > 1:
return cut_out_both_offset(data)
data = data[1:] data = data.replace('.offset(','[(', 1)
data = data.replace('(isize)', '(usize)')
data = data + ']'
data = recursive_offset_match(data)
data = balance(data)
return data
def desubarrayfun(match):
data = match.group()
if data.count('.offset') > 1:
return cut_out_both_offset(data)
data = data.replace('.offset(','[(', 1)
data = data.replace('(isize)', '(usize)')
data = data + '..]'
data = recursive_offset_match(data)
data = balance(data)
return data
def balance(data):
for ch in "[]{}()":
data = data.replace("""b'""" + ch + """'""", str(ord(ch)))
retlist = []
stack = []
bad_chars = []
rev_paren = {
'{':'}','}':'{',
'[':']',']':'[',
'(':')',')':'(',}
while True:
matches = [data.find(c) for c in "{}()[]"]
where = min(x if x >= 0 else len(data) for x in matches)
if where == len(data):
retlist.append(data)
data = b''
retlist += [b.replace(' ','').replace('\n','').replace('\t','') for b in bad_chars]
break
ch = data[where]
if ch in '({[':
stack.append(ch)
retlist.append(data[:where+1])
data = data[where + 1:]
else:
if len(bad_chars) and bad_chars[0][-1] == rev_paren[ch]:
retlist.append(bad_chars[-1])
bad_chars = bad_chars[1:]
elif len(stack) and ch == rev_paren[stack[-1]]:
retlist.append(data[:where + 1])
data = data[where+1:]
stack.pop()
while len(bad_chars) and len(stack) and bad_chars[0][-1] ==rev_paren[stack[-1][-1]]:
retlist.append(bad_chars[0])
bad_chars= bad_chars[1:]
stack.pop()
elif len(stack) != 0:
bad_chars.append(data[:where + 1])
data = data[where+1:]
else:
retlist.append(data[:where+1])
data = data[where+1:]
return ''.join(retlist)
def rem(match):
return ""
with open(sys.argv[1]) as f:
ret = p.sub(subfun, f.read())
ret = p2.sub(dereffun, ret)
ret = p2.sub(dereffun, ret)
ret = p2.sub(dereffun, ret)
ret = psubarray.sub(desubarrayfun, ret)
ret = psubarray.sub(desubarrayfun, ret)
ret = psubarray.sub(desubarrayfun, ret)
ret = p2.sub(dereffun, ret)
ret = p2.sub(dereffun, ret)
ret = p2.sub(dereffun, ret)
ret = ret.replace('i32 as (usize)', 'usize')
ret = ret.replace('i32 as (u32)', 'u32')
ret = pointer_cast.sub(rem, ret)
ret = elite_break.sub(subbreak, ret)
ret = elite_continue.sub(subbreak, ret)
ret = ret.replace("#[derive(Clone, Copy)]", "")
ret = ret.replace("#[repr(C)]", "")
ret = ret.replace("#[no_mangle]", "")
ret = ret.replace("unsafe extern ", "")
ret = ret.replace("unsafe", "")
ret = ret.replace('self', 'xself')
sys.stdout.write(ret)