1 /* -----------------------------------------------------------------------------
2  * This file is part of SWIG, which is licensed as a whole under version 3
3  * (or any later version) of the GNU General Public License. Some additional
4  * terms also apply to certain portions of SWIG. The full details of the SWIG
5  * license and copyrights can be found in the LICENSE and COPYRIGHT files
6  * included with the SWIG source code as distributed by the SWIG developers
7  * and at http://www.swig.org/legal.html.
8  *
9  * tcl8.cxx
10  *
11  * Tcl8 language module for SWIG.
12  * ----------------------------------------------------------------------------- */
13 
14 #include "swigmod.h"
15 #include "cparse.h"
16 
17 static const char *usage = "\
18 Tcl 8 Options (available with -tcl8)\n\
19      -itcl           - Enable ITcl support\n\
20      -nosafe         - Leave out SafeInit module function.\n\
21      -prefix <name>  - Set a prefix <name> to be prepended to all names\n\
22      -namespace      - Build module into a Tcl 8 namespace\n\
23      -pkgversion     - Set package version\n\n";
24 
25 static String *cmd_tab = 0;	/* Table of command names    */
26 static String *var_tab = 0;	/* Table of global variables */
27 static String *const_tab = 0;	/* Constant table            */
28 static String *methods_tab = 0;	/* Methods table             */
29 static String *attr_tab = 0;	/* Attribute table           */
30 static String *prefix = 0;
31 static String *module = 0;
32 static int namespace_option = 0;
33 static String *init_name = 0;
34 static String *ns_name = 0;
35 static int have_constructor;
36 static String *constructor_name;
37 static int have_destructor;
38 static int have_base_classes;
39 static String *destructor_action = 0;
40 static String *version = (String *) "0.0";
41 static String *class_name = 0;
42 
43 static int have_attributes;
44 static int have_methods;
45 static int nosafe = 0;
46 
47 static File *f_header = 0;
48 static File *f_wrappers = 0;
49 static File *f_init = 0;
50 static File *f_begin = 0;
51 static File *f_runtime = 0;
52 
53 
54 //  Itcl support
55 static int itcl = 0;
56 static File *f_shadow = 0;
57 static File *f_shadow_stubs = 0;
58 
59 static String *constructor = 0;
60 static String *destructor = 0;
61 static String *base_classes = 0;
62 static String *base_class_init = 0;
63 static String *methods = 0;
64 static String *imethods = 0;
65 static String *attributes = 0;
66 static String *attribute_traces = 0;
67 static String *iattribute_traces = 0;
68 
69 
70 
71 class TCL8:public Language {
72 public:
73 
74   /* ------------------------------------------------------------
75    * TCL8::main()
76    * ------------------------------------------------------------ */
77 
main(int argc,char * argv[])78   virtual void main(int argc, char *argv[]) {
79 
80      SWIG_library_directory("tcl");
81 
82     for (int i = 1; i < argc; i++) {
83       if (argv[i]) {
84 	if (strcmp(argv[i], "-prefix") == 0) {
85 	  if (argv[i + 1]) {
86 	    prefix = NewString(argv[i + 1]);
87 	    Swig_mark_arg(i);
88 	    Swig_mark_arg(i + 1);
89 	    i++;
90 	  } else
91 	     Swig_arg_error();
92 	} else if (strcmp(argv[i], "-pkgversion") == 0) {
93 	  if (argv[i + 1]) {
94 	    version = NewString(argv[i + 1]);
95 	    Swig_mark_arg(i);
96 	    Swig_mark_arg(i + 1);
97 	    i++;
98 	  }
99 	} else if (strcmp(argv[i], "-namespace") == 0) {
100 	  namespace_option = 1;
101 	  Swig_mark_arg(i);
102 	} else if (strcmp(argv[i], "-itcl") == 0) {
103 	  itcl = 1;
104 	  Swig_mark_arg(i);
105 	} else if (strcmp(argv[i], "-nosafe") == 0) {
106 	  nosafe = 1;
107 	  Swig_mark_arg(i);
108 	} else if (strcmp(argv[i], "-help") == 0) {
109 	  fputs(usage, stdout);
110 	} else if (strcmp(argv[i], "-cppcast") == 0) {
111 	  Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]);
112 	  Swig_mark_arg(i);
113 	} else if (strcmp(argv[i], "-nocppcast") == 0) {
114 	  Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
115 	  Swig_mark_arg(i);
116 	  SWIG_exit(EXIT_FAILURE);
117 	}
118       }
119     }
120 
121     Preprocessor_define("SWIGTCL 1", 0);
122     // SWIGTCL8 is deprecated, and no longer documented.
123     Preprocessor_define("SWIGTCL8 1", 0);
124     SWIG_typemap_lang("tcl8");
125     SWIG_config_file("tcl8.swg");
126     allow_overloading();
127   }
128 
129   /* ------------------------------------------------------------
130    * top()
131    * ------------------------------------------------------------ */
132 
top(Node * n)133   virtual int top(Node *n) {
134 
135     /* Initialize all of the output files */
136     String *outfile = Getattr(n, "outfile");
137 
138     f_begin = NewFile(outfile, "w", SWIG_output_files());
139     if (!f_begin) {
140       FileErrorDisplay(outfile);
141       SWIG_exit(EXIT_FAILURE);
142     }
143     f_runtime = NewString("");
144     f_init = NewString("");
145     f_header = NewString("");
146     f_wrappers = NewString("");
147 
148     /* Register file targets with the SWIG file handler */
149     Swig_register_filebyname("header", f_header);
150     Swig_register_filebyname("wrapper", f_wrappers);
151     Swig_register_filebyname("begin", f_begin);
152     Swig_register_filebyname("runtime", f_runtime);
153     Swig_register_filebyname("init", f_init);
154 
155     /* Initialize some variables for the object interface */
156 
157     cmd_tab = NewString("");
158     var_tab = NewString("");
159     methods_tab = NewString("");
160     const_tab = NewString("");
161 
162     Swig_banner(f_begin);
163 
164     Printf(f_runtime, "\n\n#ifndef SWIGTCL\n#define SWIGTCL\n#endif\n\n");
165 
166     /* Set the module name, namespace, and prefix */
167 
168     module = NewStringf("%(lower)s", Getattr(n, "name"));
169     init_name = NewStringf("%(title)s_Init", module);
170 
171     ns_name = prefix ? Copy(prefix) : Copy(module);
172     if (prefix)
173       Append(prefix, "_");
174 
175 
176     /* If shadow classing is enabled, we're going to change the module name to "_module" */
177     if (itcl) {
178       String *filen;
179       filen = NewStringf("%s%s.itcl", SWIG_output_directory(), module);
180 
181       Insert(module, 0, "_");
182 
183       if ((f_shadow = NewFile(filen, "w", SWIG_output_files())) == 0) {
184 	FileErrorDisplay(filen);
185 	SWIG_exit(EXIT_FAILURE);
186       }
187       f_shadow_stubs = NewString("");
188 
189       Swig_register_filebyname("shadow", f_shadow);
190       Swig_register_filebyname("itcl", f_shadow);
191 
192       Swig_banner_target_lang(f_shadow, "#");
193 
194       Printv(f_shadow, "\npackage require Itcl\n\n", NIL);
195       Delete(filen);
196     }
197 
198     /* Generate some macros used throughout code generation */
199 
200     Printf(f_header, "#define SWIG_init    %s\n", init_name);
201     Printf(f_header, "#define SWIG_name    \"%s\"\n", module);
202     if (namespace_option) {
203       Printf(f_header, "#define SWIG_prefix  \"%s::\"\n", ns_name);
204       Printf(f_header, "#define SWIG_namespace \"%s\"\n\n", ns_name);
205     } else {
206       Printf(f_header, "#define SWIG_prefix  \"%s\"\n", prefix);
207     }
208     Printf(f_header, "#define SWIG_version \"%s\"\n", version);
209 
210     Printf(cmd_tab, "\nstatic swig_command_info swig_commands[] = {\n");
211     Printf(var_tab, "\nstatic swig_var_info swig_variables[] = {\n");
212     Printf(const_tab, "\nstatic swig_const_info swig_constants[] = {\n");
213 
214     Printf(f_wrappers, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
215 
216     /* Start emitting code */
217     Language::top(n);
218 
219     /* Done.  Close up the module */
220     Printv(cmd_tab, tab4, "{0, 0, 0}\n", "};\n", NIL);
221     Printv(var_tab, tab4, "{0,0,0,0}\n", "};\n", NIL);
222     Printv(const_tab, tab4, "{0,0,0,0,0,0}\n", "};\n", NIL);
223 
224     Printv(f_wrappers, cmd_tab, var_tab, const_tab, NIL);
225 
226     /* Dump the pointer equivalency table */
227     SwigType_emit_type_table(f_runtime, f_wrappers);
228 
229     Printf(f_wrappers, "#ifdef __cplusplus\n}\n#endif\n");
230 
231     /* Close the init function and quit */
232     Printf(f_init, "return TCL_OK;\n}\n");
233 
234     if (!nosafe) {
235       Printf(f_init, "SWIGEXPORT int %(title)s_SafeInit(Tcl_Interp *interp) {\n", module);
236       Printf(f_init, "    return SWIG_init(interp);\n");
237       Printf(f_init, "}\n");
238     }
239 
240     if (itcl) {
241       Printv(f_shadow, f_shadow_stubs, "\n", NIL);
242       Delete(f_shadow);
243     }
244 
245     /* Close all of the files */
246     Dump(f_runtime, f_begin);
247     Printv(f_begin, f_header, f_wrappers, NIL);
248     Wrapper_pretty_print(f_init, f_begin);
249     Delete(f_header);
250     Delete(f_wrappers);
251     Delete(f_init);
252     Delete(f_runtime);
253     Delete(f_begin);
254     return SWIG_OK;
255   }
256 
257   /* ------------------------------------------------------------
258    * functionWrapper()
259    * ------------------------------------------------------------ */
260 
functionWrapper(Node * n)261   virtual int functionWrapper(Node *n) {
262     String *name = Getattr(n, "name");	/* Like to get rid of this */
263     String *iname = Getattr(n, "sym:name");
264     SwigType *type = Getattr(n, "type");
265     ParmList *parms = Getattr(n, "parms");
266     String *overname = 0;
267 
268     Parm *p;
269     int i;
270     String *tm;
271     Wrapper *f;
272     String *incode, *cleanup, *outarg, *argstr, *args;
273     int num_arguments = 0;
274     int num_required = 0;
275     int varargs = 0;
276 
277     char source[64];
278 
279     if (Getattr(n, "sym:overloaded")) {
280       overname = Getattr(n, "sym:overname");
281     } else {
282       if (!addSymbol(iname, n))
283 	return SWIG_ERROR;
284     }
285 
286     incode = NewString("");
287     cleanup = NewString("");
288     outarg = NewString("");
289     argstr = NewString("\"");
290     args = NewString("");
291 
292     f = NewWrapper();
293 
294 #ifdef SWIG_USE_RESULTOBJ
295     Wrapper_add_local(f, "resultobj", "Tcl_Obj *resultobj = NULL");
296 #endif
297 
298 
299     String *wname = Swig_name_wrapper(iname);
300     if (overname) {
301       Append(wname, overname);
302     }
303     Setattr(n, "wrap:name", wname);
304 
305     Printv(f->def, "SWIGINTERN int\n ", wname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {", NIL);
306 
307     // Emit all of the local variables for holding arguments.
308     emit_parameter_variables(parms, f);
309 
310     /* Attach standard typemaps */
311     emit_attach_parmmaps(parms, f);
312     Setattr(n, "wrap:parms", parms);
313 
314     /* Get number of require and total arguments */
315     num_arguments = emit_num_arguments(parms);
316     num_required = emit_num_required(parms);
317     varargs = emit_isvarargs(parms);
318 
319     /* Unmarshal parameters */
320 
321     for (i = 0, p = parms; i < num_arguments; i++) {
322       /* Skip ignored arguments */
323 
324       while (checkAttribute(p, "tmap:in:numinputs", "0")) {
325 	p = Getattr(p, "tmap:in:next");
326       }
327 
328       SwigType *pt = Getattr(p, "type");
329       String *ln = Getattr(p, "lname");
330 
331       /* Produce string representations of the source and target arguments */
332       sprintf(source, "objv[%d]", i + 1);
333 
334       if (i == num_required)
335 	Putc('|', argstr);
336       if ((tm = Getattr(p, "tmap:in"))) {
337 	String *parse = Getattr(p, "tmap:in:parse");
338 	if (!parse) {
339 	  Replaceall(tm, "$target", ln);
340 	  Replaceall(tm, "$source", source);
341 	  Replaceall(tm, "$input", source);
342 	  Setattr(p, "emit:input", source);
343 
344 	  if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
345 	    Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
346 	  } else {
347 	    Replaceall(tm, "$disown", "0");
348 	  }
349 
350 	  Putc('o', argstr);
351 	  Printf(args, ",(void *)0");
352 	  if (i >= num_required) {
353 	    Printf(incode, "if (objc > %d) {\n", i + 1);
354 	  }
355 	  Printf(incode, "%s\n", tm);
356 	  if (i >= num_required) {
357 	    Printf(incode, "}\n");
358 	  }
359 	} else {
360 	  Printf(argstr, "%s", parse);
361 	  Printf(args, ",&%s", ln);
362 	  if (Strcmp(parse, "p") == 0) {
363 	    SwigType *lt = SwigType_ltype(pt);
364 	    SwigType_remember(pt);
365 	    if (Cmp(lt, "p.void") == 0) {
366 	      Printf(args, ",(void *)0");
367 	    } else {
368 	      Printf(args, ",SWIGTYPE%s", SwigType_manglestr(pt));
369 	    }
370 	    Delete(lt);
371 	  }
372 	}
373 	p = Getattr(p, "tmap:in:next");
374 	continue;
375       } else {
376 	Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
377       }
378       p = nextSibling(p);
379     }
380 
381     if (!varargs) {
382       Putc(':', argstr);
383     } else {
384       Putc(';', argstr);
385       /* If variable length arguments we need to emit the in typemap here */
386       if (p && (tm = Getattr(p, "tmap:in"))) {
387 	sprintf(source, "objv[%d]", i + 1);
388 	Printf(incode, "if (objc > %d) {\n", i);
389 	Replaceall(tm, "$input", source);
390 	Printv(incode, tm, "\n", NIL);
391 	Printf(incode, "}\n");
392       }
393     }
394 
395     Printf(argstr, "%s\"", usage_string(Char(iname), type, parms));
396 
397     Printv(f->code, "if (SWIG_GetArgs(interp, objc, objv,", argstr, args, ") == TCL_ERROR) SWIG_fail;\n", NIL);
398 
399     Printv(f->code, incode, NIL);
400 
401     /* Insert constraint checking code */
402     for (p = parms; p;) {
403       if ((tm = Getattr(p, "tmap:check"))) {
404 	Replaceall(tm, "$target", Getattr(p, "lname"));
405 	Printv(f->code, tm, "\n", NIL);
406 	p = Getattr(p, "tmap:check:next");
407       } else {
408 	p = nextSibling(p);
409       }
410     }
411 
412     /* Insert cleanup code */
413     for (i = 0, p = parms; p; i++) {
414       if (!checkAttribute(p, "tmap:in:numinputs", "0")
415 	  && !Getattr(p, "tmap:in:parse") && (tm = Getattr(p, "tmap:freearg"))) {
416 	if (Len(tm) != 0) {
417 	  Replaceall(tm, "$source", Getattr(p, "lname"));
418 	  Printv(cleanup, tm, "\n", NIL);
419 	}
420 	p = Getattr(p, "tmap:freearg:next");
421       } else {
422 	p = nextSibling(p);
423       }
424     }
425 
426     /* Insert argument output code */
427     for (i = 0, p = parms; p; i++) {
428       if ((tm = Getattr(p, "tmap:argout"))) {
429 	Replaceall(tm, "$source", Getattr(p, "lname"));
430 #ifdef SWIG_USE_RESULTOBJ
431 	Replaceall(tm, "$target", "resultobj");
432 	Replaceall(tm, "$result", "resultobj");
433 #else
434 	Replaceall(tm, "$target", "(Tcl_GetObjResult(interp))");
435 	Replaceall(tm, "$result", "(Tcl_GetObjResult(interp))");
436 #endif
437 	Replaceall(tm, "$arg", Getattr(p, "emit:input"));
438 	Replaceall(tm, "$input", Getattr(p, "emit:input"));
439 	Printv(outarg, tm, "\n", NIL);
440 	p = Getattr(p, "tmap:argout:next");
441       } else {
442 	p = nextSibling(p);
443       }
444     }
445 
446     /* Now write code to make the function call */
447     String *actioncode = emit_action(n);
448 
449     /* Need to redo all of this code (eventually) */
450 
451     /* Return value if necessary  */
452     if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
453       Replaceall(tm, "$source", Swig_cresult_name());
454 #ifdef SWIG_USE_RESULTOBJ
455       Replaceall(tm, "$target", "resultobj");
456       Replaceall(tm, "$result", "resultobj");
457 #else
458       Replaceall(tm, "$target", "(Tcl_GetObjResult(interp))");
459       Replaceall(tm, "$result", "(Tcl_GetObjResult(interp))");
460 #endif
461       if (GetFlag(n, "feature:new")) {
462 	Replaceall(tm, "$owner", "SWIG_POINTER_OWN");
463       } else {
464 	Replaceall(tm, "$owner", "0");
465       }
466       Printf(f->code, "%s\n", tm);
467     } else {
468       Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(type, 0), name);
469     }
470     emit_return_variable(n, type, f);
471 
472     /* Dump output argument code */
473     Printv(f->code, outarg, NIL);
474 
475     /* Dump the argument cleanup code */
476     Printv(f->code, cleanup, NIL);
477 
478     /* Look for any remaining cleanup */
479     if (GetFlag(n, "feature:new")) {
480       if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
481 	Replaceall(tm, "$source", Swig_cresult_name());
482 	Printf(f->code, "%s\n", tm);
483       }
484     }
485 
486     if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
487       Replaceall(tm, "$source", Swig_cresult_name());
488       Printf(f->code, "%s\n", tm);
489     }
490 #ifdef SWIG_USE_RESULTOBJ
491     Printv(f->code, "if (resultobj) Tcl_SetObjResult(interp, resultobj);\n", NIL);
492 #endif
493     Printv(f->code, "return TCL_OK;\n", NIL);
494     Printv(f->code, "fail:\n", cleanup, "return TCL_ERROR;\n", NIL);
495     Printv(f->code, "}\n", NIL);
496 
497     /* Substitute the cleanup code */
498     Replaceall(f->code, "$cleanup", cleanup);
499     Replaceall(f->code, "$symname", iname);
500 
501     /* Dump out the function */
502     Wrapper_print(f, f_wrappers);
503 
504     if (!Getattr(n, "sym:overloaded")) {
505       /* Register the function with Tcl */
506       Printv(cmd_tab, tab4, "{ SWIG_prefix \"", iname, "\", (swig_wrapper_func) ", Swig_name_wrapper(iname), ", NULL},\n", NIL);
507     } else {
508       if (!Getattr(n, "sym:nextSibling")) {
509 	/* Emit overloading dispatch function */
510 
511 	int maxargs;
512 	String *dispatch = Swig_overload_dispatch(n, "return %s(clientData, interp, objc, argv - 1);", &maxargs);
513 
514 	/* Generate a dispatch wrapper for all overloaded functions */
515 
516 	Wrapper *df = NewWrapper();
517 	String *dname = Swig_name_wrapper(iname);
518 
519 	Printv(df->def, "SWIGINTERN int\n", dname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {", NIL);
520 	Printf(df->code, "Tcl_Obj *CONST *argv = objv+1;\n");
521 	Printf(df->code, "int argc = objc-1;\n");
522 	Printv(df->code, dispatch, "\n", NIL);
523 	Node *sibl = n;
524 	while (Getattr(sibl, "sym:previousSibling"))
525 	  sibl = Getattr(sibl, "sym:previousSibling");	// go all the way up
526 	String *protoTypes = NewString("");
527 	do {
528 	  String *fulldecl = Swig_name_decl(sibl);
529 	  Printf(protoTypes, "\n\"    %s\\n\"", fulldecl);
530 	  Delete(fulldecl);
531 	} while ((sibl = Getattr(sibl, "sym:nextSibling")));
532 	Printf(df->code, "Tcl_SetResult(interp,(char *) "
533 	       "\"Wrong number or type of arguments for overloaded function '%s'.\\n\""
534 	       "\n\"  Possible C/C++ prototypes are:\\n\"%s, TCL_STATIC);\n", iname, protoTypes);
535 	Delete(protoTypes);
536 	Printf(df->code, "return TCL_ERROR;\n");
537 	Printv(df->code, "}\n", NIL);
538 	Wrapper_print(df, f_wrappers);
539 	Printv(cmd_tab, tab4, "{ SWIG_prefix \"", iname, "\", (swig_wrapper_func) ", dname, ", NULL},\n", NIL);
540 	DelWrapper(df);
541 	Delete(dispatch);
542 	Delete(dname);
543       }
544     }
545 
546     Delete(incode);
547     Delete(cleanup);
548     Delete(outarg);
549     Delete(argstr);
550     Delete(args);
551     DelWrapper(f);
552     return SWIG_OK;
553   }
554 
555   /* ------------------------------------------------------------
556    * variableWrapper()
557    * ------------------------------------------------------------ */
558 
variableWrapper(Node * n)559   virtual int variableWrapper(Node *n) {
560 
561     String *name = Getattr(n, "name");
562     String *iname = Getattr(n, "sym:name");
563     SwigType *t = Getattr(n, "type");
564 
565     String *setname = 0;
566     String *setfname = 0;
567     Wrapper *setf = 0, *getf = 0;
568     int readonly = 0;
569     String *tm;
570 
571     if (!addSymbol(iname, n))
572       return SWIG_ERROR;
573 
574     /* Create a function for getting a variable */
575     int addfail = 0;
576     getf = NewWrapper();
577     String *getname = Swig_name_get(NSPACE_TODO, iname);
578     String *getfname = Swig_name_wrapper(getname);
579     Setattr(n, "wrap:name", getfname);
580     Printv(getf->def, "SWIGINTERN const char *", getfname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, char *name1, char *name2, int flags) {", NIL);
581     Wrapper_add_local(getf, "value", "Tcl_Obj *value = 0");
582     if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
583       Replaceall(tm, "$source", name);
584       Replaceall(tm, "$target", "value");
585       Replaceall(tm, "$result", "value");
586       /* Printf(getf->code, "%s\n",tm); */
587       addfail = emit_action_code(n, getf->code, tm);
588       Printf(getf->code, "if (value) {\n");
589       Printf(getf->code, "Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n");
590       Printf(getf->code, "Tcl_DecrRefCount(value);\n");
591       Printf(getf->code, "}\n");
592       Printf(getf->code, "return NULL;\n");
593       if (addfail) {
594 	Append(getf->code, "fail:\n");
595 	Printf(getf->code, "return \"%s\";\n", iname);
596       }
597       Printf(getf->code, "}\n");
598       Wrapper_print(getf, f_wrappers);
599     } else {
600       Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
601       DelWrapper(getf);
602       return SWIG_NOWRAP;
603     }
604     DelWrapper(getf);
605 
606     /* Try to create a function setting a variable */
607     if (is_assignable(n)) {
608       setf = NewWrapper();
609       setname = Swig_name_set(NSPACE_TODO, iname);
610       setfname = Swig_name_wrapper(setname);
611       Setattr(n, "wrap:name", setfname);
612       if (setf) {
613         Printv(setf->def, "SWIGINTERN const char *", setfname,
614 	     "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, char *name1, char *name2 SWIGUNUSED, int flags) {", NIL);
615         Wrapper_add_local(setf, "value", "Tcl_Obj *value = 0");
616         Wrapper_add_local(setf, "name1o", "Tcl_Obj *name1o = 0");
617 
618         if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
619 	  Replaceall(tm, "$source", "value");
620 	  Replaceall(tm, "$target", name);
621 	  Replaceall(tm, "$input", "value");
622 	  Printf(setf->code, "name1o = Tcl_NewStringObj(name1,-1);\n");
623 	  Printf(setf->code, "value = Tcl_ObjGetVar2(interp, name1o, 0, flags);\n");
624 	  Printf(setf->code, "Tcl_DecrRefCount(name1o);\n");
625 	  Printf(setf->code, "if (!value) SWIG_fail;\n");
626 	  /* Printf(setf->code,"%s\n", tm); */
627 	  emit_action_code(n, setf->code, tm);
628 	  Printf(setf->code, "return NULL;\n");
629 	  Printf(setf->code, "fail:\n");
630 	  Printf(setf->code, "return \"%s\";\n", iname);
631 	  Printf(setf->code, "}\n");
632 	  Wrapper_print(setf, f_wrappers);
633         } else {
634 	  Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
635 	  readonly = 1;
636         }
637       }
638       DelWrapper(setf);
639     } else {
640       readonly = 1;
641     }
642 
643 
644     Printv(var_tab, tab4, "{ SWIG_prefix \"", iname, "\", 0, (swig_variable_func) ", getfname, ",", NIL);
645     if (readonly) {
646       static int readonlywrap = 0;
647       if (!readonlywrap) {
648 	Wrapper *ro = NewWrapper();
649 	Printf(ro->def,
650 	       "SWIGINTERN const char *swig_readonly(ClientData clientData SWIGUNUSED, Tcl_Interp *interp SWIGUNUSED, char *name1 SWIGUNUSED, char *name2 SWIGUNUSED, int flags SWIGUNUSED) {");
651 	Printv(ro->code, "return \"Variable is read-only\";\n", "}\n", NIL);
652 	Wrapper_print(ro, f_wrappers);
653 	readonlywrap = 1;
654 	DelWrapper(ro);
655       }
656       Printf(var_tab, "(swig_variable_func) swig_readonly},\n");
657     } else {
658       Printv(var_tab, "(swig_variable_func) ", setfname, "},\n", NIL);
659     }
660     Delete(getfname);
661     Delete(setfname);
662     Delete(setname);
663     Delete(getname);
664     return SWIG_OK;
665   }
666 
667   /* ------------------------------------------------------------
668    * constantWrapper()
669    * ------------------------------------------------------------ */
670 
constantWrapper(Node * n)671   virtual int constantWrapper(Node *n) {
672     String *name = Getattr(n, "name");
673     String *iname = Getattr(n, "sym:name");
674     String *nsname = !namespace_option ? Copy(iname) : NewStringf("%s::%s", ns_name, iname);
675     SwigType *type = Getattr(n, "type");
676     String *rawval = Getattr(n, "rawval");
677     String *value = rawval ? rawval : Getattr(n, "value");
678     String *tm;
679 
680     if (!addSymbol(iname, n))
681       return SWIG_ERROR;
682     if (namespace_option)
683       Setattr(n, "sym:name", nsname);
684 
685     /* Special hook for member pointer */
686     if (SwigType_type(type) == T_MPOINTER) {
687       String *wname = Swig_name_wrapper(iname);
688       Printf(f_wrappers, "static %s = %s;\n", SwigType_str(type, wname), value);
689       value = Char(wname);
690     }
691 
692     if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) {
693       Replaceall(tm, "$source", value);
694       Replaceall(tm, "$target", name);
695       Replaceall(tm, "$value", value);
696       Replaceall(tm, "$nsname", nsname);
697       Printf(const_tab, "%s,\n", tm);
698     } else if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
699       Replaceall(tm, "$source", value);
700       Replaceall(tm, "$target", name);
701       Replaceall(tm, "$value", value);
702       Replaceall(tm, "$nsname", nsname);
703       Printf(f_init, "%s\n", tm);
704     } else {
705       Delete(nsname);
706       Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
707       return SWIG_NOWRAP;
708     }
709     Delete(nsname);
710     return SWIG_OK;
711   }
712 
713   /* ------------------------------------------------------------
714    * nativeWrapper()
715    * ------------------------------------------------------------ */
716 
nativeWrapper(Node * n)717   virtual int nativeWrapper(Node *n) {
718     String *name = Getattr(n, "sym:name");
719     String *funcname = Getattr(n, "wrap:name");
720     if (!addSymbol(funcname, n))
721       return SWIG_ERROR;
722 
723     Printf(f_init, "\t Tcl_CreateObjCommand(interp, SWIG_prefix \"%s\", (swig_wrapper_func) %s, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);\n", name,
724 	   funcname);
725     return SWIG_OK;
726   }
727 
728   /* ------------------------------------------------------------
729    * classHandler()
730    * ------------------------------------------------------------ */
731 
classHandler(Node * n)732   virtual int classHandler(Node *n) {
733     static Hash *emitted = NewHash();
734     String *mangled_classname = 0;
735     String *real_classname = 0;
736 
737     have_constructor = 0;
738     have_destructor = 0;
739     destructor_action = 0;
740     constructor_name = 0;
741 
742     if (itcl) {
743       constructor = NewString("");
744       destructor = NewString("");
745       base_classes = NewString("");
746       base_class_init = NewString("");
747       methods = NewString("");
748       imethods = NewString("");
749       attributes = NewString("");
750       attribute_traces = NewString("");
751       iattribute_traces = NewString("");
752 
753       have_base_classes = 0;
754       have_methods = 0;
755       have_attributes = 0;
756     }
757 
758     class_name = Getattr(n, "sym:name");
759     if (!addSymbol(class_name, n))
760       return SWIG_ERROR;
761 
762     real_classname = Getattr(n, "name");
763     mangled_classname = Swig_name_mangle(real_classname);
764 
765     if (Getattr(emitted, mangled_classname))
766       return SWIG_NOWRAP;
767     Setattr(emitted, mangled_classname, "1");
768 
769     attr_tab = NewString("");
770     Printf(attr_tab, "static swig_attribute swig_");
771     Printv(attr_tab, mangled_classname, "_attributes[] = {\n", NIL);
772 
773     methods_tab = NewStringf("");
774     Printf(methods_tab, "static swig_method swig_");
775     Printv(methods_tab, mangled_classname, "_methods[] = {\n", NIL);
776 
777     /* Generate normal wrappers */
778     Language::classHandler(n);
779 
780     SwigType *t = Copy(Getattr(n, "name"));
781     SwigType_add_pointer(t);
782 
783     // Catch all: eg. a class with only static functions and/or variables will not have 'remembered'
784     // SwigType_remember(t);
785     String *wrap_class = NewStringf("&_wrap_class_%s", mangled_classname);
786     SwigType_remember_clientdata(t, wrap_class);
787 
788     String *rt = Copy(getClassType());
789     SwigType_add_pointer(rt);
790 
791     // Register the class structure with the type checker
792     /*    Printf(f_init,"SWIG_TypeClientData(SWIGTYPE%s, (void *) &_wrap_class_%s);\n", SwigType_manglestr(t), mangled_classname); */
793     if (have_destructor) {
794       Printv(f_wrappers, "SWIGINTERN void swig_delete_", class_name, "(void *obj) {\n", NIL);
795       if (destructor_action) {
796 	Printv(f_wrappers, SwigType_str(rt, "arg1"), " = (", SwigType_str(rt, 0), ") obj;\n", NIL);
797 	Printv(f_wrappers, destructor_action, "\n", NIL);
798       } else {
799 	if (CPlusPlus) {
800 	  Printv(f_wrappers, "    delete (", SwigType_str(rt, 0), ") obj;\n", NIL);
801 	} else {
802 	  Printv(f_wrappers, "    free((char *) obj);\n", NIL);
803 	}
804       }
805       Printf(f_wrappers, "}\n");
806     }
807 
808     Printf(methods_tab, "    {0,0}\n};\n");
809     Printv(f_wrappers, methods_tab, NIL);
810 
811     Printf(attr_tab, "    {0,0,0}\n};\n");
812     Printv(f_wrappers, attr_tab, NIL);
813 
814     /* Handle inheritance */
815 
816     String *base_class = NewString("");
817     String *base_class_names = NewString("");
818 
819     if (itcl) {
820       base_classes = NewString("");
821     }
822 
823     List *baselist = Getattr(n, "bases");
824     if (baselist && Len(baselist)) {
825       Iterator b;
826       int index = 0;
827       b = First(baselist);
828       while (b.item) {
829 	String *bname = Getattr(b.item, "name");
830 	if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) {
831 	  b = Next(b);
832 	  continue;
833 	}
834 	if (itcl) {
835 	  have_base_classes = 1;
836 	  Printv(base_classes, bname, " ", NIL);
837 	  Printv(base_class_init, "    ", bname, "Ptr::constructor $ptr\n", NIL);
838 	}
839 	String *bmangle = Swig_name_mangle(bname);
840 	//      Printv(f_wrappers,"extern swig_class _wrap_class_", bmangle, ";\n", NIL);
841 	//      Printf(base_class,"&_wrap_class_%s",bmangle);
842 	Printf(base_class, "0");
843 	Printf(base_class_names, "\"%s *\",", SwigType_namestr(bname));
844 	/* Put code to register base classes in init function */
845 
846 	//Printf(f_init,"/* Register base : %s */\n", bmangle);
847 	//Printf(f_init,"swig_%s_bases[%d] = (swig_class *) SWIG_TypeQuery(\"%s *\")->clientdata;\n",  mangled_classname, index, SwigType_namestr(bname));
848 	b = Next(b);
849 	index++;
850 	Putc(',', base_class);
851 	Delete(bmangle);
852       }
853     }
854 
855     if (itcl) {
856       String *ptrclass = NewString("");
857 
858       // First, build the pointer base class
859       Printv(ptrclass, "itcl::class ", class_name, "Ptr {\n", NIL);
860       if (have_base_classes)
861 	Printv(ptrclass, "  inherit ", base_classes, "\n", NIL);
862 
863       //  Define protected variables for SWIG object pointer
864       Printv(ptrclass, "  protected variable swigobj\n", "  protected variable thisown\n", NIL);
865 
866       //  Define public variables
867       if (have_attributes) {
868 	Printv(ptrclass, attributes, NIL);
869 
870 	// base class swig_getset was being called for complex inheritance trees
871 	if (namespace_option) {
872 
873 	  Printv(ptrclass, "  protected method ", class_name, "_swig_getset {var name1 name2 op} {\n", NIL);
874 
875 	  Printv(ptrclass,
876 		 "    switch -exact -- $op {\n",
877 		 "      r {set $var [", ns_name, "::", class_name, "_[set var]_get $swigobj]}\n",
878 		 "      w {", ns_name, "::", class_name, "_${var}_set $swigobj [set $var]}\n", "    }\n", "  }\n", NIL);
879 	} else {
880 	  Printv(ptrclass,
881 		 "  protected method ", class_name, "_swig_getset {var name1 name2 op} {\n",
882 		 "    switch -exact -- $op {\n",
883 		 "      r {set $var [", class_name, "_[set var]_get $swigobj]}\n",
884 		 "      w {", class_name, "_${var}_set $swigobj [set $var]}\n", "    }\n", "  }\n", NIL);
885 	}
886       }
887       //  Add the constructor, which may include
888       //  calls to base class class constructors
889 
890       Printv(ptrclass, "  constructor { ptr } {\n", NIL);
891       if (have_base_classes) {
892 	Printv(ptrclass, base_class_init, NIL);
893 	Printv(ptrclass, "  } {\n", NIL);
894       }
895 
896       Printv(ptrclass, "    set swigobj $ptr\n", "    set thisown 0\n", NIL);
897 
898       if (have_attributes) {
899 	Printv(ptrclass, attribute_traces, NIL);
900       }
901       Printv(ptrclass, "  }\n", NIL);
902 
903 
904       //  Add destructor
905       Printv(ptrclass, "  destructor {\n",
906 	     "    set d_func delete_", class_name, "\n",
907 	     "    if { $thisown && ([info command $d_func] != \"\") } {\n" "      $d_func $swigobj\n", "    }\n", "  }\n", NIL);
908 
909       //  Add methods
910       if (have_methods) {
911 	Printv(ptrclass, imethods, NIL);
912       };
913 
914       //  Close out the pointer class
915       Printv(ptrclass, "}\n\n", NIL);
916       Printv(f_shadow, ptrclass, NIL);
917       // pointer class end
918 
919 
920       //  Create the "real" class.
921       Printv(f_shadow, "itcl::class ", class_name, " {\n", NIL);
922       Printv(f_shadow, "  inherit ", class_name, "Ptr\n", NIL);
923 
924       //  If we have a constructor, then use it.
925       //  If not, then we must have an abstract class without
926       //  any constructor.  So we create a class constructor
927       //  which will fail for this class (but not for inherited
928       //  classes).  Note that the constructor must fail before
929       //  calling the ptrclass constructor.
930 
931       if (have_constructor) {
932 	Printv(f_shadow, constructor, NIL);
933       } else {
934 	Printv(f_shadow, "  constructor { } {\n", NIL);
935 	Printv(f_shadow, "    # This constructor will fail if called directly\n", NIL);
936 	Printv(f_shadow, "    if { [info class] == \"::", class_name, "\" } {\n", NIL);
937 	Printv(f_shadow, "      error \"No constructor for class ", class_name, (Getattr(n, "abstracts") ? " - class is abstract" : ""), "\"\n", NIL);
938 	Printv(f_shadow, "    }\n", NIL);
939 	Printv(f_shadow, "  }\n", NIL);
940       }
941 
942       Printv(f_shadow, "}\n\n", NIL);
943     }
944 
945     Printv(f_wrappers, "static swig_class *swig_", mangled_classname, "_bases[] = {", base_class, "0};\n", NIL);
946     Printv(f_wrappers, "static const char * swig_", mangled_classname, "_base_names[] = {", base_class_names, "0};\n", NIL);
947     Delete(base_class);
948     Delete(base_class_names);
949 
950     Printv(f_wrappers, "static swig_class _wrap_class_", mangled_classname, " = { \"", class_name, "\", &SWIGTYPE", SwigType_manglestr(t), ",", NIL);
951 
952     if (have_constructor) {
953       Printf(f_wrappers, "%s", Swig_name_wrapper(Swig_name_construct(NSPACE_TODO, constructor_name)));
954       Delete(constructor_name);
955       constructor_name = 0;
956     } else {
957       Printf(f_wrappers, "0");
958     }
959     if (have_destructor) {
960       Printv(f_wrappers, ", swig_delete_", class_name, NIL);
961     } else {
962       Printf(f_wrappers, ",0");
963     }
964     Printv(f_wrappers, ", swig_", mangled_classname, "_methods, swig_", mangled_classname, "_attributes, swig_", mangled_classname, "_bases,",
965 	   "swig_", mangled_classname, "_base_names, &swig_module, SWIG_TCL_HASHTABLE_INIT };\n", NIL);
966 
967     if (!itcl) {
968       Printv(cmd_tab, tab4, "{ SWIG_prefix \"", class_name, "\", (swig_wrapper_func) SWIG_ObjectConstructor, (ClientData)&_wrap_class_", mangled_classname,
969 	     "},\n", NIL);
970     };
971 
972     Delete(t);
973     Delete(mangled_classname);
974     return SWIG_OK;
975   }
976 
977 
978   /* ------------------------------------------------------------
979    * memberfunctionHandler()
980    * ------------------------------------------------------------ */
981 
memberfunctionHandler(Node * n)982   virtual int memberfunctionHandler(Node *n) {
983     String *name = Getattr(n, "name");
984     String *iname = GetChar(n, "sym:name");
985 
986     String *realname, *rname;
987 
988     Language::memberfunctionHandler(n);
989 
990     realname = iname ? iname : name;
991     rname = Swig_name_wrapper(Swig_name_member(NSPACE_TODO, class_name, realname));
992     if (!Getattr(n, "sym:nextSibling")) {
993       Printv(methods_tab, tab4, "{\"", realname, "\", ", rname, "}, \n", NIL);
994     }
995 
996     if (itcl) {
997       ParmList *l = Getattr(n, "parms");
998       Parm *p = 0;
999       String *pname = NewString("");
1000 
1001       // Add this member to our class handler function
1002       Printv(imethods, tab2, "method ", realname, " [list ", NIL);
1003 
1004       int pnum = 0;
1005       for (p = l; p; p = nextSibling(p)) {
1006 
1007 	String *pn = Getattr(p, "name");
1008 	String *dv = Getattr(p, "value");
1009 	SwigType *pt = Getattr(p, "type");
1010 
1011 	Printv(pname, ",(", pt, ")", NIL);
1012 	Clear(pname);
1013 
1014 	/* Only print an argument if not void */
1015 	if (Cmp(pt, "void") != 0) {
1016 	  if (Len(pn) > 0) {
1017 	    Printv(pname, pn, NIL);
1018 	  } else {
1019 	    Printf(pname, "p%d", pnum);
1020 	  }
1021 
1022 	  if (Len(dv) > 0) {
1023 	    String *defval = NewString(dv);
1024 	    if (namespace_option) {
1025 	      Insert(defval, 0, "::");
1026 	      Insert(defval, 0, ns_name);
1027 	    }
1028 	    if (Strncmp(dv, "(", 1) == 0) {
1029 	      Insert(defval, 0, "$");
1030 	      Replaceall(defval, "(", "");
1031 	      Replaceall(defval, ")", "");
1032 	    }
1033 	    Printv(imethods, "[list ", pname, " ", defval, "] ", NIL);
1034 	  } else {
1035 	    Printv(imethods, pname, " ", NIL);
1036 	  }
1037 	}
1038 	++pnum;
1039       }
1040       Printv(imethods, "] ", NIL);
1041 
1042       if (namespace_option) {
1043 	Printv(imethods, "{ ", ns_name, "::", class_name, "_", realname, " $swigobj", NIL);
1044       } else {
1045 	Printv(imethods, "{ ", class_name, "_", realname, " $swigobj", NIL);
1046       };
1047 
1048       pnum = 0;
1049       for (p = l; p; p = nextSibling(p)) {
1050 
1051 	String *pn = Getattr(p, "name");
1052 	SwigType *pt = Getattr(p, "type");
1053 	Clear(pname);
1054 
1055 	/* Only print an argument if not void */
1056 	if (Cmp(pt, "void") != 0) {
1057 	  if (Len(pn) > 0) {
1058 	    Printv(pname, pn, NIL);
1059 	  } else {
1060 	    Printf(pname, "p%d", pnum);
1061 	  }
1062 	  Printv(imethods, " $", pname, NIL);
1063 	}
1064 	++pnum;
1065       }
1066       Printv(imethods, " }\n", NIL);
1067       have_methods = 1;
1068     }
1069 
1070     Delete(rname);
1071     return SWIG_OK;
1072   }
1073 
1074   /* ------------------------------------------------------------
1075    * membervariableHandler()
1076    * ------------------------------------------------------------ */
1077 
membervariableHandler(Node * n)1078   virtual int membervariableHandler(Node *n) {
1079     String *symname = Getattr(n, "sym:name");
1080     String *rname;
1081 
1082     Language::membervariableHandler(n);
1083     Printv(attr_tab, tab4, "{ \"-", symname, "\",", NIL);
1084     rname = Swig_name_wrapper(Swig_name_get(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname)));
1085     Printv(attr_tab, rname, ", ", NIL);
1086     Delete(rname);
1087     if (!GetFlag(n, "feature:immutable")) {
1088       rname = Swig_name_wrapper(Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname)));
1089       Printv(attr_tab, rname, "},\n", NIL);
1090       Delete(rname);
1091     } else {
1092       Printf(attr_tab, "0 },\n");
1093     }
1094 
1095     if (itcl) {
1096       Printv(attributes, "  public variable ", symname, "\n", NIL);
1097 
1098       Printv(attribute_traces, "    trace variable ", symname, " rw [list ", class_name, "_swig_getset ", symname, "]\n", NIL);
1099       Printv(attribute_traces, "    set ", symname, "\n", NIL);
1100 
1101       have_attributes = 1;
1102     }
1103     return SWIG_OK;
1104   }
1105 
1106   /* ------------------------------------------------------------
1107    * constructorHandler()
1108    * ------------------------------------------------------------ */
1109 
constructorHandler(Node * n)1110   virtual int constructorHandler(Node *n) {
1111     Language::constructorHandler(n);
1112 
1113     if (itcl) {
1114       String *name = Getattr(n, "name");
1115       String *iname = GetChar(n, "sym:name");
1116 
1117       String *realname;
1118 
1119       ParmList *l = Getattr(n, "parms");
1120       Parm *p = 0;
1121 
1122       String *pname = NewString("");
1123 
1124       realname = iname ? iname : name;
1125 
1126       if (!have_constructor) {
1127 	// Add this member to our class handler function
1128 	Printf(constructor, "  constructor { ");
1129 
1130 	//  Add parameter list
1131 	int pnum = 0;
1132 	for (p = l; p; p = nextSibling(p)) {
1133 
1134 	  SwigType *pt = Getattr(p, "type");
1135 	  String *pn = Getattr(p, "name");
1136 	  String *dv = Getattr(p, "value");
1137 	  Clear(pname);
1138 
1139 	  /* Only print an argument if not void */
1140 	  if (Cmp(pt, "void") != 0) {
1141 	    if (Len(pn) > 0) {
1142 	      Printv(pname, pn, NIL);
1143 	    } else {
1144 	      Printf(pname, "p%d", pnum);
1145 	    }
1146 
1147 	    if (Len(dv) > 0) {
1148 	      Printv(constructor, "{", pname, " {", dv, "} } ", NIL);
1149 	    } else {
1150 	      Printv(constructor, pname, " ", NIL);
1151 	    }
1152 	  }
1153 	  ++pnum;
1154 	}
1155 	Printf(constructor, "} { \n");
1156 
1157 	// [BRE] 08/17/00 Added test to see if we are instantiating this object
1158 	// type, or, if this constructor is being called as part of the itcl
1159 	// inheritance hierarchy.
1160 	// In the former case, we need to call the C++ constructor, in the
1161 	// latter we don't, or we end up with two C++ objects.
1162 	// Check to see if we are instantiating a 'realname' or something
1163 	// derived from it.
1164 	//
1165 	Printv(constructor, "    if { [string equal -nocase \"", realname, "\" \"[namespace tail [info class]]\" ] } {\n", NIL);
1166 
1167 	// Call to constructor wrapper and parent Ptr class
1168 	// [BRE] add -namespace/-prefix support
1169 
1170 	if (namespace_option) {
1171 	  Printv(constructor, "      ", realname, "Ptr::constructor [", ns_name, "::new_", realname, NIL);
1172 	} else {
1173 	  Printv(constructor, "      ", realname, "Ptr::constructor [new_", realname, NIL);
1174 	}
1175 
1176 	pnum = 0;
1177 	for (p = l; p; p = nextSibling(p)) {
1178 
1179 	  SwigType *pt = Getattr(p, "type");
1180 	  String *pn = Getattr(p, "name");
1181 	  Clear(pname);
1182 
1183 	  /* Only print an argument if not void */
1184 	  if (Cmp(pt, "void") != 0) {
1185 	    if (Len(pn) > 0) {
1186 	      Printv(pname, pn, NIL);
1187 	    } else {
1188 	      Printf(pname, "p%d", pnum);
1189 	    }
1190 	    Printv(constructor, " $", pname, NIL);
1191 	  }
1192 	  ++pnum;
1193 	}
1194 
1195 	Printv(constructor, "]\n", "    }\n", "  } {\n", "    set thisown 1\n", "  }\n", NIL);
1196       }
1197     }
1198 
1199     if (!have_constructor)
1200       constructor_name = NewString(Getattr(n, "sym:name"));
1201     have_constructor = 1;
1202     return SWIG_OK;
1203   }
1204 
1205   /* ------------------------------------------------------------
1206    * destructorHandler()
1207    * ------------------------------------------------------------ */
1208 
destructorHandler(Node * n)1209   virtual int destructorHandler(Node *n) {
1210     Language::destructorHandler(n);
1211     have_destructor = 1;
1212     destructor_action = Getattr(n, "wrap:action");
1213     return SWIG_OK;
1214   }
1215 
1216   /* ------------------------------------------------------------
1217    * validIdentifier()
1218    * ------------------------------------------------------------ */
1219 
validIdentifier(String * s)1220   virtual int validIdentifier(String *s) {
1221     if (Strchr(s, ' '))
1222       return 0;
1223     return 1;
1224   }
1225 
1226   /* ------------------------------------------------------------
1227    * usage_string()
1228    * ------------------------------------------------------------ */
1229 
usage_string(char * iname,SwigType *,ParmList * l)1230   char *usage_string(char *iname, SwigType *, ParmList *l) {
1231     static String *temp = 0;
1232     Parm *p;
1233     int i, numopt, pcount;
1234 
1235     if (!temp)
1236       temp = NewString("");
1237     Clear(temp);
1238     if (namespace_option) {
1239       Printf(temp, "%s::%s ", ns_name, iname);
1240     } else {
1241       Printf(temp, "%s ", iname);
1242     }
1243     /* Now go through and print parameters */
1244     i = 0;
1245     pcount = emit_num_arguments(l);
1246     numopt = pcount - emit_num_required(l);
1247     for (p = l; p; p = nextSibling(p)) {
1248 
1249       SwigType *pt = Getattr(p, "type");
1250       String *pn = Getattr(p, "name");
1251       /* Only print an argument if not ignored */
1252       if (!checkAttribute(p, "tmap:in:numinputs", "0")) {
1253 	if (i >= (pcount - numopt))
1254 	  Putc('?', temp);
1255 	if (Len(pn) > 0) {
1256 	  Printf(temp, "%s", pn);
1257 	} else {
1258 	  Printf(temp, "%s", SwigType_str(pt, 0));
1259 	}
1260 	if (i >= (pcount - numopt))
1261 	  Putc('?', temp);
1262 	Putc(' ', temp);
1263 	i++;
1264       }
1265     }
1266     return Char(temp);
1267   }
1268 
runtimeCode()1269   String *runtimeCode() {
1270     String *s = NewString("");
1271     String *serrors = Swig_include_sys("tclerrors.swg");
1272     if (!serrors) {
1273       Printf(stderr, "*** Unable to open 'tclerrors.swg'\n");
1274     } else {
1275       Append(s, serrors);
1276       Delete(serrors);
1277     }
1278     String *sapi = Swig_include_sys("tclapi.swg");
1279     if (!sapi) {
1280       Printf(stderr, "*** Unable to open 'tclapi.swg'\n");
1281     } else {
1282       Append(s, sapi);
1283       Delete(sapi);
1284     }
1285     String *srun = Swig_include_sys("tclrun.swg");
1286     if (!srun) {
1287       Printf(stderr, "*** Unable to open 'tclrun.swg'\n");
1288     } else {
1289       Append(s, srun);
1290       Delete(srun);
1291     }
1292 
1293     return s;
1294   }
1295 
defaultExternalRuntimeFilename()1296   String *defaultExternalRuntimeFilename() {
1297     return NewString("swigtclrun.h");
1298   }
1299 };
1300 
1301 /* ----------------------------------------------------------------------
1302  * swig_tcl()    - Instantiate module
1303  * ---------------------------------------------------------------------- */
1304 
new_swig_tcl()1305 static Language *new_swig_tcl() {
1306   return new TCL8();
1307 }
swig_tcl(void)1308 extern "C" Language *swig_tcl(void) {
1309   return new_swig_tcl();
1310 }
1311