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