blob: 105808cb8f9e7d468b1df0122e49077e12b9e9c4 [file] [log] [blame]
/* -----------------------------------------------------------------------------
* tcl8.cxx
*
* Tcl8.0 wrapper module.
*
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
*
* Copyright (C) 1999-2000. The University of Chicago
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
static char cvsroot[] = "$Header$";
#include "mod11.h"
#include "tcl8.h"
#include <ctype.h>
#include "swigconfig.h"
static char *usage = (char*)"\
Tcl 8.0 Options (available with -tcl)\n\
-ldflags - Print runtime libraries to link with\n\
-module name - Set name of module\n\
-prefix name - Set a prefix to be appended to all names\n\
-namespace - Build module into a Tcl 8 namespace. \n\
-noobject - Omit code for object oriented interface.\n\n";
static String *mod_init = 0;
static String *cmd_info = 0;
static String *var_info = 0;
static String *methods = 0;
static String *attributes = 0;
static String *prefix = 0;
static String *module = 0;
static int nspace = 0;
static int shadow = 1;
static String *init_name = 0;
static String *ns_name = 0;
static int have_constructor;
static int have_destructor;
static String *class_name = 0;
static String *class_type = 0;
static String *real_classname = 0;
static Hash *repeatcmd = 0;
/* -----------------------------------------------------------------------------
* TCL8::parse_args()
* ----------------------------------------------------------------------------- */
void
TCL8::parse_args(int argc, char *argv[]) {
int i;
strcpy(LibDir,"tcl");
for (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],"-module") == 0) {
if (argv[i+1]) {
set_module(argv[i+1]);
Swig_mark_arg(i);
Swig_mark_arg(i+1);
i++;
} else Swig_arg_error();
} else if (strcmp(argv[i],"-namespace") == 0) {
nspace = 1;
Swig_mark_arg(i);
} else if (strcmp(argv[i],"-noobject") == 0) {
shadow = 0;
Swig_mark_arg(i);
} else if (strcmp(argv[i],"-help") == 0) {
fputs(usage,stderr);
} else if (strcmp (argv[i], "-ldflags") == 0) {
printf("%s\n", SWIG_TCL_RUNTIME);
SWIG_exit (EXIT_SUCCESS);
}
}
}
if ((nspace) && module) {
ns_name = Copy(module);
} else if (prefix) {
ns_name = Copy(prefix);
}
if (prefix)
Append(prefix,"_");
Preprocessor_define((void *) "SWIGTCL 1",0);
Preprocessor_define((void *) "SWIGTCL8 1", 0);
typemap_lang = (char*)"tcl8";
SWIG_config_file("tcl8.swg");
}
/* -----------------------------------------------------------------------------
* TCL8::parse()
* ----------------------------------------------------------------------------- */
void
TCL8::parse() {
mod_init = NewString("");
cmd_info = NewString("");
var_info = NewString("");
methods = NewString("");
attributes = NewString("");
repeatcmd = NewHash();
Swig_banner(f_runtime);
/* Include a Tcl configuration file */
if (NoInclude) {
Printf(f_runtime,"#define SWIG_NOINCLUDE\n");
}
/* if (Swig_insert_file("common.swg",f_runtime) == -1) {
Printf(stderr,"SWIG : Fatal error. Unable to locate 'common.swg' in SWIG library.\n");
SWIG_exit (EXIT_FAILURE);
}
if (Swig_insert_file("swigtcl8.swg",f_runtime) == -1) {
Printf(stderr,"SWIG : Fatal error. Unable to locate 'swigtcl8.swg' in SWIG library.\n");
SWIG_exit (EXIT_FAILURE);
}
*/
yyparse();
}
/* -----------------------------------------------------------------------------
* TCL8::set_module()
* ----------------------------------------------------------------------------- */
void
TCL8::set_module(char *mod_name) {
char *c;
if (module) return;
module = NewString(mod_name);
/* Fix capitalization for Tcl */
for (c = Char(module); *c; c++) *c = (char) tolower(*c);
/* Now create an initialization function */
init_name = NewStringf("%s_Init",module);
c = Char(init_name);
*c = toupper(*c);
if (!ns_name) ns_name = Copy(module);
/* If namespaces have been specified, set the prefix to the module name */
if ((nspace) && (!prefix)) {
prefix = NewStringf("%s_",module);
} else {
prefix = NewString("");
}
}
/* -----------------------------------------------------------------------------
* TCL8::initialize()
* ----------------------------------------------------------------------------- */
void
TCL8::initialize() {
if ((!ns_name) && (nspace)) {
Printf(stderr,"Tcl error. Must specify a namespace.\n");
SWIG_exit (EXIT_FAILURE);
}
if (!init_name) {
Printf(stderr,"*** Error. No module name specified.\n");
SWIG_exit (EXIT_FAILURE);
}
Printf(f_header,"#define SWIG_init %s\n", init_name);
if (!module) module = NewString("swig");
Printf(f_header,"#define SWIG_name \"%s\"\n", module);
if (nspace) {
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_namespace \"\"\n\n");
}
Printf(f_header,"#ifdef __cplusplus\n");
Printf(f_header,"extern \"C\" {\n");
Printf(f_header,"#endif\n");
Printf(f_header,"#ifdef MAC_TCL\n");
Printf(f_header,"#pragma export on\n");
Printf(f_header,"#endif\n");
Printf(f_header,"SWIGEXPORT(int) %s(Tcl_Interp *);\n", init_name);
Printf(f_header,"#ifdef MAC_TCL\n");
Printf(f_header,"#pragma export off\n");
Printf(f_header,"#endif\n");
Printf(f_header,"#ifdef __cplusplus\n");
Printf(f_header,"}\n");
Printf(f_header,"#endif\n");
Printf(f_init,"SWIGEXPORT(int) %s(Tcl_Interp *interp) {\n", init_name);
Printf(f_init,"int i;\n");
Printf(f_init,"if (interp == 0) return TCL_ERROR;\n");
/* Check to see if we're adding support for Tcl8 nspaces */
if (nspace) {
Printf(f_init,"Tcl_Eval(interp,\"namespace eval %s { }\");\n", ns_name);
}
Printf(cmd_info, "\nstatic swig_command_info swig_commands[] = {\n");
Printf(var_info, "\nstatic swig_var_info swig_variables[] = {\n");
Printv(f_init,
"for (i = 0; swig_types_initial[i]; i++) {\n",
"swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]);\n",
"}\n", 0);
}
/* -----------------------------------------------------------------------------
* TCL8::close()
* ----------------------------------------------------------------------------- */
void
TCL8::close(void) {
Printv(cmd_info, tab4, "{0, 0, 0}\n", "};\n",0);
Printv(var_info, tab4, "{0,0,0,0}\n", "};\n",0);
Printf(f_wrappers,"%s", cmd_info);
Printf(f_wrappers,"%s", var_info);
Printf(f_init,"for (i = 0; swig_commands[i].name; i++) {\n");
Printf(f_init,"Tcl_CreateObjCommand(interp, (char *) swig_commands[i].name, swig_commands[i].wrapper, swig_commands[i].clientdata, NULL);\n");
Printf(f_init,"}\n");
Printf(f_init,"for (i = 0; swig_variables[i].name; i++) {\n");
Printf(f_init,"Tcl_SetVar(interp, (char *) swig_variables[i].name, (char *) \"\", TCL_GLOBAL_ONLY);\n");
Printf(f_init,"Tcl_TraceVar(interp, (char *) swig_variables[i].name, TCL_TRACE_READS | TCL_GLOBAL_ONLY, swig_variables[i].get, (ClientData) swig_variables[i].addr);\n");
Printf(f_init,"Tcl_TraceVar(interp, (char *) swig_variables[i].name, TCL_TRACE_WRITES | TCL_GLOBAL_ONLY, swig_variables[i].set, (ClientData) swig_variables[i].addr);\n");
Printf(f_init,"}\n");
/* Dump the pointer equivalency table */
SwigType_emit_type_table(f_runtime, f_wrappers);
/* Close the init function and quit */
Printf(f_init,"return TCL_OK;\n");
Printf(f_init,"}\n");
}
/* -----------------------------------------------------------------------------
* TCL8::create_command()
* ----------------------------------------------------------------------------- */
void
TCL8::create_command(char *cname, char *iname) {
String *wname = Swig_name_wrapper(cname);
Printv(cmd_info, tab4, "{ SWIG_prefix \"", iname, "\", ", wname, ", NULL},\n", 0);
/* Add interpreter name to repeatcmd hash table. This hash is used in C++ code
generation to try and find repeated wrapper functions. */
Setattr(repeatcmd,iname,wname);
}
/* -----------------------------------------------------------------------------
* TCL8::create_function()
* ----------------------------------------------------------------------------- */
void
TCL8::create_function(char *name, char *iname, SwigType *d, ParmList *l) {
Parm *p;
int pcount,i,j;
char *tm;
Wrapper *f;
String *incode, *cleanup, *outarg, *argstr, *args;
int numopt= 0;
incode = NewString("");
cleanup = NewString("");
outarg = NewString("");
argstr = NewString("\"");
args = NewString("");
f = NewWrapper();
Printv(f->def,
"static int\n ", Swig_name_wrapper(iname), "(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {",
0);
/* Print out variables for storing arguments. */
pcount = emit_args(d, l, f);
numopt = check_numopt(l);
/* Extract parameters. */
i = 0;
j = 0;
p = l;
while (p != 0) {
char source[64];
char target[64];
char argnum[64];
SwigType *pt = Gettype(p);
String *pn = Getname(p);
/* Produce string representations of the source and target arguments */
sprintf(source,"objv[%d]",j+1);
sprintf(target,"%s", Char(Getlname(p)));
sprintf(argnum,"%d",j+1);
/* See if this argument is being ignored */
if (!Getignore(p)) {
if (j == (pcount-numopt)) Putc('|',argstr);
if ((tm = Swig_typemap_lookup((char*)"in",pt,pn,source,target,f))) {
Putc('o',argstr);
Printf(args,",0");
Printf(incode,"%s\n", tm);
Replace(incode,"$argnum",argnum, DOH_REPLACE_ANY);
Replace(incode,"$arg",source, DOH_REPLACE_ANY);
} else {
switch(SwigType_type(pt)) {
case T_INT:
case T_UINT:
Putc('i', argstr);
Printf(args,",&%s",target);
break;
case T_BOOL:
Putc('i',argstr);
{
char tb[32];
sprintf(tb,"tempb%d",i);
Wrapper_add_localv(f,tb,"int",tb,0);
Printf(args,",&%s",tb);
Printv(incode, target, " = (bool) ", tb, ";\n", 0);
}
break;
case T_SHORT:
case T_USHORT:
Putc('h',argstr);
Printf(args,",&%s",target);
break;
case T_LONG:
case T_ULONG:
Putc('l',argstr);
Printf(args,",&%s",target);
break;
case T_SCHAR:
case T_UCHAR:
Putc('b',argstr);
Printf(args,",&%s", target);
break;
case T_FLOAT:
Putc('f',argstr);
Printf(args,",&%s", target);
break;
case T_DOUBLE:
Putc('d',argstr);
Printf(args,",&%s", target);
break;
case T_CHAR :
Putc('c',argstr);
Printf(args,",&%s",target);
break;
case T_VOID :
break;
case T_USER:
SwigType_add_pointer(pt);
SwigType_remember(pt);
Putc('p',argstr);
Printv(args, ",&", target, ", SWIGTYPE", SwigType_manglestr(pt), 0);
SwigType_del_pointer(pt);
break;
case T_STRING:
Putc('s',argstr);
Printf(args,",&%s",target);
break;
case T_POINTER: case T_ARRAY: case T_REFERENCE:
{
SwigType *lt;
SwigType_remember(pt);
Putc('p',argstr);
lt = Swig_clocal_type(pt);
if (Cmp(lt,"p.void") == 0) {
Printv(args, ",&", target, ", 0", 0);
} else {
Printv(args, ",&", target, ", SWIGTYPE", SwigType_manglestr(pt), 0);
}
Delete(lt);
break;
}
default :
Printf(stderr,"%s : Line %d: Unable to use type %s as a function argument.\n",
input_file, line_number, SwigType_str(pt,0));
break;
}
}
j++;
}
/* Check to see if there was any sort of a constaint typemap */
if ((tm = Swig_typemap_lookup((char*)"check",pt,pn,source,target,0))) {
Printf(incode,"%s\n", tm);
Replace(incode,"$argnum",argnum, DOH_REPLACE_ANY);
Replace(incode,"$arg",source, DOH_REPLACE_ANY);
}
/* Check if there was any cleanup code (save it for later) */
if ((tm = Swig_typemap_lookup((char*)"freearg",pt,pn,target,(char*)"tcl_result",0))) {
Printf(cleanup,"%s\n", tm);
Replace(cleanup,"$argnum",argnum, DOH_REPLACE_ANY);
Replace(cleanup,"$arg",source,DOH_REPLACE_ANY);
}
/* Look for output arguments */
if ((tm = Swig_typemap_lookup((char*)"argout",pt,pn,target,(char*)"tcl_result",0))) {
Printf(outarg,"%s\n", tm);
Replace(outarg,"$argnum",argnum, DOH_REPLACE_ANY);
Replace(outarg,"$arg",source, DOH_REPLACE_ANY);
}
i++;
p = Getnext(p);
}
Printf(argstr,":%s\"",usage_string(iname,d,l));
Printv(f->code,
"if (SWIG_GetArgs(interp, objc, objv,", argstr, args, ") == TCL_ERROR) return TCL_ERROR;\n",
0);
Printv(f->code,incode,0);
/* Now write code to make the function call */
emit_func_call(name,d,l,f);
/* Return value if necessary */
if ((tm = Swig_typemap_lookup((char*)"out",d,name,(char*)"result",(char*)"tcl_result",0))) {
Printf(f->code,"%s\n", tm);
} else {
switch(SwigType_type(d)) {
case T_BOOL:
case T_INT:
case T_SHORT:
case T_LONG :
case T_SCHAR:
case T_UINT:
case T_USHORT:
case T_ULONG:
case T_UCHAR:
Printv(f->code, "Tcl_SetObjResult(interp,Tcl_NewIntObj((long) result));\n",0);
break;
/* Is a single character. We return it as a string */
case T_CHAR :
Printv(f->code, "Tcl_SetObjResult(interp,Tcl_NewStringObj(&result,1));\n",0);
break;
case T_DOUBLE :
case T_FLOAT :
Printv(f->code, "Tcl_SetObjResult(interp,Tcl_NewDoubleObj((double) result));\n",0);
break;
case T_USER :
/* Okay. We're returning malloced memory at this point.
Probably dangerous, but safe programming is for wimps. */
SwigType_add_pointer(d);
SwigType_remember(d);
Printv(f->code, "Tcl_SetObjResult(interp,SWIG_NewPointerObj((void *) result,SWIGTYPE",
SwigType_manglestr(d), "));\n", 0);
SwigType_del_pointer(d);
break;
case T_STRING:
Printv(f->code, "Tcl_SetObjResult(interp,Tcl_NewStringObj(result,-1));\n",0);
break;
case T_POINTER: case T_REFERENCE: case T_ARRAY:
SwigType_remember(d);
Printv(f->code, "Tcl_SetObjResult(interp,SWIG_NewPointerObj((void *) result,SWIGTYPE",
SwigType_manglestr(d), "));\n",
0);
break;
case T_VOID:
break;
default :
Printf(stderr,"%s : Line %d: Unable to use return type %s in function %s.\n",
input_file, line_number, SwigType_str(d,0), name);
break;
}
}
/* Dump output argument code */
Printv(f->code,outarg,0);
/* Dump the argument cleanup code */
Printv(f->code,cleanup,0);
/* Look for any remaining cleanup */
if (NewObject) {
if ((tm = Swig_typemap_lookup((char*)"newfree",d,iname,(char*)"result",(char*)"",0))) {
Printf(f->code,"%s\n", tm);
}
}
if ((tm = Swig_typemap_lookup((char*)"ret",d,name,(char*)"result",(char*)"",0))) {
Printf(f->code,"%s\n", tm);
}
Printv(f->code, "return TCL_OK;\n}", 0);
/* Substitute the cleanup code */
Replace(f->code,"$cleanup",cleanup,DOH_REPLACE_ANY);
Replace(f->code,"$name", iname, DOH_REPLACE_ANY);
/* Dump out the function */
Wrapper_print(f,f_wrappers);
/* Register the function with Tcl */
Printv(cmd_info, tab4, "{ SWIG_prefix \"", iname, "\", ", Swig_name_wrapper(iname), ", NULL},\n", 0);
Delete(incode);
Delete(cleanup);
Delete(outarg);
Delete(argstr);
Delete(args);
DelWrapper(f);
}
/* -----------------------------------------------------------------------------
* TCL8::link_variable()
* ----------------------------------------------------------------------------- */
static Hash *setf = 0;
static Hash *getf = 0;
void
TCL8::link_variable(char *name, char *iname, SwigType *t) {
String *setname;
String *getname;
int isarray = 0;
int readonly = 0;
int setable = 1;
int tc;
if (!setf) setf = NewHash();
if (!getf) getf = NewHash();
/* See if there were any typemaps */
if (Swig_typemap_search((char *)"varin",t,name) || (Swig_typemap_search((char*)"varout",t,name))) {
Printf(stderr,"%s : Line %d. Warning. varin/varout typemap methods not supported.",
input_file, line_number);
}
if (Status & STAT_READONLY) readonly = 1;
isarray = SwigType_isarray(t);
tc = SwigType_type(t);
setname = Getattr(setf,t);
getname = Getattr(getf,t);
/* Dump a collection of set/get functions suitable for variable tracing */
if (!getname) {
Wrapper *get, *set;
setname = NewStringf("swig_%s_set", Swig_string_mangle(t));
getname = NewStringf("swig_%s_get", Swig_string_mangle(t));
get = NewWrapper();
set = NewWrapper();
Printv(set->def, "static char *", setname, "(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags) {",0);
Printv(get->def, "static char *", getname, "(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags) {",0);
SwigType *lt = Swig_clocal_type(t);
if ((tc != T_USER) && (!isarray))
SwigType_add_pointer(lt);
Wrapper_add_localv(get,"addr",SwigType_lstr(lt,"addr"),0);
Wrapper_add_localv(set,"addr",SwigType_lstr(lt,"addr"),0);
Printv(set->code, "addr = (", SwigType_lstr(lt,0), ") clientData;\n", 0);
Printv(get->code, "addr = (", SwigType_lstr(lt,0), ") clientData;\n", 0);
if ((tc != T_USER) && (!isarray))
SwigType_del_pointer(lt);
Delete(lt);
Wrapper_add_local(set, "value", "char *value");
Wrapper_add_local(get, "value", "Tcl_Obj *value");
Printv(set->code, "value = Tcl_GetVar2(interp, name1, name2, flags);\n",
"if (!value) return NULL;\n", 0);
switch(tc) {
case T_INT:
case T_SHORT:
case T_USHORT:
case T_LONG:
case T_UCHAR:
case T_SCHAR:
case T_BOOL:
Printv(set->code, "*(addr) = (", SwigType_str(t,0), ") atol(value);\n", 0);
Wrapper_add_local(get,"value","Tcl_Obj *value");
Printv(get->code,
"value = Tcl_NewIntObj((int) *addr);\n",
"Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n",
"Tcl_DecrRefCount(value);\n",
0);
break;
case T_UINT:
case T_ULONG:
Printv(set->code, "*(addr) = (", SwigType_str(t,0), ") strtoul(value,0,0);\n",0);
Wrapper_add_local(get,"value","Tcl_Obj *value");
Printv(get->code,
"value = Tcl_NewIntObj((int) *addr);\n",
"Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n",
"Tcl_DecrRefCount(value);\n",
0);
break;
case T_FLOAT:
case T_DOUBLE:
Printv(set->code, "*(addr) = (", SwigType_str(t,0), ") atof(value);\n",0);
Wrapper_add_local(get,"value","Tcl_Obj *value");
Printv(get->code,
"value = Tcl_NewDoubleObj((double) *addr);\n",
"Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n",
"Tcl_DecrRefCount(value);\n",
0);
break;
case T_CHAR:
Printv(set->code, "*(addr) = *value;\n",0);
Wrapper_add_local(get,"temp", "char temp[2]");
Printv(get->code, "temp[0] = *addr; temp[1] = 0;\n",
"Tcl_SetVar2(interp,name1,name2,temp,flags);\n",
0);
break;
case T_USER:
/* User defined type. We return it as a pointer */
SwigType_add_pointer(t);
SwigType_remember(t);
Printv(set->code, "{\n",
"void *ptr;\n",
"if (SWIG_ConvertPtrFromString(interp,value,&ptr,SWIGTYPE", SwigType_manglestr(t), ") != TCL_OK) {\n",
"return \"Type Error\";\n",
"}\n",
"*(addr) = *((", SwigType_lstr(t,0), ") ptr);\n",
"}\n",
0);
SwigType_del_pointer(t);
Wrapper_add_local(get,"value", "Tcl_Obj *value");
SwigType_add_pointer(t);
SwigType_remember(t);
Printv(get->code, "value = SWIG_NewPointerObj(addr, SWIGTYPE", SwigType_manglestr(t), ");\n",
"Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n",
"Tcl_DecrRefCount(value);\n",0);
SwigType_del_pointer(t);
break;
case T_STRING:
Printv(set->code, "if (*addr) free(*addr);\n",
"*addr = (char *) malloc(strlen(value)+1);\n",
"strcpy(*addr,value);\n",
0);
Printv(get->code, "Tcl_SetVar2(interp,name1,name2,*addr, flags);\n",0);
break;
case T_ARRAY:
{
SwigType *aop;
SwigType *ta = Copy(t);
aop = SwigType_pop(ta);
/* Printf(stdout,"'%s' '%s'\n", ta, aop);*/
setable = 0;
readonly = 1;
if (SwigType_type(ta) == T_CHAR) {
String *dim = SwigType_array_getdim(aop,0);
if (dim && Len(dim)) {
Printf(set->code, "strncpy(addr,value,%s);\n", dim);
setable = 1;
readonly = Status & STAT_READONLY;
}
Printv(get->code, "Tcl_SetVar2(interp,name1,name2,addr, flags);\n",0);
} else {
Printf(stderr,"%s:%d: Array variable '%s' will be read-only.\n", input_file, line_number, name);
Wrapper_add_local(get,"value","Tcl_Obj *value");
SwigType_remember(t);
Printv(get->code,
"value = SWIG_NewPointerObj(addr, SWIGTYPE", SwigType_manglestr(t), ");\n",
"Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n",
"Tcl_DecrRefCount(value);\n",
0);
}
Delete(ta);
Delete(aop);
}
break;
case T_POINTER: case T_REFERENCE:
SwigType_remember(t);
Printv(set->code, "{\n",
"void *ptr;\n",
"if (SWIG_ConvertPtrFromString(interp,value,&ptr,SWIGTYPE", SwigType_manglestr(t), ") != TCL_OK) {\n",
"return \"Type Error\";\n",
"}\n",
"*(addr) = (", SwigType_lstr(t,0), ") ptr;\n",
"}\n",
0);
Wrapper_add_local(get,"value","Tcl_Obj *value");
Printv(get->code,
"value = SWIG_NewPointerObj(*addr, SWIGTYPE", SwigType_manglestr(t), ");\n",
"Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n",
"Tcl_DecrRefCount(value);\n",
0);
break;
case T_VOID:
break;
default:
Printf(stderr,"TCL8::link_variable. Unknown type %s!\n", SwigType_str(t,0));
break;
}
Printv(set->code, "return NULL;\n", "}\n",0);
Printv(get->code, "return NULL;\n", "}\n",0);
Wrapper_print(get,f_wrappers);
Setattr(getf,Copy(t),getname);
if (setable) {
Wrapper_print(set,f_wrappers);
Setattr(setf,Copy(t),setname);
}
DelWrapper(get);
DelWrapper(set);
}
Printv(var_info, tab4,"{ SWIG_prefix \"", iname, "\", (void *) ", isarray ? "" : "&", name, ",", getname, ",", 0);
if (readonly) {
static int readonlywrap = 0;
if (!readonlywrap) {
Wrapper *ro = NewWrapper();
Printf(ro->def, "static char *swig_readonly(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags) {");
Printv(ro->code, "return \"Variable is read-only\";\n", "}\n", 0);
Wrapper_print(ro,f_wrappers);
readonlywrap = 1;
DelWrapper(ro);
}
Printf(var_info, "swig_readonly},\n");
} else {
Printv(var_info, setname, "},\n",0);
}
}
/* -----------------------------------------------------------------------------
* TCL8::declare_const()
* ----------------------------------------------------------------------------- */
void
TCL8::declare_const(char *name, char *, SwigType *type, char *value) {
int OldStatus = Status;
SwigType *t;
char var_name[256];
char *tm;
String *rvalue;
Status = STAT_READONLY;
/* Make a static variable */
sprintf(var_name,"_wrap_const_%s",name);
if (SwigType_type(type) == T_STRING) {
rvalue = NewStringf("\"%s\"",value);
} else if (SwigType_type(type) == T_CHAR) {
rvalue = NewStringf("\'%s\'",value);
} else {
rvalue = NewString(value);
}
if ((tm = Swig_typemap_lookup((char*)"const",type,name,Char(rvalue),name,0))) {
Printf(f_init,"%s\n",tm);
} else {
/* Create variable and assign it a value */
switch(SwigType_type(type)) {
case T_BOOL: case T_INT: case T_DOUBLE:
Printf(f_header,"static %s %s = %s;\n", SwigType_str(type,0), var_name, value);
link_variable(var_name,name,type);
break;
case T_SHORT:
case T_LONG:
case T_SCHAR:
Printf(f_header,"static %s %s = %s;\n", SwigType_str(type,0), var_name, value);
Printf(f_header,"static char *%s_char;\n", var_name);
if (CPlusPlus)
Printf(f_init,"\t %s_char = new char[32];\n",var_name);
else
Printf(f_init,"\t %s_char = (char *) malloc(32);\n",var_name);
Printf(f_init,"\t sprintf(%s_char,\"%%ld\", (long) %s);\n", var_name, var_name);
sprintf(var_name,"%s_char",var_name);
t = NewString("char");
SwigType_add_pointer(t);
link_variable(var_name,name,t);
Delete(t);
break;
case T_UINT:
case T_USHORT:
case T_ULONG:
case T_UCHAR:
Printf(f_header,"static %s %s = %s;\n", SwigType_str(type,0), var_name, value);
Printf(f_header,"static char *%s_char;\n", var_name);
if (CPlusPlus)
Printf(f_init,"\t %s_char = new char[32];\n",var_name);
else
Printf(f_init,"\t %s_char = (char *) malloc(32);\n",var_name);
Printf(f_init,"\t sprintf(%s_char,\"%%lu\", (unsigned long) %s);\n", var_name, var_name);
sprintf(var_name,"%s_char",var_name);
t = NewSwigType(T_CHAR);
SwigType_add_pointer(t);
link_variable(var_name,name,t);
Delete(t);
break;
case T_FLOAT:
Printf(f_header,"static %s %s = (%s) (%s);\n", SwigType_lstr(type,0), var_name, SwigType_lstr(type,0), value);
link_variable(var_name,name,type);
break;
case T_CHAR:
SwigType_add_pointer(type);
Printf(f_header,"static %s %s = \"%s\";\n", SwigType_lstr(type,0), var_name, value);
link_variable(var_name,name,type);
SwigType_del_pointer(type);
break;
case T_STRING:
Printf(f_header,"static %s %s = \"%s\";\n", SwigType_lstr(type,0), var_name, value);
link_variable(var_name,name,type);
break;
case T_POINTER: case T_ARRAY: case T_REFERENCE:
Printf(f_header,"static %s = %s;\n", SwigType_lstr(type,var_name), value);
Printf(f_header,"static char *%s_char;\n", var_name);
if (CPlusPlus)
Printf(f_init,"\t %s_char = new char[%d];\n",var_name,(int) Len(SwigType_manglestr(type))+ 20);
else
Printf(f_init,"\t %s_char = (char *) malloc(%d);\n",var_name, (int) Len(SwigType_manglestr(type))+ 20);
t = NewSwigType(T_CHAR);
SwigType_add_pointer(t);
SwigType_remember(type);
Printf(f_init,"\t SWIG_MakePtr(%s_char, (void *) %s, SWIGTYPE%s);\n",
var_name, var_name, SwigType_manglestr(type));
sprintf(var_name,"%s_char",var_name);
link_variable(var_name,name,t);
Delete(t);
break;
default:
Printf(stderr,"%s : Line %d. Unsupported constant value.\n", input_file, line_number);
break;
}
}
Delete(rvalue);
Status = OldStatus;
}
/* -----------------------------------------------------------------------------
* TCL8::usage_string()
* ----------------------------------------------------------------------------- */
char *
TCL8::usage_string(char *iname, SwigType *, ParmList *l) {
static String *temp = 0;
Parm *p;
int i, numopt,pcount;
if (!temp) temp = NewString("");
Clear(temp);
if (nspace) {
Printf(temp,"%s::%s", ns_name,iname);
} else {
Printf(temp,"%s ", iname);
}
/* Now go through and print parameters */
i = 0;
pcount = ParmList_len(l);
numopt = check_numopt(l);
for (p = l; p; p = Getnext(p)) {
SwigType *pt = Gettype(p);
String *pn = Getname(p);
/* Only print an argument if not ignored */
if (!Swig_typemap_search((char*)"ignore",pt,pn)) {
if (i >= (pcount-numopt))
Putc('?',temp);
/* If parameter has been named, use that. Otherwise, just print a type */
if (SwigType_type(pt) != T_VOID) {
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);
}
/* -----------------------------------------------------------------------------
* TCL8::add_native()
* ----------------------------------------------------------------------------- */
void
TCL8::add_native(char *name, char *funcname, SwigType *, ParmList *) {
Printf(f_init,"\t Tcl_CreateObjCommand(interp, SWIG_prefix \"%s\", %s, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);\n",name, funcname);
}
/* -----------------------------------------------------------------------------
* C++ Handling
* ----------------------------------------------------------------------------- */
void
TCL8::cpp_open_class(char *classname, char *rename, char *ctype, int strip) {
this->Language::cpp_open_class(classname,rename,ctype,strip);
if (shadow) {
static int included_object = 0;
if (!included_object) {
if (Swig_insert_file("object.swg",f_header) == -1) {
Printf(stderr,"SWIG : Fatal error. Unable to locate 'object.swg' in SWIG library.\n");
SWIG_exit (EXIT_FAILURE);
}
included_object = 1;
}
Clear(attributes);
Printf(attributes, "static swig_attribute swig_");
Printv(attributes, classname, "_attributes[] = {\n", 0);
Clear(methods);
Printf(methods,"static swig_method swig_");
Printv(methods, classname, "_methods[] = {\n", 0);
have_constructor = 0;
have_destructor = 0;
Delete(class_name);
Delete(class_type);
Delete(real_classname);
class_name = rename ? NewString(rename) : NewString(classname);
class_type = strip ? NewString("") : NewStringf("%s ",ctype);
real_classname = NewString(classname);
}
}
void
TCL8::cpp_close_class() {
SwigType *t;
String *code = NewString("");
this->Language::cpp_close_class();
if (shadow) {
t = NewStringf("%s%s", class_type, real_classname);
SwigType_add_pointer(t);
if (have_destructor) {
Printv(code, "static void swig_delete_", class_name, "(void *obj) {\n", 0);
if (CPlusPlus) {
Printv(code," delete (", SwigType_str(t,0), ") obj;\n",0);
} else {
Printv(code," free((char *) obj);\n",0);
}
Printf(code,"}\n");
}
Printf(methods, " {0,0}\n};\n");
Printv(code,methods,0);
Printf(attributes, " {0,0,0}\n};\n");
Printv(code,attributes,0);
Printv(code, "static swig_class _wrap_class_", class_name, " = { \"", class_name,
"\", &SWIGTYPE", SwigType_manglestr(t), ",",0);
if (have_constructor) {
Printf(code, "%s", Swig_name_wrapper(Swig_name_construct(class_name)));
} else {
Printf(code,"0");
}
if (have_destructor) {
Printv(code, ", swig_delete_", class_name,0);
} else {
Printf(code,",0");
}
Printv(code, ", swig_", real_classname, "_methods, swig_", real_classname, "_attributes };\n", 0);
Printf(f_wrappers,"%s",code);
Printv(cmd_info, tab4, "{ SWIG_prefix \"", class_name, "\", SwigObjectCmd, &_wrap_class_", class_name, "},\n", 0);
}
Delete(code);
}
void TCL8::cpp_member_func(char *name, char *iname, SwigType *t, ParmList *l) {
char *realname;
char temp[1024];
String *rname;
this->Language::cpp_member_func(name,iname,t,l);
if (shadow && !is_multiple_definition()) {
realname = iname ? iname : name;
/* Add stubs for this member to our class handler function */
strcpy(temp, Char(Swig_name_member(class_name,realname)));
rname = Getattr(repeatcmd,temp);
if (!rname) rname = Swig_name_wrapper(temp);
Printv(methods, tab4, "{\"", realname, "\", ", rname, "}, \n", 0);
}
}
void TCL8::cpp_variable(char *name, char *iname, SwigType *t) {
char *realname;
char temp[1024];
String *rname;
this->Language::cpp_variable(name, iname, t);
if (shadow && !is_multiple_definition()) {
realname = iname ? iname : name;
Printv(attributes, tab4, "{ \"-", realname, "\",", 0);
/* Try to figure out if there is a wrapper for this function */
strcpy(temp, Char(Swig_name_get(Swig_name_member(class_name,realname))));
rname = Getattr(repeatcmd,temp);
if (!rname) rname = Swig_name_wrapper(temp);
Printv(attributes, rname, ", ", 0);
if (!(Status & STAT_READONLY)) {
strcpy(temp, Char(Swig_name_set(Swig_name_member(class_name,realname))));
rname = Getattr(repeatcmd,temp);
if (!rname) rname = Swig_name_wrapper(temp);
Printv(attributes, rname, "},\n",0);
} else {
Printf(attributes, "0 },\n");
}
}
}
void
TCL8::cpp_constructor(char *name, char *iname, ParmList *l) {
this->Language::cpp_constructor(name,iname,l);
have_constructor = 1;
}
void
TCL8::cpp_destructor(char *name, char *newname) {
this->Language::cpp_destructor(name,newname);
have_destructor = 1;
}