00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef __CMD_Manager_H__
00023 #define __CMD_Manager_H__
00024
00025 #include "CMD_API.h"
00026 #include <iostream.h>
00027 #include <UT/UT_Assert.h>
00028 #include <UT/UT_String.h>
00029 #include <UT/UT_StringArray.h>
00030 #include <UT/UT_PtrArray.h>
00031 #include <UT/UT_SymbolTable.h>
00032 #include <CH/CH_Manager.h>
00033 #if !defined(GAMEOS)
00034 #include <UT/UT_Spawn.h>
00035 #endif
00036 #include <FS/FS_ServerSocketListener.h>
00037 #include "CMD_Command.h"
00038 #include "CMD_Source.h"
00039 #include "CMD_Variable.h"
00040
00041 class UT_WorkArgs;
00042 class CH_AutoEventHandler;
00043 class CMD_Args;
00044 class CMD_Loop;
00045 class CMD_AliasTable;
00046 class CMD_Manager;
00047 class CMD_Command;
00048
00049 extern "C" {
00050 DLLEXPORT extern void CMDextendLibrary(CMD_Manager *theManager);
00051 }
00052
00053 typedef void (*CMD_PostCmdCallback)(void *userdata);
00054 typedef void (*CMD_CommandEchoCallback)(const char *echo_line,void *userdata);
00055
00056 typedef UT_PtrArray<CMD_Command *> CMD_CommandList;
00057 typedef UT_PtrArray<CMD_Source *> CMD_SourceStack;
00058 typedef UT_PtrArray<char *> CMD_PromptStack;
00059
00060 #define CMD_STATUS_VARIABLE "status"
00061
00062 class CMD_API CMD_Manager : public CH_Manager {
00063 public:
00064 CMD_Manager(const char *appname, int load_dsos = 1);
00065 virtual ~CMD_Manager();
00066
00067 virtual void setContext();
00068
00069 static bool getContextExists() { return theManager != NULL; }
00070 static CMD_Manager *getContext()
00071 {
00072 UT_ASSERT( theManager );
00073 return theManager;
00074 }
00075
00076
00077
00078
00079
00080 void sendInput(const char *input, bool create_block = true);
00081
00082
00083
00084
00085 void sendMultiLineInput(char *input,
00086 bool create_block = true);
00087
00088
00089 void execute(const char *cmd, int addToHistory = 0,
00090 ostream *out=0, ostream *err=0,
00091 int doAliasExpansion = 1,
00092 bool create_block = true);
00093
00094
00095
00096 void completeCommand(const char *prefix,
00097 UT_String &command) const;
00098
00099 void matchCommands(const char *prefix,
00100 UT_StringArray &matches) const;
00101
00102
00103
00104 void installCommand(const char *name, const char *options,
00105 CMD_Callback cb, bool is_safe = true);
00106
00107
00108
00109
00110 CMD_PostCmdCallback setPostCmdCallback(
00111 CMD_PostCmdCallback callback, void *userdata);
00112 void * getPostCmdCallbackData() const
00113 { return myPostCmdCallbackData; }
00114
00115
00116
00117
00118 void setCommandEchoCallback(
00119 CMD_CommandEchoCallback callback,
00120 void *userdata);
00121 void * getCommandEchoCallbackData() const
00122 { return myCommandEchoCallbackData; }
00123
00124
00125 void commandDump(ostream &os, const char *pattern=0,
00126 const char *prefix=0) const;
00127 void commandHelp(ostream &os, const char *cmd) const;
00128 void searchHelp(CMD_CommandList &list,
00129 const char *filename,
00130 const char *pattern) const;
00131
00132 void printHelp(ostream &os, const char *filename,
00133 const char *pattern = 0) const;
00134 void saveAliases(ostream &os);
00135 void saveVariables(ostream &os);
00136
00137 int setHistoryCapture(int onOff)
00138 {
00139 int prev = myHistoryCapture;
00140 myHistoryCapture = onOff;
00141 return prev;
00142 }
00143 CMD_Source *pushSource(const char *filename, int verbose=0);
00144 CMD_Source *popSource(int checkLoop = 1);
00145 CMD_Source *getSource()
00146 {
00147 UT_ASSERT(mySourceStack.entries());
00148 return mySourceStack(mySourceStack.entries()-1);
00149 }
00150 int getSourceLevel() { return mySourceStack.entries()-1; }
00151
00152 void pushOutputStreams(ostream &out, ostream &err);
00153 void popOutputStreams();
00154
00155 void unsetVariable(const char *name);
00156 void resetVariables();
00157 void setVariable(const char *name, const char *value,
00158 int local, int uplevel=0);
00159
00160 bool hasVariable(const char *name) const;
00161 bool getVariable(const char *name, UT_String &value)
00162 { return getVariableValueByName(name, value); }
00163 bool getVariable(const char *name, float &value)
00164 { return getVariableValueByName(name, value); }
00165 bool getVariable(const char *name, int &value)
00166 { return getVariableValueByName(name, value); }
00167
00168 bool hasEnv(const char *name) const;
00169 bool getEnv(const char *name, UT_String &value);
00170 void getVariableNames(UT_StringArray &names, int dirty=0);
00171 int clearDirtyVariables();
00172 int isVariableNameOk(const char *name);
00173
00174 void setMotName(const char *path);
00175 void setJob(const char *path);
00176
00177
00178 unsigned getCommandsRun() const { return myCommandCount; }
00179
00180 ostream &getError(int printMessage = 1);
00181
00182
00183
00184 ostream *setStandardOut(ostream &os);
00185 ostream *setStandardErr(ostream &os);
00186
00187
00188 void streamDeleted(ostream &os);
00189
00190 void setPrompt(const char *prompt);
00191 const char *getPrompt(int level = -1) const
00192 {
00193 if (level < 0 || level >= myPromptStack.entries())
00194 level = myPromptStack.entries()-1;
00195 return myPromptStack(level);
00196 }
00197 void pushPrompt(const char *prompt);
00198 void popPrompt();
00199
00200 int isLoopCommand(const char *str);
00201
00202 int evaluateCondition(const char *expr);
00203 int evaluateCondition(int argc, const char *argv[]);
00204
00205
00206
00207
00208 static void saveProtectedString(ostream &os, const char *s);
00209 static void expandControlSequences(UT_String &str);
00210
00211 void dumpHistory(ostream &os) const;
00212 void clearHistory();
00213
00214
00215 const char *getHistoryCommand(int n) const;
00216 unsigned int getHistoryCount() const;
00217
00218 CMD_VariableTable *getGlobalVariables() { return myGlobals; }
00219 CMD_AliasTable *getAliases() { return myAliases; }
00220 bool getAlias(const char *name, UT_String &value);
00221 void setAlias(const char *name, const char *value);
00222 void destroyAlias(const char *name);
00223 void destroyAliases();
00224
00225
00226
00227
00228
00229 void allowEnvironmentToOverwriteVariable(
00230 const char *name, bool onoff);
00231
00232
00233 bool isEnvironmentAllowedToOverwriteVariable(
00234 const char *name);
00235
00236
00237 void setIsLoadingGlobalVariables(bool onoff)
00238 { myIsLoadingGlobalVariables = onoff; }
00239
00240 bool isLoadingGlobalVariables()
00241 { return myIsLoadingGlobalVariables; }
00242
00243 void saveCommandString(ostream &os, const UT_String &str);
00244
00245
00246 void getFrameRange(CMD_Args &args,
00247 int &fstart, int &fend, int &finc,
00248 char oframe = 'f', char ofinc = 'i');
00249
00250 void setContinueLevel(int level) { myContinueLevel=level; }
00251 int getContinueLevel() const { return myContinueLevel; }
00252 void bumpBreakLevel(int dir) { myBreakLevel += dir; }
00253 int getBreakLevel() const { return myBreakLevel; }
00254 void bumpLoopNestLevel(int dir)
00255 {
00256 myLoopNestLevel += dir;
00257 if (!myLoopNestLevel)
00258 {
00259 myBreakLevel = 0;
00260 }
00261 }
00262 int getLoopNestLevel() const { return myLoopNestLevel; }
00263 CMD_Loop *buildLoop(const char *text);
00264 void doPrompt();
00265 void getPrompt(UT_String &str);
00266
00267 void setVerbose(int on_off);
00268 int getVerbose() const;
00269
00270 void setCommandEcho(bool on_off)
00271 { myCommandEchoFlag = on_off; }
00272 bool getCommandEcho() const { return myCommandEchoFlag; }
00273
00274 void setIORedirection(int on_off);
00275 int getIORedirection() const;
00276
00277 const char *getOptions(const char *cmdName);
00278
00279 int isCommandDefined(const char *name)
00280 {
00281 return findCommand(name, 1) >= 0;
00282 }
00283 void getDSOCommands(CMD_CommandList &list);
00284
00285 bool isLoading() const { return (myInLoadCount > 0); }
00286 void beginLoading() { myInLoadCount++; }
00287 void endLoading() { myInLoadCount--; }
00288
00289 void setSafeMode(int safe_mode);
00290 int isInSafeMode() const;
00291 void setBrowserMode(int browser_mode);
00292 int isInBrowserMode() const;
00293
00294 void setStatusCode( int status_code )
00295 { myStatusCode = status_code; }
00296 int getStatusCode() const
00297 { return myStatusCode; }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 bool openPort(int port, bool safe, bool quiet,
00308 bool wait, CMD_Args &args,
00309 const char *execute, pid_t *pid,
00310 bool separateerrors, bool suppress = true,
00311 const char *ip_mask = 0,
00312 FS_ServerSocketListener::ChildExitedCallback
00313 child_exited_callback = 0,
00314 bool detach_console_for_execute=false,
00315 bool drain_queue_when_waiting_for_exec=true);
00316 bool openPort(int port, bool safe, bool quiet,
00317 bool wait, ostream &error_output,
00318 const char *execute, pid_t *pid,
00319 bool separateerrors, bool suppress = true,
00320 const char *ip_mask = 0,
00321 FS_ServerSocketListener::ChildExitedCallback
00322 child_exited_callback = 0,
00323 bool detach_console_for_execute=false,
00324 bool drain_queue_when_waiting_for_exec=true);
00325 bool openPort(int port, bool safe, bool quiet,
00326 bool wait, CMD_Args &args,
00327 const char *const*execute_argv, pid_t *pid,
00328 bool separateerrors, bool suppress = true,
00329 const char *ip_mask = 0,
00330 FS_ServerSocketListener::ChildExitedCallback
00331 child_exited_callback = 0,
00332 bool detach_console_for_execute=false,
00333 bool drain_queue_when_waiting_for_exec=true);
00334 bool openPort(int port, bool safe, bool quiet,
00335 bool wait, ostream &error_output,
00336 const char *const*execute_argv, pid_t *pid,
00337 bool separateerrors, bool suppress = true,
00338 const char *ip_mask = 0,
00339 FS_ServerSocketListener::ChildExitedCallback
00340 child_exited_callback = 0,
00341 bool detach_console_for_execute=false,
00342 bool drain_queue_when_waiting_for_exec=true);
00343
00344 void closePort(int port);
00345 void closeAutoPort();
00346
00347 bool beginChannelBlock();
00348 bool endChannelBlock();
00349
00350 void echoOff();
00351 void echoOn();
00352
00353
00354
00355 static int getHScriptPort();
00356
00357
00358
00359
00360 static void cmd_python(CMD_Args &args);
00361
00362 protected:
00363 virtual bool getVariableString(const char *name, UT_String &value,
00364 int &timeDepend, int thread);
00365
00366 private:
00367 template <typename T> bool
00368 getVariableValueByName(const char *name, T &value);
00369
00370 void internalSendInput(const char *input,
00371 bool run_pushed_source=false);
00372
00373 static void cmd_if (CMD_Args &args);
00374 static void cmd_else (CMD_Args &args);
00375 static void cmd_endif(CMD_Args &args);
00376 static void cmd_read (CMD_Args &args);
00377
00378
00379 bool openPort(int port, bool safe, bool quiet,
00380 bool wait, CMD_Args *args,
00381 ostream *error_output,
00382 const char *const*execute_argv, pid_t *pid,
00383 bool separateerrors, bool suppress,
00384 const char *ip_mask,
00385 FS_ServerSocketListener::ChildExitedCallback
00386 child_exited_callback,
00387 bool detach_console_for_execute,
00388 bool drain_queue_when_waiting_for_exec=true);
00389
00390
00391 void processInput(CMD_Source *top, const char *line);
00392 void internalExecute(const char *str);
00393 void runCommand(char *str);
00394 void initLibraryGlue(void);
00395 void setGlueContext();
00396 void setPortContext();
00397 int findCommand(const char *name, int exact = 0);
00398 void sortCommands(void);
00399 void installBaseCommands(void);
00400 void addPortExtension();
00401 CMD_CommandList *getCommandList(const char *list_name);
00402 void installBuiltIn();
00403 int aliasExpand(UT_String &str);
00404 void setReadVariables(const char *str);
00405 void breakAllSources();
00406 void updateNoAliasVariable();
00407 void pushStandardOut(ostream *os);
00408 void popStandardOut();
00409 void pushStandardErr(ostream *os);
00410 void popStandardErr();
00411 void updateStatusVariable();
00412
00413
00414
00415 void stripOptions(const CMD_Command *cmd, CMD_Args &args);
00416
00417 CMD_CommandList *myCmdList;
00418 CMD_PromptStack myPromptStack;
00419 UT_String myPendingCommands;
00420 UT_String myReadVariables;
00421 int myReadVariablesLocal;
00422 UT_SymbolTable *myExactList;
00423 CMD_SourceStack mySourceStack;
00424 CMD_VariableTable *myGlobals;
00425 UT_SymbolTable myEnvironmentOverridableGlobals;
00426 bool myIsLoadingGlobalVariables;
00427 CMD_AliasTable *myAliases;
00428 UT_PtrArray<ostream *> myStandardOuts;
00429 UT_PtrArray<ostream *> myStandardErrs;
00430 unsigned myCommandCount;
00431 int myAliasProtect;
00432 int myFlags;
00433 int myBreakLevel;
00434 int myContinueLevel;
00435 int myLoopNestLevel;
00436 int myLocalSetLevel;
00437 int myExecuteCommandStack;
00438 int myStatusCode;
00439 unsigned myAliasExpand:1,
00440 myHistoryExpand:1,
00441 myHistoryCapture:1,
00442 myIsInSafeMode:1,
00443 myIsInBrowserMode:1;
00444 UT_String myAppName;
00445 UT_String myUnfinishedInput;
00446
00447 int myInLoadCount;
00448 int myEchoOff;
00449
00450 CMD_PostCmdCallback myPostCmdCallback;
00451 void *myPostCmdCallbackData;
00452
00453
00454 CMD_CommandEchoCallback myCommandEchoCallback;
00455 void *myCommandEchoCallbackData;
00456
00457
00458
00459
00460 bool myCommandEchoFlag;
00461
00462 static CH_AutoEventHandler *theCHEventHandler;
00463 static int theChannelBlockCount;
00464 static CMD_Manager *theManager;
00465 };
00466
00467 inline
00468 CMD_Manager *CMDgetManager()
00469 {
00470 return CMD_Manager::getContext();
00471 }
00472
00473
00474
00475
00476
00477
00478 template <typename T> bool
00479 CMD_Manager::getVariableValueByName(const char *name, T &value)
00480 {
00481 CMD_Source *src;
00482 CMD_VariableTable *table;
00483 int i;
00484
00485 for (i = mySourceStack.entries()-1; i >= 0; i--)
00486 {
00487 src = mySourceStack(i);
00488 table = src->getLocalVariables();
00489 if (table->getVariable(name, value))
00490 return true;
00491 }
00492 return myGlobals->getVariable(name, value);
00493 }
00494
00495 #endif