1import re 2import sys 3 4pointer_whitelist = set([ 5 'use_rle_for_non_zero', 6 'use_rle_for_zero', 7 'self', 8 'total', 9]) 10 11p = re.compile("""fn[^(]+[(]((([^),]*),)*)(([^),]*)[)])""") 12VARIABLE_TO_DEREFERENCE="""[A-Za-z0-9_.]+""" #+"""|(\(\*[A-Za-z0-9_.]+\))[.][A-Za-z0-9_.]+)""" 13NOT_ISIZE = """([^(]|\n|(\([^i])|(\(i[^s])|(\(is[^i]))+""" 14TRAILING_PARENS = """[ \t\n\)\]\}]*""" 15offset_pat = VARIABLE_TO_DEREFERENCE + """[.]offset\(""" + NOT_ISIZE + """\(isize\)[ \n\t]*\)""" + TRAILING_PARENS 16o2 = """\*""" + offset_pat 17p2 = re.compile(o2) 18pointer_cast = re.compile("""as \(\*[^\)]+\)""") 19psubarray = re.compile(offset_pat) 20elite_something = """if[\n ]+1337i?3?2?[\n ]*!=[\n ]*0[\n ]*({[\n ]*(SOMETHING([\n ]+'[a-zA-Z0-9_]+)?(\n )*;)[\n ]*})""" 21elite_break = re.compile(elite_something.replace("SOMETHING", "break")) 22elite_continue = re.compile(elite_something.replace("SOMETHING", "continue")) 23def subbreak(match): 24 return match.group(1) 25def subfun(match): 26 all_items = match.group() 27 #if all_items.count(".offset") > 1: 28 # print "ignoring " + all_items +" for multi_item" 29 # assert not all_items 30 # return all_items # not the inner-most 31 each_arg = all_items.split(',') 32 out_arg = [] 33 for index in range(len(each_arg)): 34 v = each_arg[index] 35 out_arg.append(v) 36 is_single = False 37 for item in pointer_whitelist: 38 if item in v: 39 is_single = True 40 where = v.find('*mut') 41 if where != -1: 42 if is_single: 43 v= v.replace('*mut', '&mut', 1) 44 else: 45 v= v.replace('*mut', '&mut [', 1).replace('[ ','[') + ']' 46 where = v.find('*const') 47 if where != -1: 48 if is_single: 49 v= v.replace('*const', '&', 1) 50 else: 51 v= v.replace('*const', '& [', 1).replace('[ ','[')+']' 52 if v.endswith(')]'): 53 v = v[:-2] + '])' 54 out_arg[index] = v 55 return balance(','.join(out_arg)) 56 57def recursive_offset_match(data): 58 if data.find('.offset') != -1: 59 data = p2.sub(dereffun, data) 60 data = psubarray.sub(desubarrayfun, data) 61 return data 62 63def zerofirstoffset(data): 64 where = data.find('.offset') 65 if where == -1: 66 assert False 67 return data[0:where] + '.\xff' + data[where + 2:] 68def cut_out_both_offset(data): 69 split_loc = data.find('.offset') + 1 70 ret = data[split_loc:] 71 ret = p2.sub(dereffun, ret) 72 ret = psubarray.sub(desubarrayfun, ret) 73 return data[:split_loc] + ret 74 75def dereffun(match): 76 data = match.group() 77 if data.count('.offset') > 1: 78 return cut_out_both_offset(data) 79 data = data[1:] # zero out the * 80 data = data.replace('.offset(','[(', 1) 81 data = data.replace('(isize)', '(usize)') 82 data = data + ']' 83 data = recursive_offset_match(data) 84 data = balance(data) 85 return data 86 87def desubarrayfun(match): 88 data = match.group() 89 if data.count('.offset') > 1: 90 return cut_out_both_offset(data) 91 data = data.replace('.offset(','[(', 1) 92 data = data.replace('(isize)', '(usize)') 93 data = data + '..]' 94 data = recursive_offset_match(data) 95 data = balance(data) 96 return data 97def balance(data): 98 for ch in "[]{}()": 99 data = data.replace("""b'""" + ch + """'""", str(ord(ch))) 100 retlist = [] 101 stack = [] 102 bad_chars = [] 103 rev_paren = { 104 '{':'}','}':'{', 105 '[':']',']':'[', 106 '(':')',')':'(',} 107 while True: 108 matches = [data.find(c) for c in "{}()[]"] 109 where = min(x if x >= 0 else len(data) for x in matches) 110 if where == len(data): 111 retlist.append(data) 112 data = b'' 113 retlist += [b.replace(' ','').replace('\n','').replace('\t','') for b in bad_chars] 114 break 115 ch = data[where] 116 if ch in '({[': 117 stack.append(ch) 118 retlist.append(data[:where+1]) 119 data = data[where + 1:] 120 else: 121 if len(bad_chars) and bad_chars[0][-1] == rev_paren[ch]: 122 retlist.append(bad_chars[-1]) 123 bad_chars = bad_chars[1:] 124 elif len(stack) and ch == rev_paren[stack[-1]]: 125 retlist.append(data[:where + 1]) 126 data = data[where+1:] 127 stack.pop() 128 while len(bad_chars) and len(stack) and bad_chars[0][-1] ==rev_paren[stack[-1][-1]]: 129 retlist.append(bad_chars[0]) 130 bad_chars= bad_chars[1:] 131 stack.pop() 132 elif len(stack) != 0: 133 bad_chars.append(data[:where + 1]) 134 data = data[where+1:] 135 else: 136 retlist.append(data[:where+1]) 137 data = data[where+1:] 138 139 return ''.join(retlist) 140def rem(match): 141 return "" 142with open(sys.argv[1]) as f: 143 ret = p.sub(subfun, f.read()) 144 ret = p2.sub(dereffun, ret) 145 ret = p2.sub(dereffun, ret) 146 ret = p2.sub(dereffun, ret) 147 ret = psubarray.sub(desubarrayfun, ret) 148 ret = psubarray.sub(desubarrayfun, ret) 149 ret = psubarray.sub(desubarrayfun, ret) 150 ret = p2.sub(dereffun, ret) 151 ret = p2.sub(dereffun, ret) 152 ret = p2.sub(dereffun, ret) 153 ret = ret.replace('i32 as (usize)', 'usize') 154 ret = ret.replace('i32 as (u32)', 'u32') 155 ret = pointer_cast.sub(rem, ret) 156 ret = elite_break.sub(subbreak, ret) 157 ret = elite_continue.sub(subbreak, ret) 158 ret = ret.replace("#[derive(Clone, Copy)]", "") 159 ret = ret.replace("#[repr(C)]", "") 160 ret = ret.replace("#[no_mangle]", "") 161 ret = ret.replace("unsafe extern ", "") 162 ret = ret.replace("unsafe", "") 163 ret = ret.replace('self', 'xself') 164 #ret = balance(ret) 165 sys.stdout.write(ret) 166