xref: /PHP-7.0/ext/skeleton/create_stubs (revision 9afb29aa)
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