diff options
author | robot-piglet <[email protected]> | 2025-08-28 14:27:58 +0300 |
---|---|---|
committer | robot-piglet <[email protected]> | 2025-08-28 14:57:06 +0300 |
commit | 81d828c32c8d5477cb2f0ce5da06a1a8d9392ca3 (patch) | |
tree | 3081d566f0d5158d76e9093261344f6406fd09f7 /contrib/tools/swig/Source/Modules/tcl8.cxx | |
parent | 77ea11423f959e51795cc3ef36a48d808b4ffb98 (diff) |
Intermediate changes
commit_hash:d5b1af16dbe9030537a04c27eb410c88c2f496cd
Diffstat (limited to 'contrib/tools/swig/Source/Modules/tcl8.cxx')
-rw-r--r-- | contrib/tools/swig/Source/Modules/tcl8.cxx | 1293 |
1 files changed, 1293 insertions, 0 deletions
diff --git a/contrib/tools/swig/Source/Modules/tcl8.cxx b/contrib/tools/swig/Source/Modules/tcl8.cxx new file mode 100644 index 00000000000..0d07d0b9452 --- /dev/null +++ b/contrib/tools/swig/Source/Modules/tcl8.cxx @@ -0,0 +1,1293 @@ +/* ----------------------------------------------------------------------------- + * 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 https://www.swig.org/legal.html. + * + * tcl8.cxx + * + * Tcl8 language module for SWIG. + * ----------------------------------------------------------------------------- */ + +#include "swigmod.h" +#include "cparse.h" + +static const char *usage = "\ +Tcl 8 Options (available with -tcl8)\n\ + -itcl - Enable ITcl support\n\ + -nosafe - Leave out SafeInit module function.\n\ + -prefix <name> - Set a prefix <name> to be prepended to all names\n\ + -namespace - Build module into a Tcl 8 namespace\n\ + -pkgversion - Set package version\n\n"; + +static String *cmd_tab = 0; /* Table of command names */ +static String *var_tab = 0; /* Table of global variables */ +static String *const_tab = 0; /* Constant table */ +static String *methods_tab = 0; /* Methods table */ +static String *attr_tab = 0; /* Attribute table */ +static String *prefix = 0; +static String *module = 0; +static int namespace_option = 0; +static String *init_name = 0; +static String *ns_name = 0; +static int have_constructor; +static String *constructor_name; +static int have_destructor; +static int have_base_classes; +static String *destructor_action = 0; +static String *version = (String *) "0.0"; +static String *class_name = 0; + +static int have_attributes; +static int have_methods; +static int nosafe = 0; + +static File *f_header = 0; +static File *f_wrappers = 0; +static File *f_init = 0; +static File *f_begin = 0; +static File *f_runtime = 0; + + +// Itcl support +static int itcl = 0; +static File *f_shadow = 0; +static File *f_shadow_stubs = 0; + +static String *constructor = 0; +static String *destructor = 0; +static String *base_classes = 0; +static String *base_class_init = 0; +static String *methods = 0; +static String *imethods = 0; +static String *attributes = 0; +static String *attribute_traces = 0; +static String *iattribute_traces = 0; + + + +class TCL8:public Language { +public: + + /* ------------------------------------------------------------ + * TCL8::main() + * ------------------------------------------------------------ */ + + virtual void main(int argc, char *argv[]) { + + SWIG_library_directory("tcl"); + + for (int i = 1; i < argc; i++) { + if (argv[i]) { + if (strcmp(argv[i], "-prefix") == 0) { + if (argv[i + 1]) { + prefix = NewString(argv[i + 1]); + Swig_mark_arg(i); + Swig_mark_arg(i + 1); + i++; + } else + Swig_arg_error(); + } else if (strcmp(argv[i], "-pkgversion") == 0) { + if (argv[i + 1]) { + version = NewString(argv[i + 1]); + Swig_mark_arg(i); + Swig_mark_arg(i + 1); + i++; + } + } else if (strcmp(argv[i], "-namespace") == 0) { + namespace_option = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i], "-itcl") == 0) { + itcl = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i], "-nosafe") == 0) { + nosafe = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i], "-help") == 0) { + fputs(usage, stdout); + } else if (strcmp(argv[i], "-cppcast") == 0) { + Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]); + Swig_mark_arg(i); + } else if (strcmp(argv[i], "-nocppcast") == 0) { + Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]); + Swig_mark_arg(i); + Exit(EXIT_FAILURE); + } + } + } + + Preprocessor_define("SWIGTCL 1", 0); + // SWIGTCL8 is deprecated, and no longer documented. + Preprocessor_define("SWIGTCL8 1", 0); + SWIG_config_file("tcl8.swg"); + allow_overloading(); + } + + /* ------------------------------------------------------------ + * top() + * ------------------------------------------------------------ */ + + virtual int top(Node *n) { + + /* Initialize all of the output files */ + String *outfile = Getattr(n, "outfile"); + + f_begin = NewFile(outfile, "w", SWIG_output_files()); + if (!f_begin) { + FileErrorDisplay(outfile); + Exit(EXIT_FAILURE); + } + f_runtime = NewString(""); + f_init = 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); + + /* Initialize some variables for the object interface */ + + cmd_tab = NewString(""); + var_tab = NewString(""); + methods_tab = NewString(""); + const_tab = NewString(""); + + Swig_banner(f_begin); + + Swig_obligatory_macros(f_runtime, "TCL"); + + /* Set the module name, namespace, and prefix */ + + module = NewStringf("%(lower)s", Getattr(n, "name")); + init_name = NewStringf("%(title)s_Init", module); + + ns_name = prefix ? Copy(prefix) : Copy(module); + if (prefix) + Append(prefix, "_"); + + + /* If shadow classing is enabled, we're going to change the module name to "_module" */ + if (itcl) { + String *filen; + filen = NewStringf("%s%s.itcl", SWIG_output_directory(), module); + + Insert(module, 0, "_"); + + if ((f_shadow = NewFile(filen, "w", SWIG_output_files())) == 0) { + FileErrorDisplay(filen); + Exit(EXIT_FAILURE); + } + f_shadow_stubs = NewString(""); + + Swig_register_filebyname("shadow", f_shadow); + Swig_register_filebyname("itcl", f_shadow); + + Swig_banner_target_lang(f_shadow, "#"); + + Printv(f_shadow, "\npackage require Itcl\n\n", NIL); + Delete(filen); + } + + /* Generate some macros used throughout code generation */ + + Printf(f_header, "#define SWIG_init %s\n", init_name); + Printf(f_header, "#define SWIG_name \"%s\"\n", module); + if (namespace_option) { + Printf(f_header, "#define SWIG_prefix \"%s::\"\n", ns_name); + Printf(f_header, "#define SWIG_namespace \"%s\"\n\n", ns_name); + } else { + Printf(f_header, "#define SWIG_prefix \"%s\"\n", prefix); + } + Printf(f_header, "#define SWIG_version \"%s\"\n", version); + + Printf(cmd_tab, "\nstatic swig_command_info swig_commands[] = {\n"); + Printf(var_tab, "\nstatic swig_var_info swig_variables[] = {\n"); + Printf(const_tab, "\nstatic swig_const_info swig_constants[] = {\n"); + + Printf(f_wrappers, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); + + /* Start emitting code */ + Language::top(n); + + /* Done. Close up the module */ + Printv(cmd_tab, tab4, "{0, 0, 0}\n", "};\n", NIL); + Printv(var_tab, tab4, "{0,0,0,0}\n", "};\n", NIL); + Printv(const_tab, tab4, "{0,0,0,0,0,0}\n", "};\n", NIL); + + Printv(f_wrappers, cmd_tab, var_tab, const_tab, NIL); + + /* Dump the pointer equivalency table */ + SwigType_emit_type_table(f_runtime, f_wrappers); + + Printf(f_wrappers, "#ifdef __cplusplus\n}\n#endif\n"); + + /* Close the init function and quit */ + Printf(f_init, "return TCL_OK;\n}\n"); + + if (!nosafe) { + Printf(f_init, "SWIGEXPORT int %(title)s_SafeInit(Tcl_Interp *interp) {\n", module); + Printf(f_init, " return SWIG_init(interp);\n"); + Printf(f_init, "}\n"); + } + + if (itcl) { + Printv(f_shadow, f_shadow_stubs, "\n", NIL); + Delete(f_shadow); + } + + /* Close all of the files */ + Dump(f_runtime, f_begin); + Printv(f_begin, f_header, f_wrappers, NIL); + Wrapper_pretty_print(f_init, f_begin); + Delete(f_header); + Delete(f_wrappers); + Delete(f_init); + Delete(f_runtime); + Delete(f_begin); + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * functionWrapper() + * ------------------------------------------------------------ */ + + virtual int functionWrapper(Node *n) { + String *name = Getattr(n, "name"); /* Like to get rid of this */ + String *iname = Getattr(n, "sym:name"); + SwigType *returntype = Getattr(n, "type"); + ParmList *parms = Getattr(n, "parms"); + String *overname = 0; + + Parm *p; + int i; + String *tm; + Wrapper *f; + String *incode, *cleanup, *outarg, *argstr, *args; + int num_arguments = 0; + int num_required = 0; + int varargs = 0; + + char source[64]; + + if (Getattr(n, "sym:overloaded")) { + overname = Getattr(n, "sym:overname"); + } else { + if (!addSymbol(iname, n)) + return SWIG_ERROR; + } + + incode = NewString(""); + cleanup = NewString(""); + outarg = NewString(""); + argstr = NewString("\""); + args = NewString(""); + + f = NewWrapper(); + +#ifdef SWIG_USE_RESULTOBJ + Wrapper_add_local(f, "resultobj", "Tcl_Obj *resultobj = NULL"); +#endif + + + String *wname = Swig_name_wrapper(iname); + if (overname) { + Append(wname, overname); + } + Setattr(n, "wrap:name", wname); + + Printv(f->def, "SWIGINTERN int\n ", wname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) {", NIL); + + // Emit all of the local variables for holding arguments. + emit_parameter_variables(parms, f); + + /* Attach standard typemaps */ + emit_attach_parmmaps(parms, f); + Setattr(n, "wrap:parms", parms); + + /* Get number of require and total arguments */ + num_arguments = emit_num_arguments(parms); + num_required = emit_num_required(parms); + varargs = emit_isvarargs(parms); + + /* Unmarshal parameters */ + + for (i = 0, p = parms; i < num_arguments; i++) { + /* Skip ignored arguments */ + + while (checkAttribute(p, "tmap:in:numinputs", "0")) { + p = Getattr(p, "tmap:in:next"); + } + + SwigType *pt = Getattr(p, "type"); + String *ln = Getattr(p, "lname"); + + /* Produce string representations of the source and target arguments */ + sprintf(source, "objv[%d]", i + 1); + + if (i == num_required) + Putc('|', argstr); + if ((tm = Getattr(p, "tmap:in"))) { + String *parse = Getattr(p, "tmap:in:parse"); + if (!parse) { + Replaceall(tm, "$input", source); + Setattr(p, "emit:input", source); + + if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) { + Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); + } else { + Replaceall(tm, "$disown", "0"); + } + + Putc('o', argstr); + Printf(args, ",(void *)0"); + if (i >= num_required) { + Printf(incode, "if (objc > %d) {\n", i + 1); + } + Printf(incode, "%s\n", tm); + if (i >= num_required) { + Printf(incode, "}\n"); + } + } else { + Printf(argstr, "%s", parse); + Printf(args, ",&%s", ln); + if (Strcmp(parse, "p") == 0) { + SwigType *lt = SwigType_ltype(pt); + SwigType_remember(pt); + if (Cmp(lt, "p.void") == 0) { + Printf(args, ",(void *)0"); + } else { + Printf(args, ",SWIGTYPE%s", SwigType_manglestr(pt)); + } + Delete(lt); + } + } + 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)); + } + p = nextSibling(p); + } + + if (!varargs) { + Putc(':', argstr); + } else { + Putc(';', argstr); + /* If variable length arguments we need to emit the in typemap here */ + if (p && (tm = Getattr(p, "tmap:in"))) { + sprintf(source, "objv[%d]", i + 1); + Printf(incode, "if (objc > %d) {\n", i); + Replaceall(tm, "$input", source); + Printv(incode, tm, "\n", NIL); + Printf(incode, "}\n"); + } + } + + Printf(argstr, "%s\"", usage_string(Char(iname), returntype, parms)); + + Printv(f->code, "if (SWIG_GetArgs(interp, objc, objv,", argstr, args, ") == TCL_ERROR) SWIG_fail;\n", NIL); + + Printv(f->code, incode, NIL); + + /* Insert constraint checking code */ + for (p = parms; p;) { + if ((tm = Getattr(p, "tmap:check"))) { + Printv(f->code, tm, "\n", NIL); + p = Getattr(p, "tmap:check:next"); + } else { + p = nextSibling(p); + } + } + + /* Insert cleanup code */ + for (i = 0, p = parms; p; i++) { + if (!checkAttribute(p, "tmap:in:numinputs", "0") + && !Getattr(p, "tmap:in:parse") && (tm = Getattr(p, "tmap:freearg"))) { + if (Len(tm) != 0) { + Printv(cleanup, tm, "\n", NIL); + } + p = Getattr(p, "tmap:freearg:next"); + } else { + p = nextSibling(p); + } + } + + /* Insert argument output code */ + for (i = 0, p = parms; p; i++) { + if ((tm = Getattr(p, "tmap:argout"))) { +#ifdef SWIG_USE_RESULTOBJ + Replaceall(tm, "$result", "resultobj"); +#else + Replaceall(tm, "$result", "(Tcl_GetObjResult(interp))"); +#endif + 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); + } + } + + /* Now write code to make the function call */ + String *actioncode = emit_action(n); + + /* Need to redo all of this code (eventually) */ + + /* Return value if necessary */ + if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) { +#ifdef SWIG_USE_RESULTOBJ + Replaceall(tm, "$result", "resultobj"); +#else + Replaceall(tm, "$result", "(Tcl_GetObjResult(interp))"); +#endif + if (GetFlag(n, "feature:new")) { + Replaceall(tm, "$owner", "SWIG_POINTER_OWN"); + } else { + Replaceall(tm, "$owner", "0"); + } + 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(returntype, 0), name); + } + emit_return_variable(n, returntype, f); + + /* Dump output argument code */ + Printv(f->code, outarg, NIL); + + /* Dump the argument cleanup code */ + Printv(f->code, cleanup, NIL); + + /* Look for any remaining cleanup */ + if (GetFlag(n, "feature:new")) { + if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) { + Printf(f->code, "%s\n", tm); + } + } + + if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { + Printf(f->code, "%s\n", tm); + } +#ifdef SWIG_USE_RESULTOBJ + Printv(f->code, "if (resultobj) Tcl_SetObjResult(interp, resultobj);\n", NIL); +#endif + Printv(f->code, "return TCL_OK;\n", NIL); + Printv(f->code, "fail:\n", cleanup, "return TCL_ERROR;\n", NIL); + Printv(f->code, "}\n", NIL); + + /* Substitute the cleanup code */ + Replaceall(f->code, "$cleanup", cleanup); + + bool isvoid = !Cmp(returntype, "void"); + Replaceall(f->code, "$isvoid", isvoid ? "1" : "0"); + + Replaceall(f->code, "$symname", iname); + + /* Dump out the function */ + Wrapper_print(f, f_wrappers); + + if (!Getattr(n, "sym:overloaded")) { + /* Register the function with Tcl */ + Printv(cmd_tab, tab4, "{ SWIG_prefix \"", iname, "\", (swig_wrapper_func) ", Swig_name_wrapper(iname), ", NULL},\n", NIL); + } else { + if (!Getattr(n, "sym:nextSibling")) { + /* Emit overloading dispatch function */ + + int maxargs; + String *dispatch = Swig_overload_dispatch(n, "return %s(clientData, interp, objc, argv - 1);", &maxargs); + + /* Generate a dispatch wrapper for all overloaded functions */ + + Wrapper *df = NewWrapper(); + String *dname = Swig_name_wrapper(iname); + + Printv(df->def, "SWIGINTERN int\n", dname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) {", NIL); + Printf(df->code, "Tcl_Obj *const *argv = objv+1;\n"); + Printf(df->code, "int argc = objc-1;\n"); + Printv(df->code, dispatch, "\n", NIL); + Node *sibl = n; + while (Getattr(sibl, "sym:previousSibling")) + sibl = Getattr(sibl, "sym:previousSibling"); // go all the way up + String *protoTypes = NewString(""); + do { + String *fulldecl = Swig_name_decl(sibl); + Printf(protoTypes, "\n\" %s\\n\"", fulldecl); + Delete(fulldecl); + } while ((sibl = Getattr(sibl, "sym:nextSibling"))); + Printf(df->code, "Tcl_SetResult(interp,(char *) " + "\"Wrong number or type of arguments for overloaded function '%s'.\\n\"" + "\n\" Possible C/C++ prototypes are:\\n\"%s, TCL_STATIC);\n", iname, protoTypes); + Delete(protoTypes); + Printf(df->code, "return TCL_ERROR;\n"); + Printv(df->code, "}\n", NIL); + Wrapper_print(df, f_wrappers); + Printv(cmd_tab, tab4, "{ SWIG_prefix \"", iname, "\", (swig_wrapper_func) ", dname, ", NULL},\n", NIL); + DelWrapper(df); + Delete(dispatch); + Delete(dname); + } + } + + Delete(incode); + Delete(cleanup); + Delete(outarg); + Delete(argstr); + Delete(args); + DelWrapper(f); + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * variableWrapper() + * ------------------------------------------------------------ */ + + virtual int variableWrapper(Node *n) { + + String *name = Getattr(n, "name"); + String *iname = Getattr(n, "sym:name"); + SwigType *t = Getattr(n, "type"); + + String *setname = 0; + String *setfname = 0; + Wrapper *setf = 0, *getf = 0; + int readonly = 0; + String *tm; + + if (!addSymbol(iname, n)) + return SWIG_ERROR; + + /* Create a function for getting a variable */ + int addfail = 0; + getf = NewWrapper(); + String *getname = Swig_name_get(NSPACE_TODO, iname); + String *getfname = Swig_name_wrapper(getname); + Setattr(n, "wrap:name", getfname); + Printv(getf->def, "SWIGINTERN const char *", getfname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, char *name1, char *name2, int flags) {", NIL); + Wrapper_add_local(getf, "value", "Tcl_Obj *value = 0"); + if ((tm = Swig_typemap_lookup("varout", n, name, 0))) { + Replaceall(tm, "$result", "value"); + /* Printf(getf->code, "%s\n",tm); */ + addfail = emit_action_code(n, getf->code, tm); + Printf(getf->code, "if (value) {\n"); + Printf(getf->code, "Tcl_SetVar2(interp,name1,name2,Tcl_GetString(value), flags);\n"); + Printf(getf->code, "Tcl_DecrRefCount(value);\n"); + Printf(getf->code, "}\n"); + Printf(getf->code, "return NULL;\n"); + if (addfail) { + Append(getf->code, "fail:\n"); + Printf(getf->code, "return \"%s\";\n", iname); + } + Printf(getf->code, "}\n"); + Wrapper_print(getf, f_wrappers); + } else { + Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0)); + DelWrapper(getf); + return SWIG_NOWRAP; + } + DelWrapper(getf); + + /* Try to create a function setting a variable */ + if (!is_immutable(n)) { + setf = NewWrapper(); + setname = Swig_name_set(NSPACE_TODO, iname); + setfname = Swig_name_wrapper(setname); + Setattr(n, "wrap:name", setfname); + if (setf) { + Printv(setf->def, "SWIGINTERN const char *", setfname, + "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, char *name1, char *name2 SWIGUNUSED, int flags) {", NIL); + Wrapper_add_local(setf, "value", "Tcl_Obj *value = 0"); + Wrapper_add_local(setf, "name1o", "Tcl_Obj *name1o = 0"); + + if ((tm = Swig_typemap_lookup("varin", n, name, 0))) { + Replaceall(tm, "$input", "value"); + Printf(setf->code, "name1o = Tcl_NewStringObj(name1,-1);\n"); + Printf(setf->code, "value = Tcl_ObjGetVar2(interp, name1o, 0, flags);\n"); + Printf(setf->code, "Tcl_DecrRefCount(name1o);\n"); + Printf(setf->code, "if (!value) SWIG_fail;\n"); + /* Printf(setf->code,"%s\n", tm); */ + emit_action_code(n, setf->code, tm); + Printf(setf->code, "return NULL;\n"); + Printf(setf->code, "fail:\n"); + Printf(setf->code, "return \"%s\";\n", iname); + Printf(setf->code, "}\n"); + Wrapper_print(setf, f_wrappers); + } else { + Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0)); + readonly = 1; + } + } + DelWrapper(setf); + } else { + readonly = 1; + } + + + Printv(var_tab, tab4, "{ SWIG_prefix \"", iname, "\", 0, (swig_variable_func) ", getfname, ",", NIL); + if (readonly) { + static int readonlywrap = 0; + if (!readonlywrap) { + Wrapper *ro = NewWrapper(); + Printf(ro->def, + "SWIGINTERN const char *swig_readonly(ClientData clientData SWIGUNUSED, Tcl_Interp *interp SWIGUNUSED, char *name1 SWIGUNUSED, char *name2 SWIGUNUSED, int flags SWIGUNUSED) {"); + Printv(ro->code, "return \"Variable is read-only\";\n", "}\n", NIL); + Wrapper_print(ro, f_wrappers); + readonlywrap = 1; + DelWrapper(ro); + } + Printf(var_tab, "(swig_variable_func) swig_readonly},\n"); + } else { + Printv(var_tab, "(swig_variable_func) ", setfname, "},\n", NIL); + } + Delete(getfname); + Delete(setfname); + Delete(setname); + Delete(getname); + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * constantWrapper() + * ------------------------------------------------------------ */ + + virtual int constantWrapper(Node *n) { + String *name = Getattr(n, "name"); + String *iname = Getattr(n, "sym:name"); + String *nsname = !namespace_option ? Copy(iname) : NewStringf("%s::%s", ns_name, iname); + SwigType *type = Getattr(n, "type"); + String *value = Getattr(n, "value"); + String *tm; + + if (!addSymbol(iname, n)) + return SWIG_ERROR; + if (namespace_option) + Setattr(n, "sym:name", nsname); + + /* Special hook for member pointer */ + if (SwigType_type(type) == T_MPOINTER) { + String *wname = Swig_name_wrapper(iname); + Printf(f_wrappers, "static %s = %s;\n", SwigType_str(type, wname), value); + value = Char(wname); + } + + if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) { + Replaceall(tm, "$value", value); + Replaceall(tm, "$nsname", nsname); + Printf(const_tab, "%s,\n", tm); + } else if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) { + Replaceall(tm, "$value", value); + Replaceall(tm, "$nsname", nsname); + Printf(f_init, "%s\n", tm); + } else { + Delete(nsname); + Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n"); + return SWIG_NOWRAP; + } + Delete(nsname); + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * nativeWrapper() + * ------------------------------------------------------------ */ + + virtual int nativeWrapper(Node *n) { + String *name = Getattr(n, "sym:name"); + String *funcname = Getattr(n, "wrap:name"); + if (!addSymbol(funcname, n)) + return SWIG_ERROR; + + Printf(f_init, "\t Tcl_CreateObjCommand(interp, SWIG_prefix \"%s\", (swig_wrapper_func) %s, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);\n", name, + funcname); + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * classHandler() + * ------------------------------------------------------------ */ + + virtual int classHandler(Node *n) { + static Hash *emitted = NewHash(); + String *mangled_classname = 0; + SwigType *real_classname = 0; + + have_constructor = 0; + have_destructor = 0; + destructor_action = 0; + constructor_name = 0; + + if (itcl) { + constructor = NewString(""); + destructor = NewString(""); + base_classes = NewString(""); + base_class_init = NewString(""); + methods = NewString(""); + imethods = NewString(""); + attributes = NewString(""); + attribute_traces = NewString(""); + iattribute_traces = NewString(""); + + have_base_classes = 0; + have_methods = 0; + have_attributes = 0; + } + + class_name = Getattr(n, "sym:name"); + if (!addSymbol(class_name, n)) + return SWIG_ERROR; + + real_classname = Getattr(n, "name"); + mangled_classname = Swig_name_mangle_type(real_classname); + + if (Getattr(emitted, mangled_classname)) + return SWIG_NOWRAP; + Setattr(emitted, mangled_classname, "1"); + + attr_tab = NewString(""); + Printf(attr_tab, "static swig_attribute swig_"); + Printv(attr_tab, mangled_classname, "_attributes[] = {\n", NIL); + + methods_tab = NewStringf(""); + Printf(methods_tab, "static swig_method swig_"); + Printv(methods_tab, mangled_classname, "_methods[] = {\n", NIL); + + /* Generate normal wrappers */ + Language::classHandler(n); + + SwigType *t = Copy(Getattr(n, "name")); + SwigType_add_pointer(t); + + // Catch all: eg. a class with only static functions and/or variables will not have 'remembered' + // SwigType_remember(t); + String *wrap_class = NewStringf("&_wrap_class_%s", mangled_classname); + SwigType_remember_clientdata(t, wrap_class); + + String *rt = Copy(getClassType()); + SwigType_add_pointer(rt); + + // Register the class structure with the type checker + /* Printf(f_init,"SWIG_TypeClientData(SWIGTYPE%s, (void *) &_wrap_class_%s);\n", SwigType_manglestr(t), mangled_classname); */ + if (have_destructor) { + Printv(f_wrappers, "SWIGINTERN void swig_delete_", class_name, "(void *obj) {\n", NIL); + if (destructor_action) { + Printv(f_wrappers, SwigType_str(rt, "arg1"), " = (", SwigType_str(rt, 0), ") obj;\n", NIL); + Printv(f_wrappers, destructor_action, "\n", NIL); + } else { + if (CPlusPlus) { + Printv(f_wrappers, " delete (", SwigType_str(rt, 0), ") obj;\n", NIL); + } else { + Printv(f_wrappers, " free((char *) obj);\n", NIL); + } + } + Printf(f_wrappers, "}\n"); + } + + Printf(methods_tab, " {0,0}\n};\n"); + Printv(f_wrappers, methods_tab, NIL); + + Printf(attr_tab, " {0,0,0}\n};\n"); + Printv(f_wrappers, attr_tab, NIL); + + /* Handle inheritance */ + + String *base_class = NewString(""); + String *base_class_names = NewString(""); + + if (itcl) { + base_classes = NewString(""); + } + + List *baselist = Getattr(n, "bases"); + if (baselist && Len(baselist)) { + Iterator b; + int index = 0; + b = First(baselist); + while (b.item) { + SwigType *bname = Getattr(b.item, "name"); + if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) { + b = Next(b); + continue; + } + if (itcl) { + have_base_classes = 1; + Printv(base_classes, bname, " ", NIL); + Printv(base_class_init, " ", bname, "Ptr::constructor $ptr\n", NIL); + } + String *bmangle = Swig_name_mangle_type(bname); + // Printv(f_wrappers,"extern swig_class _wrap_class_", bmangle, ";\n", NIL); + // Printf(base_class,"&_wrap_class_%s",bmangle); + Printf(base_class, "0"); + Printf(base_class_names, "\"%s *\",", SwigType_namestr(bname)); + /* Put code to register base classes in init function */ + + //Printf(f_init,"/* Register base : %s */\n", bmangle); + //Printf(f_init,"swig_%s_bases[%d] = (swig_class *) SWIG_TypeQuery(\"%s *\")->clientdata;\n", mangled_classname, index, SwigType_namestr(bname)); + (void)index; + b = Next(b); + index++; + Putc(',', base_class); + Delete(bmangle); + } + } + + if (itcl) { + String *ptrclass = NewString(""); + + // First, build the pointer base class + Printv(ptrclass, "itcl::class ", class_name, "Ptr {\n", NIL); + if (have_base_classes) + Printv(ptrclass, " inherit ", base_classes, "\n", NIL); + + // Define protected variables for SWIG object pointer + Printv(ptrclass, " protected variable swigobj\n", " protected variable thisown\n", NIL); + + // Define public variables + if (have_attributes) { + Printv(ptrclass, attributes, NIL); + + // base class swig_getset was being called for complex inheritance trees + if (namespace_option) { + + Printv(ptrclass, " protected method ", class_name, "_swig_getset {var name1 name2 op} {\n", NIL); + + Printv(ptrclass, + " switch -exact -- $op {\n", + " r {set $var [", ns_name, "::", class_name, "_[set var]_get $swigobj]}\n", + " w {", ns_name, "::", class_name, "_${var}_set $swigobj [set $var]}\n", " }\n", " }\n", NIL); + } else { + Printv(ptrclass, + " protected method ", class_name, "_swig_getset {var name1 name2 op} {\n", + " switch -exact -- $op {\n", + " r {set $var [", class_name, "_[set var]_get $swigobj]}\n", + " w {", class_name, "_${var}_set $swigobj [set $var]}\n", " }\n", " }\n", NIL); + } + } + // Add the constructor, which may include + // calls to base class class constructors + + Printv(ptrclass, " constructor { ptr } {\n", NIL); + if (have_base_classes) { + Printv(ptrclass, base_class_init, NIL); + Printv(ptrclass, " } {\n", NIL); + } + + Printv(ptrclass, " set swigobj $ptr\n", " set thisown 0\n", NIL); + + if (have_attributes) { + Printv(ptrclass, attribute_traces, NIL); + } + Printv(ptrclass, " }\n", NIL); + + + // Add destructor + Printv(ptrclass, " destructor {\n", + " set d_func delete_", class_name, "\n", + " if { $thisown && ([info command $d_func] != \"\") } {\n" " $d_func $swigobj\n", " }\n", " }\n", NIL); + + // Add methods + if (have_methods) { + Printv(ptrclass, imethods, NIL); + } + + // Close out the pointer class + Printv(ptrclass, "}\n\n", NIL); + Printv(f_shadow, ptrclass, NIL); + // pointer class end + + + // Create the "real" class. + Printv(f_shadow, "itcl::class ", class_name, " {\n", NIL); + Printv(f_shadow, " inherit ", class_name, "Ptr\n", NIL); + + // If we have a constructor, then use it. + // If not, then we must have an abstract class without + // any constructor. So we create a class constructor + // which will fail for this class (but not for inherited + // classes). Note that the constructor must fail before + // calling the ptrclass constructor. + + if (have_constructor) { + Printv(f_shadow, constructor, NIL); + } else { + Printv(f_shadow, " constructor { } {\n", NIL); + Printv(f_shadow, " # This constructor will fail if called directly\n", NIL); + Printv(f_shadow, " if { [info class] == \"::", class_name, "\" } {\n", NIL); + Printv(f_shadow, " error \"No constructor for class ", class_name, (Getattr(n, "abstracts") ? " - class is abstract" : ""), "\"\n", NIL); + Printv(f_shadow, " }\n", NIL); + Printv(f_shadow, " }\n", NIL); + } + + Printv(f_shadow, "}\n\n", NIL); + } + + Printv(f_wrappers, "static swig_class *swig_", mangled_classname, "_bases[] = {", base_class, "0};\n", NIL); + Printv(f_wrappers, "static const char * swig_", mangled_classname, "_base_names[] = {", base_class_names, "0};\n", NIL); + Delete(base_class); + Delete(base_class_names); + + Printv(f_wrappers, "static swig_class _wrap_class_", mangled_classname, " = { \"", class_name, "\", &SWIGTYPE", SwigType_manglestr(t), ",", NIL); + + if (have_constructor) { + Printf(f_wrappers, "%s", Swig_name_wrapper(Swig_name_construct(NSPACE_TODO, constructor_name))); + Delete(constructor_name); + constructor_name = 0; + } else { + Printf(f_wrappers, "0"); + } + if (have_destructor) { + Printv(f_wrappers, ", swig_delete_", class_name, NIL); + } else { + Printf(f_wrappers, ",0"); + } + Printv(f_wrappers, ", swig_", mangled_classname, "_methods, swig_", mangled_classname, "_attributes, swig_", mangled_classname, "_bases,", + "swig_", mangled_classname, "_base_names, &swig_module, SWIG_TCL_HASHTABLE_INIT };\n", NIL); + + if (!itcl) { + Printv(cmd_tab, tab4, "{ SWIG_prefix \"", class_name, "\", (swig_wrapper_func) SWIG_ObjectConstructor, (ClientData)&_wrap_class_", mangled_classname, + "},\n", NIL); + } + + Delete(t); + Delete(mangled_classname); + return SWIG_OK; + } + + + /* ------------------------------------------------------------ + * memberfunctionHandler() + * ------------------------------------------------------------ */ + + virtual int memberfunctionHandler(Node *n) { + String *name = Getattr(n, "name"); + String *iname = GetChar(n, "sym:name"); + + String *realname, *rname; + + Language::memberfunctionHandler(n); + + realname = iname ? iname : name; + rname = Swig_name_wrapper(Swig_name_member(NSPACE_TODO, class_name, realname)); + if (!Getattr(n, "sym:nextSibling")) { + Printv(methods_tab, tab4, "{\"", realname, "\", ", rname, "}, \n", NIL); + } + + if (itcl) { + ParmList *l = Getattr(n, "parms"); + Parm *p = 0; + String *pname = NewString(""); + + // Add this member to our class handler function + Printv(imethods, tab2, "method ", realname, " [list ", NIL); + + int pnum = 0; + for (p = l; p; p = nextSibling(p)) { + + String *pn = Getattr(p, "name"); + String *dv = Getattr(p, "value"); + SwigType *pt = Getattr(p, "type"); + + Printv(pname, ",(", pt, ")", NIL); + Clear(pname); + + /* Only print an argument if not void */ + if (Cmp(pt, "void") != 0) { + if (Len(pn) > 0) { + Printv(pname, pn, NIL); + } else { + Printf(pname, "p%d", pnum); + } + + if (Len(dv) > 0) { + String *defval = NewString(dv); + if (namespace_option) { + Insert(defval, 0, "::"); + Insert(defval, 0, ns_name); + } + if (Strncmp(dv, "(", 1) == 0) { + Insert(defval, 0, "$"); + Replaceall(defval, "(", ""); + Replaceall(defval, ")", ""); + } + Printv(imethods, "[list ", pname, " ", defval, "] ", NIL); + } else { + Printv(imethods, pname, " ", NIL); + } + } + ++pnum; + } + Printv(imethods, "] ", NIL); + + if (namespace_option) { + Printv(imethods, "{ ", ns_name, "::", class_name, "_", realname, " $swigobj", NIL); + } else { + Printv(imethods, "{ ", class_name, "_", realname, " $swigobj", NIL); + } + + pnum = 0; + for (p = l; p; p = nextSibling(p)) { + + String *pn = Getattr(p, "name"); + SwigType *pt = Getattr(p, "type"); + Clear(pname); + + /* Only print an argument if not void */ + if (Cmp(pt, "void") != 0) { + if (Len(pn) > 0) { + Printv(pname, pn, NIL); + } else { + Printf(pname, "p%d", pnum); + } + Printv(imethods, " $", pname, NIL); + } + ++pnum; + } + Printv(imethods, " }\n", NIL); + have_methods = 1; + } + + Delete(rname); + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * membervariableHandler() + * ------------------------------------------------------------ */ + + virtual int membervariableHandler(Node *n) { + String *symname = Getattr(n, "sym:name"); + String *rname; + + Language::membervariableHandler(n); + Printv(attr_tab, tab4, "{ \"-", symname, "\",", NIL); + rname = Swig_name_wrapper(Swig_name_get(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname))); + Printv(attr_tab, rname, ", ", NIL); + Delete(rname); + if (!GetFlag(n, "feature:immutable")) { + rname = Swig_name_wrapper(Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname))); + Printv(attr_tab, rname, "},\n", NIL); + Delete(rname); + } else { + Printf(attr_tab, "0 },\n"); + } + + if (itcl) { + Printv(attributes, " public variable ", symname, "\n", NIL); + + Printv(attribute_traces, " trace variable ", symname, " rw [list ", class_name, "_swig_getset ", symname, "]\n", NIL); + Printv(attribute_traces, " set ", symname, "\n", NIL); + + have_attributes = 1; + } + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * constructorHandler() + * ------------------------------------------------------------ */ + + virtual int constructorHandler(Node *n) { + Language::constructorHandler(n); + + if (itcl) { + String *name = Getattr(n, "name"); + String *iname = GetChar(n, "sym:name"); + + String *realname; + + ParmList *l = Getattr(n, "parms"); + Parm *p = 0; + + String *pname = NewString(""); + + realname = iname ? iname : name; + + if (!have_constructor) { + // Add this member to our class handler function + Printf(constructor, " constructor { "); + + // Add parameter list + int pnum = 0; + for (p = l; p; p = nextSibling(p)) { + + SwigType *pt = Getattr(p, "type"); + String *pn = Getattr(p, "name"); + String *dv = Getattr(p, "value"); + Clear(pname); + + /* Only print an argument if not void */ + if (Cmp(pt, "void") != 0) { + if (Len(pn) > 0) { + Printv(pname, pn, NIL); + } else { + Printf(pname, "p%d", pnum); + } + + if (Len(dv) > 0) { + Printv(constructor, "{", pname, " {", dv, "} } ", NIL); + } else { + Printv(constructor, pname, " ", NIL); + } + } + ++pnum; + } + Printf(constructor, "} { \n"); + + // [BRE] 08/17/00 Added test to see if we are instantiating this object + // type, or, if this constructor is being called as part of the itcl + // inheritance hierarchy. + // In the former case, we need to call the C++ constructor, in the + // latter we don't, or we end up with two C++ objects. + // Check to see if we are instantiating a 'realname' or something + // derived from it. + // + Printv(constructor, " if { [string equal -nocase \"", realname, "\" \"[namespace tail [info class]]\" ] } {\n", NIL); + + // Call to constructor wrapper and parent Ptr class + // [BRE] add -namespace/-prefix support + + if (namespace_option) { + Printv(constructor, " ", realname, "Ptr::constructor [", ns_name, "::new_", realname, NIL); + } else { + Printv(constructor, " ", realname, "Ptr::constructor [new_", realname, NIL); + } + + pnum = 0; + for (p = l; p; p = nextSibling(p)) { + + SwigType *pt = Getattr(p, "type"); + String *pn = Getattr(p, "name"); + Clear(pname); + + /* Only print an argument if not void */ + if (Cmp(pt, "void") != 0) { + if (Len(pn) > 0) { + Printv(pname, pn, NIL); + } else { + Printf(pname, "p%d", pnum); + } + Printv(constructor, " $", pname, NIL); + } + ++pnum; + } + + Printv(constructor, "]\n", " }\n", " } {\n", " set thisown 1\n", " }\n", NIL); + } + } + + if (!have_constructor) + constructor_name = NewString(Getattr(n, "sym:name")); + have_constructor = 1; + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * destructorHandler() + * ------------------------------------------------------------ */ + + virtual int destructorHandler(Node *n) { + Language::destructorHandler(n); + have_destructor = 1; + destructor_action = Getattr(n, "wrap:action"); + return SWIG_OK; + } + + /* ------------------------------------------------------------ + * validIdentifier() + * ------------------------------------------------------------ */ + + virtual int validIdentifier(String *s) { + if (Strchr(s, ' ')) + return 0; + return 1; + } + + /* ------------------------------------------------------------ + * usage_string() + * ------------------------------------------------------------ */ + + char *usage_string(char *iname, SwigType *, ParmList *l) { + static String *temp = 0; + Parm *p; + int i, numopt, pcount; + + if (!temp) + temp = NewString(""); + Clear(temp); + if (namespace_option) { + Printf(temp, "%s::%s ", ns_name, iname); + } else { + Printf(temp, "%s ", iname); + } + /* Now go through and print parameters */ + i = 0; + pcount = emit_num_arguments(l); + numopt = pcount - emit_num_required(l); + for (p = l; p; p = nextSibling(p)) { + + SwigType *pt = Getattr(p, "type"); + String *pn = Getattr(p, "name"); + /* Only print an argument if not ignored */ + if (!checkAttribute(p, "tmap:in:numinputs", "0")) { + if (i >= (pcount - numopt)) + Putc('?', temp); + if (Len(pn) > 0) { + Printf(temp, "%s", pn); + } else { + Printf(temp, "%s", SwigType_str(pt, 0)); + } + if (i >= (pcount - numopt)) + Putc('?', temp); + Putc(' ', temp); + i++; + } + } + return Char(temp); + } + + String *runtimeCode() { + String *s = NewString(""); + String *serrors = Swig_include_sys("tclerrors.swg"); + if (!serrors) { + Printf(stderr, "*** Unable to open 'tclerrors.swg'\n"); + } else { + Append(s, serrors); + Delete(serrors); + } + String *sapi = Swig_include_sys("tclapi.swg"); + if (!sapi) { + Printf(stderr, "*** Unable to open 'tclapi.swg'\n"); + } else { + Append(s, sapi); + Delete(sapi); + } + String *srun = Swig_include_sys("tclrun.swg"); + if (!srun) { + Printf(stderr, "*** Unable to open 'tclrun.swg'\n"); + } else { + Append(s, srun); + Delete(srun); + } + + return s; + } + + String *defaultExternalRuntimeFilename() { + return NewString("swigtclrun.h"); + } +}; + +/* ---------------------------------------------------------------------- + * swig_tcl() - Instantiate module + * ---------------------------------------------------------------------- */ + +static Language *new_swig_tcl() { + return new TCL8(); +} +extern "C" Language *swig_tcl(void) { + return new_swig_tcl(); +} |