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 struct _line;
00063
00064 #define MAX_LOCKS 8
00065 #define TRAP_BITS (sizeof(unsigned long) * 8)
00066 #define SCRIPT_STACK_SIZE 20
00067 #define SCRIPT_TEMP_SPACE 16
00068 #define KEYWORD_INDEX_SIZE 37
00069 #define SYMBOL_INDEX_SIZE 187
00070 #define SCRIPT_INDEX_SIZE KEYWORD_INDEX_SIZE
00071
00072 typedef bool (ScriptInterp::*scriptmethod_t)(void);
00073 typedef char *(ScriptCommand::*scriptcheck_t)(struct _line *line, ScriptImage *img);
00074
00075 typedef enum
00076 {
00077 SYM_TYPE_NORMAL = 0,
00078 SYM_TYPE_ALIAS,
00079 SYM_TYPE_FIFO,
00080 SYM_TYPE_INDEX,
00081 SYM_TYPE_SEQUENCE,
00082 SYM_TYPE_STACK,
00083 SYM_TYPE_COUNTER,
00084 SYM_TYPE_TRIGGER,
00085 SYM_TYPE_POINTER
00086 } scriptsymtype_t;
00087
00088 #pragma pack(1)
00089 typedef struct _symbol
00090 {
00091 struct _symbol *next;
00092 char *id;
00093 struct
00094 {
00095 unsigned size : 16;
00096 bool initial : 1;
00097 bool system : 1;
00098 bool readonly : 1;
00099 bool commit : 1;
00100 scriptsymtype_t type : 6;
00101 } flags;
00102 char data[1];
00103 } scriptsymbol_t;
00104
00105 typedef struct _line
00106 {
00107 struct _line *next;
00108 unsigned long cmask;
00109 unsigned long mask;
00110 unsigned short loop;
00111 unsigned short line;
00112 unsigned char argc;
00113 bool error : 1;
00114 scriptmethod_t method;
00115 char *cmd;
00116 char **args;
00117 } scriptline_t;
00118
00119 typedef struct _script
00120 {
00121 struct _script *next;
00122 struct _line *first;
00123 struct _line *trap[TRAP_BITS];
00124 struct _line *skip[10];
00125 unsigned long mask;
00126 char *name;
00127 enum
00128 {
00129 SCRIPT_TYPE_ORIGINAL,
00130 SCRIPT_TYPE_COPIED,
00131 SCRIPT_TYPE_COPY
00132 } mode : 2;
00133 } scriptname_t;
00134
00135 typedef struct
00136 {
00137 const char *keyword;
00138 scriptmethod_t method;
00139 scriptcheck_t check;
00140 } SCRKEYWORDS;
00141
00142 #pragma pack()
00143
00151 class ScriptLocks : private Mutex
00152 {
00153 private:
00154 friend class ScriptInterp;
00155
00156 ScriptInterp *locks[MAX_LOCKS];
00157
00158 void Release(ScriptInterp *interp);
00159 bool Lock(ScriptInterp *interp, unsigned id);
00160 bool Unlock(ScriptInterp *interp, unsigned id);
00161
00162 ScriptLocks();
00163 };
00164
00174 class CCXX_CLASS_EXPORT ScriptSession
00175 {
00176 private:
00177 friend class ScriptInterp;
00178 ScriptInterp *interp;
00179
00180 protected:
00187 void stepScheduler(const char *sighandler = NULL);
00188
00195 void sleepScheduler(timeout_t delay);
00196
00200 ScriptSession(ScriptInterp *interp);
00201
00202 virtual ~ScriptSession()
00203 {return;};
00204
00205 public:
00209 virtual void waitHandler(void) = 0;
00210 };
00211
00219 class CCXX_CLASS_EXPORT ScriptProperty
00220 {
00221 private:
00222 friend class ScriptInterp;
00223
00224 static ScriptProperty *first;
00225 ScriptProperty *next;
00226 const char *id;
00227
00228 protected:
00237 virtual void setProperty(char *data, char *temp, size_t size) = 0;
00238
00246 virtual void getProperty(char *data, char *temp, size_t size) = 0;
00247
00255 virtual void adjProperty(char *data, size_t size, int adjust)
00256 {return;};
00257
00263 virtual size_t getPropertySize(void)
00264 {return 0;};
00265
00266 ScriptProperty(const char *name);
00267
00268 public:
00269 static ScriptProperty* find(const char *name);
00270 };
00271
00279 class CCXX_CLASS_EXPORT ScriptModule
00280 {
00281 private:
00282 friend class ScriptInterp;
00283 friend class ScriptCommand;
00284 static ScriptModule *first;
00285 ScriptModule *next;
00286 const char *cmd;
00287
00288 protected:
00294 virtual void moduleAttach(ScriptInterp *interp)
00295 {return;};
00296
00302 virtual void moduleDetach(ScriptInterp *interp)
00303 {return;};
00304
00313 virtual char *getSession(ScriptInterp *interp, scriptline_t *line, ScriptSession **session)
00314 {return NULL;};
00315
00323 virtual char *checkScript(scriptline_t *line, ScriptImage *img)
00324 {return NULL;};
00325
00331 ScriptModule(const char *name);
00332
00339 static ScriptModule *find(const char *name);
00340 };
00341
00353 class CCXX_CLASS_EXPORT ScriptCommand : public Keydata, public Mutex
00354 {
00355 private:
00356 friend class ScriptImage;
00357 friend class ScriptInterp;
00358 friend class ScriptModule;
00359
00360 #pragma pack(1)
00361 typedef struct _keyword
00362 {
00363 struct _keyword *next;
00364 scriptmethod_t method;
00365 scriptcheck_t check;
00366 char keyword[1];
00367 } keyword_t;
00368 #pragma pack()
00369
00370
00371 keyword_t *keywords[KEYWORD_INDEX_SIZE];
00372 char *traps[TRAP_BITS];
00373 ScriptImage *active;
00374 int keyword_count;
00375 int trap_count;
00376
00377 protected:
00385 scriptmethod_t getHandler(const char *keyword);
00386
00394 char *Check(char *command, scriptline_t *line, ScriptImage *img);
00395
00402 virtual unsigned getTrapId(const char *trap);
00403
00409 virtual unsigned long getTrapDefault(void)
00410 {return 0x00000003;};
00411
00417 virtual unsigned long getTrapHandler(scriptname_t *scr)
00418 {return getTrapDefault();}
00419
00427 virtual unsigned long getTrapMask(unsigned id);
00428
00437 virtual unsigned long getTrapModifier(const char *trapname)
00438 {return getTrapMask(trapname);};
00439
00448 virtual unsigned long getTrapMask(const char *trapname);
00449
00453 char *chkIgnore(scriptline_t *line, ScriptImage *img);
00454
00458 char *chkModule(scriptline_t *line, ScriptImage *img);
00459
00463 char *chkUse(scriptline_t *line, ScriptImage *img);
00464
00471 char *chkHasModify(scriptline_t *line, ScriptImage *img);
00472
00478 char *chkHasVars(scriptline_t *line, ScriptImage *img);
00479
00487 char *chkHasList(scriptline_t *line, ScriptImage *img);
00488
00496 char *chkNoArgs(scriptline_t *line, ScriptImage *img);
00497
00505 char *chkHasArgs(scriptline_t *line, ScriptImage *img);
00506
00514 void Load(SCRKEYWORDS *keywords);
00515
00524 int Trap(const char *name);
00525
00531 inline int getCount(void)
00532 {return trap_count;};
00533
00540 virtual char *Check(scriptcheck_t check, scriptline_t *line, ScriptImage *img)
00541 {return (this->*(check))(line, img);};
00542
00551 ScriptCommand(const char *cfgfile);
00552 };
00553
00563 class CCXX_CLASS_EXPORT ScriptSymbol : public SharedMemPager
00564 {
00565 private:
00566 friend class ScriptInterp;
00567
00568 int symsize;
00569 scriptsymbol_t *index[SYMBOL_INDEX_SIZE];
00570 scriptsymbol_t *trigger;
00571
00572 unsigned getIndex(const char *symbol);
00573
00574 protected:
00589 virtual scriptsymbol_t *getEntry(const char *symbol, int size = 0);
00590
00600 virtual void Commit(scriptsymbol_t *sym);
00601
00602 public:
00608 scriptsymbol_t *getTrigger(void);
00609
00615 inline int getSymbolSize(void)
00616 {return symsize;};
00617
00618 ScriptSymbol(int size, int pgsize = 1024);
00619
00626 void *getPointer(const char *symbol);
00627
00635 bool setPointer(const char *symbol, void *data);
00636
00643 char *getSymbol(const char *symbol);
00644
00652 char *setSymbol(const char *symbol, const char *value = "");
00653
00661 char *setConst(const char *symbol, const char *value = "");
00662
00671 bool makeSequence(const char *id, unsigned char count, unsigned char recsize);
00672
00681 bool makeStack(const char *id, unsigned char count, unsigned char recsize);
00682
00691 bool makeFifo(const char *id, unsigned char count, unsigned char recsize);
00692
00699 bool makeCounter(const char *id);
00700
00708 bool postSymbol(scriptsymbol_t *sym, const char *value);
00709
00710
00718 bool removeSymbol(scriptsymbol_t *sym, const char *value);
00719
00726 char *readSymbol(scriptsymbol_t *sym);
00727
00735 bool setAlias(const char *symbol, const char *source);
00736
00743 scriptsymbol_t *getAlias(const char *symbol);
00744
00752 char *setSymbol(const char *symbol, int size = 0);
00753
00761 void clrSymbol(const char *id);
00762
00766 void Purge(void);
00767
00771 unsigned Gather(scriptsymbol_t **index, unsigned max, const char *prefrix, const char *suffix = NULL);
00772 };
00773
00783 class CCXX_CLASS_EXPORT ScriptImage : public MemPager
00784 {
00785 protected:
00786 std::ifstream scrSource;
00787 std::istream *scrStream;
00788 ScriptCommand *cmds;
00789 int refcount;
00790 scriptname_t *index[SCRIPT_INDEX_SIZE];
00791 char buffer[512];
00792 char *bp;
00793 bool quote;
00794 Mutex duplock;
00795
00796 friend class ScriptInterp;
00797 friend class ScriptModule;
00798
00799 char *getToken(void);
00800
00807 scriptmethod_t getHandler(const char *keyword)
00808 {return cmds->getHandler(keyword);};
00809
00817 ScriptImage(ScriptCommand *cmdset);
00818
00822 void Purge(void);
00823
00831 scriptname_t *Include(const char *scrfile);
00832
00841 int Compile(const char *scrfile);
00842
00852 int Compile(const char *scrfile, char *name);
00853
00861 int Compile(std::istream *str, char *name, const char *scrname = NULL);
00862
00868 void Commit(void);
00869
00870 public:
00877 virtual scriptname_t *getScript(const char *name);
00878
00886 virtual scriptname_t *dupScript(const char *name, const char *target);
00887
00896 unsigned Gather(const char *suffix, scriptname_t **array, unsigned size);
00897
00904 inline std::istream *getSource(void)
00905 {return (std::istream *)&scrSource;};
00906 };
00907
00915 class CCXX_CLASS_EXPORT ScriptInterp : public ScriptSymbol
00916 {
00917 private:
00918 friend class ScriptImage;
00919 friend class ScriptSession;
00920 friend class ScriptModule;
00921
00922 #pragma pack(1)
00923 typedef struct
00924 {
00925 scriptname_t *script;
00926 scriptline_t *line, *read;
00927 unsigned char index;
00928 ScriptSymbol *local;
00929 }
00930 scriptcontext_t;
00931 #pragma pack()
00932
00933 static ScriptLocks locks;
00934 ScriptCommand *cmd;
00935 ScriptImage *image;
00936 ScriptSession *session;
00937 scriptcontext_t script[SCRIPT_STACK_SIZE + 1];
00938 char *temps[SCRIPT_TEMP_SPACE];
00939 int tempidx;
00940 int stack;
00941 size_t symsize, pgsize;
00942 bool once, loop;
00943 char packtoken;
00944 unsigned long signalmask;
00945
00946 bool scrTemplate(void);
00947 bool scrEnable(void);
00948 bool scrDisable(void);
00949 bool scrUse(void);
00950 bool scrLoadable(void);
00951 bool scrPacked(void);
00952 bool scrPack(void);
00953 bool scrUnpack(void);
00954 bool scrOn(void);
00955 bool scrSlog(void);
00956 bool scrBasename(void);
00957 bool scrDirname(void);
00958 bool scrFullpath(void);
00959 bool scrGather(void);
00960 bool scrDump(void);
00961 bool scrInc(void);
00962 bool scrDec(void);
00963 bool scrFifo(void);
00964 bool scrCounter(void);
00965 bool scrRemove(void);
00966 bool scrPost(void);
00967 bool scrStack(void);
00968 bool scrSequence(void);
00969 bool scrDup(void);
00970 bool scrArray(void);
00971 bool scrList(void);
00972 bool scrArm(void);
00973 bool scrDisarm(void);
00974 bool scrSet(void);
00975 bool scrAlias(void);
00976 bool scrConst(void);
00977 bool scrSize(void);
00978 bool scrInit(void);
00979 bool scrClear(void);
00980 bool scrCall(void);
00981 bool scrHas(void);
00982 bool scrMissing(void);
00983 bool scrIf(void);
00984 bool scrIfThen(void);
00985 bool scrFor(void);
00986 bool scrRead(void);
00987 bool scrRepeat(void);
00988 bool scrForeach(void);
00989 bool scrTryeach(void);
00990 bool scrSwap(void);
00991 bool scrDo(void);
00992 bool scrLoop(void);
00993 bool scrBreak(void);
00994 bool scrContinue(void);
00995 bool scrReturn(void);
00996 bool scrPop(void);
00997 bool scrSelect(void);
00998 bool scrOnce(void);
00999 bool scrLock(void);
01000 bool scrTry(void);
01001 bool scrSkip(void);
01002
01003 friend class ScriptCommand;
01004
01005 protected:
01012 ScriptInterp(ScriptCommand *cmd, size_t symsize, size_t pgsize = 1024);
01013
01019 void getTrigger(bool use);
01020
01026 bool getOnce(void);
01027
01033 inline void Notify(unsigned long mask)
01034 {signalmask |= mask;};
01035
01041 inline void Notify(const char *str)
01042 {signalmask |= cmd->getTrapMask(str);};
01043
01049 unsigned long getMask(void);
01050
01056 inline unsigned long getScriptMask(const char *id)
01057 {return cmd->getTrapMask(id);};
01058
01064 inline ScriptCommand *getCommand(void)
01065 {return cmd;};
01066
01074 bool Conditional(void);
01075
01081 bool scrExit(void);
01082
01086 bool scrGoto(void);
01087
01091 bool scrData(void);
01092
01098 virtual unsigned getId(void)
01099 {return 0;};
01100
01101
01108 virtual bool getGlobalTrap(unsigned id)
01109 {return false;};
01110
01118 scriptsymbol_t *getVariable(size_t size = 0);
01119
01120
01129 virtual scriptsymbol_t *getIndirect(char *sym)
01130 {return NULL;};
01131
01135 void Advance(void);
01136
01143 void Error(const char *error);
01144
01152 void Trap(unsigned id);
01153
01160 void Trap(const char *trapname);
01161
01167 bool Push(void);
01168
01174 bool Pull(void);
01175
01185 bool Signal(const char *trapname);
01186
01194 bool Signal(unsigned trapid);
01195
01203 virtual bool Execute(scriptmethod_t method)
01204 {return (this->*(method))();};
01205
01214 virtual void Stop(unsigned long mask)
01215 {return;};
01216
01221 virtual void Exit(void) = 0;
01222
01230 virtual scriptname_t *getScriptImage(const char *label);
01231
01238 scriptname_t *getScriptCopy(const char *src);
01239
01245 virtual void sleepScheduler(timeout_t timeout)
01246 {return;};
01247
01253 virtual void stepScheduler(const char *trapname)
01254 {Trap(trapname);};
01255
01256 public:
01266 scriptsymbol_t *getLocal(const char *name, size_t size = 0);
01267
01275 bool Attach(const char *scrname);
01276
01281 void Detach(void);
01282
01289 bool Redirect(const char *scrname);
01290
01299 bool Step(const char *trapname = NULL);
01300
01306 inline bool isActive(void)
01307 {return script[stack].line;};
01308
01316 char *getOption(const char *def = NULL);
01317
01325 char *getKeyword(const char *keyword);
01326
01330 int initKeywords(int size);
01331
01339 char *getValue(const char *def = NULL);
01340
01347 char *getContent(char *sym);
01348
01354 inline scriptline_t *getScript(void)
01355 {return script[stack].line;};
01356
01362 const char *getMember(void);
01363
01369 inline scriptname_t *getObject(void)
01370 {return script[stack].script;};
01371
01378 inline ScriptImage *getImage(void)
01379 {return image;};
01380
01386 inline void autoloop(bool enable)
01387 {loop = enable;};
01388 };
01389
01399 class ScriptPackage : protected DSO
01400 {
01401 private:
01402 static ScriptPackage *first;
01403 ScriptPackage *next;
01404 char *filename;
01405
01406 ScriptPackage(char *name);
01407
01408 public:
01409 CCXX_MEMBER_EXPORT(static bool) usePackage(const char *name);
01410 };
01411
01412 #ifdef CCXX_NAMESPACES
01413 };
01414 #endif
01415
01416 #endif
01417