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