license changed to LGPL for libnxcl, libnxsnmp, libnxlp, libnxsl, and libnxmap
[public/netxms.git] / include / nxsl_classes.h
1 /*
2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2010 Victor Kirhenshtein
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU Lesser General Public License as published by
7 ** the Free Software Foundation; either version 3 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU Lesser General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 **
19 ** File: nxsl_classes.h
20 **
21 **/
22
23 #ifndef _nxsl_classes_h_
24 #define _nxsl_classes_h_
25
26 #include <nms_threads.h>
27 #include <nms_util.h>
28 #include <nxcpapi.h>
29
30
31 //
32 // Constants
33 //
34
35 #define MAX_CLASS_NAME 64
36
37
38 //
39 // Data types
40 //
41
42 #define NXSL_DT_NULL 0
43 #define NXSL_DT_OBJECT 1
44 #define NXSL_DT_ARRAY 2
45 #define NXSL_DT_STRING 3
46 #define NXSL_DT_REAL 4
47 #define NXSL_DT_INT32 5
48 #define NXSL_DT_INT64 6
49 #define NXSL_DT_UINT32 7
50 #define NXSL_DT_UINT64 8
51
52
53 //
54 // Simple stack class
55 //
56
57 class LIBNXSL_EXPORTABLE NXSL_Stack
58 {
59 private:
60 int m_nStackSize;
61 int m_nStackPos;
62 void **m_ppData;
63
64 public:
65 NXSL_Stack();
66 ~NXSL_Stack();
67
68 void push(void *pData);
69 void *pop();
70 void *peek();
71 void **peekList(int nLevel) { return &m_ppData[m_nStackPos - nLevel]; }
72
73 int getSize() { return m_nStackPos; }
74 };
75
76
77 //
78 // Class representing NXSL class
79 //
80
81 class NXSL_Value;
82 class NXSL_Object;
83
84 class LIBNXSL_EXPORTABLE NXSL_Class
85 {
86 protected:
87 TCHAR m_szName[MAX_CLASS_NAME];
88
89 public:
90 NXSL_Class();
91 virtual ~NXSL_Class();
92
93 virtual NXSL_Value *getAttr(NXSL_Object *pObject, const TCHAR *pszAttr);
94 virtual BOOL setAttr(NXSL_Object *pObject, const TCHAR *pszAttr, NXSL_Value *pValue);
95
96 virtual void onObjectDelete(NXSL_Object *object);
97
98 const TCHAR *getName(void) { return m_szName; }
99 };
100
101
102 //
103 // Object instance
104 //
105
106 class LIBNXSL_EXPORTABLE NXSL_Object
107 {
108 private:
109 NXSL_Class *m_pClass;
110 void *m_pData;
111
112 public:
113 NXSL_Object(NXSL_Object *pObject);
114 NXSL_Object(NXSL_Class *pClass, void *pData);
115 ~NXSL_Object();
116
117 NXSL_Class *getClass() { return m_pClass; }
118 void *getData() { return m_pData; }
119 };
120
121
122 //
123 // Array
124 //
125
126 struct NXSL_ArrayElement
127 {
128 int index;
129 NXSL_Value *value;
130 };
131
132 class LIBNXSL_EXPORTABLE NXSL_Array
133 {
134 private:
135 int m_refCount;
136 int m_size;
137 int m_allocated;
138 NXSL_ArrayElement *m_data;
139
140 public:
141 NXSL_Array();
142 NXSL_Array(NXSL_Array *src);
143 ~NXSL_Array();
144
145 void incRefCount() { m_refCount++; }
146 void decRefCount() { m_refCount--; }
147 BOOL isUnused() { return m_refCount < 1; }
148
149 void set(int index, NXSL_Value *value);
150 NXSL_Value *get(int index);
151 };
152
153
154 //
155 // Variable or constant value
156 //
157
158 class LIBNXSL_EXPORTABLE NXSL_Value
159 {
160 protected:
161 DWORD m_dwStrLen;
162 char *m_pszValStr;
163 BYTE m_nDataType;
164 BYTE m_bStringIsValid;
165 union
166 {
167 LONG nInt32;
168 DWORD uInt32;
169 INT64 nInt64;
170 QWORD uInt64;
171 double dReal;
172 NXSL_Object *pObject;
173 NXSL_Array *pArray;
174 } m_value;
175
176 void updateNumber();
177 void updateString();
178
179 void invalidateString()
180 {
181 safe_free(m_pszValStr);
182 m_pszValStr = NULL;
183 m_bStringIsValid = FALSE;
184 }
185
186 public:
187 NXSL_Value();
188 NXSL_Value(const NXSL_Value *);
189 NXSL_Value(NXSL_Object *pObject);
190 NXSL_Value(NXSL_Array *pArray);
191 NXSL_Value(LONG nValue);
192 NXSL_Value(INT64 nValue);
193 NXSL_Value(DWORD uValue);
194 NXSL_Value(QWORD uValue);
195 NXSL_Value(double dValue);
196 NXSL_Value(const TCHAR *pszValue);
197 NXSL_Value(const TCHAR *pszValue, DWORD dwLen);
198 ~NXSL_Value();
199
200 void set(LONG nValue);
201
202 bool convert(int nDataType);
203 int getDataType() { return m_nDataType; }
204
205 bool isNull() { return (m_nDataType == NXSL_DT_NULL); }
206 bool isObject() { return (m_nDataType == NXSL_DT_OBJECT); }
207 bool isArray() { return (m_nDataType == NXSL_DT_ARRAY); }
208 bool isString() { return (m_nDataType >= NXSL_DT_STRING); }
209 bool isNumeric() { return (m_nDataType > NXSL_DT_STRING); }
210 bool isReal() { return (m_nDataType == NXSL_DT_REAL); }
211 bool isInteger() { return (m_nDataType > NXSL_DT_REAL); }
212 bool isUnsigned() { return (m_nDataType >= NXSL_DT_UINT32); }
213 bool isZero();
214 bool isNonZero();
215
216 const TCHAR *getValueAsString(DWORD *pdwLen);
217 const TCHAR *getValueAsCString();
218 LONG getValueAsInt32();
219 DWORD getValueAsUInt32();
220 INT64 getValueAsInt64();
221 QWORD getValueAsUInt64();
222 double getValueAsReal();
223 NXSL_Object *getValueAsObject() { return (m_nDataType == NXSL_DT_OBJECT) ? m_value.pObject : NULL; }
224 NXSL_Array *getValueAsArray() { return (m_nDataType == NXSL_DT_ARRAY) ? m_value.pArray : NULL; }
225
226 void concatenate(const TCHAR *pszString, DWORD dwLen);
227
228 void increment();
229 void decrement();
230 void negate();
231 void bitNot();
232
233 void add(NXSL_Value *pVal);
234 void sub(NXSL_Value *pVal);
235 void mul(NXSL_Value *pVal);
236 void div(NXSL_Value *pVal);
237 void rem(NXSL_Value *pVal);
238 void bitAnd(NXSL_Value *pVal);
239 void bitOr(NXSL_Value *pVal);
240 void bitXor(NXSL_Value *pVal);
241 void lshift(int nBits);
242 void rshift(int nBits);
243
244 BOOL EQ(NXSL_Value *pVal);
245 BOOL LT(NXSL_Value *pVal);
246 BOOL LE(NXSL_Value *pVal);
247 BOOL GT(NXSL_Value *pVal);
248 BOOL GE(NXSL_Value *pVal);
249 };
250
251
252 //
253 // Function structure
254 //
255
256 struct NXSL_Function
257 {
258 char m_szName[MAX_FUNCTION_NAME];
259 DWORD m_dwAddr;
260 };
261
262
263 //
264 // External function structure
265 //
266
267 class NXSL_Program;
268
269 struct NXSL_ExtFunction
270 {
271 char m_szName[MAX_FUNCTION_NAME];
272 int (* m_pfHandler)(int argc, NXSL_Value **argv, NXSL_Value **result, NXSL_Program *program);
273 int m_iNumArgs; // Number of arguments or -1 for variable number
274 };
275
276
277 //
278 // Environment for NXSL program
279 //
280
281 class NXSL_Library;
282
283 class LIBNXSL_EXPORTABLE NXSL_Environment
284 {
285 private:
286 DWORD m_dwNumFunctions;
287 NXSL_ExtFunction *m_pFunctionList;
288
289 NXSL_Library *m_pLibrary;
290
291 FILE *m_pStdIn;
292 FILE *m_pStdOut;
293
294 public:
295 NXSL_Environment();
296 ~NXSL_Environment();
297
298 virtual void trace(int level, const TCHAR *text);
299
300 void setIO(FILE *pIn, FILE *pOut) { m_pStdIn = pIn; m_pStdOut = pOut; }
301 FILE *getStdIn() { return m_pStdIn; }
302 FILE *getStdOut() { return m_pStdOut; }
303
304 void setLibrary(NXSL_Library *pLib) { m_pLibrary = pLib; }
305
306 NXSL_ExtFunction *findFunction(char *pszName);
307 void registerFunctionSet(DWORD dwNumFunctions, NXSL_ExtFunction *pList);
308
309 BOOL useModule(NXSL_Program *main, const TCHAR *name);
310 };
311
312
313 //
314 // Runtime variable information
315 //
316
317 class LIBNXSL_EXPORTABLE NXSL_Variable
318 {
319 protected:
320 TCHAR *m_pszName;
321 NXSL_Value *m_pValue;
322 bool m_isConstant;
323
324 public:
325 NXSL_Variable(const TCHAR *pszName);
326 NXSL_Variable(const TCHAR *pszName, NXSL_Value *pValue, bool constant = false);
327 NXSL_Variable(NXSL_Variable *pSrc);
328 ~NXSL_Variable();
329
330 const TCHAR *getName() { return m_pszName; }
331 NXSL_Value *getValue() { return m_pValue; }
332 void setValue(NXSL_Value *pValue);
333 bool isConstant() { return m_isConstant; }
334 };
335
336
337 //
338 // Varable system
339 //
340
341 class LIBNXSL_EXPORTABLE NXSL_VariableSystem
342 {
343 protected:
344 DWORD m_dwNumVariables;
345 NXSL_Variable **m_ppVariableList;
346 bool m_isConstant;
347
348 public:
349 NXSL_VariableSystem(bool constant = false);
350 NXSL_VariableSystem(NXSL_VariableSystem *pSrc);
351 ~NXSL_VariableSystem();
352
353 NXSL_Variable *find(const TCHAR *pszName);
354 NXSL_Variable *create(const TCHAR *pszName, NXSL_Value *pValue = NULL);
355 void merge(NXSL_VariableSystem *src);
356 bool isConstant() { return m_isConstant; }
357 };
358
359
360 //
361 // Single execution instruction
362 //
363
364 class LIBNXSL_EXPORTABLE NXSL_Instruction
365 {
366 friend class NXSL_Program;
367
368 protected:
369 int m_nOpCode;
370 union
371 {
372 NXSL_Value *m_pConstant;
373 char *m_pszString;
374 DWORD m_dwAddr;
375 } m_operand;
376 int m_nStackItems;
377 int m_nSourceLine;
378
379 public:
380 NXSL_Instruction(int nLine, int nOpCode);
381 NXSL_Instruction(int nLine, int nOpCode, NXSL_Value *pValue);
382 NXSL_Instruction(int nLine, int nOpCode, char *pszString);
383 NXSL_Instruction(int nLine, int nOpCode, char *pszString, int nStackItems);
384 NXSL_Instruction(int nLine, int nOpCode, DWORD dwAddr);
385 NXSL_Instruction(int nLine, int nOpCode, int nStackItems);
386 NXSL_Instruction(NXSL_Instruction *pSrc);
387 ~NXSL_Instruction();
388 };
389
390
391 //
392 // Used module information
393 //
394
395 struct NXSL_Module
396 {
397 char m_szName[MAX_PATH];
398 DWORD m_dwCodeStart;
399 DWORD m_dwCodeSize;
400 DWORD m_dwFunctionStart;
401 DWORD m_dwNumFunctions;
402 };
403
404
405 //
406 // Class representing compiled NXSL program
407 //
408
409 class LIBNXSL_EXPORTABLE NXSL_Program
410 {
411 protected:
412 NXSL_Environment *m_pEnv;
413
414 NXSL_Instruction **m_ppInstructionSet;
415 DWORD m_dwCodeSize;
416 DWORD m_dwCurrPos;
417
418 DWORD m_dwNumPreloads;
419 char **m_ppszPreloadList;
420
421 DWORD m_dwSubLevel;
422 NXSL_Stack *m_pDataStack;
423 NXSL_Stack *m_pCodeStack;
424 int m_nBindPos;
425
426 NXSL_VariableSystem *m_pConstants;
427 NXSL_VariableSystem *m_pGlobals;
428 NXSL_VariableSystem *m_pLocals;
429
430 DWORD m_dwNumFunctions;
431 NXSL_Function *m_pFunctionList;
432
433 DWORD m_dwNumModules;
434 NXSL_Module *m_pModuleList;
435
436 NXSL_Value *m_pRetValue;
437 int m_nErrorCode;
438 TCHAR *m_pszErrorText;
439
440 void execute();
441 void callFunction(int nArgCount);
442 void doUnaryOperation(int nOpCode);
443 void doBinaryOperation(int nOpCode);
444 void error(int nError);
445 NXSL_Value *matchRegexp(NXSL_Value *pValue, NXSL_Value *pRegexp, BOOL bIgnoreCase);
446
447 NXSL_Variable *findOrCreateVariable(TCHAR *pszName);
448 NXSL_Variable *createVariable(TCHAR *pszName);
449
450 DWORD getFunctionAddress(char *pszName);
451 void relocateCode(DWORD dwStartOffset, DWORD dwLen, DWORD dwShift);
452 DWORD getFinalJumpDestination(DWORD dwAddr);
453
454 public:
455 NXSL_Program();
456 ~NXSL_Program();
457
458 BOOL addFunction(const char *pszName, DWORD dwAddr, char *pszError);
459 void resolveFunctions();
460 void addInstruction(NXSL_Instruction *pInstruction);
461 void resolveLastJump(int nOpCode);
462 void createJumpAt(DWORD dwOpAddr, DWORD dwJumpAddr);
463 void addPreload(char *pszName);
464 void useModule(NXSL_Program *pModule, const char *pszName);
465 void optimize();
466
467 void setGlobalVariable(const TCHAR *pszName, NXSL_Value *pValue);
468 NXSL_Variable *findGlobalVariable(const TCHAR *pszName) { return m_pGlobals->find(pszName); }
469
470 int run(NXSL_Environment *pEnv = NULL, DWORD argc = 0,
471 NXSL_Value **argv = NULL, NXSL_VariableSystem *pUserLocals = NULL,
472 NXSL_VariableSystem **ppGlobals = NULL, NXSL_VariableSystem *pConstants = NULL);
473
474 DWORD getCodeSize() { return m_dwCodeSize; }
475
476 void trace(int level, const TCHAR *text);
477 void dump(FILE *pFile);
478 const TCHAR *getErrorText() { return CHECK_NULL_EX(m_pszErrorText); }
479 NXSL_Value *getResult() { return m_pRetValue; }
480 };
481
482
483 //
484 // Script library
485 //
486
487 class LIBNXSL_EXPORTABLE NXSL_Library
488 {
489 private:
490 DWORD m_dwNumScripts;
491 NXSL_Program **m_ppScriptList;
492 char **m_ppszNames;
493 DWORD *m_pdwIdList;
494 MUTEX m_mutex;
495
496 void deleteInternal(int nIndex);
497
498 public:
499 NXSL_Library();
500 ~NXSL_Library();
501
502 void lock() { MutexLock(m_mutex, INFINITE); }
503 void unlock() { MutexUnlock(m_mutex); }
504
505 BOOL addScript(DWORD dwId, const TCHAR *pszName, NXSL_Program *pScript);
506 void deleteScript(const TCHAR *pszName);
507 void deleteScript(DWORD dwId);
508 NXSL_Program *findScript(const TCHAR *pszName);
509
510 void fillMessage(CSCPMessage *pMsg);
511 };
512
513
514 #endif