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
00036 #include "bbtkInterpreterVirtual.h"
00037
00038 #include "bbtkConfigurationFile.h"
00039 #include "bbtkUtilities.h"
00040
00041
00042 #include <sys/stat.h>
00043 #include <algorithm>
00044 #ifdef CMAKE_HAVE_TERMIOS_H
00045 #include <termios.h>
00046 #define BBTK_USE_TERMIOS_BASED_PROMPT
00047 #endif
00048
00049 #include <string>
00050
00051 namespace bbtk
00052 {
00053
00054
00055 InterpreterVirtual::Pointer InterpreterVirtual::New()
00056 {
00057 bbtkDebugMessage("kernel",9,"InterpreterVirtual::New()"<<std::endl);
00058 return MakePointer( new InterpreterVirtual() );
00059 }
00060
00061
00062
00063 InterpreterVirtual::InterpreterVirtual()
00064 {
00065 Init();
00066 }
00067
00068
00069
00070
00071 void InterpreterVirtual::Init()
00072 {
00073 mUser = 0;
00074 mCommandLine = false;
00075 mThrow = false;
00076 bufferNb = 0;
00077 bbtk::MessageManager::RegisterMessageType("echo","Level>0 : Prints the output of the 'print' commands of the user.\n\tLevel>1 : Prints the command being interpreted",1);
00078 bbtk::MessageManager::RegisterMessageType("Interpreter","Messages of the interpreter",0);
00079 bbtkDebugMessageInc("Interpreter",9,"InterpreterVirtual::Interpreter()" <<std::endl);
00080
00081
00082
00083
00084
00085
00086
00087 CommandInfoType info;
00088
00089 info.keyword = "new";
00090 info.argmin = 2;
00091 info.argmax = 2;
00092 info.code = cNew;
00093 info.syntax = "new <type> <name>";
00094 info.help = "Creates a new black box of type <type> with name <name>";
00095 mCommandDict[info.keyword] = info;
00096
00097 info.keyword = "delete";
00098 info.argmin = 1;
00099 info.argmax = 1;
00100 info.code = cDelete;
00101 info.syntax = "delete <box>";
00102 info.help = "Deletes the black box of name <box>";
00103 mCommandDict[info.keyword] = info;
00104
00105 info.keyword = "clear";
00106 info.argmin = 0;
00107 info.argmax = 0;
00108 info.code = cClear;
00109 info.syntax = "clear";
00110 info.help = "Clears the currently defined complex box (deletes all its boxes and connections)";
00111 mCommandDict[info.keyword] = info;
00112
00113 info.keyword = "break";
00114 info.argmin = 0;
00115 info.argmax = 0;
00116 info.code = cBreak;
00117 info.syntax = "break";
00118 info.help = "Breaks the current execution";
00119 mCommandDict[info.keyword] = info;
00120
00121 info.keyword = "newgui";
00122 info.argmin = 2;
00123 info.argmax = 2;
00124 info.code = cNewGUI;
00125 info.syntax = "newgui <box> <name>";
00126 info.help = "Automatically creates a graphical user interface with name <name> for the black box <box> and connects it to the box inputs";
00127 mCommandDict[info.keyword] = info;
00128
00129 info.keyword = "connect";
00130 info.argmin = 2;
00131 info.argmax = 2;
00132 info.code = cConnect;
00133 info.syntax = "connect <box1.output> <box2.input>";
00134 info.help = "Connects the ouput <output> of black box <box1> to the input <input> of black box <box2>";
00135 mCommandDict[info.keyword] = info;
00136
00137 info.keyword = "print";
00138 info.argmin = 1;
00139 info.argmax = 1;
00140 info.code = cPrint;
00141 info.syntax = "print <string>";
00142 info.help = "Prints the string. Substitutes any token of the form '$box.output$' by the string adaptation of the output of the box (requires the right adaptor). No carriage return is issued at the end, use '\\n' to add carriage returns. The level of 'echo' messages must be greater than 1 (see the command 'message').";
00143 mCommandDict[info.keyword] = info;
00144
00145 info.keyword = "exec";
00146 info.argmin = 1;
00147 info.argmax = 2;
00148 info.code = cExec;
00149 info.syntax = "exec <box | 'freeze' | 'unfreeze' | 'freeze_no_error' >";
00150 info.help = "Executes the black box of name <box> (and connected boxes if needed). If the special keyword 'freeze' is given then freezes any further execution command. 'unfreeze' reverts to normal execution mode. 'freeze_no_error' is like freeze but also skips any error.";
00151 mCommandDict[info.keyword] = info;
00152
00153 info.keyword = "package";
00154 info.argmin = 1;
00155 info.argmax = 1;
00156 info.code = cPackage;
00157 info.syntax = "package <name>";
00158 info.help = "Begins the definition of a package.";
00159 mCommandDict[info.keyword] = info;
00160
00161 info.keyword = "endpackage";
00162 info.argmin = 0;
00163 info.argmax = 0;
00164 info.code = cEndPackage;
00165 info.syntax = "endpackage";
00166 info.help = "Ends the definition of a package.";
00167 mCommandDict[info.keyword] = info;
00168
00169 info.keyword = "define";
00170 info.argmin = 1;
00171 info.argmax = 2;
00172 info.code = cDefine;
00173 info.syntax = "define <type> [<package>]";
00174 info.help = "Begins the definition of a new type of complex black box called <type>. If <package> is provided will create it in the given package.";
00175 mCommandDict[info.keyword] = info;
00176
00177 info.keyword = "endefine";
00178 info.argmin = 0;
00179 info.argmax = 0;
00180 info.code = cEndDefine;
00181 info.syntax = "endefine";
00182 info.help = "Ends the definition of a new type of complex black box";
00183 mCommandDict[info.keyword] = info;
00184
00185 info.keyword = "kind";
00186 info.argmin = 1;
00187 info.argmax = 1;
00188 info.code = cKind;
00189 info.syntax = "kind <ADAPTOR|DEFAULT_ADAPTOR|GUI|DEFAULT_GUI>";
00190 info.help = "Sets the kind of the currently defined complex black box";
00191 mCommandDict[info.keyword] = info;
00192
00193 info.keyword = "input";
00194 info.argmin = 3;
00195 info.argmax = 3;
00196 info.code = cInput;
00197 info.syntax = "input <name> <box.input> <help>";
00198 info.help = "Defines the input <name> of the current working black box as being an alias for the input <input> of the black box <box>. <help> defines the help string for the newly created input";
00199 mCommandDict[info.keyword] = info;
00200
00201 info.keyword = "output";
00202 info.argmin = 3;
00203 info.argmax = 3;
00204 info.code = cOutput;
00205 info.syntax = "output <name> <box.output> <help>";
00206 info.help = "Defines the output <name> of the current working black box as being an alias for the output <output> of the black box <box>. <help> defines the help string for the newly created output";
00207 mCommandDict[info.keyword] = info;
00208
00209 info.keyword = "set";
00210 info.argmin = 2;
00211 info.argmax = 2;
00212 info.code = cSet;
00213 info.syntax = "set <box.input> <value>";
00214 info.help = "Sets the value of the input <input> of the black box <box> to <value>. There must exist a string to the value type adaptor";
00215 mCommandDict[info.keyword] = info;
00216
00217 info.keyword = "config";
00218 info.argmin = 0;
00219 info.argmax = 0;
00220 info.code = cConfig;
00221 info.syntax = "config";
00222 info.help = "Prints the value of all configuration parameters";
00223 mCommandDict[info.keyword] = info;
00224
00225 info.keyword = "index";
00226 info.argmin = 0;
00227 info.argmax = 2;
00228 info.code = cIndex;
00229
00230 info.syntax = "index [<filename> ['Initials'(default)|'Packages'|'Categories'|'Adaptors']]";
00231 info.help = "Creates an html index of known boxes. If filename is provided then save it to the file 'filename'. The default index entries are the initial letters of the names of the boxes. If 'Packages' or 'Categories' is provided then the entries are either the packages names or the categories. If 'Adaptors' is provided then an alphabetical index of all adaptors is created.";
00232 mCommandDict[info.keyword] = info;
00233
00234 info.keyword = "reset";
00235 info.argmin = 0;
00236 info.argmax = 0;
00237 info.code = cReset;
00238 info.syntax = "reset";
00239 info.help = "Deletes all boxes and unloads all packages (reset to start state)";
00240 mCommandDict[info.keyword] = info;
00241
00242 info.keyword = "author";
00243 info.argmin = 1;
00244 info.argmax = 1;
00245 info.code = cAuthor;
00246 info.syntax = "author <string>";
00247 info.help = "Adds the string <string> to the author information of the black box being defined";
00248 mCommandDict[info.keyword] = info;
00249
00250 info.keyword = "category";
00251 info.argmin = 1;
00252 info.argmax = 1;
00253 info.code = cCategory;
00254 info.syntax = "category <list of items, separated by ;>";
00255 info.help = "Adds the string <string> to the category information of the black box being defined";
00256 mCommandDict[info.keyword] = info;
00257
00258 info.keyword = "description";
00259 info.argmin = 1;
00260 info.argmax = 1;
00261 info.code = cDescription;
00262 info.syntax = "description <string>";
00263 info.help = "Adds the string <string> to the descriptive information of the black box being defined";
00264 mCommandDict[info.keyword] = info;
00265
00266 info.keyword = "help";
00267 info.argmin = 0;
00268 info.argmax = 2;
00269 info.code = cHelp;
00270 info.syntax = "help";
00271 info.syntax = "\n (1) help \n (2) help <command name> \n (3) help packages [all]\n (4) help <package name> [all]\n (5) help <black box type> \n (6) help <black box name>";
00272 info.help = "Effect :\n (1) Lists all available commands;\n (2) Prints help on a particular command; \n (3) Lists the packages loaded and their black boxes.\n Add 'all' to list adaptors; \n (4) Prints short help on the black boxes of a package.\n Add 'all' to include adaptors; \n (5) Prints full help on a black box type; \n (6) Prints information on the inputs, outputs and connections of a black box instance.";
00273 mCommandDict[info.keyword] = info;
00274
00275 info.keyword = "message";
00276 info.argmin = 0;
00277 info.argmax = 2;
00278 info.code = cMessage;
00279 info.syntax = "message <kind> <level>";
00280 info.help = "Sets the level of the kind of messages <kind> to <level>.\n If kind='All' then sets the level for all kinds. If no kind nor level is passed then prints info on available kinds of messages and their current level.";
00281 mCommandDict[info.keyword] = info;
00282
00283 info.keyword = "include";
00284 info.argmin = 1;
00285 info.argmax = 2;
00286 info.code = cInclude;
00287 info.syntax = "include <filename> [source]";
00288 info.help = "Includes the file <filename>.\n 'source' : If the keyword 'source' is provided then informs the interpreter that the included file is the source of the current box definition (Advanced; used to get the right 'Include' field in html doc of packages 'appli' scripts).";
00289 mCommandDict[info.keyword] = info;
00290
00291 info.keyword = "quit";
00292 info.argmin = 0;
00293 info.argmax = 0;
00294 info.code = cQuit;
00295 info.syntax = "quit";
00296 info.help = "Quits the program (during script execution it stops the complete execution)";
00297 mCommandDict[info.keyword] = info;
00298
00299 info.keyword = "load";
00300 info.argmin = 1;
00301 info.argmax = 1;
00302 info.code = cLoad;
00303 info.syntax = "load <packagename>";
00304 info.help = "Loads the black box package <packagename>";
00305 mCommandDict[info.keyword] = info;
00306
00307 info.keyword = "unload";
00308 info.argmin = 1;
00309 info.argmax = 1;
00310 info.code = cUnload;
00311 info.syntax = "unload <packagename>";
00312 info.help = "Unloads the black box package <packagename>";
00313 mCommandDict[info.keyword] = info;
00314
00315 info.keyword = "graph";
00316 info.argmin = 0;
00317 info.argmax = 6;
00318 info.code = cGraph;
00319 info.syntax = "graph [ BlackBoxName [ Detail 0..1 [ Level 0..99999 [ Output html file [ Custom header [ Custom title ]]]]]] \n graph [ BlackBoxNameType [ Detail 0..1 [ Level 0..99999 [ Output html file [ Custom header [ Custom title ]]]]]]";
00320 info.help = "Shows a graphical view of a bbtk pipeline.\n- BlackBoxName : name of the box to view. Default '.' : current box.\n- BlackBoxNameType : name of the type of box to view, ex : 'workspace')";
00321 mCommandDict[info.keyword] = info;
00322
00323 info.keyword = "debug";
00324 info.argmin = 0;
00325 info.argmax = 1;
00326 info.code = cDebug;
00327 info.syntax = "debug [expr|-C|-D]";
00328 info.help = "Prints debug info on living bbtk objects containing the string 'expr' (default expr=''). -C checks the factory integrity. -D turns on objects debug info after main ends";
00329 mCommandDict[info.keyword] = info;
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 }
00344
00345
00346
00347
00348
00352 InterpreterVirtual::~InterpreterVirtual()
00353 {
00354 bbtkDebugMessage("object",2,"==> ~Interpreter()" <<std::endl);
00355 }
00356
00357
00358
00359
00360 InterpreterException::InterpreterException( const std::string& message,
00361 bool in_script_file,
00362 const std::string& script_file,
00363 int script_line
00364 )
00365 : Exception("interpreter",0,message),
00366 mInScriptFile(in_script_file),
00367 mScriptFile(script_file),
00368 mScriptLine(script_line)
00369 {
00370 }
00371
00372
00373 InterpreterException::InterpreterException( const Exception& excep,
00374 bool in_script_file,
00375 const std::string& script_file,
00376 int script_line
00377 )
00378 : Exception(excep),
00379 mInScriptFile(in_script_file),
00380 mScriptFile(script_file),
00381 mScriptLine(script_line)
00382 {
00383 }
00384
00385
00386
00387
00388 void InterpreterVirtual::CatchInterpreterException( const InterpreterException& e )
00389 {
00390
00391
00392
00393
00394
00395
00396
00397 if (mThrow)
00398 {
00399 if (e.GetErrorMessage()!="break")
00400 {
00401 mStatus = Interpreter_ERROR;
00402 CloseAllFiles();
00403 }
00404 throw InterpreterException(e);
00405 } else {
00406 std::stringstream mess;
00407 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
00408 if (e.IsInScriptFile())
00409 {
00410 mess << "* FILE : \""<<e.GetScriptFile()<<"\""<<std::endl;
00411 mess << "* LINE : "<<e.GetScriptLine()<<std::endl;
00412 }
00413 CloseAllFiles();
00414 std::cerr << mess.str();
00415 }
00416 }
00417
00418
00419
00420 void InterpreterVirtual::CatchBbtkException( const bbtk::Exception& e )
00421 {
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 mStatus = Interpreter_ERROR;
00436 if (mThrow)
00437 {
00438 bool in_script = false;
00439 std::string file("");
00440 int line = 0;
00441 if (mFileName.size())
00442 {
00443 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
00444 if (fs!=0) in_script = true;
00445 file = mFileName.back();
00446 line = mLine.back();
00447 }
00448 if (e.GetErrorMessage()!="break")
00449 CloseAllFiles();
00450 throw InterpreterException(e,in_script,file,line);
00451 } else {
00452 std::stringstream mess;
00453 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
00454 if (mFileName.size())
00455 {
00456 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
00457 mess << "* LINE : "<<mLine.back()<<std::endl;
00458 }
00459 CloseAllFiles();
00460 std::cerr << mess.str();
00461 }
00462 }
00463
00464
00465
00466 void InterpreterVirtual::CatchStdException( const std::exception& e )
00467 {
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481 mStatus = Interpreter_ERROR;
00482 if (mThrow)
00483 {
00484 bool in_script = false;
00485 std::string file("");
00486 int line = 0;
00487 if (mFileName.size()) {
00488 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
00489 if (fs!=0) in_script = true;
00490 file = mFileName.back();
00491 line = mLine.back();
00492 }
00493 CloseAllFiles();
00494 throw InterpreterException(e.what(),in_script,file,line);
00495 } else {
00496 std::stringstream mess;
00497 mess << "* ERROR : "<<e.what()<<std::endl;
00498 if (mFileName.size())
00499 {
00500 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
00501 mess << "* LINE : "<<mLine.back()<<std::endl;
00502 }
00503 CloseAllFiles();
00504 std::cerr << mess.str();
00505 }
00506 }
00507
00508
00509
00510
00511 void InterpreterVirtual::CatchUnknownException()
00512 {
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525 mStatus = Interpreter_ERROR;
00526 if (mThrow)
00527 {
00528 bool in_script = false;
00529 std::string file("");
00530 int line = 0;
00531 if (mFileName.size()) {
00532 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
00533 if (fs!=0) in_script = true;
00534 file = mFileName.back();
00535 line = mLine.back();
00536 }
00537 CloseAllFiles();
00538 throw InterpreterException("Unknown exception caught",
00539 in_script,file,line);
00540 }
00541 else
00542 {
00543 std::stringstream mess;
00544 mess << "* UNDEFINED ERROR (not a bbtk nor a std exception)"
00545 << std::endl;
00546 if (mFileName.size()) {
00547 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
00548 mess << "* LINE : "<<mLine.back()<<std::endl;
00549 }
00550 CloseAllFiles();
00551 std::cerr << mess.str();
00552 }
00553 }
00554
00555
00556
00557
00558 #define CATCH_MACRO \
00559 catch (InterpreterException e) \
00560 { \
00561 CatchInterpreterException(e); \
00562 } \
00563 catch (bbtk::Exception e) \
00564 { \
00565 CatchBbtkException(e); \
00566 } \
00567 catch (std::exception& e) \
00568 { \
00569 CatchStdException(e); \
00570 } \
00571 catch (...) \
00572 { \
00573 CatchUnknownException(); \
00574 }
00575
00576
00577
00578
00579 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretFile( const std::string& filename, bool source )
00580 {
00581 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::InterpretFile(\""<<filename<<"\")"<<std::endl);
00582
00583 bool exm = mCommandLine;
00584 mCommandLine = false;
00585
00586 try
00587 {
00588 mStatus = Interpreter_OK;
00589 SwitchToFile(filename,source);
00590 mInsideComment = false;
00591 InterpretCurrentStreams();
00592 }
00593 CATCH_MACRO;
00594
00595 bbtkDebugMessage("interpreter",4,
00596 "<== InterpreterVirtual::InterpretFile(\""
00597 <<filename<<"\")"<<std::endl);
00598
00599
00600 mCommandLine = exm;
00601
00602 return mStatus;
00603 }
00604
00605
00606
00607
00608 InterpreterVirtual::ExitStatus
00609 InterpreterVirtual::InterpretBuffer( std::stringstream* buffer )
00610 {
00611 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::InterpretBuffer()"<<std::endl);
00612
00613 bool exm = mCommandLine;
00614 mCommandLine = false;
00615
00616 try
00617 {
00618 mStatus = Interpreter_OK;
00619 SwitchToStream(buffer);
00620 mInsideComment = false;
00621 InterpretCurrentStreams();
00622 }
00623 CATCH_MACRO;
00624
00625
00626 bbtkDebugMessage("interpreter",4,"<== InterpreterVirtual::InterpretBuffer()"<<std::endl);
00627
00628
00629 mCommandLine = exm;
00630 return mStatus;
00631 }
00632
00633
00634
00636 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretCurrentStreams()
00637 {
00638 bbtkDebugMessage("interpreter",4,
00639 "==> InterpreterVirtual::InterpretCurrentStreams()"<<std::endl);
00640
00641 while (mFile.size()>0)
00642 {
00643 while (!mFile.back()->eof()) {
00644 mLine.back()++;
00645 char buf[500];
00646 mFile.back()->getline(buf,500);
00647 std::string str(buf);
00648
00649 int size=str.length();
00650 if(size != 0){
00651 if ( str[ size-1 ]==13 )
00652 {
00653 str.erase(size-1,1);
00654 }
00655 try
00656 {
00657 DoInterpretLine(str);
00658 }
00659 CATCH_MACRO;
00660 }
00661
00662 }
00663 CloseCurrentFile();
00664 }
00665 bbtkDebugMessage("interpreter",4,
00666 "<== InterpreterVirtual::InterpretCurrentStreams()"<<std::endl);
00667
00668 return mStatus;
00669 }
00670
00671
00672
00674 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretLine( const std::string& line )
00675 {
00676 bbtkDebugMessage("interpreter",5,"==> InterpreterVirtual::InterpretLine('"<<line<<"')"<<std::endl);
00677
00678 try
00679 {
00680 mStatus = Interpreter_OK;
00681 mInsideComment = false;
00682
00683 DoInterpretLine(line );
00684 }
00685 CATCH_MACRO;
00686
00687
00688 bbtkDebugMessage("interpreter",5,"<== InterpreterVirtual::InterpretLine('"<<line<<"')"<<std::endl);
00689
00690 return mStatus;
00691 }
00692
00693
00694 void InterpreterVirtual::commandNew(const std::string &boxType, const std::string &boxName)
00695 {
00696 }
00697
00698 void InterpreterVirtual::commandDelete(const std::string &boxName)
00699 {
00700 }
00701
00702 void InterpreterVirtual::commandConnection(const std::string &nodeFrom,const std::string &outputLabel,const std::string &nodeTo,const std::string &inputLabel)
00703 {
00704 }
00705
00706 void InterpreterVirtual::commandPackage(const std::string &packageName)
00707 {
00708 }
00709
00710 void InterpreterVirtual::commandEndPackage()
00711 {
00712 }
00713
00714 void InterpreterVirtual::commandDefine(const std::string &name,const std::string &pack,const std::string &scriptfilename)
00715 {
00716 }
00717
00718 void InterpreterVirtual::commandEndDefine()
00719 {
00720 }
00721
00722 void InterpreterVirtual::commandKind(const std::string &kind)
00723 {
00724 }
00725
00726 void InterpreterVirtual::commandPrint(const std::string &value)
00727 {
00728 }
00729
00730
00731 void InterpreterVirtual::commandExec(const std::string &word)
00732 {
00733 }
00734
00735
00736 void InterpreterVirtual::commandInput(const std::string &name,const std::string &box,const std::string &input,const std::string &help)
00737 {
00738 }
00739
00740 void InterpreterVirtual::commandOutput(const std::string &name,const std::string &box,const std::string &output,const std::string &help)
00741 {
00742 }
00743
00744 void InterpreterVirtual::commandSet(const std::string &box,const std::string &input,const std::string &value)
00745 {
00746 }
00747
00748 void InterpreterVirtual::commandAuthor(const std::string &author)
00749 {
00750 }
00751
00752 void InterpreterVirtual::commandCategory(const std::string &categorytype)
00753 {
00754 }
00755
00756
00757
00758 void InterpreterVirtual::commandDescription(const std::string &description)
00759 {
00760 }
00761
00762
00763 void InterpreterVirtual::commandClear()
00764 {
00765 }
00766
00767 void InterpreterVirtual::commandInclude(const std::string &word, bool ok)
00768 {
00769 }
00770
00771
00772 void InterpreterVirtual::commandLoad(const std::string &packageName)
00773 {
00774 }
00775
00776 void InterpreterVirtual::commandUnload(const std::string &packageName)
00777 {
00778 }
00779
00780 void InterpreterVirtual::commandBreak()
00781 {
00782 }
00783
00784 void InterpreterVirtual::commandQuit()
00785 {
00786 }
00787
00788 void InterpreterVirtual::commandMessage()
00789 {
00790 }
00791
00792 void InterpreterVirtual::commandMessage(const std::string &kind,const std::string &levelstr)
00793 {
00794 }
00795
00796
00797
00798
00799 void InterpreterVirtual::DoInterpretLine( const std::string& line )
00800 {
00801
00802 bbtkDebugMessage("interpreter",6,"==> InterpreterVirtual::DoInterpretLine(\""
00803 <<line<<"\")"<<std::endl);
00804 std::vector<std::string> words;
00805 SplitLine(line,words);
00806
00807
00808
00809
00810 if (words.size()<1)
00811 {
00812 bbtkDebugDecTab("interpreter",9);
00813 return;
00814 }
00815
00816
00817 if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') )
00818 {
00819 bbtkDebugDecTab("interpreter",9);
00820 bbtkMessage("interpreter",9,"Comment"<<std::endl);
00821 return;
00822 }
00823
00824
00825
00826 if (words[0][0]=='/' && words[0][1]=='*')
00827 {
00828 bbtkDebugDecTab("interpreter",9);
00829 bbtkMessage("interpreter",9,"In multiline comment"<<std::endl);
00830 mInsideComment = true;
00831 return;
00832 }
00833
00834 if (words[0][0]=='*' && words[0][1]=='/')
00835 {
00836 bbtkDebugDecTab("interpreter",9);
00837 bbtkMessage("interpreter",9,"Out multiline comment"<<std::endl);
00838 if ( !mInsideComment ) {
00839 bbtkDebugDecTab("interpreter",9);
00840 bbtkMessage("interpreter",9,"Comment mismatch : '*/' with no matching '/*'"<<std::endl);
00841 }
00842 mInsideComment = false;
00843 return;
00844 }
00845
00846 if (mInsideComment)
00847 {
00848 bbtkDebugDecTab("interpreter",9);
00849 bbtkMessage("interpreter",9,"Multiline Comment"<<std::endl);
00850 return;
00851 }
00852
00853
00854
00855 CommandInfoType command;
00856 InterpretCommand(words,command);
00857
00858 bbtkDebugMessage("interpreter",9,
00859 "Command='"<<command.keyword
00860 <<"' code="<<command.code<<std::endl);
00861
00862 std::string left,right,left2,right2;
00863 std::string filename;
00864
00865
00866 if (command.code==cMessage)
00867 {
00868 if (words.size()<3)
00869 {
00870 commandMessage();
00871
00872 }
00873 else
00874 {
00875 commandMessage(words[1],words[2]);
00876
00877
00878 }
00879 return;
00880 }
00881 else
00882 {
00883 bbtkMessage("echo",2,line<<std::endl);
00884 }
00885
00886
00887 if ((command.code==cBreak) || (command.code==cQuit))
00888 {
00889 bool in_script = false;
00890 std::string file("");
00891 int line = 0;
00892
00893 if (mFileName.size())
00894 {
00895 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
00896 if (fs!=0) in_script = true;
00897 file = mFileName.back();
00898 line = mLine.back();
00899 }
00900 if (command.code==cBreak)
00901 {
00902
00903
00904
00905
00906
00907
00908 commandBreak();
00909
00910
00911 }
00912 else
00913 {
00914 commandQuit();
00915
00916
00917 }
00918 return;
00919 }
00920
00921
00922
00923
00924 switch (command.code)
00925 {
00926 case cNew :
00927 commandNew(words[1],words[2]);
00928
00929 break;
00930
00931 case cDelete :
00932 commandDelete(words[1]);
00933
00934 break;
00935
00936 case cConnect :
00937 Utilities::SplitAroundFirstDot(words[1],left,right);
00938 Utilities::SplitAroundFirstDot(words[2],left2,right2);
00939 commandConnection(left,right,left2,right2);
00940
00941 break;
00942
00943 case cPackage :
00944 commandPackage(words[1]);
00945
00946 break;
00947
00948 case cEndPackage :
00949 commandEndPackage();
00950
00951 break;
00952
00953 case cDefine :
00954 if (mFileName.size()>0)
00955 {
00956
00957 filename = mFileName.back();
00958 }
00959 if (words.size()==2)
00960 {
00961 std::string packTmp = "";
00962 commandDefine(words[1],packTmp,filename);
00963
00964 }
00965 else
00966 {
00967 commandDefine(words[1],words[2],filename);
00968
00969 }
00970 break;
00971
00972 case cEndDefine :
00973 commandEndDefine();
00974
00975 break;
00976
00977 case cKind :
00978 commandKind(words[1]);
00979
00980 break;
00981
00982 case cPrint :
00983 commandPrint(words[1]);
00984
00985 break;
00986
00987 case cExec :
00988 commandExec(words[1]);
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010 break;
01011
01012 case cInput :
01013 Utilities::SplitAroundFirstDot(words[2],left,right);
01014 commandInput(words[1],left,right,words[3]);
01015
01016 break;
01017
01018 case cOutput :
01019 Utilities::SplitAroundFirstDot(words[2],left,right);
01020 commandOutput(words[1],left,right,words[3]);
01021
01022 break;
01023
01024 case cSet :
01025 Utilities::SplitAroundFirstDot(words[1],left,right);
01026 commandSet(left,right,words[2]);
01027
01028 break;
01029
01030 case cAuthor :
01031 commandAuthor(words[1]);
01032
01033 break;
01034
01035 case cNewGUI :
01036 commandNewGUI(words[1],words[2]);
01037 break;
01038
01039 case cCategory :
01040 commandCategory(words[1]);
01041
01042 break;
01043
01044 case cIndex :
01045 if (words.size()==1)
01046 commandIndex("tmp_index.html");
01047 else if (words.size()==2)
01048 commandIndex(words[1]);
01049 else if (words.size()==3)
01050 commandIndex(words[1],words[2]);
01051 break;
01052
01053 case cDescription :
01054 commandDescription(words[1]);
01055
01056 break;
01057
01058 case cHelp :
01059 commandHelp(words);
01060 break;
01061
01062
01063 case cGraph :
01064 commandGraph(words);
01065 break;
01066
01067 case cConfig :
01068 commandConfig();
01069 break;
01070
01071 case cReset :
01072 commandReset();
01073 break;
01074
01075 case cClear :
01076 commandClear();
01077
01078 break;
01079
01080 case cInclude :
01081 commandInclude( words[1] , (words.size()==3) );
01082
01083
01084
01085
01086
01087
01088
01089
01090 break;
01091
01092 case cLoad:
01093 commandLoad( words[1] );
01094
01095 break;
01096
01097 case cUnload:
01098 commandUnload( words[1] );
01099
01100 break;
01101
01102 case cDebug :
01103 if (words.size()==2) commandDebug(words[1]);
01104 else commandDebug("");
01105 break;
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120 default:
01121 bbtkInternalError("should not reach here !!!");
01122 }
01123
01124 bbtkDebugMessage("interpreter",6,"<== InterpreterVirtual::DoInterpretLine(\""
01125 <<line<<"\")"<<std::endl);
01126
01127 }
01128
01129
01130
01131
01132
01133
01134
01135 void InterpreterVirtual::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
01136 {
01137 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::SplitLine(\""<<str<<"\")"<<std::endl);
01138
01139 std::string delimiters = "\"";
01140 std::vector<std::string> quote;
01141 Utilities::SplitString(str,delimiters,quote);
01142
01143 delimiters = " \t";
01144 std::vector<std::string>::iterator i;
01145 for (i=quote.begin(); i!=quote.end(); )
01146 {
01147 Utilities::SplitString(*i,delimiters,tokens);
01148 ++i;
01149 if (i!=quote.end())
01150 {
01151
01152 tokens.push_back(*i);
01153 ++i;
01154 }
01155 }
01156
01157 for (i=tokens.begin(); i!=tokens.end(); ++i)
01158 {
01159 bbtkDebugMessage("interpreter",9,"--["<<*i<<"]"<<std::endl);
01160 }
01161 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::SplitLine(\""<<str<<"\")"<<std::endl);
01162
01163 }
01164
01165
01166
01167
01168 void InterpreterVirtual::commandReset()
01169 {
01170 }
01171
01172
01173
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01253
01254 void InterpreterVirtual::SwitchToFile( const std::string& name , bool source )
01255 {
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::SwitchToFile( \""
01267 <<name<<"\")"<<std::endl);
01268
01269 std::vector<std::string> script_paths;
01270 std::string fullPathScriptName;
01271 std::string pkgname;
01272 std::vector<std::string> Filenames;
01273
01274
01275
01276
01277 bbtkMessage("interpreter",1,
01278 "look for : [" << name
01279 << "]" << std::endl);
01280
01281
01282 std::string upath;
01283 pkgname = Utilities::ExtractScriptName(name,upath);
01284
01285 bbtkMessage("interpreter",3,
01286 "package name:[" << pkgname
01287 << "] path:[" << upath << "]" << std::endl);
01288 bool fullnameGiven = false;
01289 bool foundFile = false;
01290
01291
01292
01293 if (pkgname == "*")
01294 {
01295
01296 std::stringstream* stream = new std::stringstream;
01297
01298
01299
01300 if (upath.size()==0)
01301 {
01302
01303
01304
01305 std::vector<std::string>::const_iterator i;
01306 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
01307 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
01308 i++)
01309 {
01310 script_paths.push_back(*i);
01311 }
01312 }
01313
01314 else if (upath[0]=='/' || upath[1] == ':' )
01315 {
01316 if ( Utilities::IsDirectory( upath ) )
01317 {
01318 script_paths.push_back(upath);
01319 }
01320 else
01321 {
01322 bbtkError("'"<<upath<<"' : directory does not exist");
01323 }
01324 }
01325
01326
01327 else
01328 {
01329 std::vector<std::string>::const_iterator i;
01330 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
01331 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
01332 i++)
01333 {
01334 std::string full_path(*i);
01335 printf("EED InterpreterVirtual::SwitchToFile 1. >>%s\n", full_path.c_str() );
01336
01337 if (full_path == ".")
01338 {
01339 char buf[2048];
01340 char * currentDir = getcwd(buf, 2048);
01341 std::string cwd(currentDir);
01342 full_path = currentDir;
01343 }
01344
01345 full_path += ConfigurationFile::GetInstance().Get_file_separator();
01346 full_path += upath;
01347
01348 if ( Utilities::IsDirectory( full_path ) )
01349 {
01350 script_paths.push_back(full_path);
01351 }
01352 }
01353 if (script_paths.empty())
01354 {
01355 bbtkError("no '"<<upath<<"' subdir found in search paths"
01356 << std::endl);
01357 }
01358 }
01359
01360
01361 int nbBssFiles = 0;
01362
01363 std::vector<std::string>::iterator i;
01364 for (i=script_paths.begin();i!=script_paths.end();i++)
01365 {
01366
01367 printf("EED InterpreterVirtual::SwitchToFile jaja >> %s\n", (*i).c_str() );
01368
01369 bbtkMessage("interpreter",1,
01370 "--> Looking in '" << *i << "'" << std::endl);
01371
01372 Filenames.clear();
01373
01374 Utilities::Explore(*i, false, Filenames);
01375
01376 for (std::vector<std::string>::iterator j = Filenames.begin();
01377 j!= Filenames.end(); ++j)
01378 {
01379
01380 printf("EED InterpreterVirtual::SwitchToFile kkkkk >> %s\n", (*j).c_str() );
01381
01382 int lgr = (*j).size();
01383 if (lgr < 5) continue;
01384
01385 if ( (*j).substr(lgr-4, 4) != ".bbp") continue;
01386
01387 (*stream) << "include \"" << *j << "\"\n";
01388 bbtkMessage("interpreter",2," --> Found '" << *j << "'" << std::endl);
01389
01390 nbBssFiles++;
01391 }
01392 }
01393
01394
01395 if (nbBssFiles==0)
01396 {
01397 bbtkMessage("interpreter",1,
01398 " --> No .bbp found"<< std::endl);
01399 }
01400 else
01401 {
01402 bbtkMessage("interpreter",1,
01403 " --> "<<nbBssFiles<<" .bbp found"<< std::endl);
01404 SwitchToStream(stream);
01405 }
01406 return;
01407 }
01408
01409
01410
01411
01412
01413
01414
01415
01416 if (name[0]=='/' || name[1] == ':' || name[0]=='.')
01417 {
01418
01419
01420 fullnameGiven = true;
01421
01422 fullPathScriptName = Utilities::ExpandLibName(name, false);
01423
01424
01425 int l = fullPathScriptName.size();
01426
01427 if (l!=0)
01428 {
01429 if ((fullPathScriptName.substr(l-4, 4) != ".bbs")&&
01430 (fullPathScriptName.substr(l-4, 4) != ".bbp"))
01431 {
01432 std::string tfullPathScriptName = fullPathScriptName + ".bbs";
01433 if ( Utilities::FileExists(tfullPathScriptName) )
01434 {
01435 fullPathScriptName = tfullPathScriptName;
01436 foundFile = true;
01437 }
01438 else
01439 {
01440 tfullPathScriptName = fullPathScriptName + ".bbp";
01441 if ( Utilities::FileExists(tfullPathScriptName) )
01442 {
01443 fullPathScriptName = tfullPathScriptName;
01444 foundFile = true;
01445 }
01446 }
01447 }
01448 else
01449 {
01450 if ( Utilities::FileExists(fullPathScriptName) )
01451 {
01452 foundFile = true;
01453 }
01454 }
01455 }
01456 }
01457 else
01458
01459 {
01460 script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
01461 std::string path;
01462 std::vector<std::string>::iterator i;
01463 for (i=script_paths.begin();i!=script_paths.end();++i)
01464 {
01465 path = *i;
01466
01467 if (path == ".")
01468 {
01469 char buf[2048];
01470 char * currentDir = getcwd(buf, 2048);
01471 std::string cwd(currentDir);
01472 path = currentDir;
01473 }
01474
01475 std::string tfullPathScriptName = Utilities::MakePkgnameFromPath(path, name, false);
01476
01477
01478 if(tfullPathScriptName.size()>=4){
01479 if (tfullPathScriptName.substr(tfullPathScriptName.size()-4, 3)==".bb")
01480 {
01481 fullPathScriptName = tfullPathScriptName;
01482 if ( ! Utilities::FileExists(fullPathScriptName) )
01483 {
01484
01485
01486
01487 bbtkMessage("interpreter",2,
01488 " [" <<fullPathScriptName <<"] : does not exist"
01489 <<std::endl);
01490 continue;
01491 }
01492 bbtkMessage("interpreter",2,
01493 " [" <<fullPathScriptName
01494 <<"] : found" <<std::endl);
01495 foundFile = true;
01496 break;
01497 }
01498 else
01499 {
01500 fullPathScriptName = tfullPathScriptName + ".bbs";
01501
01502 if ( ! Utilities::FileExists(fullPathScriptName) )
01503 {
01504 fullPathScriptName = tfullPathScriptName + ".bbp";
01505 if ( ! Utilities::FileExists(fullPathScriptName) )
01506 {
01507
01508
01509
01510 bbtkMessage("interpreter",2,
01511 " [" <<tfullPathScriptName <<".bbs/.bbp] : do not exist"
01512 <<std::endl);
01513 continue;
01514 }
01515 }
01516 bbtkMessage("interpreter",2,
01517 " [" <<fullPathScriptName
01518 <<"] : found" <<std::endl);
01519 foundFile = true;
01520 break;
01521 }
01522 }
01523 }
01524 }
01525
01526 if (!foundFile)
01527 {
01528 if (fullnameGiven)
01529 if(fullPathScriptName == "")
01530 bbtkError("Path ["<<upath<<"] doesn't exist");
01531 else
01532 bbtkError("Script ["<<fullPathScriptName<<"] not found");
01533 else
01534 bbtkError("No ["<<pkgname<<".bbs/.bbp] script found");
01535 return;
01536 } else {
01537
01538 LoadScript(fullPathScriptName,name);
01539
01540 if (source) SetCurrentFileName(fullPathScriptName);
01541 }
01542
01543 return;
01544 }
01545
01546
01547
01548 void InterpreterVirtual::SetCurrentFileName(const std::string &fullPathScriptName)
01549 {
01550 }
01551
01552
01553
01554 void InterpreterVirtual::SwitchToStream( std::stringstream* stream )
01555 {
01556 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::SwitchToStream()"
01557 <<std::endl);
01558 mFile.push_back(stream);
01559 std::ostringstream buffer_name;
01560 bufferNb++;
01561 buffer_name << "buffer_" ;
01562
01563 if (mFileName.size()>0 )
01564 {
01565 buffer_name << mFileName.back() << "_" << mLine.back();
01566 }
01567 mFileName.push_back(buffer_name.str());
01568 mIncludeFileName.push_back(buffer_name.str());
01569 mLine.push_back(0);
01570 }
01571
01572
01573
01574
01575 void InterpreterVirtual::LoadScript( std::string fullPathScriptName,
01576 std::string includeScriptName)
01577 {
01578 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::LoadScript("
01579 <<fullPathScriptName<<")"
01580 <<std::endl);
01581
01582 Utilities::replace( fullPathScriptName ,
01583 INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
01584
01585 if (find(mFileNameHistory.begin(),
01586 mFileNameHistory.end(),
01587 fullPathScriptName)!=mFileNameHistory.end())
01588 {
01589 return;
01590 }
01591
01592 std::ifstream* s;
01593 s = new std::ifstream;
01594 s->open(fullPathScriptName.c_str());
01595 if (!s->good())
01596 {
01597 bbtkError("Could not open file ["<<fullPathScriptName<<"]");
01598 return;
01599 }
01600
01601 bbtkMessage("interpreter",1," -->[" << fullPathScriptName
01602 << "] found" << std::endl);
01603
01604 mFile.push_back(s);
01605 mFileName.push_back(fullPathScriptName);
01606 mFileNameHistory.push_back(fullPathScriptName);
01607 mIncludeFileName.push_back(includeScriptName);
01608 mLine.push_back(0);
01609
01610 return;
01611 }
01612
01613
01614
01615 void InterpreterVirtual::CloseCurrentFile()
01616 {
01617 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::CloseCurrentFile()"
01618 <<std::endl);
01619
01620 if (mFile.size()==0)
01621 {
01622 bbtkDebugMessage("interpreter",9," -> no file left open"<<std::endl);
01623 return;
01624 }
01625
01626 bbtkDebugMessage("interpreter",9," Closing file '"<<mFileName.back()<<"'"<<std::endl);
01627
01628 std::ifstream* file = dynamic_cast<std::ifstream*>(mFile.back());
01629 if (file!=0) file->close();
01630
01631 delete mFile.back();
01632 mFile.pop_back();
01633 mFileName.pop_back();
01634 mIncludeFileName.pop_back();
01635 mLine.pop_back();
01636
01637 bbtkDebugMessage("interpreter",9," Remains "
01638 <<mFile.size()
01639 <<" open"<<std::endl);
01640 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::CloseCurrentFile()"
01641 <<std::endl);
01642 }
01643
01644
01645
01646 void InterpreterVirtual::CloseAllFiles()
01647 {
01648 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::CloseAllFiles()"
01649 <<std::endl);
01650
01651 while (mFile.size() != 0)
01652 {
01653 CloseCurrentFile();
01654 }
01655 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::CloseAllFiles()"
01656 <<std::endl);
01657 }
01658
01659
01660
01661
01662
01663 void InterpreterVirtual::InterpretCommand( const std::vector<std::string>& words,
01664 CommandInfoType& info )
01665 {
01666
01667 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::InterpretCommand(...)"<<std::endl);
01668
01669
01670 CommandDictType::iterator c;
01671 c = mCommandDict.find(words[0]);
01672 if ( c == mCommandDict.end() ) {
01673 bbtkError(words[0]<<" : unknown command");
01674 }
01675
01676
01677 if ( ( ((int)words.size())-1 < c->second.argmin ) ||
01678 ( ((int)words.size())-1 > c->second.argmax ) )
01679 {
01680
01681
01682 commandHelp(words[0]);
01683 bbtkError(words[0]<<" : wrong number of arguments");
01684 }
01685
01686 info = c->second;
01687 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::InterpretCommand(...)"<<std::endl);
01688
01689 }
01690
01691
01692
01693
01695 void InterpreterVirtual::commandHelp(const std::vector<std::string>& words)
01696 {
01697 }
01698
01699 void InterpreterVirtual::commandHelp(const std::string &words)
01700 {
01701 }
01702
01703
01704
01706 void InterpreterVirtual::commandConfig() const
01707 {
01708 }
01709
01710
01711
01712
01713
01718 void InterpreterVirtual::FindCommandsWithPrefix( char* buf,
01719 int n,
01720 std::vector<std::string>& commands )
01721 {
01722 CommandDictType::const_iterator i;
01723 for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
01724 {
01725 if ((i->first).find(buf,0,n) == 0)
01726 commands.push_back(i->first);
01727 }
01728 }
01729
01730
01731
01732
01733
01734 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
01735
01736 inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
01737 inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
01738
01739
01740
01741
01742 #define BBTK_UP_ARROW_KBCODE 0x00415B1B
01743 #define BBTK_DOWN_ARROW_KBCODE 0x00425B1B
01744 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
01745 #define BBTK_LEFT_ARROW_KBCODE 0x00445B1B
01746 #define BBTK_BACKSPACE_KBCODE 0x00000008
01747 #define BBTK_DEL_KBCODE 0x0000007F
01748 #define BBTK_SPACE_KBCODE 0x00000020
01749
01750
01751 void InterpreterVirtual::GetLineFromPrompt(std::string& s)
01752 {
01753 int c;
01754 unsigned int ind=0;
01755
01756 unsigned int MAX_LINE_SIZE = 160;
01757 unsigned int MAX_HISTORY_SIZE = 100;
01758
01759 char* newline = new char[MAX_LINE_SIZE];
01760 memset(newline,0,MAX_LINE_SIZE);
01761 char* histline = new char[MAX_LINE_SIZE];
01762 memset(histline,0,MAX_LINE_SIZE);
01763
01764 char* line = newline;
01765 unsigned int hist = mHistory.size();
01766
01767 write(1,"> ",2);
01768 while(1)
01769 {
01770 c=0;
01771 read ( STDIN_FILENO, &c, 4) ;
01772
01773 bbtkDebugMessage("debug",9,"[0x"<<std::hex<<c<<"]\n");
01774
01775
01776 if ( (ind<MAX_LINE_SIZE-1) &&
01777 ( c >= BBTK_SPACE_KBCODE ) &&
01778 ( c < BBTK_DEL_KBCODE ))
01779 {
01780 PrintChar(c);
01781 line[ind++]=c;
01782 }
01783
01784 else if (c=='\n')
01785 {
01786
01787 if (line==newline)
01788 delete histline;
01789 else
01790 delete newline;
01791
01792
01793 if (strlen(line))
01794 {
01795
01796 if (mHistory.size()>MAX_HISTORY_SIZE)
01797 {
01798 delete mHistory.front();
01799 mHistory.pop_front();
01800 }
01801 mHistory.push_back(line);
01802 }
01803 break;
01804 }
01805
01806 else if ( (ind>0) &&
01807 ((c == BBTK_BACKSPACE_KBCODE) ||
01808 (c == BBTK_DEL_KBCODE)) )
01809 {
01810 line[ind--]=' ';
01811 BackSpace();
01812 }
01813
01814 else if (c=='\t')
01815 {
01816
01817 std::vector<std::string> commands;
01818 FindCommandsWithPrefix( line,ind,commands);
01819 if (commands.size()==1)
01820 {
01821 std::string com = *commands.begin();
01822 for (; ind<com.size(); ++ind)
01823 {
01824 PrintChar(com[ind]);
01825 line[ind]=com[ind];
01826 }
01827 PrintChar(' ');
01828 line[ind++]=' ';
01829 }
01830 else if (commands.size()>1)
01831 {
01832 std::vector<std::string>::iterator i;
01833 write(1,"\n",1);
01834 for (i=commands.begin();i!=commands.end();++i)
01835 {
01836 write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
01837 PrintChar(' ');
01838 }
01839 write(STDOUT_FILENO,"\n> ",3);
01840
01841
01842 write(STDOUT_FILENO,line,ind);
01843
01844 }
01845 }
01846
01847 else if (c==BBTK_UP_ARROW_KBCODE)
01848 {
01849 if (hist)
01850 {
01851
01852 while (ind--) BackSpace();
01853
01854 hist--;
01855
01856 strcpy(histline,mHistory[hist]);
01857 line = histline;
01858 ind = strlen(line);
01859
01860 write(STDOUT_FILENO,line,ind);
01861 }
01862 }
01863
01864 else if (c==BBTK_DOWN_ARROW_KBCODE)
01865 {
01866 if (hist<mHistory.size()-1)
01867 {
01868
01869 while (ind--) BackSpace();
01870
01871 hist++;
01872
01873 strcpy(histline,mHistory[hist]);
01874 line = histline;
01875 ind = strlen(line);
01876
01877 write(STDOUT_FILENO,line,ind);
01878 }
01879
01880 else if (hist==mHistory.size()-1)
01881 {
01882
01883 while (ind--) BackSpace();
01884
01885 hist++;
01886
01887 line = newline;
01888 ind = strlen(line);
01889
01890 write(STDOUT_FILENO,line,ind);
01891 }
01892 }
01893
01894 else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
01895 {
01896 PrintChar(line[ind]);
01897 ind++;
01898 }
01899
01900
01901 else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
01902 {
01903 PrintChar('\b');
01904 ind--;
01905
01906 }
01907
01908 }
01909 write(STDOUT_FILENO,"\n\r",2);
01910
01911
01912 s = line;
01913
01914 }
01915 #else
01916
01917
01918 void InterpreterVirtual::GetLineFromPrompt(std::string& s)
01919 {
01920 s.clear();
01921
01922 putchar('>');
01923 putchar(' ');
01924
01925 do
01926 {
01927 char c = getchar();
01928 if (c=='\n')
01929 {
01930 putchar('\n');
01931 break;
01932 }
01933 if (c=='\t')
01934 {
01935
01936 continue;
01937 }
01938
01939 s += c;
01940 }
01941 while (true);
01942
01943 }
01944
01945
01946 #endif
01947
01948
01949
01950
01951 void InterpreterVirtual::CommandLineInterpreter()
01952 {
01953 bbtkDebugMessageInc("interpreter",9,
01954 "InterpreterVirtual::CommandLineInterpreter()"<<std::endl);
01955
01956 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
01957
01958
01959 struct termios ter,oter;
01960 tcgetattr(0,&ter);
01961 oter=ter;
01962 ter.c_lflag &= ~ECHO;
01963 ter.c_lflag &= ~ICANON;
01964 ter.c_cc[VMIN]=1;
01965 ter.c_cc[VTIME]=0;
01966 tcsetattr(0,TCSANOW,&ter);
01967 #endif
01968
01969 mCommandLine = true;
01970 bool again = true;
01971
01972 mInsideComment = false;
01973 do
01974 {
01975 try
01976 {
01977 std::string line;
01978 GetLineFromPrompt(line);
01979 DoInterpretLine(line);
01980 }
01981
01982
01983
01984
01985
01986
01987
01988 catch (bbtk::Exception e)
01989 {
01990 e.Print();
01991 }
01992 catch (std::exception& e)
01993 {
01994 std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
01995 }
01996 catch (...)
01997 {
01998 std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
01999 }
02000 }
02001 while (again);
02002
02003 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
02004 tcsetattr(0,TCSANOW,&oter);
02005 #endif
02006
02007 std::cout << "Good bye !" << std::endl;
02008
02009 bbtkDebugDecTab("interpreter",9);
02010 }
02011
02012
02013 void InterpreterVirtual::commandGraph(const std::vector<std::string>& words)
02014 {
02015 }
02016
02017
02018
02019
02020 void InterpreterVirtual::commandIndex(const std::string& filename, const std::string& type)
02021 {
02022 }
02023
02024
02025
02026
02027 void InterpreterVirtual::commandNewGUI(const std::string& boxname,const std::string& instanceName)
02028 {
02029 }
02030
02031
02032
02033
02034
02035 void InterpreterVirtual::commandDebug(const std::string& name)
02036 {
02037 }
02038
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051 std::string InterpreterVirtual::GetObjectName() const
02052 {
02053 return std::string("InterpreterVirtual");
02054 }
02055
02056
02057
02058 std::string InterpreterVirtual::GetObjectInfo() const
02059 {
02060 std::stringstream i;
02061 return i.str();
02062 }
02063
02064
02065
02066 size_t InterpreterVirtual::GetObjectSize() const
02067 {
02068 size_t s = Superclass::GetObjectSize();
02069 s += InterpreterVirtual::GetObjectInternalSize();
02070 return s;
02071 }
02072
02073
02074 size_t InterpreterVirtual::GetObjectInternalSize() const
02075 {
02076 size_t s = sizeof(InterpreterVirtual);
02077 return s;
02078 }
02079
02080
02081 size_t InterpreterVirtual::GetObjectRecursiveSize() const
02082 {
02083 size_t s = Superclass::GetObjectRecursiveSize();
02084 s += InterpreterVirtual::GetObjectInternalSize();
02085 return s;
02086 }
02087
02088 }
02089
02090