diff options
Diffstat (limited to 'dotfiles/system/.zsh/modules/Src/makepro.awk')
| -rw-r--r-- | dotfiles/system/.zsh/modules/Src/makepro.awk | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/dotfiles/system/.zsh/modules/Src/makepro.awk b/dotfiles/system/.zsh/modules/Src/makepro.awk new file mode 100644 index 0000000..0498c15 --- /dev/null +++ b/dotfiles/system/.zsh/modules/Src/makepro.awk @@ -0,0 +1,166 @@ +# +# makepro.awk - generate prototype lists +# + +BEGIN { + aborting = 0 + + # arg 1 is the name of the file to process + # arg 2 is the name of the subdirectory it is in + if(ARGC != 3) { + aborting = 1 + exit 1 + } + name = ARGV[1] + gsub(/^.*\//, "", name) + gsub(/\.c$/, "", name) + name = ARGV[2] "_" name + gsub(/\//, "_", name) + ARGC-- + + printf "E#ifndef have_%s_globals\n", name + printf "E#define have_%s_globals\n", name + printf "E\n" +} + +# all relevant declarations are preceded by "/**/" on a line by itself + +/^\/\*\*\/$/ { + # The declaration is on following lines. The interesting part might + # be terminated by a `{' (`int foo(void) { }' or `int bar[] = {') + # or `;' (`int x;'). + line = "" + isfunc = 0 + while(1) { + if(getline <= 0) { + aborting = 1 + exit 1 + } + if (line == "" && $0 ~ /^[ \t]*#/) { + # Directly after the /**/ was a preprocessor line. + # Spit it out and re-start the outer loop. + printf "E%s\n", $0 + printf "L%s\n", $0 + next + } + gsub(/\t/, " ") + line = line " " $0 + gsub(/\/\*([^*]|\*+[^*\/])*\*+\//, " ", line) + if(line ~ /\/\*/) + continue + # If it is a function definition, note so. + if(line ~ /\) *(VA_DCL )*[{].*$/) #} + isfunc = 1 + if(sub(/ *[{;].*$/, "", line)) #} + break + } + if (!match(line, /VA_ALIST/)) { + # Put spaces around each identifier. + while(match(line, /[^_0-9A-Za-z ][_0-9A-Za-z]/) || + match(line, /[_0-9A-Za-z][^_0-9A-Za-z ]/)) + line = substr(line, 1, RSTART) " " substr(line, RSTART+1) + } + # Separate declarations into a type and a list of declarators. + # In each declarator, "@{" and "@}" are used in place of parens to + # mark function parameter lists, and "@!" is used in place of commas + # in parameter lists. "@<" and "@>" are used in place of + # non-parameter list parens. + gsub(/ _ +/, " _ ", line) + while(1) { + if(isfunc && match(line, /\([^()]*\)$/)) + line = substr(line, 1, RSTART-1) " _ (" substr(line, RSTART) ")" + else if(match(line, / _ \(\([^,()]*,/)) + line = substr(line, 1, RSTART+RLENGTH-2) "@!" substr(line, RSTART+RLENGTH) + else if(match(line, / _ \(\([^,()]*\)\)/)) + line = substr(line, 1, RSTART-1) "@{" substr(line, RSTART+5, RLENGTH-7) "@}" substr(line, RSTART+RLENGTH) + else if(match(line, /\([^,()]*\)/)) + line = substr(line, 1, RSTART-1) "@<" substr(line, RSTART+1, RLENGTH-2) "@>" substr(line, RSTART+RLENGTH) + else + break + } + sub(/^ */, "", line) + match(line, /^((const|enum|mod_export|static|struct|union) +)*([_0-9A-Za-z]+ +|((char|double|float|int|long|short|unsigned|void) +)+)((const|static) +)*/) + dtype = substr(line, 1, RLENGTH) + sub(/ *$/, "", dtype) + if(" " dtype " " ~ / static /) + locality = "L" + else + locality = "E" + exported = " " dtype " " ~ / mod_export / + line = substr(line, RLENGTH+1) "," + # Handle each declarator. + if (match(line, /VA_ALIST/)) { + # Already has VARARGS handling. + + # Put parens etc. back + gsub(/@[{]/, "((", line) + gsub(/@}/, "))", line) + gsub(/@</, "(", line) + gsub(/@>/, ")", line) + gsub(/@!/, ",", line) + sub(/,$/, ";", line) + gsub(/mod_export/, "mod_import_function", dtype) + gsub(/VA_ALIST/, "VA_ALIST_PROTO", line) + sub(/ VA_DCL/, "", line) + + if(locality ~ /E/) + dtype = "extern " dtype + + if (match(line, /[_0-9A-Za-z]+\(VA_ALIST/)) + dnam = substr(line, RSTART, RLENGTH-9) + + # If this is exported, add it to the exported symbol list. + if (exported) + printf "X%s\n", dnam + + printf "%s%s %s\n", locality, dtype, line + } else { + while(match(line, /^[^,]*,/)) { + # Separate out the name from the declarator. Use "@+" and "@-" + # to bracket the name within the declarator. Strip off any + # initialiser. + dcltor = substr(line, 1, RLENGTH-1) + line = substr(line, RLENGTH+1) + sub(/\=.*$/, "", dcltor) + match(dcltor, /^([^_0-9A-Za-z]| const )*/) + dcltor = substr(dcltor, 1, RLENGTH) "@+" substr(dcltor, RLENGTH+1) + match(dcltor, /^.*@\+[_0-9A-Za-z]+/) + dcltor = substr(dcltor, 1, RLENGTH) "@-" substr(dcltor, RLENGTH+1) + dnam = dcltor + sub(/^.*@\+/, "", dnam) + sub(/@-.*$/, "", dnam) + + # Put parens etc. back + gsub(/@[{]/, " _((", dcltor) + gsub(/@}/, "))", dcltor) + gsub(/@</, "(", dcltor) + gsub(/@>/, ")", dcltor) + gsub(/@!/, ",", dcltor) + + # If this is exported, add it to the exported symbol list. + if(exported) + printf "X%s\n", dnam + + # Format the declaration for output + dcl = dtype " " dcltor ";" + if(locality ~ /E/) + dcl = "extern " dcl + if(isfunc) + gsub(/ mod_export /, " mod_import_function ", dcl) + else + gsub(/ mod_export /, " mod_import_variable ", dcl) + gsub(/@[+-]/, "", dcl) + gsub(/ +/, " ", dcl) + while(match(dcl, /[^_0-9A-Za-z] ./) || match(dcl, /. [^_0-9A-Za-z]/)) + dcl = substr(dcl, 1, RSTART) substr(dcl, RSTART+2) + printf "%s%s\n", locality, dcl + } + } +} + +END { + if(aborting) + exit 1 + printf "E\n" + printf "E#endif /* !have_%s_globals */\n", name +} |
