00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifndef CCXX_SCRIPT_H_
00042 #define CCXX_SCRIPT_H_
00043
00044 #ifndef CCXX_MISC_H_
00045 #include <cc++/misc.h>
00046 #endif
00047
00048 #ifndef CCXX_FILE_H_
00049 #include <cc++/file.h>
00050 #endif
00051
00052 #include <iostream>
00053 #include <fstream>
00054
00055 #ifdef CCXX_NAMESPACES
00056 namespace ost {
00057 #endif
00058
00059 class CCXX_CLASS_EXPORT ScriptCommand;
00060 class CCXX_CLASS_EXPORT ScriptImage;
00061 class CCXX_CLASS_EXPORT ScriptInterp;
00062
00063 #define MAX_LOCKS 8
00064 #define TRAP_BITS (sizeof(unsigned long) * 8)
00065 #define SCRIPT_STACK_SIZE 20
00066 #define SCRIPT_TEMP_SPACE 16
00067 #define KEYWORD_INDEX_SIZE 37
00068 #define SYMBOL_INDEX_SIZE 187
00069 #define SCRIPT_INDEX_SIZE KEYWORD_INDEX_SIZE
00070 #define SCRIPT_PREPROCESSOR_OVERRIDE 1
00071 #define SCRIPT_EXCLUSIVE_OVERRIDE 1
00072 #define SCRIPT_IF_OVERRIDE 1
00073 #define SCRIPT_MAP_TABLES 1
00074 #define SCRIPT_LOCAL_DEFINE 1
00075 #define SCRIPT_TRANSACTION_GROUPING 1
00076 #define SCRIPT_SET_READ 1
00077 #define SCRIPT_MAX_ARGS 256
00078 #define SCRIPT_DATA_SEGMENTS
00079 #define SCRIPT_EXTENDED_EXPRESSIONS
00080 #define SCRIPT_NAMED_EVENTS
00081
00082 class Script
00083 {
00084 protected:
00085 class Line;
00086
00087 typedef bool (ScriptInterp::*Method)(void);
00088 typedef char *(ScriptCommand::*Check)(Line *line, ScriptImage *img);
00089 typedef bool (*Cond)(ScriptInterp *interp, const char *v);
00090 typedef long (*Function)(long *args, unsigned prec);
00091 typedef char *(*Meta)(ScriptInterp *interp, const char *token);
00092
00093 enum SymType
00094 {
00095 NORMAL = 0,
00096 ALIAS,
00097 FIFO,
00098 INDEX,
00099 SEQUENCE,
00100 STACK,
00101 COUNTER,
00102 TRIGGER,
00103 POINTER,
00104 REF,
00105 CACHE,
00106 ARRAY
00107 };
00108 typedef enum SymType SymType;
00109
00110 #pragma pack(1)
00111 typedef struct _symbol
00112 {
00113 struct _symbol *next;
00114 const char *id;
00115 struct
00116 {
00117 unsigned size : 16;
00118 bool initial : 1;
00119 bool system : 1;
00120 bool readonly : 1;
00121 bool commit : 1;
00122 bool large : 1;
00123 SymType type : 6;
00124 } flags;
00125 char data[1];
00126 } Symbol;
00127
00128 class Test
00129 {
00130 public:
00131 const char *id;
00132 Cond handler;
00133 Test *next;
00134 };
00135
00136 class Attr
00137 {
00138 public:
00139 const char *id;
00140 Meta meta;
00141 Attr *next;
00142 };
00143
00144 class Fun
00145 {
00146 public:
00147 const char *id;
00148 unsigned args;
00149 Function fn;
00150 Fun *next;
00151 };
00152
00153 class Line
00154 {
00155 public:
00156 Line *next;
00157 unsigned long cmask;
00158 unsigned long mask;
00159 unsigned short loop;
00160 unsigned short line;
00161 unsigned char argc;
00162 bool error : 1;
00163 bool sync : 1;
00164 bool prescan : 1;
00165 Method method;
00166 char *cmd;
00167 char **args;
00168 };
00169
00170 class Name
00171 {
00172 public:
00173 class Event
00174 {
00175 public:
00176 Event *next;
00177 Line *line;
00178 const char *name;
00179 } *events;
00180
00181 Name *next;
00182 Line *first;
00183 Line *trap[TRAP_BITS];
00184 unsigned long mask;
00185 char *name;
00186 enum Mode
00187 {
00188 ORIGINAL,
00189 COPIED,
00190 COPY,
00191 DATA
00192 } mode;
00193 typedef enum Mode Mode;
00194 bool access;
00195 };
00196
00197 class Initial
00198 {
00199 public:
00200 const char *name;
00201 unsigned size;
00202 const char *value;
00203 };
00204
00205 class Define
00206 {
00207 public:
00208 const char *keyword;
00209 Method method;
00210 Check check;
00211 };
00212
00213 #pragma pack()
00214
00222 class Locks : private ThreadLock, private MemPager
00223 {
00224 private:
00225 typedef struct _lock
00226 {
00227 struct _lock *next;
00228 unsigned count;
00229 ScriptInterp *owner;
00230 char id[1];
00231 } lck;
00232
00233 unsigned count;
00234 unsigned getIndex(const char *id);
00235 lck *hash[KEYWORD_INDEX_SIZE];
00236
00237 public:
00238 void release(ScriptInterp *interp);
00239 bool lock(ScriptInterp *interp, const char *id);
00240 bool unlock(ScriptInterp *interp, const char *id);
00241
00242 Locks();
00243 };
00244
00254 class Package : protected DSO
00255 {
00256 public:
00257 static Package *first;
00258 Package *next;
00259 char *filename;
00260
00261 Package(char *name);
00262 };
00263 public:
00264 static bool use(const char *name);
00265
00275 class CCXX_CLASS_EXPORT Session
00276 {
00277 private:
00278 friend class ScriptInterp;
00279 ScriptInterp *interp;
00280
00281 protected:
00288 void stepScheduler(const char *sighandler = NULL);
00289
00296 void sleepScheduler(timeout_t delay);
00297
00301 Session(ScriptInterp *interp);
00302
00303 virtual ~Session()
00304 {return;};
00305
00306 public:
00310 virtual void waitHandler(void) = 0;
00311 };
00312
00320 class CCXX_CLASS_EXPORT Property
00321 {
00322 private:
00323 friend class ScriptInterp;
00324
00325 static Property *first;
00326 Property *next;
00327 const char *id;
00328
00329 protected:
00338 virtual void setProperty(char *data, char *temp, size_t size) = 0;
00339
00347 virtual void getProperty(char *data, char *temp, size_t size) = 0;
00348
00356 virtual void adjProperty(char *data, size_t size, int adjust)
00357 {return;};
00358
00364 virtual size_t getPropertySize(void)
00365 {return 0;};
00366
00367 Property(const char *name);
00368
00369 public:
00370 static Property* find(const char *name);
00371 };
00372 };
00373
00381 class CCXX_CLASS_EXPORT ScriptModule : public Script
00382 {
00383 private:
00384 friend class ScriptInterp;
00385 friend class ScriptCommand;
00386 static ScriptModule *first;
00387 ScriptModule *next;
00388 const char *cmd;
00389
00390 protected:
00396 virtual void moduleAttach(ScriptInterp *interp)
00397 {return;};
00398
00404 virtual void moduleDetach(ScriptInterp *interp)
00405 {return;};
00406
00415 virtual char *getSession(ScriptInterp *interp, Line *line, Session **session)
00416 {return NULL;};
00417
00425 virtual char *checkScript(Line *line, ScriptImage *img)
00426 {return NULL;};
00427
00433 ScriptModule(const char *name);
00434
00441 static ScriptModule *find(const char *name);
00442 };
00443
00455 class CCXX_CLASS_EXPORT ScriptCommand : public MemPager, public Mutex, public Script
00456 {
00457 private:
00458 friend class ScriptImage;
00459 friend class ScriptInterp;
00460 friend class ScriptModule;
00461
00462 #pragma pack(1)
00463 typedef struct _keyword
00464 {
00465 struct _keyword *next;
00466 Method method;
00467 Check check;
00468 char keyword[1];
00469 } Keyword;
00470 #pragma pack()
00471
00472
00473 Keyword *keywords[KEYWORD_INDEX_SIZE];
00474 char *traps[TRAP_BITS];
00475 ScriptImage *active;
00476 int keyword_count;
00477 int trap_count;
00478
00479 public:
00487 Method getHandler(const char *keyword);
00488
00496 char *check(char *command, Line *line, ScriptImage *img);
00497
00504 virtual unsigned getTrapId(const char *trap);
00505
00511 virtual unsigned long getTrapDefault(void)
00512 {return 0x00000003;};
00513
00519 virtual unsigned long getTrapHandler(Name *scr)
00520 {return getTrapDefault();}
00521
00529 virtual unsigned long getTrapMask(unsigned id);
00530
00539 virtual unsigned long getTrapModifier(const char *trapname)
00540 {return getTrapMask(trapname);};
00541
00550 virtual unsigned long getTrapMask(const char *trapname);
00551
00552 public:
00556 char *chkIgnore(Line *line, ScriptImage *img);
00557
00561 char *chkModule(Line *line, ScriptImage *img);
00562
00566 char *chkUse(Line *line, ScriptImage *img);
00567
00574 char *chkHasModify(Line *line, ScriptImage *img);
00575
00581 char *chkHasVars(Line *line, ScriptImage *img);
00582
00590 char *chkHasList(Line *line, ScriptImage *img);
00591
00599 char *chkNoArgs(Line *line, ScriptImage *img);
00600
00608 char *chkHasArgs(Line *line, ScriptImage *img);
00609
00617 void load(Script::Define *keywords);
00618
00627 int trap(const char *name);
00628
00634 inline int getCount(void)
00635 {return trap_count;};
00636
00643 virtual char *check(Check chk, Line *line, ScriptImage *img)
00644 {return (this->*(chk))(line, img);};
00645
00654 ScriptCommand();
00655
00656 virtual int mapicmp(const char *s1, const char *s2)
00657 {return stricmp(s1, s2);};
00658
00659 virtual int mapnicmp(const char *s1, const char *s2, size_t n)
00660 {return strnicmp(s1, s2, n);};
00661 };
00662
00672 class CCXX_CLASS_EXPORT ScriptSymbol : public SharedMemPager, public Script
00673 {
00674 private:
00675 friend class ScriptInterp;
00676
00677 int symsize, symlimit;
00678 Symbol *index[SYMBOL_INDEX_SIZE + 1];
00679 Symbol *trigger;
00680
00681 unsigned getIndex(const char *symbol);
00682
00683 protected:
00684 bool setArray(const char *sym, const char *source);
00685
00686 public:
00701 virtual Symbol *getEntry(const char *symbol, int size = 0);
00702
00706 void setExclusive(bool enable);
00707
00708 public:
00718 virtual void commit(Symbol *sym);
00719
00725 Symbol *getTrigger(void);
00726
00732 inline int getSymbolSize(void)
00733 {return symsize;};
00734
00735 ScriptSymbol(int size, int pgsize = 1024);
00736 ~ScriptSymbol();
00737
00744 void *getPointer(const char *symbol);
00745
00753 bool setPointer(const char *symbol, void *data);
00754
00761 char *getSymbol(const char *symbol);
00762
00770 char *setSymbol(const char *symbol, const char *value = "");
00771
00779 char *setConst(const char *symbol, const char *value = "");
00780
00789 bool makeSequence(const char *id, unsigned char count, unsigned char recsize);
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799 bool makeCache(const char *id, unsigned char count, unsigned char recsize);
00800
00809 bool makeStack(const char *id, unsigned char count, unsigned char recsize);
00810
00819 bool makeFifo(const char *id, unsigned char count, unsigned char recsize);
00820
00827 bool makeCounter(const char *id);
00828
00836 bool postSymbol(Symbol *sym, const char *value);
00837
00838
00846 bool removeSymbol(Symbol *sym, const char *value);
00847
00854 char *readSymbol(Symbol *sym);
00855
00863 bool setAlias(const char *symbol, const char *source);
00864
00872 bool swapSymbol(const char *oldname, const char *newname);
00873
00880 Symbol *getAlias(const char *symbol);
00881
00889 char *setSymbol(const char *symbol, int size = 0);
00890
00898 void clrSymbol(const char *id);
00899
00903 void purge(void);
00904
00908 unsigned gather(Symbol **index, unsigned max, const char *prefrix, const char *suffix = "");
00909 };
00910
00920 class CCXX_CLASS_EXPORT ScriptImage : public Keydata, public Script
00921 {
00922 protected:
00923 std::ifstream scrSource;
00924 std::istream *scrStream;
00925 ScriptCommand *cmds;
00926 int refcount;
00927 Name *index[SCRIPT_INDEX_SIZE];
00928 char *buffer;
00929 unsigned bufsize;
00930 char *bp;
00931 bool quote;
00932 unsigned paren;
00933 Mutex duplock;
00934
00935 class InitialList : public Initial
00936 {
00937 public:
00938 InitialList *next;
00939 } *ilist;
00940
00941 friend class ScriptInterp;
00942 friend class ScriptModule;
00943
00944 char *getToken(char **pre = NULL);
00945
00952 Method getHandler(const char *keyword)
00953 {return cmds->getHandler(keyword);};
00954
00962 ScriptImage(ScriptCommand *cmdset, const char *symset);
00963
00967 void purge(void);
00968
00976 Name *include(const char *scrfile);
00977
00986 int compile(const char *scrfile);
00987
00997 int compile(const char *scrfile, char *name);
00998
01006 int compile(std::istream *str, char *name, const char *scrname = NULL);
01007
01013 void commit(void);
01014
01022 virtual bool preProcess(const char *directive, Name *script)
01023 {return false;};
01024
01031 virtual const char *getDefined(const char *token)
01032 {return getLast(token);};
01033
01039 void load(Initial *ilist);
01040
01048 void initial(const char *keyword, const char *value, unsigned size = 0);
01049
01050 public:
01057 virtual Name *getScript(const char *name);
01058
01066 virtual Name *dupScript(const char *name, const char *target);
01067
01076 unsigned gather(const char *suffix, Name **array, unsigned size);
01077
01084 inline std::istream *getSource(void)
01085 {return (std::istream *)&scrSource;};
01086 };
01087
01096 typedef bool (*Cond)(ScriptInterp *interp, const char *v);
01097 typedef long (*Function)(long *args, unsigned prec);
01098 typedef char *(*Meta)(ScriptInterp *interp, const char *token);
01099
01100 void addFunction(const char *name, unsigned count, Function i);
01101 void addConditional(const char *name, Cond test);
01102 void addAttribute(const char *name, Meta meta);
01103
01104 class CCXX_CLASS_EXPORT ScriptInterp : public ScriptSymbol
01105 {
01106 private:
01107 friend class ScriptImage;
01108 friend class Script::Session;
01109 friend class Script::Locks;
01110 friend class ScriptModule;
01111
01112 #pragma pack(1)
01113 class Context
01114 {
01115 public:
01116 Name *script;
01117 Line *line, *read;
01118 unsigned short index;
01119 ScriptSymbol *local;
01120 bool caseflag : 1;
01121 bool tranflag : 1;
01122 unsigned decimal : 3;
01123 };
01124 #pragma pack()
01125
01126 static Attr *attr;
01127 static Test *test;
01128 static Fun *ifun;
01129 static Locks locks;
01130 ScriptCommand *cmd;
01131 ScriptImage *image;
01132 Session *session;
01133 Context script[SCRIPT_STACK_SIZE + 1];
01134 char *temps[SCRIPT_TEMP_SPACE];
01135 int tempidx;
01136 int stack;
01137 size_t symsize, pgsize;
01138 bool once, loop;
01139 unsigned long signalmask;
01140
01141 bool scrTemplate(void);
01142 bool scrEnable(void);
01143 bool scrDisable(void);
01144 bool scrUse(void);
01145 bool scrLoadable(void);
01146 bool scrPack(void);
01147 bool scrUnpack(void);
01148 bool scrOn(void);
01149 bool scrSlog(void);
01150 bool scrBasename(void);
01151 bool scrDirname(void);
01152 bool scrFullpath(void);
01153 bool scrGather(void);
01154 bool scrDump(void);
01155 bool scrInc(void);
01156 bool scrDec(void);
01157 bool scrFifo(void);
01158 bool scrMin(void);
01159 bool scrMax(void);
01160 bool scrCounter(void);
01161 bool scrReset(void);
01162 bool scrRemove(void);
01163 bool scrPost(void);
01164 bool scrStack(void);
01165 bool scrCache(void);
01166 bool scrSequence(void);
01167 bool scrDup(void);
01168 bool scrArray(void);
01169 bool scrList(void);
01170 bool scrArm(void);
01171 bool scrDisarm(void);
01172 bool scrNumber(void);
01173 bool scrDecimal(void);
01174 bool scrSet(void);
01175 bool scrAlias(void);
01176 bool scrRef(void);
01177 bool scrConst(void);
01178 bool scrVar(void);
01179 bool scrSize(void);
01180 bool scrInit(void);
01181 bool scrClear(void);
01182 bool scrCall(void);
01183 bool scrHas(void);
01184 bool scrMissing(void);
01185 bool scrLabel(void);
01186 bool scrCase(void);
01187 bool scrEndcase(void);
01188 bool scrError(void);
01189 bool scrIfThen(void);
01190 bool scrThen(void);
01191 bool scrElse(void);
01192 bool scrEndif(void);
01193 bool scrBegin(void);
01194 bool scrEnd(void);
01195 bool scrFor(void);
01196 bool scrRead(void);
01197 bool scrMap(void);
01198 bool scrRepeat(void);
01199 bool scrForeach(void);
01200 bool scrFordata(void);
01201 bool scrTryeach(void);
01202 bool scrSwap(void);
01203 bool scrDo(void);
01204 bool scrLoop(void);
01205 bool scrBreak(void);
01206 bool scrContinue(void);
01207 bool scrReturn(void);
01208 bool scrPop(void);
01209 bool scrSelect(void);
01210 bool scrOnce(void);
01211 bool scrLock(void);
01212 bool scrTry(void);
01213 bool scrSkip(void);
01214 bool expConditional(void);
01215
01216 public:
01217 static long getRealValue(double val, unsigned prec);
01218 long getIntValue(const char *text, unsigned prec);
01219 int getExpression(long *list, int max, unsigned prec);
01220 static double getDouble(long value, unsigned prec);
01221 static long getInteger(long value, unsigned prec);
01222 static long getTens(unsigned prec);
01223
01224 friend void addFunction(const char *name, unsigned count, Function i);
01225 friend void addConditional(const char *name, Cond test);
01226 friend void addAttribute(const char *name, Meta meta);
01227 friend class ScriptCommand;
01228
01229 protected:
01230 unsigned char lckcount;
01231
01238 ScriptInterp(ScriptCommand *cmd, size_t symsize, size_t pgsize = 1024);
01239
01240 ~ScriptInterp();
01241
01247 void getTrigger(bool use);
01248
01254 bool getOnce(void);
01255
01261 inline void Notify(unsigned long mask)
01262 {signalmask |= mask;};
01263
01269 inline void Notify(const char *str)
01270 {signalmask |= cmd->getTrapMask(str);};
01271
01277 unsigned long getMask(void);
01278
01284 void setLine(Line *line);
01285
01291 inline unsigned long getScriptMask(const char *id)
01292 {return cmd->getTrapMask(id);};
01293
01299 inline ScriptCommand *getCommand(void)
01300 {return cmd;};
01301
01309 bool conditional(void);
01310
01316 bool scrExit(void);
01317
01321 bool scrGoto(void);
01322
01326 bool scrIf(void);
01327
01331 bool ifGoto(void);
01332
01336 bool scrData(void);
01337
01343 virtual unsigned getId(void)
01344 {return 0;};
01345
01346
01353 virtual bool getGlobalTrap(unsigned id)
01354 {return false;};
01355
01356 public:
01363 bool setData(const char *scrname);
01364
01368 char getPackToken(void);
01369
01373 void clrTransactions(void)
01374 {script[stack].tranflag = false;};
01375
01383 Symbol *getVariable(size_t size = 0);
01384
01388 void rewindTemp(void);
01389
01395 void setTemp(const char *value);
01396
01405 virtual Symbol *getIndirect(char *sym)
01406 {return NULL;};
01407
01408 protected:
01412 void advance(void);
01413
01420 void error(const char *error);
01421
01429 void trap(unsigned id);
01430
01437 void trap(const char *trapname);
01438
01444 bool push(void);
01445
01451 bool pull(void);
01452
01462 bool signal(const char *trapname);
01463
01473 bool event(const char *evtname);
01474
01482 bool signal(unsigned trapid);
01483
01491 virtual bool execute(Method method)
01492 {return (this->*(method))();};
01493
01502 virtual void stop(unsigned long mask)
01503 {return;};
01504
01509 virtual void exit(void) = 0;
01510
01518 virtual Name *getScriptImage(const char *label);
01519
01526 Name *getScriptCopy(const char *src);
01527
01533 virtual void sleepScheduler(timeout_t timeout)
01534 {return;};
01535
01541 virtual void stepScheduler(const char *trapname)
01542 {trap(trapname);};
01543
01549 virtual void setExclusive(bool enable)
01550 {return;};
01551
01552 public:
01562 Symbol *getLocal(const char *name, size_t size = 0);
01563
01571 bool attach(const char *scrname);
01572
01577 void detach(void);
01578
01585 bool redirect(const char *scrname);
01586
01595 bool step(const char *trapname = NULL);
01596
01602 inline bool isActive(void)
01603 {return script[stack].line;};
01604
01612 char *getOption(const char *def = NULL);
01613
01621 char *getKeyword(const char *keyword);
01622
01626 int initKeywords(int size);
01627
01635 char *getValue(const char *def = NULL);
01636
01643 char *getString(void);
01644
01650 char *getTempBuffer(void);
01651
01658 char *getContent(char *sym);
01659
01665 inline Line *getScript(void)
01666 {return script[stack].line;};
01667
01673 inline bool hasEvents(void)
01674 {return (script[stack].script->events != NULL);};
01675
01681 Line *getPrescan(void);
01682
01688 const char *getMember(void);
01689
01695 inline Name *getObject(void)
01696 {return script[stack].script;};
01697
01704 inline ScriptImage *getImage(void)
01705 {return image;};
01706
01712 inline void autoloop(bool enable)
01713 {loop = enable;};
01714
01715 inline int mapicmp(const char *s1, const char *s2)
01716 {return cmd->mapicmp(s1, s2);};
01717
01718 inline int mapnicmp(const char *s1, const char *s2, size_t n)
01719 {return cmd->mapnicmp(s1, s2, n);};
01720
01726 inline unsigned getDecimal(void)
01727 {return script[stack].decimal;};
01728 };
01729
01730 #ifdef CCXX_NAMESPACES
01731 };
01732 #endif
01733
01734 #endif
01735