summaryrefslogtreecommitdiff
path: root/Source/Modules/pike.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Modules/pike.cxx')
-rw-r--r--Source/Modules/pike.cxx903
1 files changed, 903 insertions, 0 deletions
diff --git a/Source/Modules/pike.cxx b/Source/Modules/pike.cxx
new file mode 100644
index 0000000..00e7500
--- /dev/null
+++ b/Source/Modules/pike.cxx
@@ -0,0 +1,903 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * pike.cxx
+ *
+ * Pike language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+/*
+ * Notes:
+ *
+ * - The current approach used for "out" typemaps is inconsistent with
+ * how "out" typemaps are handled by other language modules. Instead
+ * of converting the C/C++ type ($1) to a Pike object type (e.g. a
+ * struct svalue), we're just calling the appropriate push_XXX
+ * (e.g. push_int) to push the return value onto the stack.
+ *
+ * - Pike classes can't have static member functions or data, so we need
+ * to find some other appropriate mapping for C++ static member functions
+ * and data.
+ *
+ * - Pike doesn't seem to provide any default way to print the memory
+ * address, etc. for extension objects. Should we do something here?
+ *
+ */
+
+char cvsroot_pike_cxx[] = "$Id: pike.cxx 11133 2009-02-20 07:52:24Z wsfulton $";
+
+#include "swigmod.h"
+
+#include <ctype.h> // for isalnum()
+
+static const char *usage = (char *) "\
+Pike Options (available with -pike)\n\
+ [None]\n\
+\n";
+
+class PIKE:public Language {
+private:
+
+ File *f_begin;
+ File *f_runtime;
+ File *f_header;
+ File *f_wrappers;
+ File *f_init;
+ File *f_classInit;
+
+ String *PrefixPlusUnderscore;
+ int current;
+
+ // Wrap modes
+ enum {
+ NO_CPP,
+ MEMBER_FUNC,
+ CONSTRUCTOR,
+ DESTRUCTOR,
+ MEMBER_VAR,
+ CLASS_CONST,
+ STATIC_FUNC,
+ STATIC_VAR
+ };
+
+public:
+
+ /* ---------------------------------------------------------------------
+ * PIKE()
+ *
+ * Initialize member data
+ * --------------------------------------------------------------------- */
+
+ PIKE() {
+ f_begin = 0;
+ f_runtime = 0;
+ f_header = 0;
+ f_wrappers = 0;
+ f_init = 0;
+ f_classInit = 0;
+ PrefixPlusUnderscore = 0;
+ current = NO_CPP;
+ }
+
+ /* ---------------------------------------------------------------------
+ * main()
+ *
+ * Parse command line options and initializes variables.
+ * --------------------------------------------------------------------- */
+
+ virtual void main(int argc, char *argv[]) {
+
+ /* Set location of SWIG library */
+ SWIG_library_directory("pike");
+
+ /* Look for certain command line options */
+ for (int i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp(argv[i], "-help") == 0) {
+ fputs(usage, stdout);
+ }
+ }
+ }
+
+ /* Add a symbol to the parser for conditional compilation */
+ Preprocessor_define("SWIGPIKE 1", 0);
+
+ /* Set language-specific configuration file */
+ SWIG_config_file("pike.swg");
+
+ /* Set typemap language */
+ SWIG_typemap_lang("pike");
+
+ /* Enable overloaded methods support */
+ allow_overloading();
+ }
+
+ /* ---------------------------------------------------------------------
+ * top()
+ * --------------------------------------------------------------------- */
+
+ virtual int top(Node *n) {
+ /* Get the module name */
+ String *module = Getattr(n, "name");
+
+ /* Get the output file name */
+ String *outfile = Getattr(n, "outfile");
+
+ /* Open the output file */
+ f_begin = NewFile(outfile, "w", SWIG_output_files());
+ if (!f_begin) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_runtime = NewString("");
+ f_init = NewString("");
+ f_classInit = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("header", f_header);
+ Swig_register_filebyname("wrapper", f_wrappers);
+ Swig_register_filebyname("begin", f_begin);
+ Swig_register_filebyname("runtime", f_runtime);
+ Swig_register_filebyname("init", f_init);
+ Swig_register_filebyname("classInit", f_classInit);
+
+ /* Standard stuff for the SWIG runtime section */
+ Swig_banner(f_begin);
+
+ Printf(f_runtime, "\n");
+ Printf(f_runtime, "#define SWIGPIKE\n");
+ Printf(f_runtime, "\n");
+
+ Printf(f_header, "#define SWIG_init pike_module_init\n");
+ Printf(f_header, "#define SWIG_name \"%s\"\n\n", module);
+
+ /* Change naming scheme for constructors and destructors */
+ Swig_name_register("construct", "%c_create");
+ Swig_name_register("destroy", "%c_destroy");
+
+ /* Current wrap type */
+ current = NO_CPP;
+
+ /* Emit code for children */
+ Language::top(n);
+
+ /* Close the initialization function */
+ Printf(f_init, "}\n");
+ SwigType_emit_type_table(f_runtime, f_wrappers);
+
+ /* Close all of the files */
+ Dump(f_runtime, f_begin);
+ Dump(f_header, f_begin);
+ Dump(f_wrappers, f_begin);
+ Wrapper_pretty_print(f_init, f_begin);
+
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_init);
+ Delete(f_classInit);
+
+ Close(f_begin);
+ Delete(f_runtime);
+ Delete(f_begin);
+
+ /* Done */
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * validIdentifier()
+ * ------------------------------------------------------------ */
+
+ virtual int validIdentifier(String *s) {
+ char *c = Char(s);
+ const char *c0 = c;
+ const char *c1 = c0 + 1;
+ while (*c) {
+ if (*c == '`' && c == c0) {
+ c++;
+ continue;
+ }
+ if ((*c == '+' || *c == '-' || *c == '*' || *c == '/') && c == c1) {
+ c++;
+ continue;
+ }
+ if (!(isalnum(*c) || (*c == '_')))
+ return 0;
+ c++;
+ }
+ return 1;
+ }
+
+ /* ------------------------------------------------------------
+ * importDirective()
+ * ------------------------------------------------------------ */
+
+ virtual int importDirective(Node *n) {
+ String *modname = Getattr(n, "module");
+ if (modname) {
+ Printf(f_init, "pike_require(\"%s\");\n", modname);
+ }
+ return Language::importDirective(n);
+ }
+
+ /* ------------------------------------------------------------
+ * strip()
+ *
+ * For names that begin with the current class prefix plus an
+ * underscore (e.g. "Foo_enum_test"), return the base function
+ * name (i.e. "enum_test").
+ * ------------------------------------------------------------ */
+
+ String *strip(const DOHconst_String_or_char_ptr name) {
+ String *s = Copy(name);
+ if (Strncmp(name, PrefixPlusUnderscore, Len(PrefixPlusUnderscore)) != 0) {
+ return s;
+ }
+ Replaceall(s, PrefixPlusUnderscore, "");
+ return s;
+ }
+
+ /* ------------------------------------------------------------
+ * add_method()
+ * ------------------------------------------------------------ */
+
+ void add_method(const DOHconst_String_or_char_ptr name, const DOHconst_String_or_char_ptr function, const DOHconst_String_or_char_ptr description) {
+ String *rename = NULL;
+ switch (current) {
+ case NO_CPP:
+ rename = NewString(name);
+ Printf(f_init, "ADD_FUNCTION(\"%s\", %s, tFunc(%s), 0);\n", rename, function, description);
+ break;
+ case STATIC_FUNC:
+ case STATIC_VAR:
+ rename = NewString(name);
+ Printf(f_init, "ADD_FUNCTION(\"%s\", %s, tFunc(%s), 0);\n", rename, function, description);
+ break;
+ case CONSTRUCTOR:
+ case DESTRUCTOR:
+ case MEMBER_FUNC:
+ case MEMBER_VAR:
+ rename = strip(name);
+ Printf(f_classInit, "ADD_FUNCTION(\"%s\", %s, tFunc(%s), 0);\n", rename, function, description);
+ break;
+ case CLASS_CONST:
+ assert(false); // shouldn't have gotten here for CLASS_CONST nodes
+ default:
+ assert(false); // what is this?
+ }
+ Delete(rename);
+ }
+
+ /* ---------------------------------------------------------------------
+ * functionWrapper()
+ *
+ * Create a function declaration and register it with the interpreter.
+ * --------------------------------------------------------------------- */
+
+ virtual int functionWrapper(Node *n) {
+
+ String *name = Getattr(n, "name");
+ String *iname = Getattr(n, "sym:name");
+ SwigType *d = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+
+ Parm *p;
+ String *tm;
+ int i;
+
+ String *overname = 0;
+ if (Getattr(n, "sym:overloaded")) {
+ overname = Getattr(n, "sym:overname");
+ } else {
+ if (!addSymbol(iname, n))
+ return SWIG_ERROR;
+ }
+
+ Wrapper *f = NewWrapper();
+
+ // Emit all of the local variables for holding arguments.
+ emit_parameter_variables(l, f);
+
+ /* Attach the standard typemaps */
+ emit_attach_parmmaps(l, f);
+ Setattr(n, "wrap:parms", l);
+
+ /* Get number of required and total arguments */
+ int num_arguments = emit_num_arguments(l);
+ int varargs = emit_isvarargs(l);
+
+ /* Which input argument to start with? */
+ int start = (current == MEMBER_FUNC || current == MEMBER_VAR || current == DESTRUCTOR) ? 1 : 0;
+
+ /* Offset to skip over the attribute name */
+ // int offset = (current == MEMBER_VAR) ? 1 : 0;
+ int offset = 0;
+
+ String *wname = Swig_name_wrapper(iname);
+ if (overname) {
+ Append(wname, overname);
+ }
+ Setattr(n, "wrap:name", wname);
+
+ Printv(f->def, "static void ", wname, "(INT32 args) {", NIL);
+
+ /* Generate code for argument marshalling */
+ String *description = NewString("");
+ char source[64];
+ for (i = 0, p = l; i < num_arguments; i++) {
+
+ while (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p, "type");
+ String *ln = Getattr(p, "lname");
+
+ if (i < start) {
+ String *lstr = SwigType_lstr(pt, 0);
+ Printf(f->code, "%s = (%s) THIS;\n", ln, lstr);
+ Delete(lstr);
+ } else {
+ /* Look for an input typemap */
+ sprintf(source, "Pike_sp[%d-args]", i - start + offset);
+ if ((tm = Getattr(p, "tmap:in"))) {
+ Replaceall(tm, "$source", source);
+ Replaceall(tm, "$target", ln);
+ Replaceall(tm, "$input", source);
+ Setattr(p, "emit:input", source);
+ Printf(f->code, "%s\n", tm);
+ String *pikedesc = Getattr(p, "tmap:in:pikedesc");
+ if (pikedesc) {
+ Printv(description, pikedesc, " ", NIL);
+ }
+ p = Getattr(p, "tmap:in:next");
+ continue;
+ } else {
+ Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
+ break;
+ }
+ }
+ p = nextSibling(p);
+ }
+
+ /* Check for trailing varargs */
+ if (varargs) {
+ if (p && (tm = Getattr(p, "tmap:in"))) {
+ Replaceall(tm, "$input", "varargs");
+ Printv(f->code, tm, "\n", NIL);
+ }
+ }
+
+ /* Insert constraint checking code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:check"))) {
+ Replaceall(tm, "$target", Getattr(p, "lname"));
+ Printv(f->code, tm, "\n", NIL);
+ p = Getattr(p, "tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert cleanup code */
+ String *cleanup = NewString("");
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:freearg"))) {
+ Replaceall(tm, "$source", Getattr(p, "lname"));
+ Printv(cleanup, tm, "\n", NIL);
+ p = Getattr(p, "tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert argument output code */
+ String *outarg = NewString("");
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:argout"))) {
+ Replaceall(tm, "$source", Getattr(p, "lname"));
+ Replaceall(tm, "$target", "resultobj");
+ Replaceall(tm, "$arg", Getattr(p, "emit:input"));
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printv(outarg, tm, "\n", NIL);
+ p = Getattr(p, "tmap:argout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Emit the function call */
+ String *actioncode = emit_action(n);
+
+ /* Clear the return stack */
+ Printf(actioncode, "pop_n_elems(args);\n");
+
+ /* Return the function value */
+ if (current == CONSTRUCTOR) {
+ Printv(actioncode, "THIS = (void *) result;\n", NIL);
+ Printv(description, ", tVoid", NIL);
+ } else if (current == DESTRUCTOR) {
+ Printv(description, ", tVoid", NIL);
+ } else {
+ Printv(description, ", ", NIL);
+ if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
+ actioncode = 0;
+ Replaceall(tm, "$source", "result");
+ Replaceall(tm, "$target", "resultobj");
+ Replaceall(tm, "$result", "resultobj");
+ if (GetFlag(n, "feature:new")) {
+ Replaceall(tm, "$owner", "1");
+ } else {
+ Replaceall(tm, "$owner", "0");
+ }
+ String *pikedesc = Getattr(n, "tmap:out:pikedesc");
+ if (pikedesc) {
+ Printv(description, pikedesc, NIL);
+ }
+ Printf(f->code, "%s\n", tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
+ }
+ }
+ if (actioncode) {
+ Append(f->code, actioncode);
+ Delete(actioncode);
+ }
+ emit_return_variable(n, d, f);
+
+ /* Output argument output code */
+ Printv(f->code, outarg, NIL);
+
+ /* Output cleanup code */
+ Printv(f->code, cleanup, NIL);
+
+ /* Look to see if there is any newfree cleanup code */
+ if (GetFlag(n, "feature:new")) {
+ if ((tm = Swig_typemap_lookup("newfree", n, "result", 0))) {
+ Replaceall(tm, "$source", "result");
+ Printf(f->code, "%s\n", tm);
+ }
+ }
+
+ /* See if there is any return cleanup code */
+ if ((tm = Swig_typemap_lookup("ret", n, "result", 0))) {
+ Replaceall(tm, "$source", "result");
+ Printf(f->code, "%s\n", tm);
+ }
+
+ /* Close the function */
+ Printf(f->code, "}\n");
+
+ /* Substitute the cleanup code */
+ Replaceall(f->code, "$cleanup", cleanup);
+
+ /* Substitute the function name */
+ Replaceall(f->code, "$symname", iname);
+ Replaceall(f->code, "$result", "resultobj");
+
+ /* Dump the function out */
+ Wrapper_print(f, f_wrappers);
+
+ /* Now register the function with the interpreter. */
+ if (!Getattr(n, "sym:overloaded")) {
+ add_method(iname, wname, description);
+ } else {
+ if (!Getattr(n, "sym:nextSibling")) {
+ dispatchFunction(n);
+ }
+ }
+
+ Delete(cleanup);
+ Delete(outarg);
+ Delete(description);
+ Delete(wname);
+ DelWrapper(f);
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * dispatchFunction()
+ *
+ * Emit overloading dispatch function
+ * ------------------------------------------------------------ */
+
+ void dispatchFunction(Node *n) {
+ /* Last node in overloaded chain */
+
+ int maxargs;
+ String *tmp = NewString("");
+ String *dispatch = Swig_overload_dispatch(n, "%s(args); return;", &maxargs);
+
+ /* Generate a dispatch wrapper for all overloaded functions */
+
+ Wrapper *f = NewWrapper();
+ String *symname = Getattr(n, "sym:name");
+ String *wname = Swig_name_wrapper(symname);
+
+ Printf(f->def, "static void %s(INT32 args) {", wname);
+
+ Wrapper_add_local(f, "argc", "INT32 argc");
+ Printf(tmp, "struct svalue argv[%d]", maxargs);
+ Wrapper_add_local(f, "argv", tmp);
+ Wrapper_add_local(f, "ii", "INT32 ii");
+
+ Printf(f->code, "argc = args;\n");
+ Printf(f->code, "for (ii = 0; (ii < argc) && (ii < %d); ii++) {\n", maxargs);
+ Printf(f->code, "argv[ii] = Pike_sp[ii-args];\n");
+ Printf(f->code, "}\n");
+
+ Replaceall(dispatch, "$args", "self, args");
+ Printv(f->code, dispatch, "\n", NIL);
+ Printf(f->code, "Pike_error(\"No matching function for overloaded '%s'.\");\n", symname);
+ Printv(f->code, "}\n", NIL);
+
+ Wrapper_print(f, f_wrappers);
+
+ String *description = NewString("");
+ Printf(description, "tAny,");
+ if (current == CONSTRUCTOR || current == DESTRUCTOR) {
+ Printf(description, " tVoid");
+ } else {
+ String *pd = Getattr(n, "tmap:out:pikedesc");
+ if (pd)
+ Printf(description, " %s", pd);
+ }
+ add_method(symname, wname, description);
+ Delete(description);
+
+ DelWrapper(f);
+ Delete(dispatch);
+ Delete(tmp);
+ Delete(wname);
+ }
+
+ /* ------------------------------------------------------------
+ * variableWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int variableWrapper(Node *n) {
+ return Language::variableWrapper(n);
+ }
+
+ /* ------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+
+ Swig_require("constantWrapper", n, "*sym:name", "type", "value", NIL);
+
+ String *symname = Getattr(n, "sym:name");
+ SwigType *type = Getattr(n, "type");
+ String *value = Getattr(n, "value");
+
+ /* Special hook for member pointer */
+ if (SwigType_type(type) == T_MPOINTER) {
+ String *wname = Swig_name_wrapper(symname);
+ Printf(f_header, "static %s = %s;\n", SwigType_str(type, wname), value);
+ value = wname;
+ }
+
+ /* Perform constant typemap substitution */
+ String *tm = Swig_typemap_lookup("constant", n, value, 0);
+ if (tm) {
+ Replaceall(tm, "$source", value);
+ Replaceall(tm, "$target", symname);
+ Replaceall(tm, "$symname", symname);
+ Replaceall(tm, "$value", value);
+ Printf(f_init, "%s\n", tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value %s = %s\n", SwigType_str(type, 0), value);
+ }
+
+ Swig_restore(n);
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * nativeWrapper()
+ * ------------------------------------------------------------ */
+
+ virtual int nativeWrapper(Node *n) {
+ // return Language::nativeWrapper(n);
+ String *name = Getattr(n, "sym:name");
+ String *wrapname = Getattr(n, "wrap:name");
+
+ if (!addSymbol(wrapname, n))
+ return SWIG_ERROR;
+
+ add_method(name, wrapname, 0);
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * enumDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int enumDeclaration(Node *n) {
+ return Language::enumDeclaration(n);
+ }
+
+ /* ------------------------------------------------------------
+ * enumvalueDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int enumvalueDeclaration(Node *n) {
+ return Language::enumvalueDeclaration(n);
+ }
+
+ /* ------------------------------------------------------------
+ * classDeclaration()
+ * ------------------------------------------------------------ */
+
+ virtual int classDeclaration(Node *n) {
+ return Language::classDeclaration(n);
+ }
+
+ /* ------------------------------------------------------------
+ * classHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int classHandler(Node *n) {
+
+ String *symname = Getattr(n, "sym:name");
+ if (!addSymbol(symname, n))
+ return SWIG_ERROR;
+
+ PrefixPlusUnderscore = NewStringf("%s_", getClassPrefix());
+
+ Printf(f_classInit, "start_new_program();\n");
+
+ /* Handle inheritance */
+ List *baselist = Getattr(n, "bases");
+ if (baselist && Len(baselist) > 0) {
+ Iterator base = First(baselist);
+ while (base.item) {
+ String *basename = Getattr(base.item, "name");
+ SwigType *basetype = NewString(basename);
+ SwigType_add_pointer(basetype);
+ SwigType_remember(basetype);
+ String *basemangle = SwigType_manglestr(basetype);
+ Printf(f_classInit, "low_inherit((struct program *) SWIGTYPE%s->clientdata, 0, 0, 0, 0, 0);\n", basemangle);
+ Delete(basemangle);
+ Delete(basetype);
+ base = Next(base);
+ }
+ } else {
+ Printf(f_classInit, "ADD_STORAGE(swig_object_wrapper);\n");
+ }
+
+ Language::classHandler(n);
+
+ /* Accessors for member variables */
+ /*
+ List *membervariables = Getattr(n,"membervariables");
+ if (membervariables && Len(membervariables) > 0) {
+ membervariableAccessors(membervariables);
+ }
+ */
+
+ /* Done, close the class and dump its definition to the init function */
+ Printf(f_classInit, "add_program_constant(\"%s\", pr = end_program(), 0);\n", symname);
+ Dump(f_classInit, f_init);
+ Clear(f_classInit);
+
+ SwigType *tt = NewString(symname);
+ SwigType_add_pointer(tt);
+ SwigType_remember(tt);
+ String *tm = SwigType_manglestr(tt);
+ Printf(f_init, "SWIG_TypeClientData(SWIGTYPE%s, (void *) pr);\n", tm);
+ Delete(tm);
+ Delete(tt);
+
+ Delete(PrefixPlusUnderscore);
+ PrefixPlusUnderscore = 0;
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * memberfunctionHandler()
+ *
+ * Method for adding C++ member function
+ * ------------------------------------------------------------ */
+
+ virtual int memberfunctionHandler(Node *n) {
+ current = MEMBER_FUNC;
+ Language::memberfunctionHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * constructorHandler()
+ *
+ * Method for adding C++ member constructor
+ * ------------------------------------------------------------ */
+
+ virtual int constructorHandler(Node *n) {
+ current = CONSTRUCTOR;
+ Language::constructorHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * destructorHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int destructorHandler(Node *n) {
+ current = DESTRUCTOR;
+ Language::destructorHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * membervariableAccessors()
+ * ------------------------------------------------------------ */
+
+ void membervariableAccessors(List *membervariables) {
+ String *name;
+ Iterator i;
+ bool need_setter;
+ String *funcname;
+
+ /* If at least one of them is mutable, we need a setter */
+ need_setter = false;
+ i = First(membervariables);
+ while (i.item) {
+ if (!GetFlag(i.item, "feature:immutable")) {
+ need_setter = true;
+ break;
+ }
+ i = Next(i);
+ }
+
+ /* Create a function to set the values of the (mutable) variables */
+ if (need_setter) {
+ Wrapper *wrapper = NewWrapper();
+ String *setter = Swig_name_member(getClassPrefix(), (char *) "`->=");
+ String *wname = Swig_name_wrapper(setter);
+ Printv(wrapper->def, "static void ", wname, "(INT32 args) {", NIL);
+ Printf(wrapper->locals, "char *name = (char *) STR0(Pike_sp[0-args].u.string);\n");
+
+ i = First(membervariables);
+ while (i.item) {
+ if (!GetFlag(i.item, "feature:immutable")) {
+ name = Getattr(i.item, "name");
+ funcname = Swig_name_wrapper(Swig_name_set(Swig_name_member(getClassPrefix(), name)));
+ Printf(wrapper->code, "if (!strcmp(name, \"%s\")) {\n", name);
+ Printf(wrapper->code, "%s(args);\n", funcname);
+ Printf(wrapper->code, "return;\n");
+ Printf(wrapper->code, "}\n");
+ Delete(funcname);
+ }
+ i = Next(i);
+ }
+
+ /* Close the function */
+ Printf(wrapper->code, "pop_n_elems(args);\n");
+ Printf(wrapper->code, "}\n");
+
+ /* Dump wrapper code to the output file */
+ Wrapper_print(wrapper, f_wrappers);
+
+ /* Register it with Pike */
+ String *description = NewString("tStr tFloat, tVoid");
+ add_method("`->=", wname, description);
+ Delete(description);
+
+ /* Clean up */
+ Delete(wname);
+ Delete(setter);
+ DelWrapper(wrapper);
+ }
+
+ /* Create a function to get the values of the (mutable) variables */
+ Wrapper *wrapper = NewWrapper();
+ String *getter = Swig_name_member(getClassPrefix(), (char *) "`->");
+ String *wname = Swig_name_wrapper(getter);
+ Printv(wrapper->def, "static void ", wname, "(INT32 args) {", NIL);
+ Printf(wrapper->locals, "char *name = (char *) STR0(Pike_sp[0-args].u.string);\n");
+
+ i = First(membervariables);
+ while (i.item) {
+ name = Getattr(i.item, "name");
+ funcname = Swig_name_wrapper(Swig_name_get(Swig_name_member(getClassPrefix(), name)));
+ Printf(wrapper->code, "if (!strcmp(name, \"%s\")) {\n", name);
+ Printf(wrapper->code, "%s(args);\n", funcname);
+ Printf(wrapper->code, "return;\n");
+ Printf(wrapper->code, "}\n");
+ Delete(funcname);
+ i = Next(i);
+ }
+
+ /* Close the function */
+ Printf(wrapper->code, "pop_n_elems(args);\n");
+ Printf(wrapper->code, "}\n");
+
+ /* Dump wrapper code to the output file */
+ Wrapper_print(wrapper, f_wrappers);
+
+ /* Register it with Pike */
+ String *description = NewString("tStr, tMix");
+ add_method("`->", wname, description);
+ Delete(description);
+
+ /* Clean up */
+ Delete(wname);
+ Delete(getter);
+ DelWrapper(wrapper);
+ }
+
+ /* ------------------------------------------------------------
+ * membervariableHandler()
+ * ------------------------------------------------------------ */
+
+ virtual int membervariableHandler(Node *n) {
+ List *membervariables = Getattr(getCurrentClass(), "membervariables");
+ if (!membervariables) {
+ membervariables = NewList();
+ Setattr(getCurrentClass(), "membervariables", membervariables);
+ }
+ Append(membervariables, n);
+ current = MEMBER_VAR;
+ Language::membervariableHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------
+ * staticmemberfunctionHandler()
+ *
+ * Wrap a static C++ function
+ * ---------------------------------------------------------------------- */
+
+ virtual int staticmemberfunctionHandler(Node *n) {
+ current = STATIC_FUNC;
+ Language::staticmemberfunctionHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * memberconstantHandler()
+ *
+ * Create a C++ constant
+ * ------------------------------------------------------------ */
+
+ virtual int memberconstantHandler(Node *n) {
+ current = CLASS_CONST;
+ constantWrapper(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+
+ /* ---------------------------------------------------------------------
+ * staticmembervariableHandler()
+ * --------------------------------------------------------------------- */
+
+ virtual int staticmembervariableHandler(Node *n) {
+ current = STATIC_VAR;
+ Language::staticmembervariableHandler(n);
+ current = NO_CPP;
+ return SWIG_OK;
+ }
+};
+
+/* -----------------------------------------------------------------------------
+ * swig_pike() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+static Language *new_swig_pike() {
+ return new PIKE();
+}
+extern "C" Language *swig_pike(void) {
+ return new_swig_pike();
+}