| /* ----------------------------------------------------------------------------- |
| * This file is part of SWIG, which is licensed as a whole under version 3 |
| * (or any later version) of the GNU General Public License. Some additional |
| * terms also apply to certain portions of SWIG. The full details of the SWIG |
| * license and copyrights can be found in the LICENSE and COPYRIGHT files |
| * included with the SWIG source code as distributed by the SWIG developers |
| * and at http://www.swig.org/legal.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? |
| * |
| */ |
| |
| #include "swigmod.h" |
| |
| #include <ctype.h> // for isalnum() |
| |
| static const char *usage = "\ |
| Pike Options (available with -pike)\n\ |
| [no additional options]\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\n#ifndef SWIGPIKE\n#define SWIGPIKE\n#endif\n\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", "%n%c_create"); |
| Swig_name_register("destroy", "%n%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); |
| 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 *) ", Swig_cresult_name(), ";\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, Swig_cresult_name(), f, actioncode))) { |
| actioncode = 0; |
| Replaceall(tm, "$source", Swig_cresult_name()); |
| 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, Swig_cresult_name(), 0))) { |
| Replaceall(tm, "$source", Swig_cresult_name()); |
| Printf(f->code, "%s\n", tm); |
| } |
| } |
| |
| /* See if there is any return cleanup code */ |
| if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { |
| Replaceall(tm, "$source", Swig_cresult_name()); |
| 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"); |
| bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0); |
| |
| if (SwigType_type(type) == T_MPOINTER) { |
| /* Special hook for member pointer */ |
| String *wname = Swig_name_wrapper(symname); |
| Printf(f_header, "static %s = %s;\n", SwigType_str(type, wname), value); |
| value = wname; |
| } else if (SwigType_type(type) == T_CHAR && is_enum_item) { |
| type = NewSwigType(T_INT); |
| Setattr(n, "type", type); |
| } |
| |
| /* 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(NSPACE_TODO, getClassPrefix(), "`->="); |
| 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(NSPACE_TODO, Swig_name_member(NSPACE_TODO, 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(NSPACE_TODO, getClassPrefix(), "`->"); |
| 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(NSPACE_TODO, Swig_name_member(NSPACE_TODO, 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(); |
| } |