2 # ---------------------------------------------------------------------
4 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
6 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7 # Previous Authors : Laurent Guigues, Jean-Pierre Roux
8 # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
10 # This software is governed by the CeCILL-B license under French law and
11 # abiding by the rules of distribution of free software. You can use,
12 # modify and/ or redistribute the software under the terms of the CeCILL-B
13 # license as circulated by CEA, CNRS and INRIA at the following URL
14 # http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
15 # or in the file LICENSE.txt.
17 # As a counterpart to the access to the source code and rights to copy,
18 # modify and redistribute granted by the license, users are provided only
19 # with a limited warranty and the software's author, the holder of the
20 # economic rights, and the successive licensors have only limited
23 # The fact that you are presently reading this means that you have had
24 # knowledge of the CeCILL-B license and that you accept its terms.
25 # ------------------------------------------------------------------------ */
28 /*=========================================================================
30 Module: $RCSfile: bbtkInterpreter.cxx,v $
32 Date: $Date: 2010/09/14 07:18:46 $
33 Version: $Revision: 1.88 $
34 =========================================================================*/
40 * \brief class Interpreter :
43 #include "bbtkInterpreterVirtual.h"
44 //#include "bbtkTranscriptor.h"
45 #include "bbtkConfigurationFile.h"
46 #include "bbtkUtilities.h"
47 //#include "bbtkAtomicBlackBox.h"
48 //#include "bbtkWxBlackBox.h"
51 #ifdef CMAKE_HAVE_TERMIOS_H
53 #define BBTK_USE_TERMIOS_BASED_PROMPT
61 //=======================================================================
62 InterpreterVirtual::Pointer InterpreterVirtual::New()
64 bbtkDebugMessage("kernel",9,"InterpreterVirtual::New()"<<std::endl);
65 return MakePointer( new InterpreterVirtual() );
67 //=======================================================================
69 //=======================================================================
70 InterpreterVirtual::InterpreterVirtual()
74 //=======================================================================
77 //=======================================================================
78 void InterpreterVirtual::Init()
84 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);
85 bbtk::MessageManager::RegisterMessageType("Interpreter","Messages of the interpreter",0);
86 bbtkDebugMessageInc("Interpreter",9,"InterpreterVirtual::Interpreter()" <<std::endl);
88 // For the time being, comment out previous line, and
89 // uncomment next line to check Transcriptor
91 //mVirtualExecuter = new bbtk::Transcriptor("GeneratedProgram.txt");
93 // Builds the commands dict
100 info.syntax = "new <type> <name>";
101 info.help = "Creates a new black box of type <type> with name <name>";
102 mCommandDict[info.keyword] = info;
104 info.keyword = "delete";
108 info.syntax = "delete <box>";
109 info.help = "Deletes the black box of name <box>";
110 mCommandDict[info.keyword] = info;
112 info.keyword = "clear";
116 info.syntax = "clear";
117 info.help = "Clears the currently defined complex box (deletes all its boxes and connections)";
118 mCommandDict[info.keyword] = info;
120 info.keyword = "break";
124 info.syntax = "break";
125 info.help = "Breaks the current execution";
126 mCommandDict[info.keyword] = info;
128 info.keyword = "newgui";
132 info.syntax = "newgui <box> <name>";
133 info.help = "Automatically creates a graphical user interface with name <name> for the black box <box> and connects it to the box inputs";
134 mCommandDict[info.keyword] = info;
136 info.keyword = "connect";
139 info.code = cConnect;
140 info.syntax = "connect <box1.output> <box2.input>";
141 info.help = "Connects the ouput <output> of black box <box1> to the input <input> of black box <box2>";
142 mCommandDict[info.keyword] = info;
144 info.keyword = "print";
148 info.syntax = "print <string>";
149 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').";
150 mCommandDict[info.keyword] = info;
152 info.keyword = "exec";
156 info.syntax = "exec <box | 'freeze' | 'unfreeze' | 'freeze_no_error' >";
157 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.";
158 mCommandDict[info.keyword] = info;
160 info.keyword = "package";
163 info.code = cPackage;
164 info.syntax = "package <name>";
165 info.help = "Begins the definition of a package.";
166 mCommandDict[info.keyword] = info;
168 info.keyword = "endpackage";
171 info.code = cEndPackage;
172 info.syntax = "endpackage";
173 info.help = "Ends the definition of a package.";
174 mCommandDict[info.keyword] = info;
176 info.keyword = "define";
180 info.syntax = "define <type> [<package>]";
181 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.";
182 mCommandDict[info.keyword] = info;
184 info.keyword = "endefine";
187 info.code = cEndDefine;
188 info.syntax = "endefine";
189 info.help = "Ends the definition of a new type of complex black box";
190 mCommandDict[info.keyword] = info;
192 info.keyword = "kind";
196 info.syntax = "kind <ADAPTOR|DEFAULT_ADAPTOR|GUI|DEFAULT_GUI>";
197 info.help = "Sets the kind of the currently defined complex black box";
198 mCommandDict[info.keyword] = info;
200 info.keyword = "input";
204 info.syntax = "input <name> <box.input> <help>";
205 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";
206 mCommandDict[info.keyword] = info;
208 info.keyword = "output";
212 info.syntax = "output <name> <box.output> <help>";
213 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";
214 mCommandDict[info.keyword] = info;
216 info.keyword = "set";
220 info.syntax = "set <box.input> <value>";
221 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";
222 mCommandDict[info.keyword] = info;
224 info.keyword = "config"; // JPR
228 info.syntax = "config";
229 info.help = "Prints the value of all configuration parameters";
230 mCommandDict[info.keyword] = info;
232 info.keyword = "index"; // LG
237 info.syntax = "index [<filename> ['Initials'(default)|'Packages'|'Categories'|'Adaptors']]";
238 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.";
239 mCommandDict[info.keyword] = info;
241 info.keyword = "reset";
245 info.syntax = "reset";
246 info.help = "Deletes all boxes and unloads all packages (reset to start state)";
247 mCommandDict[info.keyword] = info;
249 info.keyword = "author";
253 info.syntax = "author <string>";
254 info.help = "Adds the string <string> to the author information of the black box being defined";
255 mCommandDict[info.keyword] = info;
257 info.keyword = "category"; //JP
260 info.code = cCategory;
261 info.syntax = "category <list of items, separated by ;>";
262 info.help = "Adds the string <string> to the category information of the black box being defined";
263 mCommandDict[info.keyword] = info;
265 info.keyword = "description";
268 info.code = cDescription;
269 info.syntax = "description <string>";
270 info.help = "Adds the string <string> to the descriptive information of the black box being defined";
271 mCommandDict[info.keyword] = info;
273 info.keyword = "help";
277 info.syntax = "help";
278 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>";
279 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.";
280 mCommandDict[info.keyword] = info;
282 info.keyword = "message";
285 info.code = cMessage;
286 info.syntax = "message <kind> <level>";
287 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.";
288 mCommandDict[info.keyword] = info;
290 info.keyword = "include";
293 info.code = cInclude;
294 info.syntax = "include <filename> [source]";
295 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).";
296 mCommandDict[info.keyword] = info;
298 info.keyword = "quit";
302 info.syntax = "quit";
303 info.help = "Quits the program (during script execution it stops the complete execution)";
304 mCommandDict[info.keyword] = info;
306 info.keyword = "load";
310 info.syntax = "load <packagename>";
311 info.help = "Loads the black box package <packagename>";
312 mCommandDict[info.keyword] = info;
314 info.keyword = "unload";
318 info.syntax = "unload <packagename>";
319 info.help = "Unloads the black box package <packagename>";
320 mCommandDict[info.keyword] = info;
322 info.keyword = "graph";
326 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 ]]]]]]";
327 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')";
328 mCommandDict[info.keyword] = info;
330 info.keyword = "debug";
334 info.syntax = "debug [expr|-C|-D]";
335 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";
336 mCommandDict[info.keyword] = info;
339 info.keyword = "workspace";
342 info.code = cWorkspace;
343 info.syntax = "workspace < ( freeze | unfreeze ) | ( rename <newname> ) >";
344 info.help = "Configures the workspace.\n 'freeze' allows to block execution commands while keeping definition commands active. 'unfreeze' turns back the worspace in 'normal' mode.\n 'rename' allow to set a new name to the workspace.";
345 mCommandDict[info.keyword] = info;
350 //=======================================================================
354 //=======================================================================
358 InterpreterVirtual::~InterpreterVirtual()
360 bbtkDebugMessage("object",2,"==> ~Interpreter()" <<std::endl);
362 //=======================================================================
365 //=======================================================================
366 InterpreterException::InterpreterException( const std::string& message,
368 const std::string& script_file,
371 : Exception("interpreter",0,message),
372 mInScriptFile(in_script_file),
373 mScriptFile(script_file),
374 mScriptLine(script_line)
377 //=======================================================================
378 //=======================================================================
379 InterpreterException::InterpreterException( const Exception& excep,
381 const std::string& script_file,
385 mInScriptFile(in_script_file),
386 mScriptFile(script_file),
387 mScriptLine(script_line)
390 //=======================================================================
393 //=======================================================================
394 void InterpreterVirtual::CatchInterpreterException( const InterpreterException& e )
396 //EED Borrame if (GetExecuter()->GetNoErrorMode())
398 //EED Borrame bbtkWarning("ERROR :"<<e.GetErrorMessage()
399 //EED Borrame <<" ("<<e.GetScriptFile()<<":"<<e.GetScriptLine()
400 //EED Borrame <<" skipped");
401 //EED Borrame return;
405 if (e.GetErrorMessage()!="break")
407 mStatus = Interpreter_ERROR;
410 throw InterpreterException(e);
412 std::stringstream mess;
413 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
414 if (e.IsInScriptFile())
416 mess << "* FILE : \""<<e.GetScriptFile()<<"\""<<std::endl;
417 mess << "* LINE : "<<e.GetScriptLine()<<std::endl;
420 std::cerr << mess.str();
423 //=======================================================================
425 //=======================================================================
426 void InterpreterVirtual::CatchBbtkException( const bbtk::Exception& e )
428 //EED Borrame if (GetExecuter()->GetNoErrorMode())
430 //EED Borrame std::string file("?");
431 //EED Borrame int line = 0;
432 //EED Borrame if (mFileName.size()) {
433 //EED Borrame file = mFileName.back();
434 //EED Borrame line = mLine.back();
436 //EED Borrame bbtkWarning("ERROR '"<<e.GetErrorMessage()
437 //EED Borrame <<"' ("<<file<<":"<<line<<") skipped");
438 //EED Borrame return;
441 mStatus = Interpreter_ERROR;
444 bool in_script = false;
445 std::string file("");
447 if (mFileName.size())
449 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
450 if (fs!=0) in_script = true;
451 file = mFileName.back();
454 if (e.GetErrorMessage()!="break")
456 throw InterpreterException(e,in_script,file,line);
458 std::stringstream mess;
459 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
460 if (mFileName.size())
462 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
463 mess << "* LINE : "<<mLine.back()<<std::endl;
466 std::cerr << mess.str();
469 //=======================================================================
471 //=======================================================================
472 void InterpreterVirtual::CatchStdException( const std::exception& e )
474 //EED Borrame if (GetExecuter()->GetNoErrorMode())
476 //EED Borrame std::string file("?");
477 //EED Borrame int line = 0;
478 //EED Borrame if (mFileName.size()) {
479 //EED Borrame file = mFileName.back();
480 //EED Borrame line = mLine.back();
482 //EED Borrame bbtkWarning("ERROR '"<<e.what()
483 //EED Borrame <<"' ("<<file<<":"<<line<<") skipped");
484 //EED Borrame return;
487 mStatus = Interpreter_ERROR;
490 bool in_script = false;
491 std::string file("");
493 if (mFileName.size()) {
494 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
495 if (fs!=0) in_script = true;
496 file = mFileName.back();
500 throw InterpreterException(e.what(),in_script,file,line);
502 std::stringstream mess;
503 mess << "* ERROR : "<<e.what()<<std::endl;
504 if (mFileName.size())
506 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
507 mess << "* LINE : "<<mLine.back()<<std::endl;
510 std::cerr << mess.str();
514 //=======================================================================
516 //=======================================================================
517 void InterpreterVirtual::CatchUnknownException()
519 //EED Borrame if (GetExecuter()->GetNoErrorMode())
521 //EED Borrame std::string file("?");
522 //EED Borrame int line = 0;
523 //EED Borrame if (mFileName.size()) {
524 //EED Borrame file = mFileName.back();
525 //EED Borrame line = mLine.back();
527 //EED Borrame bbtkWarning("UNDEFINED ERROR "
528 //EED Borrame <<"("<<file<<":"<<line<<") skipped");
529 //EED Borrame return;
531 mStatus = Interpreter_ERROR;
534 bool in_script = false;
535 std::string file("");
537 if (mFileName.size()) {
538 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
539 if (fs!=0) in_script = true;
540 file = mFileName.back();
544 throw InterpreterException("Unknown exception caught",
545 in_script,file,line);
549 std::stringstream mess;
550 mess << "* UNDEFINED ERROR (not a bbtk nor a std exception)"
552 if (mFileName.size()) {
553 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
554 mess << "* LINE : "<<mLine.back()<<std::endl;
557 std::cerr << mess.str();
560 //=======================================================================
562 //=======================================================================
564 #define CATCH_MACRO \
565 catch (InterpreterException e) \
567 CatchInterpreterException(e); \
569 catch (bbtk::Exception e) \
571 CatchBbtkException(e); \
573 catch (std::exception& e) \
575 CatchStdException(e); \
579 CatchUnknownException(); \
581 //=======================================================================
584 //=======================================================================
585 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretFile( const std::string& filename, bool source )
587 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::InterpretFile(\""<<filename<<"\")"<<std::endl);
589 bool exm = mCommandLine;
590 mCommandLine = false;
594 mStatus = Interpreter_OK;
595 SwitchToFile(filename,source);
596 mInsideComment = false;
597 InterpretCurrentStreams();
601 bbtkDebugMessage("interpreter",4,
602 "<== InterpreterVirtual::InterpretFile(\""
603 <<filename<<"\")"<<std::endl);
610 //=======================================================================
613 //=======================================================================
614 InterpreterVirtual::ExitStatus
615 InterpreterVirtual::InterpretBuffer( std::stringstream* buffer )
617 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::InterpretBuffer()"<<std::endl);
619 bool exm = mCommandLine;
620 mCommandLine = false;
624 mStatus = Interpreter_OK;
625 SwitchToStream(buffer);
626 mInsideComment = false;
627 InterpretCurrentStreams();
632 bbtkDebugMessage("interpreter",4,"<== InterpreterVirtual::InterpretBuffer()"<<std::endl);
638 //=======================================================================
640 //=======================================================================
641 /// Interprets the currently open streams
642 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretCurrentStreams()
644 bbtkDebugMessage("interpreter",4,
645 "==> InterpreterVirtual::InterpretCurrentStreams()"<<std::endl);
647 while (mFile.size()>0)
649 while (!mFile.back()->eof()) {
652 mFile.back()->getline(buf,500);
653 std::string str(buf);
654 //size 0 JCP 21-09-2009
655 int size=str.length();
657 if ( str[ size-1 ]==13 )
663 DoInterpretLine(str);
671 bbtkDebugMessage("interpreter",4,
672 "<== InterpreterVirtual::InterpretCurrentStreams()"<<std::endl);
676 //=======================================================================
678 //=======================================================================
679 /// Runs the interpretation of a command
680 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretLine( const std::string& line )
682 bbtkDebugMessage("interpreter",5,"==> InterpreterVirtual::InterpretLine('"<<line<<"')"<<std::endl);
686 mStatus = Interpreter_OK;
687 mInsideComment = false;
688 //std::cout<<"JCP bbtkInterpreter.cxx InterpreterVirtual::InterpretLine("<<std::endl;
689 DoInterpretLine(line );
694 bbtkDebugMessage("interpreter",5,"<== InterpreterVirtual::InterpretLine('"<<line<<"')"<<std::endl);
698 //=======================================================================
700 void InterpreterVirtual::commandNew(const std::string &boxType, const std::string &boxName) // virtual
704 void InterpreterVirtual::commandDelete(const std::string &boxName)
708 void InterpreterVirtual::commandConnection(const std::string &nodeFrom,const std::string &outputLabel,const std::string &nodeTo,const std::string &inputLabel)
712 void InterpreterVirtual::commandPackage(const std::string &packageName)
716 void InterpreterVirtual::commandEndPackage()
720 void InterpreterVirtual::commandDefine(const std::string &name,const std::string &pack,const std::string &scriptfilename)
724 void InterpreterVirtual::commandEndDefine()
728 void InterpreterVirtual::commandKind(const std::string &kind)
732 void InterpreterVirtual::commandPrint(const std::string &value)
737 void InterpreterVirtual::commandExec(const std::string &word)
742 void InterpreterVirtual::commandInput(const std::string &name,const std::string &box,const std::string &input,const std::string &help)
746 void InterpreterVirtual::commandOutput(const std::string &name,const std::string &box,const std::string &output,const std::string &help)
750 void InterpreterVirtual::commandSet(const std::string &box,const std::string &input,const std::string &value)
754 void InterpreterVirtual::commandAuthor(const std::string &author)
758 void InterpreterVirtual::commandCategory(const std::string &categorytype)
764 void InterpreterVirtual::commandDescription(const std::string &description)
769 void InterpreterVirtual::commandClear()
773 void InterpreterVirtual::commandInclude(const std::string &word, bool ok)
778 void InterpreterVirtual::commandLoad(const std::string &packageName)
782 void InterpreterVirtual::commandUnload(const std::string &packageName)
786 void InterpreterVirtual::commandBreak()
790 void InterpreterVirtual::commandQuit()
794 void InterpreterVirtual::commandMessage()
798 void InterpreterVirtual::commandMessage(const std::string &kind,const std::string &levelstr)
804 //=======================================================================
805 void InterpreterVirtual::DoInterpretLine( const std::string& line )
807 bbtkDebugMessage("interpreter",6,"==> InterpreterVirtual::DoInterpretLine(\""
808 <<line<<"\")"<<std::endl);
809 std::vector<std::string> words;
810 SplitLine(line,words);
817 bbtkDebugDecTab("interpreter",9);
821 // Single line comment : # or //
822 if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') )
824 bbtkDebugDecTab("interpreter",9);
825 bbtkMessage("interpreter",9,"Comment"<<std::endl);
829 // Multi line comment ( /* ... */ ) -delimiters on different lines !-
831 if (words[0][0]=='/' && words[0][1]=='*')
833 bbtkDebugDecTab("interpreter",9);
834 bbtkMessage("interpreter",9,"In multiline comment"<<std::endl);
835 mInsideComment = true;
839 if (words[0][0]=='*' && words[0][1]=='/')
841 bbtkDebugDecTab("interpreter",9);
842 bbtkMessage("interpreter",9,"Out multiline comment"<<std::endl);
843 if ( !mInsideComment ) {
844 bbtkDebugDecTab("interpreter",9);
845 bbtkMessage("interpreter",9,"Comment mismatch : '*/' with no matching '/*'"<<std::endl);
847 mInsideComment = false;
853 bbtkDebugDecTab("interpreter",9);
854 bbtkMessage("interpreter",9,"Multiline Comment"<<std::endl);
860 CommandInfoType command;
861 InterpretCommand(words,command);
862 //std::cout<<"JCP bbtkInterpreter command.keyword ="<<command.keyword<<std::endl;
863 bbtkDebugMessage("interpreter",9,
864 "Command='"<<command.keyword
865 <<"' code="<<command.code<<std::endl);
867 std::string left,right,left2,right2;
868 std::string filename;
871 if (command.code==cMessage)
876 //EED Borrame mVirtualExecuter->HelpMessages();
880 commandMessage(words[1],words[2]);
881 //EED Borrame sscanf(words[2].c_str(),"%d",&level);
882 //EED Borrame mVirtualExecuter->SetMessageLevel(words[1],level);
888 bbtkMessage("echo",2,line<<std::endl);
891 // break and quit commands
892 if ((command.code==cBreak) || (command.code==cQuit))
894 //EED-Borrame bool in_script = false;
895 //EED-Borrame std::string file("");
896 //EED-Borrame int line = 0;
898 //EED-Borrame if (mFileName.size())
900 //EED-Borrame std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
901 //EED-Borrame if (fs!=0) in_script = true;
902 //EED-Borrame file = mFileName.back();
903 //EED-Borrame line = mLine.back();
905 if (command.code==cBreak)
908 std::cout << "BreakException("
911 <<line<<")"<<std::endl;
914 //EED Borrame bbtkError("break");//,in_script,file,line);
915 // throw BreakException(in_script,file,line);
918 //EED Borrame bbtkError("quit");//,in_script,file,line);
919 //throw QuitException(in_script,file,line);
923 //std::cout<<" mVirtualExecuter->Create(words[1],words[2]); "<<line<<std::endl;
927 switch (command.code)
930 commandNew(words[1],words[2]);
931 //EED Borrame mVirtualExecuter->Create(words[1],words[2]);
935 commandDelete(words[1]);
936 //EED Borrame mVirtualExecuter->Destroy(words[1]);
940 Utilities::SplitAroundFirstDot(words[1],left,right);
941 Utilities::SplitAroundFirstDot(words[2],left2,right2);
942 commandConnection(left,right,left2,right2);
943 //EED Borrame mVirtualExecuter->Connect(left,right,left2,right2);
947 commandPackage(words[1]);
948 //EED Borrame mVirtualExecuter->BeginPackage(words[1]);
953 //EED Borrame mVirtualExecuter->EndPackage();
957 if (mFileName.size()>0)
959 //??? commandDefine(????);
960 filename = mFileName.back(); //mIncludeFileName.back(); //Utilities::get_file_name(mFileName.back());
964 std::string packTmp = "";
965 commandDefine(words[1],packTmp,filename);
966 //EED Borrame mVirtualExecuter->Define(words[1],"",filename);
970 commandDefine(words[1],words[2],filename);
971 //EED Borrame mVirtualExecuter->Define(words[1],words[2],filename);
977 //EED Borrame mVirtualExecuter->EndDefine();
981 commandKind(words[1]);
982 //EED Borrame mVirtualExecuter->Kind(words[1]);
986 commandPrint(words[1]);
987 //EED Borrame mVirtualExecuter->Print(words[1]);
991 commandExec(words[1]);
992 //EED Borrame if (words[1]=="freeze")
994 //EED Borrame mVirtualExecuter->SetNoExecMode(true);
995 //EED Borrame mThrow = false;
997 //EED Borrame else if (words[1]=="freeze_no_error")
999 //EED Borrame mVirtualExecuter->SetNoExecMode(true);
1000 //EED Borrame mVirtualExecuter->SetNoErrorMode(true);
1001 //EED Borrame mThrow = false;
1003 //EED Borrame else if (words[1]=="unfreeze")
1005 //EED Borrame mVirtualExecuter->SetNoExecMode(false);
1006 //EED Borrame mVirtualExecuter->SetNoErrorMode(false);
1010 //EED Borrame mVirtualExecuter->Execute(words[1]);
1016 Utilities::SplitAroundFirstDot(words[2],left,right);
1017 commandInput(words[1],left,right,words[3]);
1018 //EED Borrame mVirtualExecuter->DefineInput(words[1],left,right,words[3]);
1022 Utilities::SplitAroundFirstDot(words[2],left,right);
1023 commandOutput(words[1],left,right,words[3]);
1024 //EED Borrame mVirtualExecuter->DefineOutput(words[1],left,right,words[3]);
1028 Utilities::SplitAroundFirstDot(words[1],left,right);
1029 commandSet(left,right,words[2]);
1030 //EED Borrame mVirtualExecuter->Set(left,right,words[2]);
1034 commandAuthor(words[1]);
1035 //EED Borrame mVirtualExecuter->Author(words[1]);
1039 commandNewGUI(words[1],words[2]);
1043 commandCategory(words[1]);
1044 //EED Borrame mVirtualExecuter->Category(words[1]);
1048 if (words.size()==1)
1049 commandIndex("tmp_index.html");
1050 else if (words.size()==2)
1051 commandIndex(words[1]);
1052 else if (words.size()==3)
1053 commandIndex(words[1],words[2]);
1057 commandDescription(words[1]);
1058 //EED Borrame mVirtualExecuter->Description(words[1]);
1067 commandGraph(words);
1080 //EED Borrame mVirtualExecuter->Clear();
1084 commandInclude( words[1] , (words.size()==3) );
1085 //EED Borrame // if 'source' was given (words.size()==3) then tell to set the
1086 //EED Borrame // source file name of the current complex box with the full file name included
1087 //EED Borrame if (mCommandLine)
1089 //EED Borrame InterpretFile(words[1],(words.size()==3));
1090 //EED Borrame } else{
1091 //EED Borrame SwitchToFile(words[1],(words.size()==3) );
1096 commandLoad( words[1] );
1097 //EED Borrame GetExecuter()->LoadPackage(words[1]);
1101 commandUnload( words[1] );
1102 //EED Borrame GetExecuter()->UnLoadPackage(words[1]);
1106 if (words.size()==2) commandDebug(words[1]);
1107 else commandDebug("");
1112 if (words.size() == 2)
1114 if (words[1]=="freeze") mVirtualExecuter->SetNoExecMode(true);
1115 else if (words[1]=="unfreeze") mVirtualExecuter->SetNoExecMode(false);
1119 mVirtualExecuter->SetWorkspaceName(words[2]);
1124 bbtkInternalError("should not reach here !!!");
1127 bbtkDebugMessage("interpreter",6,"<== InterpreterVirtual::DoInterpretLine(\""
1128 <<line<<"\")"<<std::endl);
1131 //=======================================================================
1137 //=======================================================================
1138 void InterpreterVirtual::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
1140 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::SplitLine(\""<<str<<"\")"<<std::endl);
1142 std::string delimiters = "\"";
1143 std::vector<std::string> quote;
1144 Utilities::SplitString(str,delimiters,quote);
1147 std::vector<std::string>::iterator i;
1148 for (i=quote.begin(); i!=quote.end(); )
1150 Utilities::SplitString(*i,delimiters,tokens);
1154 // bbtkDebugMessage("interpreter",0,"\""<<*i<<"\""<<std::endl);
1155 tokens.push_back(*i);
1160 for (i=tokens.begin(); i!=tokens.end(); ++i)
1162 bbtkDebugMessage("interpreter",9,"--["<<*i<<"]"<<std::endl);
1164 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::SplitLine(\""<<str<<"\")"<<std::endl);
1167 //=======================================================================
1170 //=======================================================================
1171 void InterpreterVirtual::commandReset()
1174 //=======================================================================
1176 //=======================================================================
1181 void InterpreterVirtual::Print( const std::string& str)
1183 if (mVirtualExecuter->GetNoExecMode()) return;
1185 bbtkDebugMessageInc("interpreter",9,"InterpreterVirtual::Print(\""<<str<<"\")"<<std::endl);
1188 // InterpretLine ("load std")
1189 // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande
1190 // InterpretLine("new Print _P_")
1191 // InterpretLine("connect _C_.Out _P_.In")
1195 std::vector<std::string> chains;
1196 std::string delimiters("$");
1198 // Skip delimiters at beginning.
1199 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
1200 bool is_text = true;
1201 if (lastPos>0) is_text = false;
1203 // Find first delimiter.
1204 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
1206 while (std::string::npos != pos || std::string::npos != lastPos)
1210 // Found a text token, add it to the vector.
1211 chains.push_back(str.substr(lastPos, pos - lastPos));
1212 // std::string token = str.substr(lastPos, pos - lastPos)
1213 // InterpretLine("set _C_.In%num% %token%")
1219 // is an output (between $$) : decode
1220 std::string tok,box,output;
1221 tok = str.substr(lastPos, pos - lastPos);
1222 Utilities::SplitAroundFirstDot(tok,box,output);
1223 chains.push_back( mVirtualExecuter->Get(box,output) );
1225 // InterpretLine("connect %tok% _C_.In%num%")
1228 // Skip delimiters. Note the "not_of"
1229 lastPos = str.find_first_not_of(delimiters, pos);
1230 // Find next delimiter
1231 pos = str.find_first_of(delimiters, lastPos);
1236 // InterpretLine("exec _P_")
1237 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
1239 std::vector<std::string>::iterator i;
1240 for (i= chains.begin(); i!=chains.end(); ++i)
1243 Utilities::SubsBackslashN(*i);
1246 std::cout << std::endl;
1247 bbtkDebugDecTab("interpreter",9);
1251 //=======================================================================
1256 // =========================================================================
1257 void InterpreterVirtual::SwitchToFile( const std::string& name , bool source )
1259 // Note : in the following :
1260 // name : the user supplied name
1261 // - abreviated name e.g. scr scr.bbs
1262 // - relative full name e.g. ./scr.bbs ../../scr.bbs
1263 // - absolute full name e.g. /home/usrname/proj/dir/scr.bbs
1264 // same for Windows, with c:, d: ...
1266 // use ./directory/subdir/scrname.bbs
1269 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::SwitchToFile( \""
1270 <<name<<"\")"<<std::endl);
1272 std::vector<std::string> script_paths;
1273 std::string fullPathScriptName; // full path script name
1274 std::string pkgname; // e.g. <scriptname>.bbs
1275 std::vector<std::string> Filenames;
1276 std::string tmpFilenames;
1278 // The following is *NOT* a debug time message :
1279 // It's a user intended message.
1280 // Please don't remove it.
1281 bbtkMessage("interpreter",1,
1282 "look for : [" << name
1283 << "]" << std::endl);
1287 pkgname = Utilities::ExtractScriptName(name,upath);
1289 bbtkMessage("interpreter",3,
1290 "package name:[" << pkgname
1291 << "] path:[" << upath << "]" << std::endl);
1292 bool fullnameGiven = false;
1293 bool foundFile = false;
1295 // ==== "*" provided : load all scripts in given path
1296 // relative (e.g. std/boxes/*) or absolute
1300 std::stringstream* stream = new std::stringstream;
1301 //if (upath.size()!=0) // avoid troubles for "*"
1303 // ==== no path provided : look in root bbs path
1304 if (upath.size()==0)
1306 // bbtkMessage("interpreter",1,
1307 // LG : add all bbs path
1308 // script_paths.push_back( ConfigurationFile::GetInstance().Get_root_bbs_path() );
1309 std::vector<std::string>::const_iterator i;
1310 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1311 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1314 script_paths.push_back(*i);
1317 // ==== absolute path provided
1318 else if (upath[0]=='/' || upath[1] == ':' )
1320 if ( Utilities::IsDirectory( upath ) )
1322 script_paths.push_back(upath);
1326 bbtkError("'"<<upath<<"' : directory does not exist");
1329 // ==== relative path provided : search all bbs path appended with
1330 // the relative path provided
1333 std::vector<std::string>::const_iterator i;
1334 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1335 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1338 std::string full_path(*i);
1339 printf("EED InterpreterVirtual::SwitchToFile 1. >>%s\n", full_path.c_str() );
1340 // we *really* want '.' to be the current working directory
1341 if (full_path == ".")
1343 char buf[2048]; // for getcwd
1344 char * currentDir = getcwd(buf, 2048);
1345 std::string cwd(currentDir);
1346 full_path = currentDir;
1349 full_path += ConfigurationFile::GetInstance().Get_file_separator();
1352 if ( Utilities::IsDirectory( full_path ) )
1354 script_paths.push_back(full_path);
1357 if (script_paths.empty())
1359 bbtkError("no '"<<upath<<"' subdir found in search paths"
1364 // === search paths list complete : now explore it
1366 // ==== relative name, iterate + load all .bbs/.bbp files
1367 std::vector<std::string>::iterator i;
1368 for (i=script_paths.begin();i!=script_paths.end();i++)
1371 printf("EED InterpreterVirtual::SwitchToFile (1) >> %s\n", (*i).c_str() );
1373 bbtkMessage("interpreter",1,
1374 "--> Looking in '" << *i << "'" << std::endl);
1378 Utilities::Explore(*i, false, Filenames);
1380 int iFilesnames,jFilesnames,sizeFilenames;
1381 sizeFilenames=Filenames.size();
1384 // EEDd 30 sept 2012
1385 //Sorting list of files
1386 for (iFilesnames=0;iFilesnames<sizeFilenames; iFilesnames++)
1388 for (jFilesnames=iFilesnames;jFilesnames<sizeFilenames; jFilesnames++)
1390 if ( Filenames[iFilesnames] > Filenames[jFilesnames] )
1392 tmpFilenames = Filenames[iFilesnames];
1393 Filenames[iFilesnames] = Filenames[jFilesnames];
1394 Filenames[jFilesnames] = tmpFilenames;
1396 } // for iFilesnames
1397 } // for iFilesnames
1401 for (std::vector<std::string>::iterator j = Filenames.begin();
1402 j!= Filenames.end(); ++j)
1405 printf("EED InterpreterVirtual::SwitchToFile (2) >> %s\n", (*j).c_str() );
1407 int lgr = (*j).size();
1408 if (lgr < 5) continue;
1409 // ignore non .bbp file
1410 if ( (*j).substr(lgr-4, 4) != ".bbp") continue;
1412 (*stream) << "include \"" << *j << "\"\n";
1413 bbtkMessage("interpreter",2," --> Found '" << *j << "'" << std::endl);
1416 } // for (std::vector...
1417 } // for (i=script_...
1422 bbtkMessage("interpreter",1,
1423 " --> No .bbp found"<< std::endl);
1427 bbtkMessage("interpreter",1,
1428 " --> "<<nbBssFiles<<" .bbp found"<< std::endl);
1429 SwitchToStream(stream);
1433 //=============== end pkgname=="*" ===========
1436 // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name
1437 // (not only a plain script name)
1438 // we trust him, and try to expland the directory name
1439 // WARNING : starting from current local directory : ./whatYouWant (./ mandatory!)
1441 if (name[0]=='/' || name[1] == ':' || name[0]=='.') // absolute path (linux/windows) or relative path
1444 // ===========================================================check user supplied location
1445 fullnameGiven = true;
1447 fullPathScriptName = Utilities::ExpandLibName(name, false);
1449 // allow user to always forget ".bbs"
1450 int l = fullPathScriptName.size();
1454 if ((fullPathScriptName.substr(l-4, 4) != ".bbs")&&
1455 (fullPathScriptName.substr(l-4, 4) != ".bbp"))
1457 std::string tfullPathScriptName = fullPathScriptName + ".bbs";
1458 if ( Utilities::FileExists(tfullPathScriptName) )
1460 fullPathScriptName = tfullPathScriptName;
1465 tfullPathScriptName = fullPathScriptName + ".bbp";
1466 if ( Utilities::FileExists(tfullPathScriptName) )
1468 fullPathScriptName = tfullPathScriptName;
1475 if ( Utilities::FileExists(fullPathScriptName) )
1483 // =============================== iterate on the paths
1485 script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
1487 std::vector<std::string>::iterator i;
1488 for (i=script_paths.begin();i!=script_paths.end();++i)
1491 // we *really* want '.' to be the current working directory
1494 char buf[2048]; // for getcwd
1495 char * currentDir = getcwd(buf, 2048);
1496 std::string cwd(currentDir);
1500 std::string tfullPathScriptName = Utilities::MakePkgnameFromPath(path, name, false);
1502 //Addition JCP tfullPathScriptName.size()>=4
1503 if(tfullPathScriptName.size()>=4){
1504 if (tfullPathScriptName.substr(tfullPathScriptName.size()-4, 3)==".bb")
1506 fullPathScriptName = tfullPathScriptName;
1507 if ( ! Utilities::FileExists(fullPathScriptName) )
1509 // The following is *NOT* a debug time message :
1510 // It's a user intended message.
1511 // Please don't remove it.
1512 bbtkMessage("interpreter",2,
1513 " [" <<fullPathScriptName <<"] : does not exist"
1515 continue; // try next path
1517 bbtkMessage("interpreter",2,
1518 " [" <<fullPathScriptName
1519 <<"] : found" <<std::endl);
1521 break; // a script was found; we stop iterating
1525 fullPathScriptName = tfullPathScriptName + ".bbs";
1526 // Check if library exists
1527 if ( ! Utilities::FileExists(fullPathScriptName) )
1529 fullPathScriptName = tfullPathScriptName + ".bbp";
1530 if ( ! Utilities::FileExists(fullPathScriptName) )
1532 // The following is *NOT* a debug time message :
1533 // It's a user intended message.
1534 // Please don't remove it.
1535 bbtkMessage("interpreter",2,
1536 " [" <<tfullPathScriptName <<".bbs/.bbp] : do not exist"
1538 continue; // try next path
1541 bbtkMessage("interpreter",2,
1542 " [" <<fullPathScriptName
1543 <<"] : found" <<std::endl);
1545 break; // a script was found; we stop iterating
1548 } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
1554 if(fullPathScriptName == "")
1555 bbtkError("Path ["<<upath<<"] doesn't exist");
1557 bbtkError("Script ["<<fullPathScriptName<<"] not found");
1559 bbtkError("No ["<<pkgname<<".bbs/.bbp] script found");
1562 //EED printf("EED D. SwitchToFile %s\n", fullPathScriptName.c_str() );
1563 LoadScript(fullPathScriptName,name);
1564 //EED Borrame if (source) GetExecuter()->SetCurrentFileName(fullPathScriptName);
1567 // Over writing the fullpath of the bbp file.
1568 SetCurrentFileName( fullPathScriptName );
1569 SetTypeOfScript_Application();
1575 //=======================================================================
1577 //=======================================================================
1578 void InterpreterVirtual::SetCurrentFileName(const std::string &fullPathScriptName) // virtual
1581 //=======================================================================
1584 //=======================================================================
1585 void InterpreterVirtual::SetTypeOfScript_Application( )
1588 //=======================================================================
1591 //=======================================================================
1592 void InterpreterVirtual::SwitchToStream( std::stringstream* stream )
1594 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::SwitchToStream()"
1596 mFile.push_back(stream);
1597 std::ostringstream buffer_name;
1599 buffer_name << "buffer_" ;
1601 if (mFileName.size()>0 )
1603 buffer_name << mFileName.back() << "_" << mLine.back();
1605 mFileName.push_back(buffer_name.str());
1606 mIncludeFileName.push_back(buffer_name.str());
1609 //=======================================================================
1611 //=======================================================================
1613 void InterpreterVirtual::LoadScript( std::string fullPathScriptName,
1614 std::string includeScriptName)
1616 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::LoadScript("
1617 <<fullPathScriptName<<")"
1620 Utilities::replace( fullPathScriptName ,
1621 INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
1623 if (find(mFileNameHistory.begin(),
1624 mFileNameHistory.end(),
1625 fullPathScriptName)!=mFileNameHistory.end())
1631 s = new std::ifstream;
1632 s->open(fullPathScriptName.c_str());
1635 bbtkError("Could not open file ["<<fullPathScriptName<<"]");
1639 bbtkMessage("interpreter",1," -->[" << fullPathScriptName
1640 << "] found" << std::endl);
1643 mFileName.push_back(fullPathScriptName);
1644 mFileNameHistory.push_back(fullPathScriptName);
1645 mIncludeFileName.push_back(includeScriptName);
1650 //=======================================================================
1652 //=======================================================================
1653 void InterpreterVirtual::CloseCurrentFile()
1655 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::CloseCurrentFile()"
1658 if (mFile.size()==0)
1660 bbtkDebugMessage("interpreter",9," -> no file left open"<<std::endl);
1664 bbtkDebugMessage("interpreter",9," Closing file '"<<mFileName.back()<<"'"<<std::endl);
1666 std::ifstream* file = dynamic_cast<std::ifstream*>(mFile.back());
1667 if (file!=0) file->close();
1669 delete mFile.back();
1671 mFileName.pop_back();
1672 mIncludeFileName.pop_back();
1675 bbtkDebugMessage("interpreter",9," Remains "
1677 <<" open"<<std::endl);
1678 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::CloseCurrentFile()"
1681 //=======================================================================
1683 //=======================================================================
1684 void InterpreterVirtual::CloseAllFiles()
1686 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::CloseAllFiles()"
1689 while (mFile.size() != 0)
1693 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::CloseAllFiles()"
1696 //=======================================================================
1700 //=======================================================================
1701 void InterpreterVirtual::InterpretCommand( const std::vector<std::string>& words,
1702 CommandInfoType& info )
1705 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::InterpretCommand(...)"<<std::endl);
1707 // searches the command keyword
1708 CommandDictType::iterator c;
1709 c = mCommandDict.find(words[0]);
1710 if ( c == mCommandDict.end() ) {
1711 bbtkError(words[0]<<" : unknown command");
1714 // tests the number of args
1715 if ( ( ((int)words.size())-1 < c->second.argmin ) ||
1716 ( ((int)words.size())-1 > c->second.argmax ) )
1719 //EED HelpCommand(words[0]);
1720 commandHelp(words[0]);
1721 bbtkError(words[0]<<" : wrong number of arguments");
1723 //std::cout<<"InterpreterVirtual::InterpretCommand( const std::vector<std::string>& words,"<<std::endl;
1725 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::InterpretCommand(...)"<<std::endl);
1728 //=======================================================================
1731 //=======================================================================
1732 /// Displays help on all the commands
1733 void InterpreterVirtual::commandHelp(const std::vector<std::string>& words)
1736 //=======================================================================
1737 void InterpreterVirtual::commandHelp(const std::string &words)
1740 //=======================================================================
1742 //===================================================================
1743 /// Displays the Configuration
1744 void InterpreterVirtual::commandConfig() const
1747 //===================================================================
1751 //=======================================================================
1752 /// Fills the vector commands with the commands which
1753 /// have the first n chars of buf for prefix
1754 /// TODO : skip initial spaces in buf and also return the position of first
1755 /// non blank char in buf
1756 void InterpreterVirtual::FindCommandsWithPrefix( char* buf,
1758 std::vector<std::string>& commands )
1760 CommandDictType::const_iterator i;
1761 for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
1763 if ((i->first).find(buf,0,n) == 0)
1764 commands.push_back(i->first);
1767 //=======================================================================
1771 //=======================================================================
1772 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1774 inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
1775 inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
1777 // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
1778 // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
1779 // E.G. STORE THIS IN bbtk_config.xml
1780 #define BBTK_UP_ARROW_KBCODE 0x00415B1B
1781 #define BBTK_DOWN_ARROW_KBCODE 0x00425B1B
1782 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
1783 #define BBTK_LEFT_ARROW_KBCODE 0x00445B1B
1784 #define BBTK_BACKSPACE_KBCODE 0x00000008
1785 #define BBTK_DEL_KBCODE 0x0000007F
1786 #define BBTK_SPACE_KBCODE 0x00000020
1788 //=======================================================================
1789 void InterpreterVirtual::GetLineFromPrompt(std::string& s)
1794 unsigned int MAX_LINE_SIZE = 160;
1795 unsigned int MAX_HISTORY_SIZE = 100;
1797 char* newline = new char[MAX_LINE_SIZE];
1798 memset(newline,0,MAX_LINE_SIZE);
1799 char* histline = new char[MAX_LINE_SIZE];
1800 memset(histline,0,MAX_LINE_SIZE);
1802 char* line = newline;
1803 unsigned int hist = mHistory.size();
1809 read ( STDIN_FILENO, &c, 4) ;
1811 bbtkDebugMessage("debug",9,"[0x"<<std::hex<<c<<"]\n");
1813 // Printable character
1814 if ( (ind<MAX_LINE_SIZE-1) &&
1815 ( c >= BBTK_SPACE_KBCODE ) &&
1816 ( c < BBTK_DEL_KBCODE ))
1824 // delete the unused line
1830 // empty lines are not stored in from history
1833 // if history too long : delete oldest command
1834 if (mHistory.size()>MAX_HISTORY_SIZE)
1836 delete mHistory.front();
1837 mHistory.pop_front();
1839 mHistory.push_back(line);
1844 else if ( (ind>0) &&
1845 ((c == BBTK_BACKSPACE_KBCODE) ||
1846 (c == BBTK_DEL_KBCODE)) )
1854 // TODO : Command completion
1855 std::vector<std::string> commands;
1856 FindCommandsWithPrefix( line,ind,commands);
1857 if (commands.size()==1)
1859 std::string com = *commands.begin();
1860 for (; ind<com.size(); ++ind)
1862 PrintChar(com[ind]);
1868 else if (commands.size()>1)
1870 std::vector<std::string>::iterator i;
1872 for (i=commands.begin();i!=commands.end();++i)
1874 write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
1877 write(STDOUT_FILENO,"\n> ",3);
1878 //for (int j=0;j<ind;++j)
1880 write(STDOUT_FILENO,line,ind);
1884 // Arrow up : back in history
1885 else if (c==BBTK_UP_ARROW_KBCODE)
1889 // erase current line
1890 while (ind--) BackSpace();
1894 strcpy(histline,mHistory[hist]);
1898 write(STDOUT_FILENO,line,ind);
1901 // Arrow down : down in history
1902 else if (c==BBTK_DOWN_ARROW_KBCODE)
1904 if (hist<mHistory.size()-1)
1906 // erase current line
1907 while (ind--) BackSpace();
1911 strcpy(histline,mHistory[hist]);
1915 write(STDOUT_FILENO,line,ind);
1917 // end of history : switch back to newline
1918 else if (hist==mHistory.size()-1)
1920 // erase current line
1921 while (ind--) BackSpace();
1928 write(STDOUT_FILENO,line,ind);
1932 else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
1934 PrintChar(line[ind]);
1939 else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
1947 write(STDOUT_FILENO,"\n\r",2);
1955 //=======================================================================
1956 void InterpreterVirtual::GetLineFromPrompt(std::string& s)
1982 //=======================================================================
1988 //=======================================================================
1989 void InterpreterVirtual::CommandLineInterpreter()
1991 bbtkDebugMessageInc("interpreter",9,
1992 "InterpreterVirtual::CommandLineInterpreter()"<<std::endl);
1994 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1995 // Initialise the tty in non canonical mode with no echo
1996 // oter remembers the previous settings to restore them after
1997 struct termios ter,oter;
2000 ter.c_lflag &= ~ECHO;
2001 ter.c_lflag &= ~ICANON;
2004 tcsetattr(0,TCSANOW,&ter);
2007 mCommandLine = true;
2009 // bool insideComment = false; // for multiline comment
2010 mInsideComment = false;
2016 GetLineFromPrompt(line);
2017 DoInterpretLine(line); //, insideComment);
2020 catch (QuitException e)
2022 bbtkMessage("interpreter",1,"Interpreter : Quit"<<std::endl);
2026 catch (bbtk::Exception e)
2030 catch (std::exception& e)
2032 std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
2036 std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
2041 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
2042 tcsetattr(0,TCSANOW,&oter);
2045 std::cout << "Good bye !" << std::endl;
2047 bbtkDebugDecTab("interpreter",9);
2050 //=======================================================================
2051 void InterpreterVirtual::commandGraph(const std::vector<std::string>& words)
2054 //=======================================================================
2057 //=======================================================================
2058 void InterpreterVirtual::commandIndex(const std::string& filename, const std::string& type)
2061 //=======================================================================
2064 //=======================================================================
2065 void InterpreterVirtual::commandNewGUI(const std::string& boxname,const std::string& instanceName)
2068 //=======================================================================
2072 //==========================================================================
2073 void InterpreterVirtual::commandDebug(const std::string& name)
2076 //==========================================================================
2079 //==========================================================================
2080 // Adds a callback when 'break' command issued
2081 void InterpreterVirtual::AddBreakObserver( BreakCallbackType c )
2083 mBreakSignal.connect(c);
2085 //==========================================================================
2088 //==========================================================================
2089 std::string InterpreterVirtual::GetObjectName() const
2091 return std::string("InterpreterVirtual");
2093 //==========================================================================
2095 //==========================================================================
2096 std::string InterpreterVirtual::GetObjectInfo() const
2098 std::stringstream i;
2101 //==========================================================================
2103 //==========================================================================
2104 size_t InterpreterVirtual::GetObjectSize() const
2106 size_t s = Superclass::GetObjectSize();
2107 s += InterpreterVirtual::GetObjectInternalSize();
2110 //==========================================================================
2111 //==========================================================================
2112 size_t InterpreterVirtual::GetObjectInternalSize() const
2114 size_t s = sizeof(InterpreterVirtual);
2117 //==========================================================================
2118 //==========================================================================
2119 size_t InterpreterVirtual::GetObjectRecursiveSize() const
2121 size_t s = Superclass::GetObjectRecursiveSize();
2122 s += InterpreterVirtual::GetObjectInternalSize();
2125 //==========================================================================