1 /*=========================================================================
3 Module: $RCSfile: bbtkInterpreter.cxx,v $
5 Date: $Date: 2010/09/14 07:18:46 $
6 Version: $Revision: 1.88 $
7 =========================================================================*/
9 /* ---------------------------------------------------------------------
11 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
12 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
14 * This software is governed by the CeCILL-B license under French law and
15 * abiding by the rules of distribution of free software. You can use,
16 * modify and/ or redistribute the software under the terms of the CeCILL-B
17 * license as circulated by CEA, CNRS and INRIA at the following URL
18 * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
19 * or in the file LICENSE.txt.
21 * As a counterpart to the access to the source code and rights to copy,
22 * modify and redistribute granted by the license, users are provided only
23 * with a limited warranty and the software's author, the holder of the
24 * economic rights, and the successive licensors have only limited
27 * The fact that you are presently reading this means that you have had
28 * knowledge of the CeCILL-B license and that you accept its terms.
29 * ------------------------------------------------------------------------ */
33 * \brief class Interpreter :
36 #include "bbtkInterpreterVirtual.h"
37 //#include "bbtkTranscriptor.h"
38 #include "bbtkConfigurationFile.h"
39 #include "bbtkUtilities.h"
40 //#include "bbtkAtomicBlackBox.h"
41 //#include "bbtkWxBlackBox.h"
44 #ifdef CMAKE_HAVE_TERMIOS_H
46 #define BBTK_USE_TERMIOS_BASED_PROMPT
54 //=======================================================================
55 InterpreterVirtual::Pointer InterpreterVirtual::New()
57 bbtkDebugMessage("kernel",9,"InterpreterVirtual::New()"<<std::endl);
58 return MakePointer( new InterpreterVirtual() );
60 //=======================================================================
62 //=======================================================================
63 InterpreterVirtual::InterpreterVirtual()
67 //=======================================================================
70 //=======================================================================
71 void InterpreterVirtual::Init()
77 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);
78 bbtk::MessageManager::RegisterMessageType("Interpreter","Messages of the interpreter",0);
79 bbtkDebugMessageInc("Interpreter",9,"InterpreterVirtual::Interpreter()" <<std::endl);
81 // For the time being, comment out previous line, and
82 // uncomment next line to check Transcriptor
84 //mVirtualExecuter = new bbtk::Transcriptor("GeneratedProgram.txt");
86 // Builds the commands dict
93 info.syntax = "new <type> <name>";
94 info.help = "Creates a new black box of type <type> with name <name>";
95 mCommandDict[info.keyword] = info;
97 info.keyword = "delete";
101 info.syntax = "delete <box>";
102 info.help = "Deletes the black box of name <box>";
103 mCommandDict[info.keyword] = info;
105 info.keyword = "clear";
109 info.syntax = "clear";
110 info.help = "Clears the currently defined complex box (deletes all its boxes and connections)";
111 mCommandDict[info.keyword] = info;
113 info.keyword = "break";
117 info.syntax = "break";
118 info.help = "Breaks the current execution";
119 mCommandDict[info.keyword] = info;
121 info.keyword = "newgui";
125 info.syntax = "newgui <box> <name>";
126 info.help = "Automatically creates a graphical user interface with name <name> for the black box <box> and connects it to the box inputs";
127 mCommandDict[info.keyword] = info;
129 info.keyword = "connect";
132 info.code = cConnect;
133 info.syntax = "connect <box1.output> <box2.input>";
134 info.help = "Connects the ouput <output> of black box <box1> to the input <input> of black box <box2>";
135 mCommandDict[info.keyword] = info;
137 info.keyword = "print";
141 info.syntax = "print <string>";
142 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').";
143 mCommandDict[info.keyword] = info;
145 info.keyword = "exec";
149 info.syntax = "exec <box | 'freeze' | 'unfreeze' | 'freeze_no_error' >";
150 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.";
151 mCommandDict[info.keyword] = info;
153 info.keyword = "package";
156 info.code = cPackage;
157 info.syntax = "package <name>";
158 info.help = "Begins the definition of a package.";
159 mCommandDict[info.keyword] = info;
161 info.keyword = "endpackage";
164 info.code = cEndPackage;
165 info.syntax = "endpackage";
166 info.help = "Ends the definition of a package.";
167 mCommandDict[info.keyword] = info;
169 info.keyword = "define";
173 info.syntax = "define <type> [<package>]";
174 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.";
175 mCommandDict[info.keyword] = info;
177 info.keyword = "endefine";
180 info.code = cEndDefine;
181 info.syntax = "endefine";
182 info.help = "Ends the definition of a new type of complex black box";
183 mCommandDict[info.keyword] = info;
185 info.keyword = "kind";
189 info.syntax = "kind <ADAPTOR|DEFAULT_ADAPTOR|GUI|DEFAULT_GUI>";
190 info.help = "Sets the kind of the currently defined complex black box";
191 mCommandDict[info.keyword] = info;
193 info.keyword = "input";
197 info.syntax = "input <name> <box.input> <help>";
198 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";
199 mCommandDict[info.keyword] = info;
201 info.keyword = "output";
205 info.syntax = "output <name> <box.output> <help>";
206 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";
207 mCommandDict[info.keyword] = info;
209 info.keyword = "set";
213 info.syntax = "set <box.input> <value>";
214 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";
215 mCommandDict[info.keyword] = info;
217 info.keyword = "config"; // JPR
221 info.syntax = "config";
222 info.help = "Prints the value of all configuration parameters";
223 mCommandDict[info.keyword] = info;
225 info.keyword = "index"; // LG
230 info.syntax = "index [<filename> ['Initials'(default)|'Packages'|'Categories'|'Adaptors']]";
231 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.";
232 mCommandDict[info.keyword] = info;
234 info.keyword = "reset";
238 info.syntax = "reset";
239 info.help = "Deletes all boxes and unloads all packages (reset to start state)";
240 mCommandDict[info.keyword] = info;
242 info.keyword = "author";
246 info.syntax = "author <string>";
247 info.help = "Adds the string <string> to the author information of the black box being defined";
248 mCommandDict[info.keyword] = info;
250 info.keyword = "category"; //JP
253 info.code = cCategory;
254 info.syntax = "category <list of items, separated by ;>";
255 info.help = "Adds the string <string> to the category information of the black box being defined";
256 mCommandDict[info.keyword] = info;
258 info.keyword = "description";
261 info.code = cDescription;
262 info.syntax = "description <string>";
263 info.help = "Adds the string <string> to the descriptive information of the black box being defined";
264 mCommandDict[info.keyword] = info;
266 info.keyword = "help";
270 info.syntax = "help";
271 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>";
272 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.";
273 mCommandDict[info.keyword] = info;
275 info.keyword = "message";
278 info.code = cMessage;
279 info.syntax = "message <kind> <level>";
280 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.";
281 mCommandDict[info.keyword] = info;
283 info.keyword = "include";
286 info.code = cInclude;
287 info.syntax = "include <filename> [source]";
288 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).";
289 mCommandDict[info.keyword] = info;
291 info.keyword = "quit";
295 info.syntax = "quit";
296 info.help = "Quits the program (during script execution it stops the complete execution)";
297 mCommandDict[info.keyword] = info;
299 info.keyword = "load";
303 info.syntax = "load <packagename>";
304 info.help = "Loads the black box package <packagename>";
305 mCommandDict[info.keyword] = info;
307 info.keyword = "unload";
311 info.syntax = "unload <packagename>";
312 info.help = "Unloads the black box package <packagename>";
313 mCommandDict[info.keyword] = info;
315 info.keyword = "graph";
319 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 ]]]]]]";
320 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')";
321 mCommandDict[info.keyword] = info;
323 info.keyword = "debug";
327 info.syntax = "debug [expr|-C|-D]";
328 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";
329 mCommandDict[info.keyword] = info;
332 info.keyword = "workspace";
335 info.code = cWorkspace;
336 info.syntax = "workspace < ( freeze | unfreeze ) | ( rename <newname> ) >";
337 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.";
338 mCommandDict[info.keyword] = info;
344 //=======================================================================
348 //=======================================================================
352 InterpreterVirtual::~InterpreterVirtual()
354 bbtkDebugMessage("object",2,"==> ~Interpreter()" <<std::endl);
356 //=======================================================================
359 //=======================================================================
360 InterpreterException::InterpreterException( const std::string& message,
362 const std::string& script_file,
365 : Exception("interpreter",0,message),
366 mInScriptFile(in_script_file),
367 mScriptFile(script_file),
368 mScriptLine(script_line)
371 //=======================================================================
372 //=======================================================================
373 InterpreterException::InterpreterException( const Exception& excep,
375 const std::string& script_file,
379 mInScriptFile(in_script_file),
380 mScriptFile(script_file),
381 mScriptLine(script_line)
384 //=======================================================================
387 //=======================================================================
388 void InterpreterVirtual::CatchInterpreterException( const InterpreterException& e )
390 //EED Borrame if (GetExecuter()->GetNoErrorMode())
392 //EED Borrame bbtkWarning("ERROR :"<<e.GetErrorMessage()
393 //EED Borrame <<" ("<<e.GetScriptFile()<<":"<<e.GetScriptLine()
394 //EED Borrame <<" skipped");
395 //EED Borrame return;
399 if (e.GetErrorMessage()!="break")
401 mStatus = Interpreter_ERROR;
404 throw InterpreterException(e);
406 std::stringstream mess;
407 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
408 if (e.IsInScriptFile())
410 mess << "* FILE : \""<<e.GetScriptFile()<<"\""<<std::endl;
411 mess << "* LINE : "<<e.GetScriptLine()<<std::endl;
414 std::cerr << mess.str();
417 //=======================================================================
419 //=======================================================================
420 void InterpreterVirtual::CatchBbtkException( const bbtk::Exception& e )
422 //EED Borrame if (GetExecuter()->GetNoErrorMode())
424 //EED Borrame std::string file("?");
425 //EED Borrame int line = 0;
426 //EED Borrame if (mFileName.size()) {
427 //EED Borrame file = mFileName.back();
428 //EED Borrame line = mLine.back();
430 //EED Borrame bbtkWarning("ERROR '"<<e.GetErrorMessage()
431 //EED Borrame <<"' ("<<file<<":"<<line<<") skipped");
432 //EED Borrame return;
435 mStatus = Interpreter_ERROR;
438 bool in_script = false;
439 std::string file("");
441 if (mFileName.size())
443 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
444 if (fs!=0) in_script = true;
445 file = mFileName.back();
448 if (e.GetErrorMessage()!="break")
450 throw InterpreterException(e,in_script,file,line);
452 std::stringstream mess;
453 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
454 if (mFileName.size())
456 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
457 mess << "* LINE : "<<mLine.back()<<std::endl;
460 std::cerr << mess.str();
463 //=======================================================================
465 //=======================================================================
466 void InterpreterVirtual::CatchStdException( const std::exception& e )
468 //EED Borrame if (GetExecuter()->GetNoErrorMode())
470 //EED Borrame std::string file("?");
471 //EED Borrame int line = 0;
472 //EED Borrame if (mFileName.size()) {
473 //EED Borrame file = mFileName.back();
474 //EED Borrame line = mLine.back();
476 //EED Borrame bbtkWarning("ERROR '"<<e.what()
477 //EED Borrame <<"' ("<<file<<":"<<line<<") skipped");
478 //EED Borrame return;
481 mStatus = Interpreter_ERROR;
484 bool in_script = false;
485 std::string file("");
487 if (mFileName.size()) {
488 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
489 if (fs!=0) in_script = true;
490 file = mFileName.back();
494 throw InterpreterException(e.what(),in_script,file,line);
496 std::stringstream mess;
497 mess << "* ERROR : "<<e.what()<<std::endl;
498 if (mFileName.size())
500 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
501 mess << "* LINE : "<<mLine.back()<<std::endl;
504 std::cerr << mess.str();
508 //=======================================================================
510 //=======================================================================
511 void InterpreterVirtual::CatchUnknownException()
513 //EED Borrame if (GetExecuter()->GetNoErrorMode())
515 //EED Borrame std::string file("?");
516 //EED Borrame int line = 0;
517 //EED Borrame if (mFileName.size()) {
518 //EED Borrame file = mFileName.back();
519 //EED Borrame line = mLine.back();
521 //EED Borrame bbtkWarning("UNDEFINED ERROR "
522 //EED Borrame <<"("<<file<<":"<<line<<") skipped");
523 //EED Borrame return;
525 mStatus = Interpreter_ERROR;
528 bool in_script = false;
529 std::string file("");
531 if (mFileName.size()) {
532 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
533 if (fs!=0) in_script = true;
534 file = mFileName.back();
538 throw InterpreterException("Unknown exception caught",
539 in_script,file,line);
543 std::stringstream mess;
544 mess << "* UNDEFINED ERROR (not a bbtk nor a std exception)"
546 if (mFileName.size()) {
547 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
548 mess << "* LINE : "<<mLine.back()<<std::endl;
551 std::cerr << mess.str();
554 //=======================================================================
556 //=======================================================================
558 #define CATCH_MACRO \
559 catch (InterpreterException e) \
561 CatchInterpreterException(e); \
563 catch (bbtk::Exception e) \
565 CatchBbtkException(e); \
567 catch (std::exception& e) \
569 CatchStdException(e); \
573 CatchUnknownException(); \
575 //=======================================================================
578 //=======================================================================
579 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretFile( const std::string& filename, bool source )
581 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::InterpretFile(\""<<filename<<"\")"<<std::endl);
583 bool exm = mCommandLine;
584 mCommandLine = false;
588 mStatus = Interpreter_OK;
589 SwitchToFile(filename,source);
590 mInsideComment = false;
591 InterpretCurrentStreams();
595 bbtkDebugMessage("interpreter",4,
596 "<== InterpreterVirtual::InterpretFile(\""
597 <<filename<<"\")"<<std::endl);
604 //=======================================================================
607 //=======================================================================
608 InterpreterVirtual::ExitStatus
609 InterpreterVirtual::InterpretBuffer( std::stringstream* buffer )
611 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::InterpretBuffer()"<<std::endl);
613 bool exm = mCommandLine;
614 mCommandLine = false;
618 mStatus = Interpreter_OK;
619 SwitchToStream(buffer);
620 mInsideComment = false;
621 InterpretCurrentStreams();
626 bbtkDebugMessage("interpreter",4,"<== InterpreterVirtual::InterpretBuffer()"<<std::endl);
632 //=======================================================================
634 //=======================================================================
635 /// Interprets the currently open streams
636 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretCurrentStreams()
638 bbtkDebugMessage("interpreter",4,
639 "==> InterpreterVirtual::InterpretCurrentStreams()"<<std::endl);
641 while (mFile.size()>0)
643 while (!mFile.back()->eof()) {
646 mFile.back()->getline(buf,500);
647 std::string str(buf);
648 //size 0 JCP 21-09-2009
649 int size=str.length();
651 if ( str[ size-1 ]==13 )
657 DoInterpretLine(str);
665 bbtkDebugMessage("interpreter",4,
666 "<== InterpreterVirtual::InterpretCurrentStreams()"<<std::endl);
670 //=======================================================================
672 //=======================================================================
673 /// Runs the interpretation of a command
674 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretLine( const std::string& line )
676 bbtkDebugMessage("interpreter",5,"==> InterpreterVirtual::InterpretLine('"<<line<<"')"<<std::endl);
680 mStatus = Interpreter_OK;
681 mInsideComment = false;
682 //std::cout<<"JCP bbtkInterpreter.cxx InterpreterVirtual::InterpretLine("<<std::endl;
683 DoInterpretLine(line );
688 bbtkDebugMessage("interpreter",5,"<== InterpreterVirtual::InterpretLine('"<<line<<"')"<<std::endl);
692 //=======================================================================
694 void InterpreterVirtual::commandNew(const std::string &boxType, const std::string &boxName) // virtual
698 void InterpreterVirtual::commandDelete(const std::string &boxName)
702 void InterpreterVirtual::commandConnection(const std::string &nodeFrom,const std::string &outputLabel,const std::string &nodeTo,const std::string &inputLabel)
706 void InterpreterVirtual::commandPackage(const std::string &packageName)
710 void InterpreterVirtual::commandEndPackage()
714 void InterpreterVirtual::commandDefine(const std::string &name,const std::string &pack,const std::string &scriptfilename)
718 void InterpreterVirtual::commandEndDefine()
722 void InterpreterVirtual::commandKind(const std::string &kind)
726 void InterpreterVirtual::commandPrint(const std::string &value)
731 void InterpreterVirtual::commandExec(const std::string &word)
736 void InterpreterVirtual::commandInput(const std::string &name,const std::string &box,const std::string &input,const std::string &help)
740 void InterpreterVirtual::commandOutput(const std::string &name,const std::string &box,const std::string &output,const std::string &help)
744 void InterpreterVirtual::commandSet(const std::string &box,const std::string &input,const std::string &value)
748 void InterpreterVirtual::commandAuthor(const std::string &author)
752 void InterpreterVirtual::commandCategory(const std::string &categorytype)
758 void InterpreterVirtual::commandDescription(const std::string &description)
763 void InterpreterVirtual::commandClear()
767 void InterpreterVirtual::commandInclude(const std::string &word, bool ok)
772 void InterpreterVirtual::commandLoad(const std::string &packageName)
776 void InterpreterVirtual::commandUnload(const std::string &packageName)
780 void InterpreterVirtual::commandBreak()
784 void InterpreterVirtual::commandQuit()
788 void InterpreterVirtual::commandMessage()
792 void InterpreterVirtual::commandMessage(const std::string &kind,const std::string &levelstr)
798 //=======================================================================
799 void InterpreterVirtual::DoInterpretLine( const std::string& line )
802 bbtkDebugMessage("interpreter",6,"==> InterpreterVirtual::DoInterpretLine(\""
803 <<line<<"\")"<<std::endl);
804 std::vector<std::string> words;
805 SplitLine(line,words);
812 bbtkDebugDecTab("interpreter",9);
816 // Single line comment : # or //
817 if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') )
819 bbtkDebugDecTab("interpreter",9);
820 bbtkMessage("interpreter",9,"Comment"<<std::endl);
824 // Multi line comment ( /* ... */ ) -delimiters on different lines !-
826 if (words[0][0]=='/' && words[0][1]=='*')
828 bbtkDebugDecTab("interpreter",9);
829 bbtkMessage("interpreter",9,"In multiline comment"<<std::endl);
830 mInsideComment = true;
834 if (words[0][0]=='*' && words[0][1]=='/')
836 bbtkDebugDecTab("interpreter",9);
837 bbtkMessage("interpreter",9,"Out multiline comment"<<std::endl);
838 if ( !mInsideComment ) {
839 bbtkDebugDecTab("interpreter",9);
840 bbtkMessage("interpreter",9,"Comment mismatch : '*/' with no matching '/*'"<<std::endl);
842 mInsideComment = false;
848 bbtkDebugDecTab("interpreter",9);
849 bbtkMessage("interpreter",9,"Multiline Comment"<<std::endl);
855 CommandInfoType command;
856 InterpretCommand(words,command);
857 //std::cout<<"JCP bbtkInterpreter command.keyword ="<<command.keyword<<std::endl;
858 bbtkDebugMessage("interpreter",9,
859 "Command='"<<command.keyword
860 <<"' code="<<command.code<<std::endl);
862 std::string left,right,left2,right2;
863 std::string filename;
866 if (command.code==cMessage)
871 //EED Borrame mVirtualExecuter->HelpMessages();
875 commandMessage(words[1],words[2]);
876 //EED Borrame sscanf(words[2].c_str(),"%d",&level);
877 //EED Borrame mVirtualExecuter->SetMessageLevel(words[1],level);
883 bbtkMessage("echo",2,line<<std::endl);
886 // break and quit commands
887 if ((command.code==cBreak) || (command.code==cQuit))
889 bool in_script = false;
890 std::string file("");
893 if (mFileName.size())
895 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
896 if (fs!=0) in_script = true;
897 file = mFileName.back();
900 if (command.code==cBreak)
903 std::cout << "BreakException("
906 <<line<<")"<<std::endl;
909 //EED Borrame bbtkError("break");//,in_script,file,line);
910 // throw BreakException(in_script,file,line);
915 //EED Borrame bbtkError("quit");//,in_script,file,line);
916 //throw QuitException(in_script,file,line);
920 //std::cout<<" mVirtualExecuter->Create(words[1],words[2]); "<<line<<std::endl;
924 switch (command.code)
927 commandNew(words[1],words[2]);
928 //EED Borrame mVirtualExecuter->Create(words[1],words[2]);
932 commandDelete(words[1]);
933 //EED Borrame mVirtualExecuter->Destroy(words[1]);
937 Utilities::SplitAroundFirstDot(words[1],left,right);
938 Utilities::SplitAroundFirstDot(words[2],left2,right2);
939 commandConnection(left,right,left2,right2);
940 //EED Borrame mVirtualExecuter->Connect(left,right,left2,right2);
944 commandPackage(words[1]);
945 //EED Borrame mVirtualExecuter->BeginPackage(words[1]);
950 //EED Borrame mVirtualExecuter->EndPackage();
954 if (mFileName.size()>0)
956 //??? commandDefine(????);
957 filename = mFileName.back(); //mIncludeFileName.back(); //Utilities::get_file_name(mFileName.back());
961 std::string packTmp = "";
962 commandDefine(words[1],packTmp,filename);
963 //EED Borrame mVirtualExecuter->Define(words[1],"",filename);
967 commandDefine(words[1],words[2],filename);
968 //EED Borrame mVirtualExecuter->Define(words[1],words[2],filename);
974 //EED Borrame mVirtualExecuter->EndDefine();
978 commandKind(words[1]);
979 //EED Borrame mVirtualExecuter->Kind(words[1]);
983 commandPrint(words[1]);
984 //EED Borrame mVirtualExecuter->Print(words[1]);
988 commandExec(words[1]);
989 //EED Borrame if (words[1]=="freeze")
991 //EED Borrame mVirtualExecuter->SetNoExecMode(true);
992 //EED Borrame mThrow = false;
994 //EED Borrame else if (words[1]=="freeze_no_error")
996 //EED Borrame mVirtualExecuter->SetNoExecMode(true);
997 //EED Borrame mVirtualExecuter->SetNoErrorMode(true);
998 //EED Borrame mThrow = false;
1000 //EED Borrame else if (words[1]=="unfreeze")
1002 //EED Borrame mVirtualExecuter->SetNoExecMode(false);
1003 //EED Borrame mVirtualExecuter->SetNoErrorMode(false);
1007 //EED Borrame mVirtualExecuter->Execute(words[1]);
1013 Utilities::SplitAroundFirstDot(words[2],left,right);
1014 commandInput(words[1],left,right,words[3]);
1015 //EED Borrame mVirtualExecuter->DefineInput(words[1],left,right,words[3]);
1019 Utilities::SplitAroundFirstDot(words[2],left,right);
1020 commandOutput(words[1],left,right,words[3]);
1021 //EED Borrame mVirtualExecuter->DefineOutput(words[1],left,right,words[3]);
1025 Utilities::SplitAroundFirstDot(words[1],left,right);
1026 commandSet(left,right,words[2]);
1027 //EED Borrame mVirtualExecuter->Set(left,right,words[2]);
1031 commandAuthor(words[1]);
1032 //EED Borrame mVirtualExecuter->Author(words[1]);
1036 commandNewGUI(words[1],words[2]);
1040 commandCategory(words[1]);
1041 //EED Borrame mVirtualExecuter->Category(words[1]);
1045 if (words.size()==1)
1046 commandIndex("tmp_index.html");
1047 else if (words.size()==2)
1048 commandIndex(words[1]);
1049 else if (words.size()==3)
1050 commandIndex(words[1],words[2]);
1054 commandDescription(words[1]);
1055 //EED Borrame mVirtualExecuter->Description(words[1]);
1064 commandGraph(words);
1077 //EED Borrame mVirtualExecuter->Clear();
1081 commandInclude( words[1] , (words.size()==3) );
1082 //EED Borrame // if 'source' was given (words.size()==3) then tell to set the
1083 //EED Borrame // source file name of the current complex box with the full file name included
1084 //EED Borrame if (mCommandLine)
1086 //EED Borrame InterpretFile(words[1],(words.size()==3));
1087 //EED Borrame } else{
1088 //EED Borrame SwitchToFile(words[1],(words.size()==3) );
1093 commandLoad( words[1] );
1094 //EED Borrame GetExecuter()->LoadPackage(words[1]);
1098 commandUnload( words[1] );
1099 //EED Borrame GetExecuter()->UnLoadPackage(words[1]);
1103 if (words.size()==2) commandDebug(words[1]);
1104 else commandDebug("");
1109 if (words.size() == 2)
1111 if (words[1]=="freeze") mVirtualExecuter->SetNoExecMode(true);
1112 else if (words[1]=="unfreeze") mVirtualExecuter->SetNoExecMode(false);
1116 mVirtualExecuter->SetWorkspaceName(words[2]);
1121 bbtkInternalError("should not reach here !!!");
1124 bbtkDebugMessage("interpreter",6,"<== InterpreterVirtual::DoInterpretLine(\""
1125 <<line<<"\")"<<std::endl);
1128 //=======================================================================
1134 //=======================================================================
1135 void InterpreterVirtual::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
1137 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::SplitLine(\""<<str<<"\")"<<std::endl);
1139 std::string delimiters = "\"";
1140 std::vector<std::string> quote;
1141 Utilities::SplitString(str,delimiters,quote);
1144 std::vector<std::string>::iterator i;
1145 for (i=quote.begin(); i!=quote.end(); )
1147 Utilities::SplitString(*i,delimiters,tokens);
1151 // bbtkDebugMessage("interpreter",0,"\""<<*i<<"\""<<std::endl);
1152 tokens.push_back(*i);
1157 for (i=tokens.begin(); i!=tokens.end(); ++i)
1159 bbtkDebugMessage("interpreter",9,"--["<<*i<<"]"<<std::endl);
1161 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::SplitLine(\""<<str<<"\")"<<std::endl);
1164 //=======================================================================
1167 //=======================================================================
1168 void InterpreterVirtual::commandReset()
1171 //=======================================================================
1173 //=======================================================================
1178 void InterpreterVirtual::Print( const std::string& str)
1180 if (mVirtualExecuter->GetNoExecMode()) return;
1182 bbtkDebugMessageInc("interpreter",9,"InterpreterVirtual::Print(\""<<str<<"\")"<<std::endl);
1185 // InterpretLine ("load std")
1186 // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande
1187 // InterpretLine("new Print _P_")
1188 // InterpretLine("connect _C_.Out _P_.In")
1192 std::vector<std::string> chains;
1193 std::string delimiters("$");
1195 // Skip delimiters at beginning.
1196 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
1197 bool is_text = true;
1198 if (lastPos>0) is_text = false;
1200 // Find first delimiter.
1201 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
1203 while (std::string::npos != pos || std::string::npos != lastPos)
1207 // Found a text token, add it to the vector.
1208 chains.push_back(str.substr(lastPos, pos - lastPos));
1209 // std::string token = str.substr(lastPos, pos - lastPos)
1210 // InterpretLine("set _C_.In%num% %token%")
1216 // is an output (between $$) : decode
1217 std::string tok,box,output;
1218 tok = str.substr(lastPos, pos - lastPos);
1219 Utilities::SplitAroundFirstDot(tok,box,output);
1220 chains.push_back( mVirtualExecuter->Get(box,output) );
1222 // InterpretLine("connect %tok% _C_.In%num%")
1225 // Skip delimiters. Note the "not_of"
1226 lastPos = str.find_first_not_of(delimiters, pos);
1227 // Find next delimiter
1228 pos = str.find_first_of(delimiters, lastPos);
1233 // InterpretLine("exec _P_")
1234 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
1236 std::vector<std::string>::iterator i;
1237 for (i= chains.begin(); i!=chains.end(); ++i)
1240 Utilities::SubsBackslashN(*i);
1243 std::cout << std::endl;
1244 bbtkDebugDecTab("interpreter",9);
1248 //=======================================================================
1253 // =========================================================================
1254 void InterpreterVirtual::SwitchToFile( const std::string& name , bool source )
1256 // Note : in the following :
1257 // name : the user supplied name
1258 // - abreviated name e.g. scr scr.bbs
1259 // - relative full name e.g. ./scr.bbs ../../scr.bbs
1260 // - absolute full name e.g. /home/usrname/proj/dir/scr.bbs
1261 // same for Windows, with c:, d: ...
1263 // use ./directory/subdir/scrname.bbs
1266 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::SwitchToFile( \""
1267 <<name<<"\")"<<std::endl);
1269 std::vector<std::string> script_paths;
1270 std::string fullPathScriptName; // full path script name
1271 std::string pkgname; // e.g. <scriptname>.bbs
1272 std::vector<std::string> Filenames;
1273 std::string tmpFilenames;
1275 // The following is *NOT* a debug time message :
1276 // It's a user intended message.
1277 // Please don't remove it.
1278 bbtkMessage("interpreter",1,
1279 "look for : [" << name
1280 << "]" << std::endl);
1284 pkgname = Utilities::ExtractScriptName(name,upath);
1286 bbtkMessage("interpreter",3,
1287 "package name:[" << pkgname
1288 << "] path:[" << upath << "]" << std::endl);
1289 bool fullnameGiven = false;
1290 bool foundFile = false;
1292 // ==== "*" provided : load all scripts in given path
1293 // relative (e.g. std/boxes/*) or absolute
1297 std::stringstream* stream = new std::stringstream;
1298 //if (upath.size()!=0) // avoid troubles for "*"
1300 // ==== no path provided : look in root bbs path
1301 if (upath.size()==0)
1303 // bbtkMessage("interpreter",1,
1304 // LG : add all bbs path
1305 // script_paths.push_back( ConfigurationFile::GetInstance().Get_root_bbs_path() );
1306 std::vector<std::string>::const_iterator i;
1307 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1308 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1311 script_paths.push_back(*i);
1314 // ==== absolute path provided
1315 else if (upath[0]=='/' || upath[1] == ':' )
1317 if ( Utilities::IsDirectory( upath ) )
1319 script_paths.push_back(upath);
1323 bbtkError("'"<<upath<<"' : directory does not exist");
1326 // ==== relative path provided : search all bbs path appended with
1327 // the relative path provided
1330 std::vector<std::string>::const_iterator i;
1331 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1332 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1335 std::string full_path(*i);
1336 printf("EED InterpreterVirtual::SwitchToFile 1. >>%s\n", full_path.c_str() );
1337 // we *really* want '.' to be the current working directory
1338 if (full_path == ".")
1340 char buf[2048]; // for getcwd
1341 char * currentDir = getcwd(buf, 2048);
1342 std::string cwd(currentDir);
1343 full_path = currentDir;
1346 full_path += ConfigurationFile::GetInstance().Get_file_separator();
1349 if ( Utilities::IsDirectory( full_path ) )
1351 script_paths.push_back(full_path);
1354 if (script_paths.empty())
1356 bbtkError("no '"<<upath<<"' subdir found in search paths"
1361 // === search paths list complete : now explore it
1363 // ==== relative name, iterate + load all .bbs/.bbp files
1364 std::vector<std::string>::iterator i;
1365 for (i=script_paths.begin();i!=script_paths.end();i++)
1368 printf("EED InterpreterVirtual::SwitchToFile jaja >> %s\n", (*i).c_str() );
1370 bbtkMessage("interpreter",1,
1371 "--> Looking in '" << *i << "'" << std::endl);
1375 Utilities::Explore(*i, false, Filenames);
1377 int iFilesnames,jFilesnames,sizeFilenames;
1378 sizeFilenames=Filenames.size();
1381 // EEDd 30 sept 2012
1382 //Sorting list of files
1383 for (iFilesnames=0;iFilesnames<sizeFilenames; iFilesnames++)
1385 for (jFilesnames=iFilesnames;jFilesnames<sizeFilenames; jFilesnames++)
1387 if ( Filenames[iFilesnames] > Filenames[jFilesnames] )
1389 tmpFilenames = Filenames[iFilesnames];
1390 Filenames[iFilesnames] = Filenames[jFilesnames];
1391 Filenames[jFilesnames] = tmpFilenames;
1393 } // for iFilesnames
1394 } // for iFilesnames
1398 for (std::vector<std::string>::iterator j = Filenames.begin();
1399 j!= Filenames.end(); ++j)
1402 printf("EED InterpreterVirtual::SwitchToFile kkkkk >> %s\n", (*j).c_str() );
1404 int lgr = (*j).size();
1405 if (lgr < 5) continue;
1406 // ignore non .bbp file
1407 if ( (*j).substr(lgr-4, 4) != ".bbp") continue;
1409 (*stream) << "include \"" << *j << "\"\n";
1410 bbtkMessage("interpreter",2," --> Found '" << *j << "'" << std::endl);
1413 } // for (std::vector...
1414 } // for (i=script_...
1419 bbtkMessage("interpreter",1,
1420 " --> No .bbp found"<< std::endl);
1424 bbtkMessage("interpreter",1,
1425 " --> "<<nbBssFiles<<" .bbp found"<< std::endl);
1426 SwitchToStream(stream);
1430 //=============== end pkgname=="*" ===========
1433 // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name
1434 // (not only a plain script name)
1435 // we trust him, and try to expland the directory name
1436 // WARNING : starting from current local directory : ./whatYouWant (./ mandatory!)
1438 if (name[0]=='/' || name[1] == ':' || name[0]=='.') // absolute path (linux/windows) or relative path
1441 // ===========================================================check user supplied location
1442 fullnameGiven = true;
1444 fullPathScriptName = Utilities::ExpandLibName(name, false);
1446 // allow user to always forget ".bbs"
1447 int l = fullPathScriptName.size();
1451 if ((fullPathScriptName.substr(l-4, 4) != ".bbs")&&
1452 (fullPathScriptName.substr(l-4, 4) != ".bbp"))
1454 std::string tfullPathScriptName = fullPathScriptName + ".bbs";
1455 if ( Utilities::FileExists(tfullPathScriptName) )
1457 fullPathScriptName = tfullPathScriptName;
1462 tfullPathScriptName = fullPathScriptName + ".bbp";
1463 if ( Utilities::FileExists(tfullPathScriptName) )
1465 fullPathScriptName = tfullPathScriptName;
1472 if ( Utilities::FileExists(fullPathScriptName) )
1480 // =============================== iterate on the paths
1482 script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
1484 std::vector<std::string>::iterator i;
1485 for (i=script_paths.begin();i!=script_paths.end();++i)
1488 // we *really* want '.' to be the current working directory
1491 char buf[2048]; // for getcwd
1492 char * currentDir = getcwd(buf, 2048);
1493 std::string cwd(currentDir);
1497 std::string tfullPathScriptName = Utilities::MakePkgnameFromPath(path, name, false);
1499 //Addition JCP tfullPathScriptName.size()>=4
1500 if(tfullPathScriptName.size()>=4){
1501 if (tfullPathScriptName.substr(tfullPathScriptName.size()-4, 3)==".bb")
1503 fullPathScriptName = tfullPathScriptName;
1504 if ( ! Utilities::FileExists(fullPathScriptName) )
1506 // The following is *NOT* a debug time message :
1507 // It's a user intended message.
1508 // Please don't remove it.
1509 bbtkMessage("interpreter",2,
1510 " [" <<fullPathScriptName <<"] : does not exist"
1512 continue; // try next path
1514 bbtkMessage("interpreter",2,
1515 " [" <<fullPathScriptName
1516 <<"] : found" <<std::endl);
1518 break; // a script was found; we stop iterating
1522 fullPathScriptName = tfullPathScriptName + ".bbs";
1523 // Check if library exists
1524 if ( ! Utilities::FileExists(fullPathScriptName) )
1526 fullPathScriptName = tfullPathScriptName + ".bbp";
1527 if ( ! Utilities::FileExists(fullPathScriptName) )
1529 // The following is *NOT* a debug time message :
1530 // It's a user intended message.
1531 // Please don't remove it.
1532 bbtkMessage("interpreter",2,
1533 " [" <<tfullPathScriptName <<".bbs/.bbp] : do not exist"
1535 continue; // try next path
1538 bbtkMessage("interpreter",2,
1539 " [" <<fullPathScriptName
1540 <<"] : found" <<std::endl);
1542 break; // a script was found; we stop iterating
1545 } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
1551 if(fullPathScriptName == "")
1552 bbtkError("Path ["<<upath<<"] doesn't exist");
1554 bbtkError("Script ["<<fullPathScriptName<<"] not found");
1556 bbtkError("No ["<<pkgname<<".bbs/.bbp] script found");
1559 //EED printf("EED D. SwitchToFile %s\n", fullPathScriptName.c_str() );
1560 LoadScript(fullPathScriptName,name);
1561 //EED Borrame if (source) GetExecuter()->SetCurrentFileName(fullPathScriptName);
1562 if (source) SetCurrentFileName(fullPathScriptName);
1567 //=======================================================================
1569 //=======================================================================
1570 void InterpreterVirtual::SetCurrentFileName(const std::string &fullPathScriptName) // virtual
1573 //=======================================================================
1575 //=======================================================================
1576 void InterpreterVirtual::SwitchToStream( std::stringstream* stream )
1578 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::SwitchToStream()"
1580 mFile.push_back(stream);
1581 std::ostringstream buffer_name;
1583 buffer_name << "buffer_" ;
1585 if (mFileName.size()>0 )
1587 buffer_name << mFileName.back() << "_" << mLine.back();
1589 mFileName.push_back(buffer_name.str());
1590 mIncludeFileName.push_back(buffer_name.str());
1593 //=======================================================================
1595 //=======================================================================
1597 void InterpreterVirtual::LoadScript( std::string fullPathScriptName,
1598 std::string includeScriptName)
1600 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::LoadScript("
1601 <<fullPathScriptName<<")"
1604 Utilities::replace( fullPathScriptName ,
1605 INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
1607 if (find(mFileNameHistory.begin(),
1608 mFileNameHistory.end(),
1609 fullPathScriptName)!=mFileNameHistory.end())
1615 s = new std::ifstream;
1616 s->open(fullPathScriptName.c_str());
1619 bbtkError("Could not open file ["<<fullPathScriptName<<"]");
1623 bbtkMessage("interpreter",1," -->[" << fullPathScriptName
1624 << "] found" << std::endl);
1627 mFileName.push_back(fullPathScriptName);
1628 mFileNameHistory.push_back(fullPathScriptName);
1629 mIncludeFileName.push_back(includeScriptName);
1634 //=======================================================================
1636 //=======================================================================
1637 void InterpreterVirtual::CloseCurrentFile()
1639 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::CloseCurrentFile()"
1642 if (mFile.size()==0)
1644 bbtkDebugMessage("interpreter",9," -> no file left open"<<std::endl);
1648 bbtkDebugMessage("interpreter",9," Closing file '"<<mFileName.back()<<"'"<<std::endl);
1650 std::ifstream* file = dynamic_cast<std::ifstream*>(mFile.back());
1651 if (file!=0) file->close();
1653 delete mFile.back();
1655 mFileName.pop_back();
1656 mIncludeFileName.pop_back();
1659 bbtkDebugMessage("interpreter",9," Remains "
1661 <<" open"<<std::endl);
1662 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::CloseCurrentFile()"
1665 //=======================================================================
1667 //=======================================================================
1668 void InterpreterVirtual::CloseAllFiles()
1670 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::CloseAllFiles()"
1673 while (mFile.size() != 0)
1677 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::CloseAllFiles()"
1680 //=======================================================================
1684 //=======================================================================
1685 void InterpreterVirtual::InterpretCommand( const std::vector<std::string>& words,
1686 CommandInfoType& info )
1689 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::InterpretCommand(...)"<<std::endl);
1691 // searches the command keyword
1692 CommandDictType::iterator c;
1693 c = mCommandDict.find(words[0]);
1694 if ( c == mCommandDict.end() ) {
1695 bbtkError(words[0]<<" : unknown command");
1698 // tests the number of args
1699 if ( ( ((int)words.size())-1 < c->second.argmin ) ||
1700 ( ((int)words.size())-1 > c->second.argmax ) )
1703 //EED HelpCommand(words[0]);
1704 commandHelp(words[0]);
1705 bbtkError(words[0]<<" : wrong number of arguments");
1707 //std::cout<<"InterpreterVirtual::InterpretCommand( const std::vector<std::string>& words,"<<std::endl;
1709 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::InterpretCommand(...)"<<std::endl);
1712 //=======================================================================
1715 //=======================================================================
1716 /// Displays help on all the commands
1717 void InterpreterVirtual::commandHelp(const std::vector<std::string>& words)
1720 //=======================================================================
1721 void InterpreterVirtual::commandHelp(const std::string &words)
1724 //=======================================================================
1726 //===================================================================
1727 /// Displays the Configuration
1728 void InterpreterVirtual::commandConfig() const
1731 //===================================================================
1735 //=======================================================================
1736 /// Fills the vector commands with the commands which
1737 /// have the first n chars of buf for prefix
1738 /// TODO : skip initial spaces in buf and also return the position of first
1739 /// non blank char in buf
1740 void InterpreterVirtual::FindCommandsWithPrefix( char* buf,
1742 std::vector<std::string>& commands )
1744 CommandDictType::const_iterator i;
1745 for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
1747 if ((i->first).find(buf,0,n) == 0)
1748 commands.push_back(i->first);
1751 //=======================================================================
1755 //=======================================================================
1756 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1758 inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
1759 inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
1761 // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
1762 // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
1763 // E.G. STORE THIS IN bbtk_config.xml
1764 #define BBTK_UP_ARROW_KBCODE 0x00415B1B
1765 #define BBTK_DOWN_ARROW_KBCODE 0x00425B1B
1766 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
1767 #define BBTK_LEFT_ARROW_KBCODE 0x00445B1B
1768 #define BBTK_BACKSPACE_KBCODE 0x00000008
1769 #define BBTK_DEL_KBCODE 0x0000007F
1770 #define BBTK_SPACE_KBCODE 0x00000020
1772 //=======================================================================
1773 void InterpreterVirtual::GetLineFromPrompt(std::string& s)
1778 unsigned int MAX_LINE_SIZE = 160;
1779 unsigned int MAX_HISTORY_SIZE = 100;
1781 char* newline = new char[MAX_LINE_SIZE];
1782 memset(newline,0,MAX_LINE_SIZE);
1783 char* histline = new char[MAX_LINE_SIZE];
1784 memset(histline,0,MAX_LINE_SIZE);
1786 char* line = newline;
1787 unsigned int hist = mHistory.size();
1793 read ( STDIN_FILENO, &c, 4) ;
1795 bbtkDebugMessage("debug",9,"[0x"<<std::hex<<c<<"]\n");
1797 // Printable character
1798 if ( (ind<MAX_LINE_SIZE-1) &&
1799 ( c >= BBTK_SPACE_KBCODE ) &&
1800 ( c < BBTK_DEL_KBCODE ))
1808 // delete the unused line
1814 // empty lines are not stored in from history
1817 // if history too long : delete oldest command
1818 if (mHistory.size()>MAX_HISTORY_SIZE)
1820 delete mHistory.front();
1821 mHistory.pop_front();
1823 mHistory.push_back(line);
1828 else if ( (ind>0) &&
1829 ((c == BBTK_BACKSPACE_KBCODE) ||
1830 (c == BBTK_DEL_KBCODE)) )
1838 // TODO : Command completion
1839 std::vector<std::string> commands;
1840 FindCommandsWithPrefix( line,ind,commands);
1841 if (commands.size()==1)
1843 std::string com = *commands.begin();
1844 for (; ind<com.size(); ++ind)
1846 PrintChar(com[ind]);
1852 else if (commands.size()>1)
1854 std::vector<std::string>::iterator i;
1856 for (i=commands.begin();i!=commands.end();++i)
1858 write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
1861 write(STDOUT_FILENO,"\n> ",3);
1862 //for (int j=0;j<ind;++j)
1864 write(STDOUT_FILENO,line,ind);
1868 // Arrow up : back in history
1869 else if (c==BBTK_UP_ARROW_KBCODE)
1873 // erase current line
1874 while (ind--) BackSpace();
1878 strcpy(histline,mHistory[hist]);
1882 write(STDOUT_FILENO,line,ind);
1885 // Arrow down : down in history
1886 else if (c==BBTK_DOWN_ARROW_KBCODE)
1888 if (hist<mHistory.size()-1)
1890 // erase current line
1891 while (ind--) BackSpace();
1895 strcpy(histline,mHistory[hist]);
1899 write(STDOUT_FILENO,line,ind);
1901 // end of history : switch back to newline
1902 else if (hist==mHistory.size()-1)
1904 // erase current line
1905 while (ind--) BackSpace();
1912 write(STDOUT_FILENO,line,ind);
1916 else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
1918 PrintChar(line[ind]);
1923 else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
1931 write(STDOUT_FILENO,"\n\r",2);
1939 //=======================================================================
1940 void InterpreterVirtual::GetLineFromPrompt(std::string& s)
1966 //=======================================================================
1972 //=======================================================================
1973 void InterpreterVirtual::CommandLineInterpreter()
1975 bbtkDebugMessageInc("interpreter",9,
1976 "InterpreterVirtual::CommandLineInterpreter()"<<std::endl);
1978 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1979 // Initialise the tty in non canonical mode with no echo
1980 // oter remembers the previous settings to restore them after
1981 struct termios ter,oter;
1984 ter.c_lflag &= ~ECHO;
1985 ter.c_lflag &= ~ICANON;
1988 tcsetattr(0,TCSANOW,&ter);
1991 mCommandLine = true;
1993 // bool insideComment = false; // for multiline comment
1994 mInsideComment = false;
2000 GetLineFromPrompt(line);
2001 DoInterpretLine(line); //, insideComment);
2004 catch (QuitException e)
2006 bbtkMessage("interpreter",1,"Interpreter : Quit"<<std::endl);
2010 catch (bbtk::Exception e)
2014 catch (std::exception& e)
2016 std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
2020 std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
2025 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
2026 tcsetattr(0,TCSANOW,&oter);
2029 std::cout << "Good bye !" << std::endl;
2031 bbtkDebugDecTab("interpreter",9);
2034 //=======================================================================
2035 void InterpreterVirtual::commandGraph(const std::vector<std::string>& words)
2038 //=======================================================================
2041 //=======================================================================
2042 void InterpreterVirtual::commandIndex(const std::string& filename, const std::string& type)
2045 //=======================================================================
2048 //=======================================================================
2049 void InterpreterVirtual::commandNewGUI(const std::string& boxname,const std::string& instanceName)
2052 //=======================================================================
2056 //==========================================================================
2057 void InterpreterVirtual::commandDebug(const std::string& name)
2060 //==========================================================================
2063 //==========================================================================
2064 // Adds a callback when 'break' command issued
2065 void InterpreterVirtual::AddBreakObserver( BreakCallbackType c )
2067 mBreakSignal.connect(c);
2069 //==========================================================================
2072 //==========================================================================
2073 std::string InterpreterVirtual::GetObjectName() const
2075 return std::string("InterpreterVirtual");
2077 //==========================================================================
2079 //==========================================================================
2080 std::string InterpreterVirtual::GetObjectInfo() const
2082 std::stringstream i;
2085 //==========================================================================
2087 //==========================================================================
2088 size_t InterpreterVirtual::GetObjectSize() const
2090 size_t s = Superclass::GetObjectSize();
2091 s += InterpreterVirtual::GetObjectInternalSize();
2094 //==========================================================================
2095 //==========================================================================
2096 size_t InterpreterVirtual::GetObjectInternalSize() const
2098 size_t s = sizeof(InterpreterVirtual);
2101 //==========================================================================
2102 //==========================================================================
2103 size_t InterpreterVirtual::GetObjectRecursiveSize() const
2105 size_t s = Superclass::GetObjectRecursiveSize();
2106 s += InterpreterVirtual::GetObjectInternalSize();
2109 //==========================================================================