1 /* 2 * Next Scripting Framework 3 * 4 * Copyright (C) 1999-2017 Gustaf Neumann (a) (b) 5 * Copyright (C) 1999-2007 Uwe Zdun (a) (b) 6 * Copyright (C) 2007-2008 Martin Matuska (b) 7 * Copyright (C) 2010-2017 Stefan Sobernig (b) 8 * 9 * (a) University of Essen 10 * Specification of Software Systems 11 * Altendorferstrasse 97-101 12 * D-45143 Essen, Germany 13 * 14 * (b) Vienna University of Economics and Business 15 * Institute of Information Systems and New Media 16 * A-1090, Augasse 2-6 17 * Vienna, Austria 18 * 19 * Permission is hereby granted, free of charge, to any person obtaining a 20 * copy of this software and associated documentation files (the "Software"), 21 * to deal in the Software without restriction, including without limitation 22 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 23 * and/or sell copies of the Software, and to permit persons to whom the 24 * Software is furnished to do so, subject to the following conditions: 25 * 26 * The above copyright notice and this permission notice shall be included in 27 * all copies or substantial portions of the Software. 28 * 29 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 34 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 35 * DEALINGS IN THE SOFTWARE. 36 * */ 37 38 #ifndef _nsf_h_ 39 #define _nsf_h_ 40 41 #include "tcl.h" 42 43 #undef TCL_STORAGE_CLASS 44 #ifdef BUILD_nsf 45 # define TCL_STORAGE_CLASS DLLEXPORT 46 #else 47 # ifdef USE_NSF_STUBS 48 # define TCL_STORAGE_CLASS 49 # else 50 # define TCL_STORAGE_CLASS DLLIMPORT 51 # endif 52 #endif 53 54 /* 55 * prevent old TCL-versions 56 */ 57 58 #if TCL_MAJOR_VERSION < 8 59 # error Tcl distribution is TOO OLD, we require at least tcl8.5 60 #endif 61 62 #if TCL_MAJOR_VERSION==8 && TCL_MINOR_VERSION<5 63 # error Tcl distribution is TOO OLD, we require at least tcl8.5 64 #endif 65 66 #if TCL_MAJOR_VERSION==8 && TCL_MINOR_VERSION<6 67 # define PRE86 68 #endif 69 70 #if defined(PRE86) 71 # define CONST86 72 # define Tcl_GetErrorLine(interp) (interp)->errorLine 73 #else 74 # define NRE 75 #endif 76 77 /* 78 * Feature activation/deactivation 79 */ 80 81 /* 82 * The following features are controlled via 83 * configure flags 84 * 85 * --with-dtrace 86 * --enable-development 87 * --enable-profile 88 * --enable-memcount=yes|trace 89 * --enable-assertions 90 * 91 * Are we developing? 92 * 93 #define NSF_DEVELOPMENT 1 94 * 95 * Activate/deactivate profiling information 96 * 97 #define NSF_PROFILE 1 98 * 99 * Compile with dtrace support 100 * 101 #define NSF_DTRACE 1 102 * 103 * Scripting level assertions 104 * 105 #define NSF_WITH_ASSERTIONS 1 106 * 107 * Activate/deactivate memory tracing 108 * 109 #define NSF_MEM_TRACE 1 110 #define NSF_MEM_COUNT 1 111 * 112 * Activate/deactivate valgrind support 113 * 114 #define NSF_VALGRIND 1 115 */ 116 117 /* Activate bytecode support 118 #define NSF_BYTECODE 119 */ 120 121 /* Activate/deactivate C-level assert() 122 Activated automatically when 123 NSF_DEVELOPMENT is set 124 #define NDEBUG 1 125 */ 126 127 /* Experimental language feature 128 #define NSF_WITH_INHERIT_NAMESPACES 1 129 #define NSF_WITH_TCL_OBJ_TYPES_AS_CONVERTER 1 130 */ 131 132 #define NSF_WITH_OS_RESOLVER 1 133 #define NSF_WITH_VALUE_WARNINGS 1 134 135 /* turn tracing output on/off 136 #define NSFOBJ_TRACE 1 137 #define NAMESPACE_TRACE 1 138 #define OBJDELETION_TRACE 1 139 #define STACK_TRACE 1 140 #define PARSE_TRACE 1 141 #define PARSE_TRACE_FULL 1 142 #define CONFIGURE_ARGS_TRACE 1 143 #define TCL_STACK_ALLOC_TRACE 1 144 #define VAR_RESOLVER_TRACE 1 145 #define CMD_RESOLVER_TRACE 1 146 #define NRE_CALLBACK_TRACE 1 147 #define METHOD_OBJECT_TRACE 1 148 #define NSF_LINEARIZER_TRACE 1 149 #define NSF_STACKCHECK 1 150 #define NSF_CLASSLIST_PRINT 1 151 #define NSF_PRINT_OBJV 1 152 */ 153 154 #define PER_OBJECT_PARAMETER_CACHING 1 155 156 /* 157 * Sanity checks and dependencies for optional compile flags 158 */ 159 #if defined(PARSE_TRACE_FULL) 160 # define PARSE_TRACE 1 161 #endif 162 163 #ifdef NSF_MEM_COUNT 164 # define DO_FULL_CLEANUP 1 165 #endif 166 167 #ifdef AOL_SERVER 168 # ifndef TCL_THREADS 169 # define TCL_THREADS 170 # endif 171 #endif 172 173 #ifdef TCL_THREADS 174 # define DO_CLEANUP 175 #endif 176 177 #ifdef DO_FULL_CLEANUP 178 # define DO_CLEANUP 179 #endif 180 181 #ifdef NSF_LINEARIZER_TRACE 182 # if !defined(NSF_CLASSLIST_PRINT) 183 # define NSF_CLASSLIST_PRINT 1 184 # endif 185 #endif 186 187 #ifdef NSF_DTRACE 188 # define NSF_DTRACE_METHOD_RETURN_PROBE(cscPtr,retCode) \ 189 if (cscPtr->cmdPtr && NSF_DTRACE_METHOD_RETURN_ENABLED()) { \ 190 NSF_DTRACE_METHOD_RETURN(ObjectName((cscPtr)->self), \ 191 (cscPtr)->cl ? ClassName((cscPtr)->cl) : ObjectName((cscPtr)->self), \ 192 (char *)(cscPtr)->methodName, \ 193 (retCode)); \ 194 } 195 #else 196 # define NSF_DTRACE_METHOD_RETURN_PROBE(cscPtr,retCode) {} 197 #endif 198 199 #if defined(NSF_DEVELOPMENT_FULL) && !defined(NSF_DEVELOPMENT) 200 # define NSF_DEVELOPMENT 1 201 #endif 202 203 #ifdef NSF_DEVELOPMENT 204 /* 205 * The activation counts checking is best performed via the MEM_COUNT 206 * macros. In case, the MEM_COUNT macros indicate a problem, setting 207 * CHECK_ACTIVATION_COUNTS might help to locate the problem more 208 * precisely. The CHECK_ACTIVATION_COUNTS tester might however still 209 * report false positives. 210 */ 211 /*# define CHECK_ACTIVATION_COUNTS 1*/ 212 # define NsfCleanupObject(object,string) \ 213 /*fprintf(stderr, "NsfCleanupObject %p %s\n",object,string);*/ \ 214 NsfCleanupObject_((object)) 215 # define CscFinish(interp,cscPtr,retCode,string) \ 216 /*fprintf(stderr, "CscFinish %p %s\n",cscPtr,string); */ \ 217 NSF_DTRACE_METHOD_RETURN_PROBE((cscPtr),(retCode)); \ 218 CscFinish_((interp), (cscPtr)) 219 #else 220 # define NDEBUG 1 221 # define NsfCleanupObject(object,string) \ 222 NsfCleanupObject_((object)) 223 # define CscFinish(interp,cscPtr,retCode,string) \ 224 NSF_DTRACE_METHOD_RETURN_PROBE(cscPtr,retCode); \ 225 CscFinish_((interp), (cscPtr)) 226 #endif 227 228 #if defined(NSF_MEM_TRACE) && !defined(NSF_MEM_COUNT) 229 # define NSF_MEM_COUNT 1 230 #endif 231 232 /* if ((cmd) != NULL) {fprintf(stderr, "METHOD %s cmd %p flags %.8x (%.8x)\n", (method), (cmd), Tcl_Command_flags((cmd)), NSF_CMD_DEPRECATED_METHOD);} */ 233 #if defined(NSF_PROFILE) 234 # define CscInit(cscPtr, object, cl, cmd, frametype, flags, method) \ 235 CscInit_((cscPtr), (object), (cl), (cmd), (frametype), (flags)); (cscPtr)->methodName = (method); \ 236 NsfProfileTraceCall((interp), (object), (cl), (method)); 237 #else 238 # if defined(NSF_DTRACE) 239 # define CscInit(cscPtr, object, cl, cmd, frametype, flags, method) \ 240 CscInit_((cscPtr), (object), (cl), (cmd), (frametype), (flags)); (cscPtr)->methodName = (method); 241 # else 242 # define CscInit(cscPtr, object, cl, cmd, frametype, flags, methodName) \ 243 CscInit_((cscPtr), (object), (cl), (cmd), (frametype), (flags)) 244 # endif 245 #endif 246 247 #if !defined(CHECK_ACTIVATION_COUNTS) 248 # define CscListAdd(interp, cscPtr) 249 # define CscListRemove(interp, cscPtr, cscListPtr) 250 #endif 251 252 #if defined(TCL_THREADS) 253 # define NsfMutex Tcl_Mutex 254 # define NsfMutexLock(a) Tcl_MutexLock((a)) 255 # define NsfMutexUnlock(a) Tcl_MutexUnlock((a)) 256 #else 257 # define NsfMutex int 258 # define NsfMutexLock(a) (*(a))++ 259 # define NsfMutexUnlock(a) (*(a))-- 260 #endif 261 262 /* 263 * A special definition used to allow this header file to be included 264 * in resource files so that they can get obtain version information from 265 * this file. Resource compilers don't like all the C stuff, like typedefs 266 * and procedure declarations, that occur below. 267 */ 268 269 #ifndef RC_INVOKED 270 271 /* 272 * The structures Nsf_Object and Nsf_Class define mostly opaque 273 * data structures for the internal use structures NsfObject and 274 * NsfClass (both defined in NsfInt.h). Modification of elements 275 * visible elements must be mirrored in both incarnations. 276 * 277 * Warning: These structures are just containing a few public 278 * fields. These structures must not be used for querying the size or 279 * allocating the data structures. 280 */ 281 282 typedef struct Nsf_Object { 283 Tcl_Obj *cmdName; 284 } Nsf_Object; 285 286 typedef struct Nsf_Class { 287 struct Nsf_Object object; 288 } Nsf_Class; 289 290 typedef struct Nsf_ParseContext { 291 ClientData *clientData; 292 int status; 293 } Nsf_ParseContext; 294 295 296 struct Nsf_Param; 297 typedef int (Nsf_TypeConverter)(Tcl_Interp *interp, 298 Tcl_Obj *obj, 299 struct Nsf_Param const *pPtr, 300 ClientData *clientData, 301 Tcl_Obj **outObjPtr); 302 303 typedef struct { 304 Nsf_TypeConverter *converter; 305 const char *domain; 306 } Nsf_EnumeratorConverterEntry; 307 308 EXTERN Nsf_TypeConverter Nsf_ConvertToBoolean, Nsf_ConvertToClass, 309 Nsf_ConvertToInteger, Nsf_ConvertToInt32, 310 Nsf_ConvertToObject, Nsf_ConvertToParameter, 311 Nsf_ConvertToString, Nsf_ConvertToSwitch, 312 Nsf_ConvertToTclobj, Nsf_ConvertToPointer; 313 314 typedef struct Nsf_Param { 315 const char *name; 316 unsigned int flags; 317 int nrArgs; 318 Nsf_TypeConverter *converter; 319 Tcl_Obj *converterArg; 320 Tcl_Obj *defaultValue; 321 const char *type; 322 Tcl_Obj *nameObj; 323 Tcl_Obj *converterName; 324 Tcl_Obj *paramObj; 325 Tcl_Obj *slotObj; 326 Tcl_Obj *method; 327 } Nsf_Param; 328 329 /* Argument parse processing flags */ 330 #define NSF_ARGPARSE_CHECK 0x0001 331 #define NSF_ARGPARSE_FORCE_REQUIRED 0x0002 332 #define NSF_ARGPARSE_BUILTIN (NSF_ARGPARSE_CHECK|NSF_ARGPARSE_FORCE_REQUIRED) 333 #define NSF_ARGPARSE_START_ZERO 0x0010 334 /* Special flags for process method arguments */ 335 #define NSF_ARGPARSE_METHOD_PUSH 0x0100 336 337 338 /* flags for NsfParams */ 339 340 #define NSF_ARG_REQUIRED 0x00000001u 341 #define NSF_ARG_MULTIVALUED 0x00000002u 342 #define NSF_ARG_NOARG 0x00000004u 343 #define NSF_ARG_NOCONFIG 0x00000008u 344 #define NSF_ARG_CURRENTLY_UNKNOWN 0x00000010u 345 #define NSF_ARG_SUBST_DEFAULT 0x00000020u 346 #define NSF_ARG_ALLOW_EMPTY 0x00000040u 347 #define NSF_ARG_INITCMD 0x00000080u 348 #define NSF_ARG_CMD 0x00000100u 349 #define NSF_ARG_ALIAS 0x00000200u 350 #define NSF_ARG_FORWARD 0x00000400u 351 #define NSF_ARG_SWITCH 0x00000800u 352 #define NSF_ARG_BASECLASS 0x00001000u 353 #define NSF_ARG_METACLASS 0x00002000u 354 #define NSF_ARG_HAS_DEFAULT 0x00004000u 355 #define NSF_ARG_IS_CONVERTER 0x00008000u 356 #define NSF_ARG_IS_ENUMERATION 0x00010000u 357 #define NSF_ARG_CHECK_NONPOS 0x00020000u 358 #define NSF_ARG_SET 0x00040000u 359 #define NSF_ARG_WARN 0x00080000u 360 #define NSF_ARG_UNNAMED 0x00100000u 361 #define NSF_ARG_IS_RETURNVALUE 0x00200000u 362 #define NSF_ARG_NODASHALNUM 0x00400000u 363 #define NSF_ARG_SLOTSET 0x00800000u 364 #define NSF_ARG_SLOTINITIALIZE 0x01000000u 365 #define NSF_ARG_SUBST_DEFAULT_COMMANDS 0x10000000u 366 #define NSF_ARG_SUBST_DEFAULT_VARIABLES 0x20000000u 367 #define NSF_ARG_SUBST_DEFAULT_BACKSLASHES 0x40000000u 368 #define NSF_ARG_SUBST_DEFAULT_ALL 0x70000000u 369 370 #undef __GNUC_PREREQ 371 #if defined __GNUC__ && defined __GNUC_MINOR__ 372 # define __GNUC_PREREQ(maj, min) \ 373 ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) 374 #else 375 # define __GNUC_PREREQ(maj, min) (0) 376 #endif 377 378 #if __GNUC_PREREQ(3, 3) 379 # define NSF_nonnull(ARGS) __attribute__((__nonnull__(ARGS))) 380 #else 381 # define NSF_nonnull(ARGS) 382 #endif 383 384 #if __GNUC_PREREQ(6, 0) 385 # define NSF_nonnull_assert(assertion) 386 #else 387 # define NSF_nonnull_assert(assertion) assert((assertion)) 388 #endif 389 390 391 /* 392 * Unfortunately, we can't combine NSF_attribute_format() with 393 * functions called via stubs. 394 */ 395 #if __GNUC_PREREQ(3, 4) 396 # define NSF_attribute_format(ARGS) __attribute__((__format__ ARGS)) 397 #else 398 # define NSF_attribute_format(ARGS) 399 #endif 400 401 EXTERN int 402 NsfArgumentError(Tcl_Interp *interp, const char *errorMsg, Nsf_Param const *paramPtr, 403 Tcl_Obj *cmdNameObj, Tcl_Obj *methodPathObj) 404 NSF_nonnull(1) NSF_nonnull(2) NSF_nonnull(3); 405 406 407 EXTERN int 408 NsfDispatchClientDataError(Tcl_Interp *interp, ClientData clientData, 409 const char *what, const char *methodName) 410 NSF_nonnull(1) NSF_nonnull(3) NSF_nonnull(4); 411 412 EXTERN int 413 NsfNoCurrentObjectError(Tcl_Interp *interp, const char *methodName) 414 NSF_nonnull(1); 415 416 EXTERN int 417 NsfUnexpectedArgumentError(Tcl_Interp *interp, const char *argumentString, 418 Nsf_Object *object, Nsf_Param const *paramPtr, 419 Tcl_Obj *methodPathObj) 420 NSF_nonnull(1) NSF_nonnull(2) NSF_nonnull(4) NSF_nonnull(5); 421 422 EXTERN int 423 NsfUnexpectedNonposArgumentError(Tcl_Interp *interp, 424 const char *argumentString, 425 Nsf_Object *object, 426 Nsf_Param const *currentParamPtr, 427 Nsf_Param const *paramPtr, 428 Tcl_Obj *methodPathObj) 429 NSF_nonnull(1) NSF_nonnull(2) NSF_nonnull(4) NSF_nonnull(5) NSF_nonnull(6); 430 431 /* 432 * logging severities 433 */ 434 #define NSF_LOG_ERROR 3 435 #define NSF_LOG_WARN 2 436 #define NSF_LOG_NOTICE 1 437 #define NSF_LOG_DEBUG 0 438 439 EXTERN void 440 NsfLog(Tcl_Interp *interp, int requiredLevel, const char *fmt, ...) 441 NSF_nonnull(1) NSF_nonnull(3) NSF_attribute_format((printf,3,4)); 442 443 /* 444 * Nsf Pointer converter interface 445 */ 446 447 EXTERN int Nsf_PointerAdd(Tcl_Interp *interp, char *buffer, size_t size, const char *typeName, void *valuePtr) 448 NSF_nonnull(1) NSF_nonnull(2) NSF_nonnull(4) NSF_nonnull(5); 449 450 EXTERN int Nsf_PointerDelete(const char *key, void *valuePtr, int free) 451 NSF_nonnull(2); 452 453 EXTERN void Nsf_PointerInit(void); 454 455 EXTERN void Nsf_PointerExit(Tcl_Interp *interp) 456 NSF_nonnull(1); 457 458 EXTERN void *Nsf_PointerTypeLookup(const char* typeName) 459 NSF_nonnull(1); 460 461 EXTERN int Nsf_PointerTypeRegister(Tcl_Interp *interp, const char* typeName, int *counterPtr) 462 NSF_nonnull(1) NSF_nonnull(2) NSF_nonnull(3); 463 464 /* 465 * methodDefinition 466 */ 467 468 typedef struct Nsf_methodDefinition { 469 const char *methodName; 470 Tcl_ObjCmdProc *proc; 471 int nrParameters; 472 Nsf_Param paramDefs[12]; 473 } Nsf_methodDefinition; 474 475 /* 476 * Nsf Enumeration type interface 477 */ 478 EXTERN int Nsf_EnumerationTypeRegister(Tcl_Interp *interp, Nsf_EnumeratorConverterEntry *typeRecords) 479 NSF_nonnull(1) NSF_nonnull(2); 480 481 482 /* 483 * Nsf Cmd definition interface 484 */ 485 EXTERN int Nsf_CmdDefinitionRegister(Tcl_Interp *interp, Nsf_methodDefinition *definitionRecords) 486 NSF_nonnull(1) NSF_nonnull(2); 487 488 489 /* 490 * Include the public function declarations that are accessible via 491 * the stubs table. 492 */ 493 #if defined(NRE) 494 # include "stubs8.6/nsfDecls.h" 495 #else 496 # include "stubs8.5/nsfDecls.h" 497 #endif 498 499 /* 500 * Nsf_InitStubs is used by extensions that can be linked 501 * against the nsf stubs library. If we are not using stubs 502 * then this reduces to package require. 503 */ 504 505 #ifdef USE_NSF_STUBS 506 507 # ifdef __cplusplus 508 EXTERN "C" 509 # endif 510 const char * 511 Nsf_InitStubs(Tcl_Interp *interp, const char *version, int exact); 512 #else 513 # define Nsf_InitStubs(interp, version, exact) \ 514 Tcl_PkgRequire(interp, "nx", version, exact) 515 #endif 516 517 #endif /* RC_INVOKED */ 518 519 /* 520 #undef TCL_STORAGE_CLASS 521 #define TCL_STORAGE_CLASS DLLIMPORT 522 */ 523 524 #endif /* _nsf_h_ */ 525