00001 /* 00002 * ------------------------------------------------------------------------ 00003 * PACKAGE: [incr Tcl] 00004 * DESCRIPTION: Object-Oriented Extensions to Tcl 00005 * 00006 * [incr Tcl] provides object-oriented extensions to Tcl, much as 00007 * C++ provides object-oriented extensions to C. It provides a means 00008 * of encapsulating related procedures together with their shared data 00009 * in a local namespace that is hidden from the outside world. It 00010 * promotes code re-use through inheritance. More than anything else, 00011 * it encourages better organization of Tcl applications through the 00012 * object-oriented paradigm, leading to code that is easier to 00013 * understand and maintain. 00014 * 00015 * ADDING [incr Tcl] TO A Tcl-BASED APPLICATION: 00016 * 00017 * To add [incr Tcl] facilities to a Tcl application, modify the 00018 * Tcl_AppInit() routine as follows: 00019 * 00020 * 1) Include this header file near the top of the file containing 00021 * Tcl_AppInit(): 00022 * 00023 * #include "itcl.h" 00024 * 00025 * 2) Within the body of Tcl_AppInit(), add the following lines: 00026 * 00027 * if (Itcl_Init(interp) == TCL_ERROR) { 00028 * return TCL_ERROR; 00029 * } 00030 * 00031 * 3) Link your application with libitcl.a 00032 * 00033 * NOTE: An example file "tclAppInit.c" containing the changes shown 00034 * above is included in this distribution. 00035 * 00036 * ======================================================================== 00037 * AUTHOR: Michael J. McLennan 00038 * Bell Labs Innovations for Lucent Technologies 00039 * mmclennan@lucent.com 00040 * http://www.tcltk.com/itcl 00041 * 00042 * RCS: $Id: itclInt.h,v 14.1 2004/11/16 19:42:10 morrison Exp $ 00043 * ======================================================================== 00044 * Copyright (c) 1993-1998 Lucent Technologies, Inc. 00045 * ------------------------------------------------------------------------ 00046 * See the file "license.terms" for information on usage and redistribution 00047 * of this file, and for a DISCLAIMER OF ALL WARRANTIES. 00048 */ 00049 #ifndef ITCLINT_H 00050 #define ITCLINT_H 00051 00052 #include "tclInt.h" 00053 #include "itcl.h" 00054 00055 #ifdef BUILD_itcl 00056 # undef TCL_STORAGE_CLASS 00057 # define TCL_STORAGE_CLASS DLLEXPORT 00058 #endif 00059 00060 /* 00061 * Fix Tcl bug #803489 the right way. We need to always use the old Stub 00062 * slot positions, not the new broken ones part of TIP 127. I do like 00063 * that these functions have moved to the public space (about time), but 00064 * the slot change is the killer and is the painful side affect. 00065 */ 00066 00067 #if defined(USE_TCL_STUBS) && \ 00068 (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 5) 00069 # undef Tcl_CreateNamespace 00070 # define Tcl_CreateNamespace \ 00071 (tclIntStubsPtr->tcl_CreateNamespace) 00072 # undef Tcl_DeleteNamespace 00073 # define Tcl_DeleteNamespace \ 00074 (tclIntStubsPtr->tcl_DeleteNamespace) 00075 # undef Tcl_AppendExportList 00076 # define Tcl_AppendExportList \ 00077 (tclIntStubsPtr->tcl_AppendExportList) 00078 # undef Tcl_Export 00079 # define Tcl_Export \ 00080 (tclIntStubsPtr->tcl_Export) 00081 # undef Tcl_Import 00082 # define Tcl_Import \ 00083 (tclIntStubsPtr->tcl_Import) 00084 # undef Tcl_ForgetImport 00085 # define Tcl_ForgetImport \ 00086 (tclIntStubsPtr->tcl_ForgetImport) 00087 # undef Tcl_GetCurrentNamespace 00088 # define Tcl_GetCurrentNamespace \ 00089 (tclIntStubsPtr->tcl_GetCurrentNamespace) 00090 # undef Tcl_GetGlobalNamespace 00091 # define Tcl_GetGlobalNamespace \ 00092 (tclIntStubsPtr->tcl_GetGlobalNamespace) 00093 # undef Tcl_FindNamespace 00094 # define Tcl_FindNamespace \ 00095 (tclIntStubsPtr->tcl_FindNamespace) 00096 # undef Tcl_FindCommand 00097 # define Tcl_FindCommand \ 00098 (tclIntStubsPtr->tcl_FindCommand) 00099 # undef Tcl_GetCommandFromObj 00100 # define Tcl_GetCommandFromObj \ 00101 (tclIntStubsPtr->tcl_GetCommandFromObj) 00102 # undef Tcl_GetCommandFullName 00103 # define Tcl_GetCommandFullName \ 00104 (tclIntStubsPtr->tcl_GetCommandFullName) 00105 #endif 00106 00107 /* 00108 * Some backward compatability adjustments. 00109 */ 00110 00111 #if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 00112 # define Tcl_GetString(obj) Tcl_GetStringFromObj((obj), NULL) 00113 # define TCL_DECLARE_MUTEX(mutexVar) 00114 # define Tcl_MutexLock(mutexVar) 00115 # define Tcl_MutexUnlock(mutexVar) 00116 # define Tcl_Panic panic 00117 #endif 00118 00119 #define TCL_DOES_STUBS \ 00120 (TCL_MAJOR_VERSION > 8 || TCL_MAJOR_VERSION == 8 && (TCL_MINOR_VERSION > 1 || \ 00121 (TCL_MINOR_VERSION == 1 && TCL_RELEASE_LEVEL == TCL_FINAL_RELEASE))) 00122 00123 00124 /* 00125 * Common info for managing all known objects. 00126 * Each interpreter has one of these data structures stored as 00127 * clientData in the "itcl" namespace. It is also accessible 00128 * as associated data via the key ITCL_INTERP_DATA. 00129 */ 00130 struct ItclObject; 00131 typedef struct ItclObjectInfo { 00132 Tcl_Interp *interp; /* interpreter that manages this info */ 00133 Tcl_HashTable objects; /* list of all known objects */ 00134 00135 Itcl_Stack transparentFrames; /* stack of call frames that should be 00136 * treated transparently. When 00137 * Itcl_EvalMemberCode is invoked in 00138 * one of these contexts, it does an 00139 * "uplevel" to get past the transparent 00140 * frame and back to the calling context. */ 00141 Tcl_HashTable contextFrames; /* object contexts for active call frames */ 00142 00143 int protection; /* protection level currently in effect */ 00144 00145 Itcl_Stack cdefnStack; /* stack of class definitions currently 00146 * being parsed */ 00147 } ItclObjectInfo; 00148 00149 #define ITCL_INTERP_DATA "itcl_data" 00150 00151 /* 00152 * Representation for each [incr Tcl] class. 00153 */ 00154 typedef struct ItclClass { 00155 char *name; /* class name */ 00156 char *fullname; /* fully qualified class name */ 00157 Tcl_Interp *interp; /* interpreter that manages this info */ 00158 Tcl_Namespace *namesp; /* namespace representing class scope */ 00159 Tcl_Command accessCmd; /* access command for creating instances */ 00160 00161 struct ItclObjectInfo *info; /* info about all known objects */ 00162 Itcl_List bases; /* list of base classes */ 00163 Itcl_List derived; /* list of all derived classes */ 00164 Tcl_HashTable heritage; /* table of all base classes. Look up 00165 * by pointer to class definition. This 00166 * provides fast lookup for inheritance 00167 * tests. */ 00168 Tcl_Obj *initCode; /* initialization code for new objs */ 00169 Tcl_HashTable variables; /* definitions for all data members 00170 in this class. Look up simple string 00171 names and get back ItclVarDefn* ptrs */ 00172 Tcl_HashTable functions; /* definitions for all member functions 00173 in this class. Look up simple string 00174 names and get back ItclMemberFunc* ptrs */ 00175 int numInstanceVars; /* number of instance vars in variables 00176 table */ 00177 Tcl_HashTable resolveVars; /* all possible names for variables in 00178 * this class (e.g., x, foo::x, etc.) */ 00179 Tcl_HashTable resolveCmds; /* all possible names for functions in 00180 * this class (e.g., x, foo::x, etc.) */ 00181 int unique; /* unique number for #auto generation */ 00182 int flags; /* maintains class status */ 00183 } ItclClass; 00184 00185 typedef struct ItclHierIter { 00186 ItclClass *current; /* current position in hierarchy */ 00187 Itcl_Stack stack; /* stack used for traversal */ 00188 } ItclHierIter; 00189 00190 /* 00191 * Representation for each [incr Tcl] object. 00192 */ 00193 typedef struct ItclObject { 00194 ItclClass *classDefn; /* most-specific class */ 00195 Tcl_Command accessCmd; /* object access command */ 00196 00197 int dataSize; /* number of elements in data array */ 00198 Var** data; /* all object-specific data members */ 00199 Tcl_HashTable* constructed; /* temp storage used during construction */ 00200 Tcl_HashTable* destructed; /* temp storage used during destruction */ 00201 } ItclObject; 00202 00203 #define ITCL_IGNORE_ERRS 0x002 /* useful for construction/destruction */ 00204 00205 /* 00206 * Implementation for any code body in an [incr Tcl] class. 00207 */ 00208 typedef struct ItclMemberCode { 00209 int flags; /* flags describing implementation */ 00210 CompiledLocal *arglist; /* list of arg names and initial values */ 00211 int argcount; /* number of args in arglist */ 00212 Proc *procPtr; /* Tcl proc representation (needed to 00213 * handle compiled locals) */ 00214 union { 00215 Tcl_CmdProc *argCmd; /* (argc,argv) C implementation */ 00216 Tcl_ObjCmdProc *objCmd; /* (objc,objv) C implementation */ 00217 } cfunc; 00218 00219 ClientData clientData; /* client data for C implementations */ 00220 00221 } ItclMemberCode; 00222 00223 /* 00224 * Basic representation for class members (commands/variables) 00225 */ 00226 typedef struct ItclMember { 00227 Tcl_Interp* interp; /* interpreter containing the class */ 00228 ItclClass* classDefn; /* class containing this member */ 00229 char* name; /* member name */ 00230 char* fullname; /* member name with "class::" qualifier */ 00231 int protection; /* protection level */ 00232 int flags; /* flags describing member (see below) */ 00233 ItclMemberCode *code; /* code associated with member */ 00234 } ItclMember; 00235 00236 /* 00237 * Flag bits for ItclMemberCode and ItclMember: 00238 */ 00239 #define ITCL_IMPLEMENT_NONE 0x001 /* no implementation */ 00240 #define ITCL_IMPLEMENT_TCL 0x002 /* Tcl implementation */ 00241 #define ITCL_IMPLEMENT_ARGCMD 0x004 /* (argc,argv) C implementation */ 00242 #define ITCL_IMPLEMENT_OBJCMD 0x008 /* (objc,objv) C implementation */ 00243 #define ITCL_IMPLEMENT_C 0x00c /* either kind of C implementation */ 00244 #define ITCL_CONSTRUCTOR 0x010 /* non-zero => is a constructor */ 00245 #define ITCL_DESTRUCTOR 0x020 /* non-zero => is a destructor */ 00246 #define ITCL_COMMON 0x040 /* non-zero => is a "proc" */ 00247 #define ITCL_ARG_SPEC 0x080 /* non-zero => has an argument spec */ 00248 00249 #define ITCL_OLD_STYLE 0x100 /* non-zero => old-style method 00250 * (process "config" argument) */ 00251 00252 #define ITCL_THIS_VAR 0x200 /* non-zero => built-in "this" variable */ 00253 00254 /* 00255 * Representation of member functions in an [incr Tcl] class. 00256 */ 00257 typedef struct ItclMemberFunc { 00258 ItclMember *member; /* basic member info */ 00259 Tcl_Command accessCmd; /* Tcl command installed for this function */ 00260 CompiledLocal *arglist; /* list of arg names and initial values */ 00261 int argcount; /* number of args in arglist */ 00262 } ItclMemberFunc; 00263 00264 /* 00265 * Instance variables. 00266 */ 00267 typedef struct ItclVarDefn { 00268 ItclMember *member; /* basic member info */ 00269 char* init; /* initial value */ 00270 } ItclVarDefn; 00271 00272 /* 00273 * Instance variable lookup entry. 00274 */ 00275 typedef struct ItclVarLookup { 00276 ItclVarDefn* vdefn; /* variable definition */ 00277 int usage; /* number of uses for this record */ 00278 int accessible; /* non-zero => accessible from class with 00279 * this lookup record in its resolveVars */ 00280 char *leastQualName; /* simplist name for this variable, with 00281 * the fewest qualifiers. This string is 00282 * taken from the resolveVars table, so 00283 * it shouldn't be freed. */ 00284 union { 00285 int index; /* index into virtual table (instance data) */ 00286 Tcl_Var common; /* variable (common data) */ 00287 } var; 00288 } ItclVarLookup; 00289 00290 /* 00291 * Representation for the context in which a body of [incr Tcl] 00292 * code executes. In ordinary Tcl, this is a CallFrame. But for 00293 * [incr Tcl] code bodies, we must be careful to set up the 00294 * CallFrame properly, to plug in instance variables before 00295 * executing the code body. 00296 */ 00297 typedef struct ItclContext { 00298 ItclClass *classDefn; /* class definition */ 00299 CallFrame frame; /* call frame for object context */ 00300 Var *compiledLocals; /* points to storage for compiled locals */ 00301 Var localStorage[20]; /* default storage for compiled locals */ 00302 } ItclContext; 00303 00304 /* 00305 * Compatibility flags. Used to support small "hacks". These are stored 00306 * in the global variable named itclCompatFlags. 00307 */ 00308 #define ITCL_COMPAT_USECMDFLAGS 0x0001 /* Tcl8.4a1 introduced a different Command 00309 * structure, and we need to adapt 00310 * dynamically */ 00311 00312 #include "itclIntDecls.h" 00313 00314 /* 00315 * Since the Tcl/Tk distribution doesn't perform any asserts, 00316 * dynamic loading can fail to find the __assert function. 00317 * As a workaround, we'll include our own. 00318 */ 00319 00320 #undef assert 00321 #ifndef DEBUG 00322 #define assert(EX) ((void)0) 00323 #else 00324 #define assert(EX) (void)((EX) || (Itcl_Assert(STRINGIFY(EX), __FILE__, __LINE__), 0)) 00325 #endif /* DEBUG */ 00326 00327 #undef TCL_STORAGE_CLASS 00328 #define TCL_STORAGE_CLASS DLLIMPORT 00329 00330 #endif /* ITCLINT_H */ 00331 00332 /* 00333 * Local Variables: 00334 * mode: C 00335 * tab-width: 8 00336 * c-basic-offset: 4 00337 * indent-tabs-mode: t 00338 * End: 00339 * ex: shiftwidth=4 tabstop=8 00340 */