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 CCXX_MEMBER_EXPORT(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 protected:
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 public:
00657 virtual int mapicmp(const char *s1, const char *s2)
00658 {return stricmp(s1, s2);};
00659
00660 virtual int mapnicmp(const char *s1, const char *s2, size_t n)
00661 {return strnicmp(s1, s2, n);};
00662 };
00663
00673 class CCXX_CLASS_EXPORT ScriptSymbol : public SharedMemPager, public Script
00674 {
00675 private:
00676 friend class ScriptInterp;
00677
00678 int symsize, symlimit;
00679 Symbol *index[SYMBOL_INDEX_SIZE + 1];
00680 Symbol *trigger;
00681
00682 unsigned getIndex(const char *symbol);
00683
00684 protected:
00685 bool setArray(const char *sym, const char *source);
00686
00687 public:
00702 virtual Symbol *getEntry(const char *symbol, int size = 0);
00703
00707 void setExclusive(bool enable);
00708
00709 public:
00719 virtual void commit(Symbol *sym);
00720
00726 Symbol *getTrigger(void);
00727
00733 inline int getSymbolSize(void)
00734 {return symsize;};
00735
00736 ScriptSymbol(int size, int pgsize = 1024);
00737 ~ScriptSymbol();
00738
00745 void *getPointer(const char *symbol);
00746
00754 bool setPointer(const char *symbol, void *data);
00755
00762 char *getSymbol(const char *symbol);
00763
00771 char *setSymbol(const char *symbol, const char *value = "");
00772
00780 char *setConst(const char *symbol, const char *value = "");
00781
00790 bool makeSequence(const char *id, unsigned char count, unsigned char recsize);
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800 bool makeCache(const char *id, unsigned char count, unsigned char recsize);
00801
00810 bool makeStack(const char *id, unsigned char count, unsigned char recsize);
00811
00820 bool makeFifo(const char *id, unsigned char count, unsigned char recsize);
00821
00828 bool makeCounter(const char *id);
00829
00837 bool postSymbol(Symbol *sym, const char *value);
00838
00839
00847 bool removeSymbol(Symbol *sym, const char *value);
00848
00855 char *readSymbol(Symbol *sym);
00856
00864 bool setAlias(const char *symbol, const char *source);
00865
00873 bool swapSymbol(const char *oldname, const char *newname);
00874
00881 Symbol *getAlias(const char *symbol);
00882
00890 char *setSymbol(const char *symbol, int size = 0);
00891
00899 void clrSymbol(const char *id);
00900
00904 void purge(void);
00905
00909 unsigned gather(Symbol **index, unsigned max, const char *prefrix, const char *suffix = "");
00910 };
00911
00921 class CCXX_CLASS_EXPORT ScriptImage : public Keydata, public Script
00922 {
00923 protected:
00924 std::ifstream scrSource;
00925 std::istream *scrStream;
00926 ScriptCommand *cmds;
00927 int refcount;
00928 Name *index[SCRIPT_INDEX_SIZE];
00929 char *buffer;
00930 unsigned bufsize;
00931 char *bp;
00932 bool quote;
00933 unsigned paren;
00934 Mutex duplock;
00935
00936 class InitialList : public Initial
00937 {
00938 public:
00939 InitialList *next;
00940 } *ilist;
00941
00942 friend class ScriptInterp;
00943 friend class ScriptModule;
00944
00945 char *getToken(char **pre = NULL);
00946
00953 Method getHandler(const char *keyword)
00954 {return cmds->getHandler(keyword);};
00955
00963 ScriptImage(ScriptCommand *cmdset, const char *symset);
00964
00968 void purge(void);
00969
00977 Name *include(const char *scrfile);
00978
00987 int compile(const char *scrfile);
00988
00998 int compile(const char *scrfile, char *name);
00999
01007 int compile(std::istream *str, char *name, const char *scrname = NULL);
01008
01014 void commit(void);
01015
01023 virtual bool preProcess(const char *directive, Name *script)
01024 {return false;};
01025
01032 virtual const char *getDefined(const char *token)
01033 {return getLast(token);};
01034
01040 void load(Initial *ilist);
01041
01049 void initial(const char *keyword, const char *value, unsigned size = 0);
01050
01051 public:
01058 virtual Name *getScript(const char *name);
01059
01067 virtual Name *dupScript(const char *name, const char *target);
01068
01077 unsigned gather(const char *suffix, Name **array, unsigned size);
01078
01085 inline std::istream *getSource(void)
01086 {return (std::istream *)&scrSource;};
01087 };
01088
01096 class CCXX_CLASS_EXPORT ScriptInterp : public ScriptSymbol
01097 {
01098 private:
01099 friend class ScriptImage;
01100 friend class Script::Session;
01101 friend class Script::Locks;
01102 friend class ScriptModule;
01103
01104 #pragma pack(1)
01105 class Context
01106 {
01107 public:
01108 Name *script;
01109 Line *line, *read;
01110 unsigned short index;
01111 ScriptSymbol *local;
01112 bool caseflag : 1;
01113 bool tranflag : 1;
01114 unsigned decimal : 3;
01115 };
01116 #pragma pack()
01117
01118 static Attr *attr;
01119 static Test *test;
01120 static Fun *ifun;
01121 static Locks locks;
01122 ScriptCommand *cmd;
01123 ScriptImage *image;
01124 Session *session;
01125 Context script[SCRIPT_STACK_SIZE + 1];
01126 char *temps[SCRIPT_TEMP_SPACE];
01127 int tempidx;
01128 int stack;
01129 size_t symsize, pgsize;
01130 bool once, loop;
01131 unsigned long signalmask;
01132
01133 bool scrTemplate(void);
01134 bool scrEnable(void);
01135 bool scrDisable(void);
01136 bool scrUse(void);
01137 bool scrLoadable(void);
01138 bool scrPack(void);
01139 bool scrUnpack(void);
01140 bool scrOn(void);
01141 bool scrSlog(void);
01142 bool scrBasename(void);
01143 bool scrDirname(void);
01144 bool scrFullpath(void);
01145 bool scrGather(void);
01146 bool scrDump(void);
01147 bool scrInc(void);
01148 bool scrDec(void);
01149 bool scrFifo(void);
01150 bool scrMin(void);
01151 bool scrMax(void);
01152 bool scrCounter(void);
01153 bool scrReset(void);
01154 bool scrRemove(void);
01155 bool scrPost(void);
01156 bool scrStack(void);
01157 bool scrCache(void);
01158 bool scrSequence(void);
01159 bool scrDup(void);
01160 bool scrArray(void);
01161 bool scrList(void);
01162 bool scrArm(void);
01163 bool scrDisarm(void);
01164 bool scrNumber(void);
01165 bool scrDecimal(void);
01166 bool scrSet(void);
01167 bool scrAlias(void);
01168 bool scrRef(void);
01169 bool scrConst(void);
01170 bool scrVar(void);
01171 bool scrSize(void);
01172 bool scrInit(void);
01173 bool scrClear(void);
01174 bool scrCall(void);
01175 bool scrHas(void);
01176 bool scrMissing(void);
01177 bool scrLabel(void);
01178 bool scrCase(void);
01179 bool scrEndcase(void);
01180 bool scrError(void);
01181 bool scrIfThen(void);
01182 bool scrThen(void);
01183 bool scrElse(void);
01184 bool scrEndif(void);
01185 bool scrBegin(void);
01186 bool scrEnd(void);
01187 bool scrFor(void);
01188 bool scrRead(void);
01189 bool scrMap(void);
01190 bool scrRepeat(void);
01191 bool scrForeach(void);
01192 bool scrFordata(void);
01193 bool scrTryeach(void);
01194 bool scrSwap(void);
01195 bool scrDo(void);
01196 bool scrLoop(void);
01197 bool scrBreak(void);
01198 bool scrContinue(void);
01199 bool scrReturn(void);
01200 bool scrPop(void);
01201 bool scrSelect(void);
01202 bool scrOnce(void);
01203 bool scrLock(void);
01204 bool scrTry(void);
01205 bool scrSkip(void);
01206 bool expConditional(void);
01207
01208 public:
01209 static long getRealValue(double val, unsigned prec);
01210 long getIntValue(const char *text, unsigned prec);
01211 int getExpression(long *list, int max, unsigned prec);
01212 static double getDouble(long value, unsigned prec);
01213 static long getInteger(long value, unsigned prec);
01214 static long getTens(unsigned prec);
01215
01216 friend void addFunction(const char *name, unsigned count, Function i);
01217 friend void addConditional(const char *name, Cond test);
01218 friend void addAttribute(const char *name, Meta meta);
01219 friend class ScriptCommand;
01220
01221 protected:
01222 unsigned char lckcount;
01223
01230 ScriptInterp(ScriptCommand *cmd, size_t symsize, size_t pgsize = 1024);
01231
01232 ~ScriptInterp();
01233
01239 void getTrigger(bool use);
01240
01246 bool getOnce(void);
01247
01253 inline void Notify(unsigned long mask)
01254 {signalmask |= mask;};
01255
01261 inline void Notify(const char *str)
01262 {signalmask |= cmd->getTrapMask(str);};
01263
01269 unsigned long getMask(void);
01270
01276 void setLine(Line *line);
01277
01283 inline unsigned long getScriptMask(const char *id)
01284 {return cmd->getTrapMask(id);};
01285
01291 inline ScriptCommand *getCommand(void)
01292 {return cmd;};
01293
01301 bool conditional(void);
01302
01308 bool scrExit(void);
01309
01313 bool scrGoto(void);
01314
01318 bool scrIf(void);
01319
01323 bool ifGoto(void);
01324
01328 bool scrData(void);
01329
01335 virtual unsigned getId(void)
01336 {return 0;};
01337
01338
01345 virtual bool getGlobalTrap(unsigned id)
01346 {return false;};
01347
01348 public:
01355 bool setData(const char *scrname);
01356
01360 char getPackToken(void);
01361
01365 void clrTransactions(void)
01366 {script[stack].tranflag = false;};
01367
01375 Symbol *getVariable(size_t size = 0);
01376
01380 void rewindTemp(void);
01381
01387 void setTemp(const char *value);
01388
01397 virtual Symbol *getIndirect(char *sym)
01398 {return NULL;};
01399
01400 protected:
01404 void advance(void);
01405
01412 void error(const char *error);
01413
01421 void trap(unsigned id);
01422
01429 void trap(const char *trapname);
01430
01436 bool push(void);
01437
01443 bool pull(void);
01444
01454 bool signal(const char *trapname);
01455
01465 bool event(const char *evtname);
01466
01474 bool signal(unsigned trapid);
01475
01483 virtual bool execute(Method method)
01484 {return (this->*(method))();};
01485
01494 virtual void stop(unsigned long mask)
01495 {return;};
01496
01501 virtual void exit(void) = 0;
01502
01510 virtual Name *getScriptImage(const char *label);
01511
01518 Name *getScriptCopy(const char *src);
01519
01525 virtual void sleepScheduler(timeout_t timeout)
01526 {return;};
01527
01533 virtual void stepScheduler(const char *trapname)
01534 {trap(trapname);};
01535
01541 virtual void setExclusive(bool enable)
01542 {return;};
01543
01544 public:
01554 Symbol *getLocal(const char *name, size_t size = 0);
01555
01563 bool attach(const char *scrname);
01564
01569 void detach(void);
01570
01577 bool redirect(const char *scrname);
01578
01587 bool step(const char *trapname = NULL);
01588
01594 inline bool isActive(void)
01595 {return script[stack].line;};
01596
01604 char *getOption(const char *def = NULL);
01605
01613 char *getKeyword(const char *keyword);
01614
01618 int initKeywords(int size);
01619
01627 char *getValue(const char *def = NULL);
01628
01635 char *getString(void);
01636
01642 char *getTempBuffer(void);
01643
01650 char *getContent(char *sym);
01651
01657 inline Line *getScript(void)
01658 {return script[stack].line;};
01659
01665 inline bool hasEvents(void)
01666 {return (script[stack].script->events != NULL);};
01667
01673 Line *getPrescan(void);
01674
01680 const char *getMember(void);
01681
01687 inline Name *getObject(void)
01688 {return script[stack].script;};
01689
01696 inline ScriptImage *getImage(void)
01697 {return image;};
01698
01704 inline void autoloop(bool enable)
01705 {loop = enable;};
01706
01707 inline int mapicmp(const char *s1, const char *s2)
01708 {return cmd->mapicmp(s1, s2);};
01709
01710 inline int mapnicmp(const char *s1, const char *s2, size_t n)
01711 {return cmd->mapnicmp(s1, s2, n);};
01712
01718 inline unsigned getDecimal(void)
01719 {return script[stack].decimal;};
01720 };
01721
01722 #ifdef CCXX_NAMESPACES
01723 };
01724 #endif
01725
01726 #endif
01727