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