#!/usr/bin/awk -f function gobble(s, x) { sub(/^ /, "", line) match(line, "^" "(" s ")") x = substr(line, 1, RLENGTH) line = substr(line, RLENGTH+1) return x } function convert(i, j, t) { type = argtypes[i,j] name = argnames[i,j] opt = optionals[i,j] tabs = x = "" for (i = 0; i < t; i++) { tabs = tabs "\t" } if (type == "int" || type == "long") { longs = longs "\tlong " name ";\n" } else if (type == "bool" || type == "boolean") { bools = bools "\tzend_bool " name ";\n" } else if (type == "double" || type == "float") { doubles = doubles "\tdouble " name ";\n" } else if (type == "string") { strings = strings "\tchar *" name " = NULL;\n" ints = ints "\tint " name "_len;\n" } else if (type == "array" || type == "object" || type == "mixed") { zvals = zvals "\tzval *" name " = NULL;\n" } else if (type == "resource" || type == "handle") { zvals = zvals "\tzval *" name " = NULL;\n" resources = resources "\tif (" name ") {\n" \ "\t\tZEND_FETCH_RESOURCE(???, ???, " name ", " name "_id, \"???\", ???_rsrc_id);\n\t}\n" ints = ints "\tint " name "_id = -1;\n" } } function comment(s) { if (i_know_what_to_do_shut_up_i_dont_need_your_help_mode) { return } else { return s } } BEGIN { name = "[_A-Za-z][_A-Za-z0-9]*" type = "int|long|double|float|string|bool|boolean|array|object|resource|handle|mixed|void" spec = "l|l|d|d|s|b|b|a|o|r|r|z|" num_funcs = 0 # create a map from type name to the spec split(type, type_array, "\|") split(spec, spec_array, "\|") for (i in type_array) { spec_map[type_array[i]] = spec_array[i] } if (xml && xml != "yes") { xmldoc = xml } else { xmldoc = extname "/" extname ".xml" } xmlhead = "\n" \ "\n" \ " \n" \ " functions\n" \ " \n\n" \ " \n" \ " &warn.experimental;\n" \ " \n" \ " \n" \ " \n\n"; xmlfoot = " \n\n" \ "\n" } { args_max = args_min = optional = i = spec_opt = 0 line = $0 spec_str = "\"" ## php extension must use lower case function names. ## this will translate any capitalized letter to lowercase ## and warn the user if (match(func_name,"[A-Z]") != 0) { printf("NOTICE: lower casing function name '%s'\n",func_name) func_name = tolower(func_name) } func_type = gobble(type); func_name = gobble(name); if (gobble("\\(")) { if (gobble("\\[")) optional = 1 while (arg_type = gobble(type)) { arg_name = gobble(name) if(arg_type == "void") { args_max = 0; args_min = 0; break; } else { argtypes[num_funcs,args_max] = arg_type argnames[num_funcs,args_max] = arg_name args_max++ if (optional) { if (!spec_opt) { spec_str = spec_str "|" spec_opt = 1 } optionals[num_funcs,i] = optional } else { args_min++ } spec_str = spec_str spec_map[arg_type] if (x = gobble("\\[")) { optional++ } y = gobble(",") if (!x && y && optional) { grouped_optional_param[num_funcs,i] = 1 } i++ } } } # if (x = gobble("\\)")) { gobble("\\]* *\\)") sub(/^[ \t]+/, "", line) fcomments[num_funcs] = line # } spec_str = spec_str "\"" funcs[num_funcs] = func_name types[num_funcs] = func_type maxargs[num_funcs] = args_max minargs[num_funcs] = args_min specs[num_funcs] = spec_str spec_opts[num_funcs] = spec_opt num_funcs++ } END { if (xml) print xmlhead > xmldoc for (i = 0; i < num_funcs; i++) { compareargc = maxargs[i] - minargs[i] closefetch = fetchargs = zvals = xmlparams = funcvals = resources = handleargs = closeopts = "" ints = longs = doubles = strings = bools = zvals = "" proto = "/* {{{ proto " types[i] " " funcs[i] "(" refid = funcs[i] gsub(/_/, "-", refid) xmlstr = " \n" \ " \n" \ " " funcs[i] "\n" \ " " fcomments[i] "\n" \ " \n" \ " \n" \ " Description\n" \ " \n" \ " \n" \ " " types[i] " " funcs[i] "\n" if (maxargs[i]>0) { fetchargs = "\tif (zend_parse_parameters(" ints = ints "\tint argc = ZEND_NUM_ARGS();\n" fetchargs = fetchargs "argc TSRMLS_CC, " specs[i] } else { fetchargs = fetchargs "\tif (zend_parse_parameters_none() == FAILURE) {\n\t\treturn;\n\t}" xmlparams = xmlparams " \n" } for (j = 0; j < maxargs[i]; j++) { fetchargs = fetchargs ", " fetchargs = fetchargs "&" argnames[i,j] if (argtypes[i,j] == "string") { fetchargs = fetchargs ", &" argnames[i,j] "_len" } xmlparams = xmlparams " " argtypes[i,j] if (j > minargs[i]-1) { if (!grouped_optional_param[i,j-1]) { if (j > 0) proto = proto " " proto = proto "[" closeopts = closeopts "]" } xmlparams = xmlparams "\n " \ argnames[i,j] \ "\n \n" } else { xmlparams = xmlparams \ " " \ argnames[i,j] \ "\n" } if (j > 0) proto = proto ", " proto = proto argtypes[i,j] " " argnames[i,j] convert(i, j, 1) } proto = proto closeopts ")\n " fcomments[i] " */\nPHP_FUNCTION(" funcs[i] ")\n{" if (maxargs[i]>0) { fetchargs = fetchargs ") == FAILURE)" closefetch " \n\t\treturn;\n" } funcvals = strings ints longs doubles bools zvals xmlstr = xmlstr xmlparams \ " \n" \ " \n" \ " &warn.experimental.func;\n" \ " \n" \ " &warn.undocumented.func;\n" \ " \n" \ " \n" \ " \n" print proto > stubfile if (funcvals) print funcvals > stubfile if (fetchargs) print fetchargs > stubfile if (resources) { print resources > stubfile if (!stubs) print "" > extname "/function_warning" } if (!i_know_what_to_do_shut_up_i_dont_need_your_help_mode) { print "\tphp_error(E_WARNING, \"" funcs[i] ": not yet implemented\");" > stubfile } print "}\n/* }}} */\n" > stubfile if (stubs) { h_stubs = h_stubs "PHP_FUNCTION(" funcs[i] ");\n" c_stubs = c_stubs "\tPHP_FE(" funcs[i] ",\tNULL)\n" } else { print "PHP_FUNCTION(" funcs[i] ");" > extname "/function_declarations" print "\tPHP_FE(" funcs[i] ",\tNULL)" > extname "/function_entries" } if (xml) print xmlstr > xmldoc } if (stubs) { print "\n/* ----------------------------------------------------------- */\n" > stubfile print c_stubs > stubfile print "\n/* ----------------------------------------------------------- */\n" > stubfile print h_stubs > stubfile } if (xml) print xmlfoot > xmldoc } # # Local variables: # tab-width: 2 # c-basic-offset: 2 # End: