summaryrefslogtreecommitdiff
path: root/dotfiles/system/.zsh/modules/Src/makepro.awk
diff options
context:
space:
mode:
Diffstat (limited to 'dotfiles/system/.zsh/modules/Src/makepro.awk')
-rw-r--r--dotfiles/system/.zsh/modules/Src/makepro.awk166
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
+}