create_stubs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. #!/usr/bin/awk -f
  2. function gobble(s, x)
  3. {
  4. sub(/^ /, "", line)
  5. match(line, "^" "(" s ")")
  6. x = substr(line, 1, RLENGTH)
  7. line = substr(line, RLENGTH+1)
  8. return x
  9. }
  10. function convert(i, j, t)
  11. {
  12. type = argtypes[i,j]
  13. name = argnames[i,j]
  14. opt = optionals[i,j]
  15. tabs = x = ""
  16. for (i = 0; i < t; i++) { tabs = tabs "\t" }
  17. if (type == "int" || type == "long") {
  18. longs = longs "\tlong " name ";\n"
  19. } else if (type == "bool" || type == "boolean") {
  20. bools = bools "\tzend_bool " name ";\n"
  21. } else if (type == "double" || type == "float") {
  22. doubles = doubles "\tdouble " name ";\n"
  23. } else if (type == "string") {
  24. strings = strings "\tchar *" name " = NULL;\n"
  25. ints = ints "\tint " name "_len;\n"
  26. } else if (type == "array" || type == "object" || type == "mixed") {
  27. zvals = zvals "\tzval *" name " = NULL;\n"
  28. } else if (type == "resource" || type == "handle") {
  29. zvals = zvals "\tzval *" name " = NULL;\n"
  30. resources = resources "\tif (" name ") {\n" \
  31. "\t\tZEND_FETCH_RESOURCE(???, ???, " name ", " name "_id, \"???\", ???_rsrc_id);\n\t}\n"
  32. ints = ints "\tint " name "_id = -1;\n"
  33. }
  34. }
  35. function comment(s)
  36. {
  37. if (i_know_what_to_do_shut_up_i_dont_need_your_help_mode) {
  38. return
  39. } else {
  40. return s
  41. }
  42. }
  43. BEGIN {
  44. name = "[_A-Za-z][_A-Za-z0-9]*"
  45. type = "int|long|double|float|string|bool|boolean|array|object|resource|handle|mixed|void"
  46. spec = "l|l|d|d|s|b|b|a|o|r|r|z|"
  47. num_funcs = 0
  48. # create a map from type name to the spec
  49. split(type, type_array, "\|")
  50. split(spec, spec_array, "\|")
  51. for (i in type_array) {
  52. spec_map[type_array[i]] = spec_array[i]
  53. }
  54. if (xml && xml != "yes") {
  55. xmldoc = xml
  56. } else {
  57. xmldoc = extname "/" extname ".xml"
  58. }
  59. xmlhead = "<?xml version='1.0' encoding='iso-8859-1'?>\n" \
  60. "<!-- $Id$ -->\n" \
  61. " <reference id=\"ref." extname "\">\n" \
  62. " <title> functions</title>\n" \
  63. " <titleabbrev></titleabbrev>\n\n" \
  64. " <partintro>\n" \
  65. " &warn.experimental;\n" \
  66. " <para>\n" \
  67. " </para>\n" \
  68. " </partintro>\n\n";
  69. xmlfoot = " </reference>\n\n" \
  70. "<!-- Keep this comment at the end of the file\n" \
  71. "Local variables:\n" \
  72. "mode: sgml\n" \
  73. "sgml-omittag:t\n" \
  74. "sgml-shorttag:t\n" \
  75. "sgml-minimize-attributes:nil\n" \
  76. "sgml-always-quote-attributes:t\n" \
  77. "sgml-indent-step:1\n" \
  78. "sgml-indent-data:t\n" \
  79. "indent-tabs-mode:nil\n" \
  80. "sgml-parent-document:nil\n" \
  81. "sgml-default-dtd-file:\"../../manual.ced\"\n" \
  82. "sgml-exposed-tags:nil\n" \
  83. "sgml-local-catalogs:nil\n" \
  84. "sgml-local-ecat-files:nil\n" \
  85. "End:\n" \
  86. "vim600: syn=xml fen fdm=syntax fdl=2 si\n" \
  87. "vim: et tw=78 syn=sgml\n" \
  88. "vi: ts=1 sw=1\n" \
  89. "-->\n"
  90. }
  91. {
  92. args_max = args_min = optional = i = spec_opt = 0
  93. line = $0
  94. spec_str = "\""
  95. ## php extension must use lower case function names.
  96. ## this will translate any capitalized letter to lowercase
  97. ## and warn the user
  98. if (match(func_name,"[A-Z]") != 0) {
  99. printf("NOTICE: lower casing function name '%s'\n",func_name)
  100. func_name = tolower(func_name)
  101. }
  102. func_type = gobble(type);
  103. func_name = gobble(name);
  104. if (gobble("\\(")) {
  105. if (gobble("\\[")) optional = 1
  106. while (arg_type = gobble(type)) {
  107. arg_name = gobble(name)
  108. if(arg_type == "void") {
  109. args_max = 0;
  110. args_min = 0;
  111. break;
  112. } else {
  113. argtypes[num_funcs,args_max] = arg_type
  114. argnames[num_funcs,args_max] = arg_name
  115. args_max++
  116. if (optional) {
  117. if (!spec_opt) {
  118. spec_str = spec_str "|"
  119. spec_opt = 1
  120. }
  121. optionals[num_funcs,i] = optional
  122. } else {
  123. args_min++
  124. }
  125. spec_str = spec_str spec_map[arg_type]
  126. if (x = gobble("\\[")) {
  127. optional++
  128. }
  129. y = gobble(",")
  130. if (!x && y && optional) {
  131. grouped_optional_param[num_funcs,i] = 1
  132. }
  133. i++
  134. }
  135. }
  136. }
  137. # if (x = gobble("\\)")) {
  138. gobble("\\]* *\\)")
  139. sub(/^[ \t]+/, "", line)
  140. fcomments[num_funcs] = line
  141. # }
  142. spec_str = spec_str "\""
  143. funcs[num_funcs] = func_name
  144. types[num_funcs] = func_type
  145. maxargs[num_funcs] = args_max
  146. minargs[num_funcs] = args_min
  147. specs[num_funcs] = spec_str
  148. spec_opts[num_funcs] = spec_opt
  149. num_funcs++
  150. }
  151. END {
  152. if (xml) print xmlhead > xmldoc
  153. for (i = 0; i < num_funcs; i++) {
  154. compareargc = maxargs[i] - minargs[i]
  155. closefetch = fetchargs = zvals = xmlparams = funcvals = resources = handleargs = closeopts = ""
  156. ints = longs = doubles = strings = bools = zvals = ""
  157. proto = "/* {{{ proto " types[i] " " funcs[i] "("
  158. refid = funcs[i]
  159. gsub(/_/, "-", refid)
  160. xmlstr = " <refentry id=\"function." refid "\">\n" \
  161. " <refnamediv>\n" \
  162. " <refname>" funcs[i] "</refname>\n" \
  163. " <refpurpose>" fcomments[i] "</refpurpose>\n" \
  164. " </refnamediv>\n" \
  165. " <refsect1>\n" \
  166. " <title>Description</title>\n" \
  167. " <funcsynopsis>\n" \
  168. " <funcprototype>\n" \
  169. " <funcdef>" types[i] " <function>" funcs[i] "</function></funcdef>\n"
  170. if (maxargs[i]>0) {
  171. fetchargs = "\tif (zend_parse_parameters("
  172. ints = ints "\tint argc = ZEND_NUM_ARGS();\n"
  173. fetchargs = fetchargs "argc TSRMLS_CC, " specs[i]
  174. } else {
  175. fetchargs = fetchargs "\tif (zend_parse_parameters_none() == FAILURE) {\n\t\treturn;\n\t}"
  176. xmlparams = xmlparams " <void/>\n"
  177. }
  178. for (j = 0; j < maxargs[i]; j++) {
  179. fetchargs = fetchargs ", "
  180. fetchargs = fetchargs "&" argnames[i,j]
  181. if (argtypes[i,j] == "string") {
  182. fetchargs = fetchargs ", &" argnames[i,j] "_len"
  183. }
  184. xmlparams = xmlparams " <paramdef>" argtypes[i,j]
  185. if (j > minargs[i]-1) {
  186. if (!grouped_optional_param[i,j-1]) {
  187. if (j > 0) proto = proto " "
  188. proto = proto "["
  189. closeopts = closeopts "]"
  190. }
  191. xmlparams = xmlparams "\n <parameter><optional>" \
  192. argnames[i,j] \
  193. "</optional></parameter>\n </paramdef>\n"
  194. } else {
  195. xmlparams = xmlparams \
  196. " <parameter>" \
  197. argnames[i,j] \
  198. "</parameter></paramdef>\n"
  199. }
  200. if (j > 0) proto = proto ", "
  201. proto = proto argtypes[i,j] " " argnames[i,j]
  202. convert(i, j, 1)
  203. }
  204. proto = proto closeopts ")\n " fcomments[i] " */\nPHP_FUNCTION(" funcs[i] ")\n{"
  205. if (maxargs[i]>0) {
  206. fetchargs = fetchargs ") == FAILURE)" closefetch " \n\t\treturn;\n"
  207. }
  208. funcvals = strings ints longs doubles bools zvals
  209. xmlstr = xmlstr xmlparams \
  210. " </funcprototype>\n" \
  211. " </funcsynopsis>\n" \
  212. " &warn.experimental.func;\n" \
  213. " <para>\n" \
  214. " &warn.undocumented.func;\n" \
  215. " </para>\n" \
  216. " </refsect1>\n" \
  217. " </refentry>\n"
  218. print proto > stubfile
  219. if (funcvals) print funcvals > stubfile
  220. if (fetchargs) print fetchargs > stubfile
  221. if (resources) {
  222. print resources > stubfile
  223. if (!stubs) print "" > extname "/function_warning"
  224. }
  225. if (!i_know_what_to_do_shut_up_i_dont_need_your_help_mode) {
  226. print "\tphp_error(E_WARNING, \"" funcs[i] ": not yet implemented\");" > stubfile
  227. }
  228. print "}\n/* }}} */\n" > stubfile
  229. if (stubs) {
  230. h_stubs = h_stubs "PHP_FUNCTION(" funcs[i] ");\n"
  231. c_stubs = c_stubs "\tPHP_FE(" funcs[i] ",\tNULL)\n"
  232. } else {
  233. print "PHP_FUNCTION(" funcs[i] ");" > extname "/function_declarations"
  234. print "\tPHP_FE(" funcs[i] ",\tNULL)" > extname "/function_entries"
  235. }
  236. if (xml) print xmlstr > xmldoc
  237. }
  238. if (stubs) {
  239. print "\n/* ----------------------------------------------------------- */\n" > stubfile
  240. print c_stubs > stubfile
  241. print "\n/* ----------------------------------------------------------- */\n" > stubfile
  242. print h_stubs > stubfile
  243. }
  244. if (xml) print xmlfoot > xmldoc
  245. }
  246. #
  247. # Local variables:
  248. # tab-width: 2
  249. # c-basic-offset: 2
  250. # End: