PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/Src/makepro.awk

https://bitbucket.org/ZyX_I/zsh
AWK | 166 lines | 124 code | 14 blank | 28 comment | 0 complexity | 0fe0f55a1ab52fa230204e8142aa2e0a MD5 | raw file
  1. #
  2. # makepro.awk - generate prototype lists
  3. #
  4. BEGIN {
  5. aborting = 0
  6. # arg 1 is the name of the file to process
  7. # arg 2 is the name of the subdirectory it is in
  8. if(ARGC != 3) {
  9. aborting = 1
  10. exit 1
  11. }
  12. name = ARGV[1]
  13. gsub(/^.*\//, "", name)
  14. gsub(/\.c$/, "", name)
  15. name = ARGV[2] "_" name
  16. gsub(/\//, "_", name)
  17. ARGC--
  18. printf "E#ifndef have_%s_globals\n", name
  19. printf "E#define have_%s_globals\n", name
  20. printf "E\n"
  21. }
  22. # all relevant declarations are preceded by "/**/" on a line by itself
  23. /^\/\*\*\/$/ {
  24. # The declaration is on following lines. The interesting part might
  25. # be terminated by a `{' (`int foo(void) { }' or `int bar[] = {')
  26. # or `;' (`int x;').
  27. line = ""
  28. isfunc = 0
  29. while(1) {
  30. if(getline <= 0) {
  31. aborting = 1
  32. exit 1
  33. }
  34. if (line == "" && $0 ~ /^[ \t]*#/) {
  35. # Directly after the /**/ was a preprocessor line.
  36. # Spit it out and re-start the outer loop.
  37. printf "E%s\n", $0
  38. printf "L%s\n", $0
  39. next
  40. }
  41. gsub(/\t/, " ")
  42. line = line " " $0
  43. gsub(/\/\*([^*]|\*+[^*\/])*\*+\//, " ", line)
  44. if(line ~ /\/\*/)
  45. continue
  46. # If it is a function definition, note so.
  47. if(line ~ /\) *(VA_DCL )*[{].*$/) #}
  48. isfunc = 1
  49. if(sub(/ *[{;].*$/, "", line)) #}
  50. break
  51. }
  52. if (!match(line, /VA_ALIST/)) {
  53. # Put spaces around each identifier.
  54. while(match(line, /[^_0-9A-Za-z ][_0-9A-Za-z]/) ||
  55. match(line, /[_0-9A-Za-z][^_0-9A-Za-z ]/))
  56. line = substr(line, 1, RSTART) " " substr(line, RSTART+1)
  57. }
  58. # Separate declarations into a type and a list of declarators.
  59. # In each declarator, "@{" and "@}" are used in place of parens to
  60. # mark function parameter lists, and "@!" is used in place of commas
  61. # in parameter lists. "@<" and "@>" are used in place of
  62. # non-parameter list parens.
  63. gsub(/ _ +/, " _ ", line)
  64. while(1) {
  65. if(isfunc && match(line, /\([^()]*\)$/))
  66. line = substr(line, 1, RSTART-1) " _ (" substr(line, RSTART) ")"
  67. else if(match(line, / _ \(\([^,()]*,/))
  68. line = substr(line, 1, RSTART+RLENGTH-2) "@!" substr(line, RSTART+RLENGTH)
  69. else if(match(line, / _ \(\([^,()]*\)\)/))
  70. line = substr(line, 1, RSTART-1) "@{" substr(line, RSTART+5, RLENGTH-7) "@}" substr(line, RSTART+RLENGTH)
  71. else if(match(line, /\([^,()]*\)/))
  72. line = substr(line, 1, RSTART-1) "@<" substr(line, RSTART+1, RLENGTH-2) "@>" substr(line, RSTART+RLENGTH)
  73. else
  74. break
  75. }
  76. sub(/^ */, "", line)
  77. match(line, /^((const|enum|mod_export|static|struct|union) +)*([_0-9A-Za-z]+ +|((char|double|float|int|long|short|unsigned|void) +)+)((const|static) +)*/)
  78. dtype = substr(line, 1, RLENGTH)
  79. sub(/ *$/, "", dtype)
  80. if(" " dtype " " ~ / static /)
  81. locality = "L"
  82. else
  83. locality = "E"
  84. exported = " " dtype " " ~ / mod_export /
  85. line = substr(line, RLENGTH+1) ","
  86. # Handle each declarator.
  87. if (match(line, /VA_ALIST/)) {
  88. # Already has VARARGS handling.
  89. # Put parens etc. back
  90. gsub(/@[{]/, "((", line)
  91. gsub(/@}/, "))", line)
  92. gsub(/@</, "(", line)
  93. gsub(/@>/, ")", line)
  94. gsub(/@!/, ",", line)
  95. sub(/,$/, ";", line)
  96. gsub(/mod_export/, "mod_import_function", dtype)
  97. gsub(/VA_ALIST/, "VA_ALIST_PROTO", line)
  98. sub(/ VA_DCL/, "", line)
  99. if(locality ~ /E/)
  100. dtype = "extern " dtype
  101. if (match(line, /[_0-9A-Za-z]+\(VA_ALIST/))
  102. dnam = substr(line, RSTART, RLENGTH-9)
  103. # If this is exported, add it to the exported symbol list.
  104. if (exported)
  105. printf "X%s\n", dnam
  106. printf "%s%s %s\n", locality, dtype, line
  107. } else {
  108. while(match(line, /^[^,]*,/)) {
  109. # Separate out the name from the declarator. Use "@+" and "@-"
  110. # to bracket the name within the declarator. Strip off any
  111. # initialiser.
  112. dcltor = substr(line, 1, RLENGTH-1)
  113. line = substr(line, RLENGTH+1)
  114. sub(/\=.*$/, "", dcltor)
  115. match(dcltor, /^([^_0-9A-Za-z]| const )*/)
  116. dcltor = substr(dcltor, 1, RLENGTH) "@+" substr(dcltor, RLENGTH+1)
  117. match(dcltor, /^.*@\+[_0-9A-Za-z]+/)
  118. dcltor = substr(dcltor, 1, RLENGTH) "@-" substr(dcltor, RLENGTH+1)
  119. dnam = dcltor
  120. sub(/^.*@\+/, "", dnam)
  121. sub(/@-.*$/, "", dnam)
  122. # Put parens etc. back
  123. gsub(/@[{]/, " _((", dcltor)
  124. gsub(/@}/, "))", dcltor)
  125. gsub(/@</, "(", dcltor)
  126. gsub(/@>/, ")", dcltor)
  127. gsub(/@!/, ",", dcltor)
  128. # If this is exported, add it to the exported symbol list.
  129. if(exported)
  130. printf "X%s\n", dnam
  131. # Format the declaration for output
  132. dcl = dtype " " dcltor ";"
  133. if(locality ~ /E/)
  134. dcl = "extern " dcl
  135. if(isfunc)
  136. gsub(/ mod_export /, " mod_import_function ", dcl)
  137. else
  138. gsub(/ mod_export /, " mod_import_variable ", dcl)
  139. gsub(/@[+-]/, "", dcl)
  140. gsub(/ +/, " ", dcl)
  141. while(match(dcl, /[^_0-9A-Za-z] ./) || match(dcl, /. [^_0-9A-Za-z]/))
  142. dcl = substr(dcl, 1, RSTART) substr(dcl, RSTART+2)
  143. printf "%s%s\n", locality, dcl
  144. }
  145. }
  146. }
  147. END {
  148. if(aborting)
  149. exit 1
  150. printf "E\n"
  151. printf "E#endif /* !have_%s_globals */\n", name
  152. }