#!/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") { x = tabs "convert_to_long_ex(" name ext ");\n" \ (ext? tabs name " = Z_LVAL_PP(" name ext ");\n": "") ints = ints "\tint " name ";\n" } else if (type == "bool") { x = tabs "convert_to_long_ex(" name ext ");\n" \ (ext? tabs name " = Z_LVAL_PP(" name ext ");\n": "") ints = ints "\tint " name ";\n" } else if (type == "double") { x = tabs "convert_to_double_ex(" name ext ");\n" \ (ext? tabs name " = Z_DVAL_PP(" name ext ");\n": "") doubles = doubles "\tdouble " name ";\n" } else if (type == "float") { x = tabs "convert_to_double_ex(" name ext ");\n" \ (ext? tabs name " = (float) Z_DVAL_PP(" name ext ");\n": "") floats = floats "\tfloat " name ";\n" } else if (type == "string") { x = tabs "convert_to_string_ex(" name ext ");\n" \ (ext? tabs name " = Z_STRVAL_PP(" name ext ");\n": "") (ext ? strings = strings "\tchar *" name " = NULL;\n" : 0) if (string_lens) { x = x tabs name "_len = Z_STRLEN_PP(" name ext ");\n" ints = ints "\tint " name "_len;\n" } } else if (type == "array") { x = "convert_to_array_ex(" name ext ");\n" } else if (type == "resource") { if (opt && i > -1) { resources = resources "\tif (argc < " j+1 ") {\n" \ comment("\t\t/* Argument not given, do something before\n\t\t trying to fetch resource " name ". */\n") \ "\t}\n\tZEND_FETCH_RESOURCE(???, ???, " name ext ", " name "_id, \"???\", ???G());\n" } else { resources = resources "\tZEND_FETCH_RESOURCE(???, ???, " name ext ", " name "_id, \"???\", ???G());\n" } funcvals = funcvals "\tint " name "_id = -1;\n" } else { x = comment(tabs "/* Write your own code here to handle argument " name ". */\n") } if (x) return x } 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|double|float|string|bool|array|object|resource|mixed|void" num_funcs = 0 if (assign_params) ext = "_arg" if (xml && xml != "yes") { xmldoc = xml } else { xmldoc = extname "/" extname ".xml" } xmlhead = " \n" \ " functions\n" \ " \n\n" xmlfoot = " \n\n" \ "\n" } { args_max = args_min = optional = i = 0 line = $0 func_type = gobble(type); func_name = gobble(name); if (gobble("\\(")) { if (gobble("\\[")) optional = 1 while (arg_type = gobble(type)) { arg_name = gobble(name) argtypes[num_funcs,args_max] = arg_type argnames[num_funcs,args_max] = arg_name args_max++ if (optional) { optionals[num_funcs,i] = optional if (arg_type != "resource") { useswitch[num_funcs] = 1 } } else { args_min++ } if (x = gobble("\\[")) { optional++ } y = gobble(",") if (!x && y && optional) { check_argc_in_switch[num_funcs] = 1 grouped_optional_param[num_funcs,i] = 1 } i++ } } funcs[num_funcs] = func_name types[num_funcs] = func_type maxargs[num_funcs] = args_max minargs[num_funcs] = args_min num_funcs++ } END { if (xml) print xmlhead > xmldoc for (i = 0; i < num_funcs; i++) { compareargc = maxargs[i] - minargs[i] closefetch = xmlparams = funcvals = resources = handleargs = closeopts = "" ints = doubles = floats = strings = arrays = "" proto = "/* {{{ proto " types[i] " " funcs[i] "(" refid = funcs[i] gsub(/_/, "-", refid) xmlstr = " \n" \ " \n" \ " " funcs[i] "\n" \ " \n" \ " \n" \ " \n" \ " Description\n" \ " \n" \ " \n" \ " " types[i] " " funcs[i] "\n" if (maxargs[i]) { zvals = "\tzval " if (compareargc) { funcvals = "\tint argc;\n" if (minargs[i]) { fetchargs = "\targc = ZEND_NUM_ARGS();\n\tif (argc < " \ minargs[i] " || argc > " maxargs[i] \ " || zend_get_parameters_ex(argc, " } else { fetchargs = "\targc = ZEND_NUM_ARGS();\n\tif (argc > " \ maxargs[i] " || (argc && zend_get_parameters_ex(argc, " closefetch = ")" } } else { fetchargs = "\tif (ZEND_NUM_ARGS() != " maxargs[i] \ " || zend_get_parameters_ex(" maxargs[i] ", " } } for (j = 0; j < maxargs[i]; j++) { if (j) { zvals = zvals ", " fetchargs = fetchargs ", " } zvals = zvals "**" argnames[i,j] ext fetchargs = fetchargs "&" argnames[i,j] ext 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] # Clean up this mess... if (useswitch[i]) { if (grouped_optional_param[i,j] && code) { handleargs = convert(i, j, 3) \ ((grouped_optional_param[i,j-1]) ? "" : comment("\t\t\t/* Fall-through. */\n")) \ handleargs } else { if (j > minargs[i]-1) { if (code = convert(i, j, 3)) { handleargs = "\t\tcase " j+1 ":\n" code \ ((grouped_optional_param[i,j-1]) ? "" : comment("\t\t\t/* Fall-through. */\n")) \ handleargs } else { handleargs = "\t\tcase " j+1 ":" \ comment("\t/* Fall-through. */") \ "\n" handleargs } } else if (j >= minargs[i]-1) { if (code = convert(i, j, 3)) { handleargs = "\t\tcase " j+1 ":\n" code handleargs } else { handleargs = "\t\tcase " j+1 ":\n" handleargs } } else { if (code = convert(i, j, 3)) handleargs = code handleargs } } } else { if (code = convert(i, j, 1)) handleargs = handleargs code } } proto = proto closeopts ")\n */\nPHP_FUNCTION(" funcs[i] ")\n{" if (maxargs[i]) { zvals = zvals ";" fetchargs = fetchargs ") == FAILURE)" closefetch "{\n\t\tWRONG_PARAM_COUNT;\n\t}\n" } if (assign_params) funcvals = ints doubles floats strings if (resources) funcvals = funcvals "\t???LS_FETCH();\n" if (useswitch[i]) { if (check_argc_in_switch[i]) { check_argc = "\t\tdefault:\n\t\t\tWRONG_PARAM_COUNT;\n" } else { check_argc = "" } handleargs = "\tswitch (argc) {\n" \ handleargs \ (minargs[i] ? "" : "\t\tcase 0:\n") \ "\t\t\tbreak;\n" check_argc "\t}" } xmlstr = xmlstr xmlparams \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" print proto > stubfile if (zvals) print zvals > stubfile if (funcvals) print funcvals > stubfile if (fetchargs) print fetchargs > stubfile if (resources) { print resources > stubfile if (!stubs) print "" > extname "/function_warning" } if (handleargs) print handleargs > stubfile if (!i_know_what_to_do_shut_up_i_dont_need_your_help_mode) { print "\n\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: