/Src/makepro.awk
AWK | 166 lines | 124 code | 14 blank | 28 comment | 0 complexity | 0fe0f55a1ab52fa230204e8142aa2e0a MD5 | raw file
- #
- # 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
- }