diff options
Diffstat (limited to 'script')
-rw-r--r-- | script/gen-manual-mach.py | 52 | ||||
-rwxr-xr-x | script/gen-manual-mach.sh | 26 |
2 files changed, 52 insertions, 26 deletions
diff --git a/script/gen-manual-mach.py b/script/gen-manual-mach.py new file mode 100644 index 0000000..00317e9 --- /dev/null +++ b/script/gen-manual-mach.py @@ -0,0 +1,52 @@ +import subprocess, re +# i wish there was a good simple tooling/ast library that could do this more cleanly +# maybe libTooling, but instability and dependencies... + +desired = ['thread_get_state', 'thread_set_state', 'mach_vm_remap'] + +def pipe(cmd, stdin='', expected_returncode=0): + p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) + stdout, _ = p.communicate(stdin) + if p.returncode != expected_returncode: + raise Exception('process failed: %s => %d (not %d)' % (cmd, p.returncode, expected_returncode)) + return stdout +text = pipe('mig -user /dev/stdout -server /dev/null -header /dev/stdout /usr/include/mach/{thread_act,mach_vm}.defs') +text = pipe('unifdef -D__MigTypeCheck -Umig_external -UUseStaticTemplates', text, expected_returncode=1) +# remove voucher/etc code +text = re.sub('/\* BEGIN (VOUCHER|MIG_STRNCPY_ZEROFILL) CODE \*/.*?/\* END \\1 CODE \*/', + '', text, flags=re.S) +# and union +text = re.sub('\/\* union of all requests.*?#endif \/\* !__RequestUnion[^\n]*', + '', text, flags=re.S) +# simplify function names +text = text.replace('_kernelrpc_', '') +# extern->static +text = re.sub('(extern|mig_internal|mig_external)', 'static', text) +# add extra argument reply_port +text = re.sub('^\)', ', mach_port_t reply_port)', text, flags=re.M) +text = text.replace('mig_get_reply_port()', 'reply_port') +# don't use stdlib functions +text = re.sub(r'\b(mach_msg|memcpy)\b', r'manual_\1', text) +# change symbols to avoid collision: types +text = re.sub('(Request|Reply)__', r'\1__manual_', text) +# and functions +text = re.sub('^([a-z].+|)kern_return_t\s+([a-z])', r'\1kern_return_t manual_\2', text, flags=re.M) + +text = re.sub('^#(if|ifdef|define|endif)\s.*_check__Reply.*', '', text, flags=re.M) + +# filter out unused parts +patterns = '(^/\* Routine [^ ]* \*/.*?(?:^}|reply_port\);)|' \ + '#if __MIG_check__Reply.*?#endif /\* __MIG_check__Reply[^\n]*|' \ + '#ifdef\s+__MigPackStructs.*?typedef struct {.*?(?:Request|Reply)__.*?#endif|' \ + '#ifndef\s+LimitCheck.*?msgh_local_port)' +bits = re.split(patterns, text, flags=re.M | re.S) +out = '' +for bit in bits: + #print bit; print ';;;' + if 'subsystem_to_name_map' in bit: + continue + if 'LimitCheck' in bit or any(d in bit for d in desired): + out += bit + '\n' +#print out;die + +open('generated/manual-mach.inc.h', 'w').write(out) diff --git a/script/gen-manual-mach.sh b/script/gen-manual-mach.sh deleted file mode 100755 index 2676915..0000000 --- a/script/gen-manual-mach.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -out=generated/manual-mach.inc.h -pat='/thread_[gs]et_state|vm_remap/' -(mig -user /dev/stdout -server /dev/null -header /dev/stdout /usr/include/mach/{thread_act,mach_vm}.defs | - egrep -v '^(#ifndef|#define|#endif).*_user_' | - egrep -v '#include "stdout"' | - unifdef -D__MigTypeCheck -Umig_external -UUSING_VOUCHERS | - egrep -v 'voucher_mach_msg_set' | - egrep -v '#define mig_external' | - sed -E 's/(mach_msg|memcpy)\(/manual_\1(/g; - s/^\)/, mach_port_t reply_port)/; - s/_kernelrpc_//g; - s/(Request|Reply)__/\1__manual_/g; - s/[[:<:]]extern[[:>:]]/static/g; - s/^([a-z].*)?kern_return_t[[:blank:]]+([a-z])/\1kern_return_t manual_\2/; - s/mig_external/static/g; - s/mig_get_reply_port\(\)/reply_port/g' | - awk 'BEGIN { on = 1; } - /^\/\* Routine / || - (/__MIG_check__Reply__/ && /^#[ie]/) { on = '"$pat"'; } - on { print; } - /typedef struct {/ { xon = 1; accum = ""; } - xon { accum = accum $0 "\n"; } - xon && /} / { if('"$pat"') print accum; xon = 0; } - /#endif.*__AfterMigUserHeader/ { on = 1; } - ' > $out) || rm -f $out |