php-src/ext/skeleton/create_stubs
2000-06-24 07:40:32 +00:00

327 lines
8.7 KiB
Awk
Executable File

#!/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 = " <reference id=\"ref." extname "\">\n" \
" <title> functions</title>\n" \
" <titleabbrev></titleabbrev>\n\n"
xmlfoot = " </reference>\n\n" \
"<!-- Keep this comment at the end of the file\n" \
"Local variables:\n" \
"mode: sgml\n" \
"sgml-omittag:t\n" \
"sgml-shorttag:t\n" \
"sgml-minimize-attributes:nil\n" \
"sgml-always-quote-attributes:t\n" \
"sgml-indent-step:1\n" \
"sgml-indent-data:t\n" \
"sgml-parent-document:nil\n" \
"sgml-default-dtd-file:\"../../manual.ced\"\n" \
"sgml-exposed-tags:nil\n" \
"sgml-local-catalogs:nil\n" \
"sgml-local-ecat-files:nil\n" \
"End:\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 = " <refentry id=\"function." refid "\">\n" \
" <refnamediv>\n" \
" <refname>" funcs[i] "</refname>\n" \
" <refpurpose></refpurpose>\n" \
" </refnamediv>\n" \
" <refsect1>\n" \
" <title>Description</title>\n" \
" <funcsynopsis>\n" \
" <funcprototype>\n" \
" <funcdef>" types[i] " <function>" funcs[i] "</function></funcdef>\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 " <paramdef>" 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 <parameter><optional>" \
argnames[i,j] \
"</optional></parameter>\n </paramdef>\n"
} else {
xmlparams = xmlparams \
" <parameter>" \
argnames[i,j] \
"</parameter></paramdef>\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 \
" </funcprototype>\n" \
" </funcsynopsis>\n" \
" <para>\n" \
" </para>\n" \
" </refsect1>\n" \
" </refentry>\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: