r8397: merged an upstream fix for the expression bug tpot found yesterday
[jra/samba/.git] / source4 / lib / ejs / var.h
1 /*
2  *      @file   var.h
3  *      @brief  MPR Universal Variable Type
4  *      @copy   default.m
5  *      
6  *      Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
7  *      Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
8  *      
9  *      This software is distributed under commercial and open source licenses.
10  *      You may use the GPL open source license described below or you may acquire 
11  *      a commercial license from Mbedthis Software. You agree to be fully bound 
12  *      by the terms of either license. Consult the LICENSE.TXT distributed with 
13  *      this software for full details.
14  *      
15  *      This software is open source; you can redistribute it and/or modify it 
16  *      under the terms of the GNU General Public License as published by the 
17  *      Free Software Foundation; either version 2 of the License, or (at your 
18  *      option) any later version. See the GNU General Public License for more 
19  *      details at: http://www.mbedthis.com/downloads/gplLicense.html
20  *      
21  *      This program is distributed WITHOUT ANY WARRANTY; without even the 
22  *      implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
23  *      
24  *      This GPL license does NOT permit incorporating this software into 
25  *      proprietary programs. If you are unable to comply with the GPL, you must
26  *      acquire a commercial license to use this software. Commercial licenses 
27  *      for this software and support services are available from Mbedthis 
28  *      Software at http://www.mbedthis.com 
29  *      
30  *      @end
31  */
32
33 /******************************* Documentation ********************************/
34 /*
35  *      Variables can efficiently store primitive types and can hold references to
36  *      objects. Objects can store properties which are themselves variables.
37  *      Properties can be primitive data types, other objects or functions. 
38  *      Properties are indexed by a character name. A variable may store one of 
39  *      the following types: 
40  *
41  *              string, integer, integer-64bit, C function, C function with string args,
42  *               Javascript function, Floating point number, boolean value, Undefined 
43  *              value and the Null value. 
44  *
45  *      Variables have names while objects may be referenced by multiple variables.
46  *      Objects use reference counting for garbage collection.
47  *
48  *      This module is not thread safe for performance and compactness. It relies
49  *      on upper modules to provide thread synchronization as required. The API
50  *      provides primitives to get variable/object references or to get copies of 
51  *      variables which will help minimize required lock times.
52  */
53
54 #ifndef _h_MPR_VAR
55 #define _h_MPR_VAR 1
56
57 /********************************* Includes ***********************************/
58
59 #include        "miniMpr.h"
60
61 /********************************** Defines ***********************************/
62
63 /*
64  *      Define VAR_DEBUG if you want to track objects. However, this code is not
65  *      thread safe and you need to run the server single threaded.
66  *
67  *              #define VAR_DEBUG 1
68  */
69
70 #ifdef __cplusplus
71 extern "C" {
72 #endif
73 /*
74  *      Forward declare types
75  */
76 struct MprProperties;
77 struct MprVar;
78
79 /*
80  *      Possible variable types. Don't use enum because we need to be able to
81  *      do compile time conditional compilation on BLD_FEATURE_NUM_TYPE_ID.
82  */
83 typedef int MprType;
84 #define MPR_TYPE_UNDEFINED                      0       /* Undefined. No value has been set. */
85 #define MPR_TYPE_NULL                           1       /* Value defined to be null. */
86 #define MPR_TYPE_BOOL                           2       /* Boolean type. */
87 #define MPR_TYPE_CFUNCTION                      3       /* C function or C++ method */
88 #define MPR_TYPE_FLOAT                          4       /* Floating point number */
89 #define MPR_TYPE_INT                            5       /* Integer number */
90 #define MPR_TYPE_INT64                          6       /* 64-bit Integer number */
91 #define MPR_TYPE_OBJECT                         7       /* Object reference */
92 #define MPR_TYPE_FUNCTION                       8       /* JavaScript function */
93 #define MPR_TYPE_STRING                         9       /* String (immutable) */
94 #define MPR_TYPE_STRING_CFUNCTION       10      /* C/C++ function with string args */
95 #define MPR_TYPE_PTR                            11      /* Opaque pointer */
96
97 /*
98  *      Create a type for the default number type
99  *      Config.h will define the default number type. For example:
100  *
101  *              BLD_FEATURE_NUM_TYPE=int
102  *              BLD_FEATURE_NUM_TYPE_ID=MPR_TYPE_INT
103  */
104
105 /**
106  *      Set to the type used for MPR numeric variables. Will equate to int, int64 
107  *      or double. 
108  */
109 typedef BLD_FEATURE_NUM_TYPE MprNum;
110
111 /**
112  *      Set to the MPR_TYPE used for MPR numeric variables. Will equate to 
113  *      MPR_TYPE_INT, MPR_TYPE_INT64 or MPR_TYPE_FLOAT.
114  */
115 #define MPR_NUM_VAR BLD_FEATURE_NUM_TYPE_ID
116 #define MPR_TYPE_NUM BLD_FEATURE_NUM_TYPE_ID
117
118 /*
119  *      Return TRUE if a variable is a function type
120  */
121 #define mprVarIsFunction(type) \
122         (type == MPR_TYPE_FUNCTION || type == MPR_TYPE_STRING_CFUNCTION || \
123          type == MPR_TYPE_CFUNCTION)
124
125 /*
126  *      Return TRUE if a variable is a numeric type
127  */
128 #define mprVarIsNumber(type) \
129         (type == MPR_TYPE_INT || type == MPR_TYPE_INT64 || type == MPR_TYPE_FLOAT)
130
131 /*
132  *      Return TRUE if a variable is a boolean
133  */
134 #define mprVarIsBoolean(type) \
135         (type == MPR_TYPE_BOOL)
136 #define mprVarIsString(type) \
137         (type == MPR_TYPE_STRING)
138 #define mprVarIsObject(type) \
139         (type == MPR_TYPE_OBJECT)
140 #define mprVarIsFloating(type) \
141         (type == MPR_TYPE_FLOAT)
142 #define mprVarIsPtr(type) \
143         (type == MPR_TYPE_PTR)
144 #define mprVarIsUndefined(var) \
145         ((var)->type == MPR_TYPE_UNDEFINED)
146 #define mprVarIsNull(var) \
147         ((var)->type == MPR_TYPE_NULL)
148 #define mprVarIsValid(var) \
149         (((var)->type != MPR_TYPE_NULL) && ((var)->type != MPR_TYPE_UNDEFINED))
150
151 #define MPR_VAR_MAX_RECURSE             5                               /* Max object loops */
152
153 #if BLD_FEATURE_SQUEEZE
154 #define MPR_MAX_VAR                             64                              /* Max var full name */
155 #else
156 #define MPR_MAX_VAR                             512
157 #endif
158
159 #ifndef __NO_PACK
160 #pragma pack(2)
161 #endif /* _NO_PACK */
162
163 /*
164  *      Function signatures
165  */
166 typedef int     MprVarHandle;
167 typedef int (*MprCFunction)(MprVarHandle userHandle, int argc, 
168         struct MprVar **argv);
169 typedef int (*MprStringCFunction)(MprVarHandle userHandle, int argc, 
170         char **argv);
171
172 /*
173  *      Triggers
174  */
175 typedef enum {
176         MPR_VAR_WRITE,                                          /* This property is being updated */
177         MPR_VAR_READ,                                           /* This property is being read */
178         MPR_VAR_CREATE_PROPERTY,                        /* A property is being created */
179         MPR_VAR_DELETE_PROPERTY,                        /* A property is being deleted */
180         MPR_VAR_DELETE                                          /* This object is being deleted */
181 } MprVarTriggerOp;
182
183 /*
184  *      Trigger function return codes.
185  */
186 typedef enum {
187         MPR_TRIGGER_ABORT,                                      /* Abort the current operation */
188         MPR_TRIGGER_USE_NEW_VALUE,                      /* Proceed and use the newValue */
189         MPR_TRIGGER_PROCEED                                     /* Proceed with the operation */
190 } MprVarTriggerStatus;
191
192 /*
193  *      The MprVarTrigger arguments have the following meaning:
194  *
195  *              op                                      The operation being performed. See MprVarTriggerOp.
196  *              parentProperties        Pointer to the MprProperties structure.
197  *              vp                                      Pointer to the property that registered the trigger.
198  *              newValue                        New value (see below for more details).
199  *              copyDepth                       Specify what data items to copy.
200  *
201  *      For VAR_READ, newVar is set to a temporary variable that the trigger 
202  *              function may assign a value to be returned instead of the actual 
203  *              property value. 
204  *      For VAR_WRITE, newValue holds the new value. The old existing value may be
205  *              accessed via vp.
206  *      For DELETE_PROPERTY, vp is the property being deleted. newValue is null.
207  *      For ADD_PROPERTY, vp is set to the property being added and newValue holds 
208  *              the new value.
209  */
210 typedef MprVarTriggerStatus (*MprVarTrigger)(MprVarTriggerOp op, 
211         struct MprProperties *parentProperties, struct MprVar *vp, 
212         struct MprVar *newValue, int copyDepth);
213
214 /*
215  *      mprCreateFunctionVar flags
216  */
217 /** Use the alternate handle on function callbacks */
218 #define MPR_VAR_ALT_HANDLE              0x1
219
220 /** Use the script handle on function callbacks */
221 #define MPR_VAR_SCRIPT_HANDLE   0x2
222
223 /*
224  *      Useful define for the copyDepth argument
225  */
226 /** Don't copy any data. Copy only the variable name */
227 #define MPR_NO_COPY                     0
228
229 /** Copy strings. Increment object reference counts. */
230 #define MPR_SHALLOW_COPY        1
231
232 /** Copy strings and do complete object copies. */
233 #define MPR_DEEP_COPY           2
234
235 /*
236  *      GetFirst / GetNext flags
237  */
238 /** Step into data properties. */
239 #define MPR_ENUM_DATA           0x1
240
241 /** Step into functions properties. */
242 #define MPR_ENUM_FUNCTIONS      0x2
243
244 /*
245  *      Collection type to hold properties in an object
246  */
247 typedef struct MprProperties {                                  /* Collection of properties */
248 #if VAR_DEBUG
249         struct MprProperties *next;                                     /* Linked list */
250         struct MprProperties *prev;                                     /* Linked list */
251         char                            name[32];                               /* Debug name */
252 #endif
253         struct MprVar           **buckets;                              /* Hash chains */
254         int                                     numItems;                               /* Total count of items */
255         /* FUTURE - Better way of doing this */
256         int                                     numDataItems;                   /* Enumerable data items */
257         uint                            hashSize                : 8;    /* Size of the hash table */
258         /* FUTURE -- increase size of refCount */
259         uint                            refCount                : 8;    /* References to this property*/
260         /* FUTURE - make these flags */
261         uint                            deleteProtect   : 8;    /* Don't recursively delete */
262         uint                            visited                 : 8;    /* Node has been processed */
263 } MprProperties;
264
265 /*
266  *      Universal Variable Type
267  */
268 typedef struct MprVar {
269         /* FUTURE - remove name to outside reference */
270         MprStr                          name;                                   /* Property name */
271         /* FUTURE - remove */
272         MprStr                          fullName;                               /* Full object name */
273         /* FUTURE - make part of the union */
274         MprProperties           *properties;                    /* Pointer to properties */
275
276         /*
277          *      Packed bit field
278          */
279         MprType                         type                    : 8;    /* Selector into union */
280         uint                            bucketIndex             : 8;    /* Copy of bucket index */
281
282         uint                            flags                   : 5;    /* Type specific flags */
283         uint                            allocatedData   : 1;    /* Data needs freeing */
284         uint                            readonly                : 1;    /* Unmodifiable */
285         uint                            deleteProtect   : 1;    /* Don't recursively delete */
286
287         uint                            visited                 : 1;    /* Node has been processed */
288         uint                            allocatedVar    : 1;    /* Var needs freeing */
289         uint                            spare                   : 6;    /* Unused */
290
291         struct MprVar           *forw;                                  /* Hash table linkage */
292         MprVarTrigger           trigger;                                /* Trigger function */
293
294 #if UNUSED && KEEP
295         struct MprVar           *baseClass;                             /* Pointer to class object */
296 #endif
297         MprProperties           *parentProperties;              /* Pointer to parent object */
298
299         /*
300          *      Union of primitive types. When debugging on Linux, don't use unions 
301          *      as the gdb debugger can't display them.
302          */
303 #if !BLD_DEBUG && !LINUX && !VXWORKS
304         union {
305 #endif
306                 int                             boolean;                                /* Use int for speed */
307 #if BLD_FEATURE_FLOATING_POINT
308                 double                  floating;
309 #endif
310                 int                             integer;
311 #if BLD_FEATURE_INT64
312                 int64                   integer64;
313 #endif
314                 struct {                                                                /* Javascript functions */
315                         MprArray        *args;                                  /* Null terminated */
316                         char            *body;
317                 } function;
318                 struct {                                                                /* Function with MprVar args */
319                         MprCFunction fn;
320                         void            *thisPtr;
321                 } cFunction;
322                 struct {                                                                /* Function with string args */
323                         MprStringCFunction fn;
324                         void            *thisPtr;
325                 } cFunctionWithStrings;
326                 MprStr                  string;                                 /* Allocated string */
327                 void                    *ptr;                                   /* Opaque pointer */
328 #if !BLD_DEBUG && !LINUX && !VXWORKS
329         };
330 #endif
331 } MprVar;
332
333 /*
334  *      Define a field macro so code an use numbers in a "generic" fashion.
335  */
336 #if MPR_NUM_VAR == MPR_TYPE_INT || DOXYGEN
337 /*      Default numeric type */
338 #define mprNumber integer
339 #endif
340 #if MPR_NUM_VAR == MPR_TYPE_INT64
341 /*      Default numeric type */
342 #define mprNumber integer64
343 #endif
344 #if MPR_NUM_VAR == MPR_TYPE_FLOAT
345 /*      Default numeric type */
346 #define mprNumber floating
347 #endif
348
349 typedef BLD_FEATURE_NUM_TYPE MprNumber;
350
351
352 #ifndef __NO_PACK
353 #pragma pack()
354 #endif /* __NO_PACK */
355
356 /********************************* Prototypes *********************************/
357 /*
358  *      Variable constructors and destructors
359  */
360 extern MprVar   mprCreateObjVar(const char *name, int hashSize);
361 extern MprVar   mprCreateBoolVar(bool value);
362 extern MprVar   mprCreateCFunctionVar(MprCFunction fn, void *thisPtr, 
363                                         int flags);
364 #if BLD_FEATURE_FLOATING_POINT
365 extern MprVar   mprCreateFloatVar(double value);
366 #endif
367 extern MprVar   mprCreateIntegerVar(int value);
368 #if BLD_FEATURE_INT64
369 extern MprVar   mprCreateInteger64Var(int64 value);
370 #endif
371 extern MprVar   mprCreateFunctionVar(char *args, char *body, int flags);
372 extern MprVar   mprCreateNullVar(void);
373 extern MprVar   mprCreateNumberVar(MprNumber value);
374 extern MprVar   mprCreateStringCFunctionVar(MprStringCFunction fn, 
375                                         void *thisPtr, int flags);
376 extern MprVar   mprCreateStringVar(const char *value, bool allocate);
377 extern MprVar   mprCreateUndefinedVar(void);
378 extern MprVar   mprCreatePtrVar(void *ptr);
379 extern bool     mprDestroyVar(MprVar *vp);
380 extern bool     mprDestroyAllVars(MprVar* vp);
381 extern MprType  mprGetVarType(MprVar *vp);
382
383 /*
384  *      Copy
385  */
386 extern void             mprCopyVar(MprVar *dest, MprVar *src, int copyDepth);
387 extern void             mprCopyVarValue(MprVar *dest, MprVar src, int copyDepth);
388 extern MprVar   *mprDupVar(MprVar *src, int copyDepth);
389
390 /*
391  *      Manage vars
392  */
393 extern MprVarTrigger 
394                                 mprAddVarTrigger(MprVar *vp, MprVarTrigger fn);
395 extern int              mprGetVarRefCount(MprVar *vp);
396 extern void     mprSetVarDeleteProtect(MprVar *vp, int deleteProtect);
397 extern void     mprSetVarFullName(MprVar *vp, char *name);
398 extern void     mprSetVarReadonly(MprVar *vp, int readonly);
399 extern void     mprSetVarName(MprVar *vp, char *name);
400
401 /*
402  *      Create properties and return a reference to the property.
403  */
404 extern MprVar   *mprCreateProperty(MprVar *obj, const char *property, 
405                                         MprVar *newValue);
406 extern MprVar   *mprCreatePropertyValue(MprVar *obj, const char *property, 
407                                         MprVar newValue);
408 extern int              mprDeleteProperty(MprVar *obj, const char *property);
409
410 /*
411  *      Get/Set properties. Set will update/create.
412  */
413 extern MprVar   *mprGetProperty(MprVar *obj, const char *property, 
414                                         MprVar *value);
415 extern MprVar   *mprSetProperty(MprVar *obj, const char *property, 
416                                         MprVar *value);
417 extern MprVar   *mprSetPropertyValue(MprVar *obj, const char *property, 
418                                         MprVar value);
419
420 /*
421  *      Directly read/write property values (the property must already exist)
422  *      For mprCopyProperty, mprDestroyVar must always called on the var.
423  */
424 extern int              mprReadProperty(MprVar *prop, MprVar *value);
425 extern int              mprWriteProperty(MprVar *prop, MprVar *newValue);
426 extern int              mprWritePropertyValue(MprVar *prop, MprVar newValue);
427
428 /*
429  *      Copy a property. NOTE: reverse of most other args: (dest, src)
430  */
431 extern int              mprCopyProperty(MprVar *dest, MprVar *prop, int copyDepth);
432
433 /*
434  *      Enumerate properties
435  */
436 extern MprVar   *mprGetFirstProperty(MprVar *obj, int includeFlags);
437 extern MprVar   *mprGetNextProperty(MprVar *obj, MprVar *currentProperty, 
438                                         int includeFlags);
439
440 /*
441  *      Query properties characteristics
442  */
443 extern int              mprGetPropertyCount(MprVar *obj, int includeFlags);
444
445 /*
446  *      Conversion routines
447  */
448 extern MprVar   mprParseVar(char *str, MprType prefType);
449 extern MprNum   mprVarToNumber(const MprVar *vp);
450 extern int              mprVarToInteger(const MprVar *vp);
451 #if BLD_FEATURE_INT64
452 extern int64    mprVarToInteger64(const MprVar *vp);
453 #endif
454 extern bool     mprVarToBool(const MprVar *vp);
455 #if BLD_FEATURE_FLOATING_POINT
456 extern double   mprVarToFloat(const MprVar *vp);
457 #endif
458 extern void     mprVarToString(char** buf, int size, char *fmt, MprVar *vp);
459
460 /*
461  *      Parsing and utility routines
462  */
463 extern MprNum   mprParseNumber(char *str);
464 extern int              mprParseInteger(char *str);
465
466 #if BLD_FEATURE_INT64
467 extern int64    mprParseInteger64(char *str);
468 #endif
469
470 #if BLD_FEATURE_FLOATING_POINT
471 extern double   mprParseFloat(char *str);
472 extern bool     mprIsInfinite(double f);
473 extern bool     mprIsNan(double f);
474 #endif
475
476 #if VAR_DEBUG
477 extern void     mprPrintObjects(char *msg);
478 extern void     mprPrintObjRefCount(MprVar *vp);
479 #endif
480
481 #ifdef __cplusplus
482 }
483 #endif
484
485 /*****************************************************************************/
486 #endif /* _h_MPR_VAR */
487
488 /*
489  * Local variables:
490  * tab-width: 4
491  * c-basic-offset: 4
492  * End:
493  * vim:tw=78
494  * vim600: sw=4 ts=4 fdm=marker
495  * vim<600: sw=4 ts=4
496  */