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 printf("EED InterpreterVirtual::CatchUnknownException Start\n");
520 //EED Borrame if (GetExecuter()->GetNoErrorMode())
522 //EED Borrame std::string file("?");
523 //EED Borrame int line = 0;
524 //EED Borrame if (mFileName.size()) {
525 //EED Borrame file = mFileName.back();
526 //EED Borrame line = mLine.back();
528 //EED Borrame bbtkWarning("UNDEFINED ERROR "
529 //EED Borrame <<"("<<file<<":"<<line<<") skipped");
530 //EED Borrame return;
532 mStatus = Interpreter_ERROR;
535 bool in_script = false;
536 std::string file("");
538 if (mFileName.size()) {
539 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
540 if (fs!=0) in_script = true;
541 file = mFileName.back();
545 throw InterpreterException("Unknown exception caught",
546 in_script,file,line);
550 std::stringstream mess;
551 mess << "* UNDEFINED ERROR (not a bbtk nor a std exception)"
553 if (mFileName.size()) {
554 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
555 mess << "* LINE : "<<mLine.back()<<std::endl;
558 std::cerr << mess.str();
560 printf("EED InterpreterVirtual::CatchUnknownException End\n");
562 //=======================================================================
564 //=======================================================================
566 #define CATCH_MACRO \
567 catch (InterpreterException e) \
569 CatchInterpreterException(e); \
571 catch (bbtk::Exception e) \
573 CatchBbtkException(e); \
575 catch (std::exception& e) \
577 CatchStdException(e); \
581 CatchUnknownException(); \
583 //=======================================================================
586 //=======================================================================
587 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretFile( const std::string& filename, bool source )
589 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::InterpretFile(\""<<filename<<"\")"<<std::endl);
591 bool exm = mCommandLine;
592 mCommandLine = false;
596 mStatus = Interpreter_OK;
597 SwitchToFile(filename,source);
598 mInsideComment = false;
599 InterpretCurrentStreams();
603 bbtkDebugMessage("interpreter",4,
604 "<== InterpreterVirtual::InterpretFile(\""
605 <<filename<<"\")"<<std::endl);
612 //=======================================================================
615 //=======================================================================
616 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretBuffer( std::stringstream* buffer )
618 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::InterpretBuffer()"<<std::endl);
620 bool exm = mCommandLine;
621 mCommandLine = false;
625 mStatus = Interpreter_OK;
626 SwitchToStream(buffer);
627 mInsideComment = false;
628 InterpretCurrentStreams();
633 bbtkDebugMessage("interpreter",4,"<== InterpreterVirtual::InterpretBuffer()"<<std::endl);
640 //=======================================================================
642 //=======================================================================
643 /// Interprets the currently open streams
644 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretCurrentStreams()
646 bbtkDebugMessage("interpreter",4,
647 "==> InterpreterVirtual::InterpretCurrentStreams()"<<std::endl);
649 while (mFile.size()>0)
651 while (!mFile.back()->eof()) {
654 mFile.back()->getline(buf,500);
655 std::string str(buf);
656 //size 0 JCP 21-09-2009
657 int size=str.length();
659 if ( str[ size-1 ]==13 )
665 DoInterpretLine(str);
673 bbtkDebugMessage("interpreter",4,
674 "<== InterpreterVirtual::InterpretCurrentStreams()"<<std::endl);
678 //=======================================================================
680 //=======================================================================
681 /// Runs the interpretation of a command
682 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretLine( const std::string& line )
684 bbtkDebugMessage("interpreter",5,"==> InterpreterVirtual::InterpretLine('"<<line<<"')"<<std::endl);
688 mStatus = Interpreter_OK;
689 mInsideComment = false;
690 //std::cout<<"JCP bbtkInterpreter.cxx InterpreterVirtual::InterpretLine("<<std::endl;
691 DoInterpretLine(line );
696 bbtkDebugMessage("interpreter",5,"<== InterpreterVirtual::InterpretLine('"<<line<<"')"<<std::endl);
700 //=======================================================================
702 void InterpreterVirtual::commandNew(const std::string &boxType, const std::string &boxName) // virtual
706 void InterpreterVirtual::commandDelete(const std::string &boxName)
710 void InterpreterVirtual::commandConnection(const std::string &nodeFrom,const std::string &outputLabel,const std::string &nodeTo,const std::string &inputLabel)
714 void InterpreterVirtual::commandPackage(const std::string &packageName)
718 void InterpreterVirtual::commandEndPackage()
722 void InterpreterVirtual::commandDefine(const std::string &name,const std::string &pack,const std::string &scriptfilename)
726 void InterpreterVirtual::commandEndDefine()
730 void InterpreterVirtual::commandKind(const std::string &kind)
734 void InterpreterVirtual::commandPrint(const std::string &value)
739 void InterpreterVirtual::commandExec(const std::string &word)
744 void InterpreterVirtual::commandInput(const std::string &name,const std::string &box,const std::string &input,const std::string &help)
748 void InterpreterVirtual::commandOutput(const std::string &name,const std::string &box,const std::string &output,const std::string &help)
752 void InterpreterVirtual::commandSet(const std::string &box,const std::string &input,const std::string &value)
756 void InterpreterVirtual::commandAuthor(const std::string &author)
760 void InterpreterVirtual::commandCategory(const std::string &categorytype)
766 void InterpreterVirtual::commandDescription(const std::string &description)
771 void InterpreterVirtual::commandClear()
775 void InterpreterVirtual::commandInclude(const std::string &word, bool ok)
780 void InterpreterVirtual::commandLoad(const std::string &packageName)
784 void InterpreterVirtual::commandUnload(const std::string &packageName)
788 void InterpreterVirtual::commandBreak()
792 void InterpreterVirtual::commandQuit()
796 void InterpreterVirtual::commandMessage()
800 void InterpreterVirtual::commandMessage(const std::string &kind,const std::string &levelstr)
806 //=======================================================================
807 void InterpreterVirtual::DoInterpretLine( const std::string& line )
809 bbtkDebugMessage("interpreter",6,"==> InterpreterVirtual::DoInterpretLine(\""
810 <<line<<"\")"<<std::endl);
811 std::vector<std::string> words;
812 SplitLine(line,words);
819 bbtkDebugDecTab("interpreter",9);
823 // Single line comment : # or //
824 if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') )
826 bbtkDebugDecTab("interpreter",9);
827 bbtkMessage("interpreter",9,"Comment"<<std::endl);
831 // Multi line comment ( /* ... */ ) -delimiters on different lines !-
833 if (words[0][0]=='/' && words[0][1]=='*')
835 bbtkDebugDecTab("interpreter",9);
836 bbtkMessage("interpreter",9,"In multiline comment"<<std::endl);
837 mInsideComment = true;
841 if (words[0][0]=='*' && words[0][1]=='/')
843 bbtkDebugDecTab("interpreter",9);
844 bbtkMessage("interpreter",9,"Out multiline comment"<<std::endl);
845 if ( !mInsideComment ) {
846 bbtkDebugDecTab("interpreter",9);
847 bbtkMessage("interpreter",9,"Comment mismatch : '*/' with no matching '/*'"<<std::endl);
849 mInsideComment = false;
855 bbtkDebugDecTab("interpreter",9);
856 bbtkMessage("interpreter",9,"Multiline Comment"<<std::endl);
862 CommandInfoType command;
863 InterpretCommand(words,command);
864 //std::cout<<"JCP bbtkInterpreter command.keyword ="<<command.keyword<<std::endl;
865 bbtkDebugMessage("interpreter",9,
866 "Command='"<<command.keyword
867 <<"' code="<<command.code<<std::endl);
869 std::string left,right,left2,right2;
870 std::string filename;
873 if (command.code==cMessage)
878 //EED Borrame mVirtualExecuter->HelpMessages();
882 commandMessage(words[1],words[2]);
883 //EED Borrame sscanf(words[2].c_str(),"%d",&level);
884 //EED Borrame mVirtualExecuter->SetMessageLevel(words[1],level);
890 bbtkMessage("echo",2,line<<std::endl);
893 // break and quit commands
894 if ((command.code==cBreak) || (command.code==cQuit))
896 //EED-Borrame bool in_script = false;
897 //EED-Borrame std::string file("");
898 //EED-Borrame int line = 0;
900 //EED-Borrame if (mFileName.size())
902 //EED-Borrame std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
903 //EED-Borrame if (fs!=0) in_script = true;
904 //EED-Borrame file = mFileName.back();
905 //EED-Borrame line = mLine.back();
907 if (command.code==cBreak)
910 std::cout << "BreakException("
913 <<line<<")"<<std::endl;
916 //EED Borrame bbtkError("break");//,in_script,file,line);
917 // throw BreakException(in_script,file,line);
920 //EED Borrame bbtkError("quit");//,in_script,file,line);
921 //throw QuitException(in_script,file,line);
925 //std::cout<<" mVirtualExecuter->Create(words[1],words[2]); "<<line<<std::endl;
929 switch (command.code)
932 commandNew(words[1],words[2]);
933 //EED Borrame mVirtualExecuter->Create(words[1],words[2]);
937 commandDelete(words[1]);
938 //EED Borrame mVirtualExecuter->Destroy(words[1]);
942 Utilities::SplitAroundFirstDot(words[1],left,right);
943 Utilities::SplitAroundFirstDot(words[2],left2,right2);
944 commandConnection(left,right,left2,right2);
945 //EED Borrame mVirtualExecuter->Connect(left,right,left2,right2);
949 commandPackage(words[1]);
950 //EED Borrame mVirtualExecuter->BeginPackage(words[1]);
955 //EED Borrame mVirtualExecuter->EndPackage();
959 if (mFileName.size()>0)
961 //??? commandDefine(????);
962 filename = mFileName.back(); //mIncludeFileName.back(); //Utilities::get_file_name(mFileName.back());
966 std::string packTmp = "";
967 commandDefine(words[1],packTmp,filename);
968 //EED Borrame mVirtualExecuter->Define(words[1],"",filename);
972 commandDefine(words[1],words[2],filename);
973 //EED Borrame mVirtualExecuter->Define(words[1],words[2],filename);
979 //EED Borrame mVirtualExecuter->EndDefine();
983 commandKind(words[1]);
984 //EED Borrame mVirtualExecuter->Kind(words[1]);
988 commandPrint(words[1]);
989 //EED Borrame mVirtualExecuter->Print(words[1]);
993 commandExec(words[1]);
994 //EED Borrame if (words[1]=="freeze")
996 //EED Borrame mVirtualExecuter->SetNoExecMode(true);
997 //EED Borrame mThrow = false;
999 //EED Borrame else if (words[1]=="freeze_no_error")
1001 //EED Borrame mVirtualExecuter->SetNoExecMode(true);
1002 //EED Borrame mVirtualExecuter->SetNoErrorMode(true);
1003 //EED Borrame mThrow = false;
1005 //EED Borrame else if (words[1]=="unfreeze")
1007 //EED Borrame mVirtualExecuter->SetNoExecMode(false);
1008 //EED Borrame mVirtualExecuter->SetNoErrorMode(false);
1012 //EED Borrame mVirtualExecuter->Execute(words[1]);
1018 Utilities::SplitAroundFirstDot(words[2],left,right);
1019 commandInput(words[1],left,right,words[3]);
1020 //EED Borrame mVirtualExecuter->DefineInput(words[1],left,right,words[3]);
1024 Utilities::SplitAroundFirstDot(words[2],left,right);
1025 commandOutput(words[1],left,right,words[3]);
1026 //EED Borrame mVirtualExecuter->DefineOutput(words[1],left,right,words[3]);
1030 Utilities::SplitAroundFirstDot(words[1],left,right);
1031 commandSet(left,right,words[2]);
1032 //EED Borrame mVirtualExecuter->Set(left,right,words[2]);
1036 commandAuthor(words[1]);
1037 //EED Borrame mVirtualExecuter->Author(words[1]);
1041 commandNewGUI(words[1],words[2]);
1045 commandCategory(words[1]);
1046 //EED Borrame mVirtualExecuter->Category(words[1]);
1050 if (words.size()==1)
1051 commandIndex("tmp_index.html");
1052 else if (words.size()==2)
1053 commandIndex(words[1]);
1054 else if (words.size()==3)
1055 commandIndex(words[1],words[2]);
1059 commandDescription(words[1]);
1060 //EED Borrame mVirtualExecuter->Description(words[1]);
1069 commandGraph(words);
1082 //EED Borrame mVirtualExecuter->Clear();
1086 commandInclude( words[1] , (words.size()==3) );
1087 //EED Borrame // if 'source' was given (words.size()==3) then tell to set the
1088 //EED Borrame // source file name of the current complex box with the full file name included
1089 //EED Borrame if (mCommandLine)
1091 //EED Borrame InterpretFile(words[1],(words.size()==3));
1092 //EED Borrame } else{
1093 //EED Borrame SwitchToFile(words[1],(words.size()==3) );
1098 commandLoad( words[1] );
1099 //EED Borrame GetExecuter()->LoadPackage(words[1]);
1103 commandUnload( words[1] );
1104 //EED Borrame GetExecuter()->UnLoadPackage(words[1]);
1108 if (words.size()==2) commandDebug(words[1]);
1109 else commandDebug("");
1114 if (words.size() == 2)
1116 if (words[1]=="freeze") mVirtualExecuter->SetNoExecMode(true);
1117 else if (words[1]=="unfreeze") mVirtualExecuter->SetNoExecMode(false);
1121 mVirtualExecuter->SetWorkspaceName(words[2]);
1126 bbtkInternalError("should not reach here !!!");
1129 bbtkDebugMessage("interpreter",6,"<== InterpreterVirtual::DoInterpretLine(\""
1130 <<line<<"\")"<<std::endl);
1133 //=======================================================================
1139 //=======================================================================
1140 void InterpreterVirtual::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
1142 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::SplitLine(\""<<str<<"\")"<<std::endl);
1144 std::string delimiters = "\"";
1145 std::vector<std::string> quote;
1146 Utilities::SplitString(str,delimiters,quote);
1149 std::vector<std::string>::iterator i;
1150 for (i=quote.begin(); i!=quote.end(); )
1152 Utilities::SplitString(*i,delimiters,tokens);
1156 // bbtkDebugMessage("interpreter",0,"\""<<*i<<"\""<<std::endl);
1157 tokens.push_back(*i);
1162 for (i=tokens.begin(); i!=tokens.end(); ++i)
1164 bbtkDebugMessage("interpreter",9,"--["<<*i<<"]"<<std::endl);
1166 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::SplitLine(\""<<str<<"\")"<<std::endl);
1169 //=======================================================================
1172 //=======================================================================
1173 void InterpreterVirtual::commandReset()
1176 //=======================================================================
1178 //=======================================================================
1183 void InterpreterVirtual::Print( const std::string& str)
1185 if (mVirtualExecuter->GetNoExecMode()) return;
1187 bbtkDebugMessageInc("interpreter",9,"InterpreterVirtual::Print(\""<<str<<"\")"<<std::endl);
1190 // InterpretLine ("load std")
1191 // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande
1192 // InterpretLine("new Print _P_")
1193 // InterpretLine("connect _C_.Out _P_.In")
1197 std::vector<std::string> chains;
1198 std::string delimiters("$");
1200 // Skip delimiters at beginning.
1201 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
1202 bool is_text = true;
1203 if (lastPos>0) is_text = false;
1205 // Find first delimiter.
1206 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
1208 while (std::string::npos != pos || std::string::npos != lastPos)
1212 // Found a text token, add it to the vector.
1213 chains.push_back(str.substr(lastPos, pos - lastPos));
1214 // std::string token = str.substr(lastPos, pos - lastPos)
1215 // InterpretLine("set _C_.In%num% %token%")
1221 // is an output (between $$) : decode
1222 std::string tok,box,output;
1223 tok = str.substr(lastPos, pos - lastPos);
1224 Utilities::SplitAroundFirstDot(tok,box,output);
1225 chains.push_back( mVirtualExecuter->Get(box,output) );
1227 // InterpretLine("connect %tok% _C_.In%num%")
1230 // Skip delimiters. Note the "not_of"
1231 lastPos = str.find_first_not_of(delimiters, pos);
1232 // Find next delimiter
1233 pos = str.find_first_of(delimiters, lastPos);
1238 // InterpretLine("exec _P_")
1239 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
1241 std::vector<std::string>::iterator i;
1242 for (i= chains.begin(); i!=chains.end(); ++i)
1245 Utilities::SubsBackslashN(*i);
1248 std::cout << std::endl;
1249 bbtkDebugDecTab("interpreter",9);
1253 //=======================================================================
1258 // =========================================================================
1259 void InterpreterVirtual::SwitchToFile( const std::string& name , bool source )
1261 // Note : in the following :
1262 // name : the user supplied name
1263 // - abreviated name e.g. scr scr.bbs
1264 // - relative full name e.g. ./scr.bbs ../../scr.bbs
1265 // - absolute full name e.g. /home/usrname/proj/dir/scr.bbs
1266 // same for Windows, with c:, d: ...
1268 // use ./directory/subdir/scrname.bbs
1271 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::SwitchToFile( \""
1272 <<name<<"\")"<<std::endl);
1274 std::vector<std::string> script_paths;
1275 std::string fullPathScriptName; // full path script name
1276 std::string pkgname; // e.g. <scriptname>.bbs
1277 std::vector<std::string> Filenames;
1278 std::string tmpFilenames;
1280 // The following is *NOT* a debug time message :
1281 // It's a user intended message.
1282 // Please don't remove it.
1283 bbtkMessage("interpreter",1,
1284 "look for : [" << name
1285 << "]" << std::endl);
1289 pkgname = Utilities::ExtractScriptName(name,upath);
1291 bbtkMessage("interpreter",3,
1292 "package name:[" << pkgname
1293 << "] path:[" << upath << "]" << std::endl);
1294 bool fullnameGiven = false;
1295 bool foundFile = false;
1297 // ==== "*" provided : load all scripts in given path
1298 // relative (e.g. std/boxes/*) or absolute
1302 std::stringstream* stream = new std::stringstream;
1303 //if (upath.size()!=0) // avoid troubles for "*"
1305 // ==== no path provided : look in root bbs path
1306 if (upath.size()==0)
1308 // bbtkMessage("interpreter",1,
1309 // LG : add all bbs path
1310 // script_paths.push_back( ConfigurationFile::GetInstance().Get_root_bbs_path() );
1311 std::vector<std::string>::const_iterator i;
1312 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1313 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1316 script_paths.push_back(*i);
1319 // ==== absolute path provided
1320 else if (upath[0]=='/' || upath[1] == ':' )
1322 if ( Utilities::IsDirectory( upath ) )
1324 script_paths.push_back(upath);
1328 bbtkError("'"<<upath<<"' : directory does not exist");
1331 // ==== relative path provided : search all bbs path appended with
1332 // the relative path provided
1335 std::vector<std::string>::const_iterator i;
1336 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1337 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1340 std::string full_path(*i);
1341 // we *really* want '.' to be the current working directory
1342 if (full_path == ".")
1344 char buf[2048]; // for getcwd
1345 char * currentDir = getcwd(buf, 2048);
1346 std::string cwd(currentDir);
1347 full_path = currentDir;
1350 full_path += ConfigurationFile::GetInstance().Get_file_separator();
1353 if ( Utilities::IsDirectory( full_path ) )
1355 script_paths.push_back(full_path);
1358 if (script_paths.empty())
1360 bbtkError("no '"<<upath<<"' subdir found in search paths"
1365 // === search paths list complete : now explore it
1367 // ==== relative name, iterate + load all .bbs/.bbp files
1368 std::vector<std::string>::iterator i;
1369 for (i=script_paths.begin();i!=script_paths.end();i++)
1372 bbtkMessage("interpreter",1,
1373 "--> Looking in '" << *i << "'" << std::endl);
1377 Utilities::Explore(*i, false, Filenames);
1379 int iFilesnames,jFilesnames,sizeFilenames;
1380 sizeFilenames=Filenames.size();
1383 // EEDd 30 sept 2012
1384 //Sorting list of files
1385 for (iFilesnames=0;iFilesnames<sizeFilenames; iFilesnames++)
1387 for (jFilesnames=iFilesnames;jFilesnames<sizeFilenames; jFilesnames++)
1389 if ( Filenames[iFilesnames] > Filenames[jFilesnames] )
1391 tmpFilenames = Filenames[iFilesnames];
1392 Filenames[iFilesnames] = Filenames[jFilesnames];
1393 Filenames[jFilesnames] = tmpFilenames;
1395 } // for iFilesnames
1396 } // for iFilesnames
1400 for (std::vector<std::string>::iterator j = Filenames.begin();
1401 j!= Filenames.end(); ++j)
1403 int lgr = (*j).size();
1404 if (lgr < 5) continue;
1405 // ignore non .bbp file
1406 if ( (*j).substr(lgr-4, 4) != ".bbp") continue;
1408 (*stream) << "include \"" << *j << "\"\n";
1409 bbtkMessage("interpreter",2," --> Found '" << *j << "'" << std::endl);
1412 } // for (std::vector...
1413 } // for (i=script_...
1418 bbtkMessage("interpreter",1,
1419 " --> No .bbp found"<< std::endl);
1423 bbtkMessage("interpreter",1,
1424 " --> "<<nbBssFiles<<" .bbp found"<< std::endl);
1425 SwitchToStream(stream);
1429 //=============== end pkgname=="*" ===========
1432 // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name
1433 // (not only a plain script name)
1434 // we trust him, and try to expland the directory name
1435 // WARNING : starting from current local directory : ./whatYouWant (./ mandatory!)
1437 if (name[0]=='/' || name[1] == ':' || name[0]=='.') // absolute path (linux/windows) or relative path
1440 // ===========================================================check user supplied location
1441 fullnameGiven = true;
1443 fullPathScriptName = Utilities::ExpandLibName(name, false);
1445 // allow user to always forget ".bbs"
1446 int l = fullPathScriptName.size();
1450 if ((fullPathScriptName.substr(l-4, 4) != ".bbs")&&
1451 (fullPathScriptName.substr(l-4, 4) != ".bbp"))
1453 std::string tfullPathScriptName = fullPathScriptName + ".bbs";
1454 if ( Utilities::FileExists(tfullPathScriptName) )
1456 fullPathScriptName = tfullPathScriptName;
1461 tfullPathScriptName = fullPathScriptName + ".bbp";
1462 if ( Utilities::FileExists(tfullPathScriptName) )
1464 fullPathScriptName = tfullPathScriptName;
1471 if ( Utilities::FileExists(fullPathScriptName) )
1479 // =============================== iterate on the paths
1481 script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
1483 std::vector<std::string>::iterator i;
1484 for (i=script_paths.begin();i!=script_paths.end();++i)
1487 // we *really* want '.' to be the current working directory
1490 char buf[2048]; // for getcwd
1491 char * currentDir = getcwd(buf, 2048);
1492 std::string cwd(currentDir);
1496 std::string tfullPathScriptName = Utilities::MakePkgnameFromPath(path, name, false);
1498 //Addition JCP tfullPathScriptName.size()>=4
1499 if(tfullPathScriptName.size()>=4){
1500 if (tfullPathScriptName.substr(tfullPathScriptName.size()-4, 3)==".bb")
1502 fullPathScriptName = tfullPathScriptName;
1503 if ( ! Utilities::FileExists(fullPathScriptName) )
1505 // The following is *NOT* a debug time message :
1506 // It's a user intended message.
1507 // Please don't remove it.
1508 bbtkMessage("interpreter",2,
1509 " [" <<fullPathScriptName <<"] : does not exist"
1511 continue; // try next path
1513 bbtkMessage("interpreter",2,
1514 " [" <<fullPathScriptName
1515 <<"] : found" <<std::endl);
1517 break; // a script was found; we stop iterating
1521 fullPathScriptName = tfullPathScriptName + ".bbs";
1522 // Check if library exists
1523 if ( ! Utilities::FileExists(fullPathScriptName) )
1525 fullPathScriptName = tfullPathScriptName + ".bbp";
1526 if ( ! Utilities::FileExists(fullPathScriptName) )
1528 // The following is *NOT* a debug time message :
1529 // It's a user intended message.
1530 // Please don't remove it.
1531 bbtkMessage("interpreter",2,
1532 " [" <<tfullPathScriptName <<".bbs/.bbp] : do not exist"
1534 continue; // try next path
1537 bbtkMessage("interpreter",2,
1538 " [" <<fullPathScriptName
1539 <<"] : found" <<std::endl);
1541 break; // a script was found; we stop iterating
1544 } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
1550 if(fullPathScriptName == "")
1551 bbtkError("Path ["<<upath<<"] doesn't exist");
1553 bbtkError("Script ["<<fullPathScriptName<<"] not found");
1555 bbtkError("No ["<<pkgname<<".bbs/.bbp] script found");
1558 LoadScript(fullPathScriptName,name);
1561 // Over writing the fullpath of the bbp file.
1562 SetCurrentFileName( fullPathScriptName );
1563 SetTypeOfScript_Application();
1569 //=======================================================================
1571 //=======================================================================
1572 void InterpreterVirtual::SetCurrentFileName(const std::string &fullPathScriptName) // virtual
1575 //=======================================================================
1578 //=======================================================================
1579 void InterpreterVirtual::SetTypeOfScript_Application( )
1582 //=======================================================================
1585 //=======================================================================
1586 void InterpreterVirtual::SwitchToStream( std::stringstream* stream )
1588 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::SwitchToStream()"
1590 mFile.push_back(stream);
1591 std::ostringstream buffer_name;
1593 buffer_name << "buffer_" ;
1595 if (mFileName.size()>0 )
1597 buffer_name << mFileName.back() << "_" << mLine.back();
1599 mFileName.push_back(buffer_name.str());
1600 mIncludeFileName.push_back(buffer_name.str());
1603 //=======================================================================
1605 //=======================================================================
1607 void InterpreterVirtual::LoadScript( std::string fullPathScriptName,
1608 std::string includeScriptName)
1610 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::LoadScript("
1611 <<fullPathScriptName<<")"
1614 Utilities::replace( fullPathScriptName ,
1615 INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
1617 if (find(mFileNameHistory.begin(),
1618 mFileNameHistory.end(),
1619 fullPathScriptName)!=mFileNameHistory.end())
1625 s = new std::ifstream;
1626 s->open(fullPathScriptName.c_str());
1629 bbtkError("Could not open file ["<<fullPathScriptName<<"]");
1633 bbtkMessage("interpreter",1," -->[" << fullPathScriptName
1634 << "] found" << std::endl);
1637 mFileName.push_back(fullPathScriptName);
1638 mFileNameHistory.push_back(fullPathScriptName);
1639 mIncludeFileName.push_back(includeScriptName);
1644 //=======================================================================
1646 //=======================================================================
1647 void InterpreterVirtual::CloseCurrentFile()
1649 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::CloseCurrentFile()"
1652 if (mFile.size()==0)
1654 bbtkDebugMessage("interpreter",9," -> no file left open"<<std::endl);
1658 bbtkDebugMessage("interpreter",9," Closing file '"<<mFileName.back()<<"'"<<std::endl);
1660 std::ifstream* file = dynamic_cast<std::ifstream*>(mFile.back());
1661 if (file!=0) file->close();
1663 delete mFile.back();
1665 mFileName.pop_back();
1666 mIncludeFileName.pop_back();
1669 bbtkDebugMessage("interpreter",9," Remains "
1671 <<" open"<<std::endl);
1672 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::CloseCurrentFile()"
1675 //=======================================================================
1677 //=======================================================================
1678 void InterpreterVirtual::CloseAllFiles()
1680 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::CloseAllFiles()"
1683 while (mFile.size() != 0)
1687 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::CloseAllFiles()"
1690 //=======================================================================
1694 //=======================================================================
1695 void InterpreterVirtual::InterpretCommand( const std::vector<std::string>& words,
1696 CommandInfoType& info )
1699 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::InterpretCommand(...)"<<std::endl);
1701 // searches the command keyword
1702 CommandDictType::iterator c;
1703 c = mCommandDict.find(words[0]);
1704 if ( c == mCommandDict.end() ) {
1705 bbtkError(words[0]<<" : unknown command");
1708 // tests the number of args
1709 if ( ( ((int)words.size())-1 < c->second.argmin ) ||
1710 ( ((int)words.size())-1 > c->second.argmax ) )
1713 //EED HelpCommand(words[0]);
1714 commandHelp(words[0]);
1715 bbtkError(words[0]<<" : wrong number of arguments");
1717 //std::cout<<"InterpreterVirtual::InterpretCommand( const std::vector<std::string>& words,"<<std::endl;
1719 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::InterpretCommand(...)"<<std::endl);
1722 //=======================================================================
1725 //=======================================================================
1726 /// Displays help on all the commands
1727 void InterpreterVirtual::commandHelp(const std::vector<std::string>& words)
1730 //=======================================================================
1731 void InterpreterVirtual::commandHelp(const std::string &words)
1734 //=======================================================================
1736 //===================================================================
1737 /// Displays the Configuration
1738 void InterpreterVirtual::commandConfig() const
1741 //===================================================================
1745 //=======================================================================
1746 /// Fills the vector commands with the commands which
1747 /// have the first n chars of buf for prefix
1748 /// TODO : skip initial spaces in buf and also return the position of first
1749 /// non blank char in buf
1750 void InterpreterVirtual::FindCommandsWithPrefix( char* buf,
1752 std::vector<std::string>& commands )
1754 CommandDictType::const_iterator i;
1755 for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
1757 if ((i->first).find(buf,0,n) == 0)
1758 commands.push_back(i->first);
1761 //=======================================================================
1765 //=======================================================================
1766 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1768 inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
1769 inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
1771 // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
1772 // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
1773 // E.G. STORE THIS IN bbtk_config.xml
1774 #define BBTK_UP_ARROW_KBCODE 0x00415B1B
1775 #define BBTK_DOWN_ARROW_KBCODE 0x00425B1B
1776 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
1777 #define BBTK_LEFT_ARROW_KBCODE 0x00445B1B
1778 #define BBTK_BACKSPACE_KBCODE 0x00000008
1779 #define BBTK_DEL_KBCODE 0x0000007F
1780 #define BBTK_SPACE_KBCODE 0x00000020
1782 //=======================================================================
1783 void InterpreterVirtual::GetLineFromPrompt(std::string& s)
1788 unsigned int MAX_LINE_SIZE = 160;
1789 unsigned int MAX_HISTORY_SIZE = 100;
1791 char* newline = new char[MAX_LINE_SIZE];
1792 memset(newline,0,MAX_LINE_SIZE);
1793 char* histline = new char[MAX_LINE_SIZE];
1794 memset(histline,0,MAX_LINE_SIZE);
1796 char* line = newline;
1797 unsigned int hist = mHistory.size();
1803 read ( STDIN_FILENO, &c, 4) ;
1805 bbtkDebugMessage("debug",9,"[0x"<<std::hex<<c<<"]\n");
1807 // Printable character
1808 if ( (ind<MAX_LINE_SIZE-1) &&
1809 ( c >= BBTK_SPACE_KBCODE ) &&
1810 ( c < BBTK_DEL_KBCODE ))
1818 // delete the unused line
1824 // empty lines are not stored in from history
1827 // if history too long : delete oldest command
1828 if (mHistory.size()>MAX_HISTORY_SIZE)
1830 delete mHistory.front();
1831 mHistory.pop_front();
1833 mHistory.push_back(line);
1838 else if ( (ind>0) &&
1839 ((c == BBTK_BACKSPACE_KBCODE) ||
1840 (c == BBTK_DEL_KBCODE)) )
1848 // TODO : Command completion
1849 std::vector<std::string> commands;
1850 FindCommandsWithPrefix( line,ind,commands);
1851 if (commands.size()==1)
1853 std::string com = *commands.begin();
1854 for (; ind<com.size(); ++ind)
1856 PrintChar(com[ind]);
1862 else if (commands.size()>1)
1864 std::vector<std::string>::iterator i;
1866 for (i=commands.begin();i!=commands.end();++i)
1868 write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
1871 write(STDOUT_FILENO,"\n> ",3);
1872 //for (int j=0;j<ind;++j)
1874 write(STDOUT_FILENO,line,ind);
1878 // Arrow up : back in history
1879 else if (c==BBTK_UP_ARROW_KBCODE)
1883 // erase current line
1884 while (ind--) BackSpace();
1888 strcpy(histline,mHistory[hist]);
1892 write(STDOUT_FILENO,line,ind);
1895 // Arrow down : down in history
1896 else if (c==BBTK_DOWN_ARROW_KBCODE)
1898 if (hist<mHistory.size()-1)
1900 // erase current line
1901 while (ind--) BackSpace();
1905 strcpy(histline,mHistory[hist]);
1909 write(STDOUT_FILENO,line,ind);
1911 // end of history : switch back to newline
1912 else if (hist==mHistory.size()-1)
1914 // erase current line
1915 while (ind--) BackSpace();
1922 write(STDOUT_FILENO,line,ind);
1926 else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
1928 PrintChar(line[ind]);
1933 else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
1941 write(STDOUT_FILENO,"\n\r",2);
1949 //=======================================================================
1950 void InterpreterVirtual::GetLineFromPrompt(std::string& s)
1976 //=======================================================================
1982 //=======================================================================
1983 void InterpreterVirtual::CommandLineInterpreter()
1985 bbtkDebugMessageInc("interpreter",9,
1986 "InterpreterVirtual::CommandLineInterpreter()"<<std::endl);
1988 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1989 // Initialise the tty in non canonical mode with no echo
1990 // oter remembers the previous settings to restore them after
1991 struct termios ter,oter;
1994 ter.c_lflag &= ~ECHO;
1995 ter.c_lflag &= ~ICANON;
1998 tcsetattr(0,TCSANOW,&ter);
2001 mCommandLine = true;
2003 // bool insideComment = false; // for multiline comment
2004 mInsideComment = false;
2010 GetLineFromPrompt(line);
2011 DoInterpretLine(line); //, insideComment);
2014 catch (QuitException e)
2016 bbtkMessage("interpreter",1,"Interpreter : Quit"<<std::endl);
2020 catch (bbtk::Exception e)
2024 catch (std::exception& e)
2026 std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
2030 std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
2035 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
2036 tcsetattr(0,TCSANOW,&oter);
2039 std::cout << "Good bye !" << std::endl;
2041 bbtkDebugDecTab("interpreter",9);
2044 //=======================================================================
2045 void InterpreterVirtual::commandGraph(const std::vector<std::string>& words)
2048 //=======================================================================
2051 //=======================================================================
2052 void InterpreterVirtual::commandIndex(const std::string& filename, const std::string& type)
2055 //=======================================================================
2058 //=======================================================================
2059 void InterpreterVirtual::commandNewGUI(const std::string& boxname,const std::string& instanceName)
2062 //=======================================================================
2066 //==========================================================================
2067 void InterpreterVirtual::commandDebug(const std::string& name)
2070 //==========================================================================
2073 //==========================================================================
2074 // Adds a callback when 'break' command issued
2075 void InterpreterVirtual::AddBreakObserver( BreakCallbackType c )
2077 mBreakSignal.connect(c);
2079 //==========================================================================
2082 //==========================================================================
2083 std::string InterpreterVirtual::GetObjectName() const
2085 return std::string("InterpreterVirtual");
2087 //==========================================================================
2089 //==========================================================================
2090 std::string InterpreterVirtual::GetObjectInfo() const
2092 std::stringstream i;
2095 //==========================================================================
2097 //==========================================================================
2098 size_t InterpreterVirtual::GetObjectSize() const
2100 size_t s = Superclass::GetObjectSize();
2101 s += InterpreterVirtual::GetObjectInternalSize();
2104 //==========================================================================
2105 //==========================================================================
2106 size_t InterpreterVirtual::GetObjectInternalSize() const
2108 size_t s = sizeof(InterpreterVirtual);
2111 //==========================================================================
2112 //==========================================================================
2113 size_t InterpreterVirtual::GetObjectRecursiveSize() const
2115 size_t s = Superclass::GetObjectRecursiveSize();
2116 s += InterpreterVirtual::GetObjectInternalSize();
2119 //==========================================================================