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;
351 //=======================================================================
355 //=======================================================================
359 InterpreterVirtual::~InterpreterVirtual()
361 bbtkDebugMessage("object",2,"==> ~Interpreter()" <<std::endl);
363 //=======================================================================
366 //=======================================================================
367 InterpreterException::InterpreterException( const std::string& message,
369 const std::string& script_file,
372 : Exception("interpreter",0,message),
373 mInScriptFile(in_script_file),
374 mScriptFile(script_file),
375 mScriptLine(script_line)
378 //=======================================================================
379 //=======================================================================
380 InterpreterException::InterpreterException( const Exception& excep,
382 const std::string& script_file,
386 mInScriptFile(in_script_file),
387 mScriptFile(script_file),
388 mScriptLine(script_line)
391 //=======================================================================
394 //=======================================================================
395 void InterpreterVirtual::CatchInterpreterException( const InterpreterException& e )
397 //EED Borrame if (GetExecuter()->GetNoErrorMode())
399 //EED Borrame bbtkWarning("ERROR :"<<e.GetErrorMessage()
400 //EED Borrame <<" ("<<e.GetScriptFile()<<":"<<e.GetScriptLine()
401 //EED Borrame <<" skipped");
402 //EED Borrame return;
406 if (e.GetErrorMessage()!="break")
408 mStatus = Interpreter_ERROR;
411 throw InterpreterException(e);
413 std::stringstream mess;
414 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
415 if (e.IsInScriptFile())
417 mess << "* FILE : \""<<e.GetScriptFile()<<"\""<<std::endl;
418 mess << "* LINE : "<<e.GetScriptLine()<<std::endl;
421 std::cerr << mess.str();
424 //=======================================================================
426 //=======================================================================
427 void InterpreterVirtual::CatchBbtkException( const bbtk::Exception& e )
429 //EED Borrame if (GetExecuter()->GetNoErrorMode())
431 //EED Borrame std::string file("?");
432 //EED Borrame int line = 0;
433 //EED Borrame if (mFileName.size()) {
434 //EED Borrame file = mFileName.back();
435 //EED Borrame line = mLine.back();
437 //EED Borrame bbtkWarning("ERROR '"<<e.GetErrorMessage()
438 //EED Borrame <<"' ("<<file<<":"<<line<<") skipped");
439 //EED Borrame return;
442 mStatus = Interpreter_ERROR;
445 bool in_script = false;
446 std::string file("");
448 if (mFileName.size())
450 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
451 if (fs!=0) in_script = true;
452 file = mFileName.back();
455 if (e.GetErrorMessage()!="break")
457 throw InterpreterException(e,in_script,file,line);
459 std::stringstream mess;
460 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
461 if (mFileName.size())
463 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
464 mess << "* LINE : "<<mLine.back()<<std::endl;
467 std::cerr << mess.str();
470 //=======================================================================
472 //=======================================================================
473 void InterpreterVirtual::CatchStdException( const std::exception& e )
475 //EED Borrame if (GetExecuter()->GetNoErrorMode())
477 //EED Borrame std::string file("?");
478 //EED Borrame int line = 0;
479 //EED Borrame if (mFileName.size()) {
480 //EED Borrame file = mFileName.back();
481 //EED Borrame line = mLine.back();
483 //EED Borrame bbtkWarning("ERROR '"<<e.what()
484 //EED Borrame <<"' ("<<file<<":"<<line<<") skipped");
485 //EED Borrame return;
488 mStatus = Interpreter_ERROR;
491 bool in_script = false;
492 std::string file("");
494 if (mFileName.size()) {
495 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
496 if (fs!=0) in_script = true;
497 file = mFileName.back();
501 throw InterpreterException(e.what(),in_script,file,line);
503 std::stringstream mess;
504 mess << "* ERROR : "<<e.what()<<std::endl;
505 if (mFileName.size())
507 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
508 mess << "* LINE : "<<mLine.back()<<std::endl;
511 std::cerr << mess.str();
515 //=======================================================================
517 //=======================================================================
518 void InterpreterVirtual::CatchUnknownException()
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();
561 //=======================================================================
563 //=======================================================================
565 #define CATCH_MACRO \
566 catch (InterpreterException e) \
568 CatchInterpreterException(e); \
570 catch (bbtk::Exception e) \
572 CatchBbtkException(e); \
574 catch (std::exception& e) \
576 CatchStdException(e); \
580 CatchUnknownException(); \
582 //=======================================================================
585 //=======================================================================
586 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretFile( const std::string& filename, bool source )
588 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::InterpretFile(\""<<filename<<"\")"<<std::endl);
590 bool exm = mCommandLine;
591 mCommandLine = false;
595 mStatus = Interpreter_OK;
596 SwitchToFile(filename,source);
597 mInsideComment = false;
598 InterpretCurrentStreams();
602 bbtkDebugMessage("interpreter",4,
603 "<== InterpreterVirtual::InterpretFile(\""
604 <<filename<<"\")"<<std::endl);
611 //=======================================================================
614 //=======================================================================
615 InterpreterVirtual::ExitStatus
616 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);
639 //=======================================================================
641 //=======================================================================
642 /// Interprets the currently open streams
643 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretCurrentStreams()
645 bbtkDebugMessage("interpreter",4,
646 "==> InterpreterVirtual::InterpretCurrentStreams()"<<std::endl);
648 while (mFile.size()>0)
650 while (!mFile.back()->eof()) {
653 mFile.back()->getline(buf,500);
654 std::string str(buf);
655 //size 0 JCP 21-09-2009
656 int size=str.length();
658 if ( str[ size-1 ]==13 )
664 DoInterpretLine(str);
672 bbtkDebugMessage("interpreter",4,
673 "<== InterpreterVirtual::InterpretCurrentStreams()"<<std::endl);
677 //=======================================================================
679 //=======================================================================
680 /// Runs the interpretation of a command
681 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretLine( const std::string& line )
683 bbtkDebugMessage("interpreter",5,"==> InterpreterVirtual::InterpretLine('"<<line<<"')"<<std::endl);
687 mStatus = Interpreter_OK;
688 mInsideComment = false;
689 //std::cout<<"JCP bbtkInterpreter.cxx InterpreterVirtual::InterpretLine("<<std::endl;
690 DoInterpretLine(line );
695 bbtkDebugMessage("interpreter",5,"<== InterpreterVirtual::InterpretLine('"<<line<<"')"<<std::endl);
699 //=======================================================================
701 void InterpreterVirtual::commandNew(const std::string &boxType, const std::string &boxName) // virtual
705 void InterpreterVirtual::commandDelete(const std::string &boxName)
709 void InterpreterVirtual::commandConnection(const std::string &nodeFrom,const std::string &outputLabel,const std::string &nodeTo,const std::string &inputLabel)
713 void InterpreterVirtual::commandPackage(const std::string &packageName)
717 void InterpreterVirtual::commandEndPackage()
721 void InterpreterVirtual::commandDefine(const std::string &name,const std::string &pack,const std::string &scriptfilename)
725 void InterpreterVirtual::commandEndDefine()
729 void InterpreterVirtual::commandKind(const std::string &kind)
733 void InterpreterVirtual::commandPrint(const std::string &value)
738 void InterpreterVirtual::commandExec(const std::string &word)
743 void InterpreterVirtual::commandInput(const std::string &name,const std::string &box,const std::string &input,const std::string &help)
747 void InterpreterVirtual::commandOutput(const std::string &name,const std::string &box,const std::string &output,const std::string &help)
751 void InterpreterVirtual::commandSet(const std::string &box,const std::string &input,const std::string &value)
755 void InterpreterVirtual::commandAuthor(const std::string &author)
759 void InterpreterVirtual::commandCategory(const std::string &categorytype)
765 void InterpreterVirtual::commandDescription(const std::string &description)
770 void InterpreterVirtual::commandClear()
774 void InterpreterVirtual::commandInclude(const std::string &word, bool ok)
779 void InterpreterVirtual::commandLoad(const std::string &packageName)
783 void InterpreterVirtual::commandUnload(const std::string &packageName)
787 void InterpreterVirtual::commandBreak()
791 void InterpreterVirtual::commandQuit()
795 void InterpreterVirtual::commandMessage()
799 void InterpreterVirtual::commandMessage(const std::string &kind,const std::string &levelstr)
805 //=======================================================================
806 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 bool in_script = false;
897 std::string file("");
900 if (mFileName.size())
902 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
903 if (fs!=0) in_script = true;
904 file = mFileName.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);
922 //EED Borrame bbtkError("quit");//,in_script,file,line);
923 //throw QuitException(in_script,file,line);
927 //std::cout<<" mVirtualExecuter->Create(words[1],words[2]); "<<line<<std::endl;
931 switch (command.code)
934 commandNew(words[1],words[2]);
935 //EED Borrame mVirtualExecuter->Create(words[1],words[2]);
939 commandDelete(words[1]);
940 //EED Borrame mVirtualExecuter->Destroy(words[1]);
944 Utilities::SplitAroundFirstDot(words[1],left,right);
945 Utilities::SplitAroundFirstDot(words[2],left2,right2);
946 commandConnection(left,right,left2,right2);
947 //EED Borrame mVirtualExecuter->Connect(left,right,left2,right2);
951 commandPackage(words[1]);
952 //EED Borrame mVirtualExecuter->BeginPackage(words[1]);
957 //EED Borrame mVirtualExecuter->EndPackage();
961 if (mFileName.size()>0)
963 //??? commandDefine(????);
964 filename = mFileName.back(); //mIncludeFileName.back(); //Utilities::get_file_name(mFileName.back());
968 std::string packTmp = "";
969 commandDefine(words[1],packTmp,filename);
970 //EED Borrame mVirtualExecuter->Define(words[1],"",filename);
974 commandDefine(words[1],words[2],filename);
975 //EED Borrame mVirtualExecuter->Define(words[1],words[2],filename);
981 //EED Borrame mVirtualExecuter->EndDefine();
985 commandKind(words[1]);
986 //EED Borrame mVirtualExecuter->Kind(words[1]);
990 commandPrint(words[1]);
991 //EED Borrame mVirtualExecuter->Print(words[1]);
995 commandExec(words[1]);
996 //EED Borrame if (words[1]=="freeze")
998 //EED Borrame mVirtualExecuter->SetNoExecMode(true);
999 //EED Borrame mThrow = false;
1001 //EED Borrame else if (words[1]=="freeze_no_error")
1003 //EED Borrame mVirtualExecuter->SetNoExecMode(true);
1004 //EED Borrame mVirtualExecuter->SetNoErrorMode(true);
1005 //EED Borrame mThrow = false;
1007 //EED Borrame else if (words[1]=="unfreeze")
1009 //EED Borrame mVirtualExecuter->SetNoExecMode(false);
1010 //EED Borrame mVirtualExecuter->SetNoErrorMode(false);
1014 //EED Borrame mVirtualExecuter->Execute(words[1]);
1020 Utilities::SplitAroundFirstDot(words[2],left,right);
1021 commandInput(words[1],left,right,words[3]);
1022 //EED Borrame mVirtualExecuter->DefineInput(words[1],left,right,words[3]);
1026 Utilities::SplitAroundFirstDot(words[2],left,right);
1027 commandOutput(words[1],left,right,words[3]);
1028 //EED Borrame mVirtualExecuter->DefineOutput(words[1],left,right,words[3]);
1032 Utilities::SplitAroundFirstDot(words[1],left,right);
1033 commandSet(left,right,words[2]);
1034 //EED Borrame mVirtualExecuter->Set(left,right,words[2]);
1038 commandAuthor(words[1]);
1039 //EED Borrame mVirtualExecuter->Author(words[1]);
1043 commandNewGUI(words[1],words[2]);
1047 commandCategory(words[1]);
1048 //EED Borrame mVirtualExecuter->Category(words[1]);
1052 if (words.size()==1)
1053 commandIndex("tmp_index.html");
1054 else if (words.size()==2)
1055 commandIndex(words[1]);
1056 else if (words.size()==3)
1057 commandIndex(words[1],words[2]);
1061 commandDescription(words[1]);
1062 //EED Borrame mVirtualExecuter->Description(words[1]);
1071 commandGraph(words);
1084 //EED Borrame mVirtualExecuter->Clear();
1088 commandInclude( words[1] , (words.size()==3) );
1089 //EED Borrame // if 'source' was given (words.size()==3) then tell to set the
1090 //EED Borrame // source file name of the current complex box with the full file name included
1091 //EED Borrame if (mCommandLine)
1093 //EED Borrame InterpretFile(words[1],(words.size()==3));
1094 //EED Borrame } else{
1095 //EED Borrame SwitchToFile(words[1],(words.size()==3) );
1100 commandLoad( words[1] );
1101 //EED Borrame GetExecuter()->LoadPackage(words[1]);
1105 commandUnload( words[1] );
1106 //EED Borrame GetExecuter()->UnLoadPackage(words[1]);
1110 if (words.size()==2) commandDebug(words[1]);
1111 else commandDebug("");
1116 if (words.size() == 2)
1118 if (words[1]=="freeze") mVirtualExecuter->SetNoExecMode(true);
1119 else if (words[1]=="unfreeze") mVirtualExecuter->SetNoExecMode(false);
1123 mVirtualExecuter->SetWorkspaceName(words[2]);
1128 bbtkInternalError("should not reach here !!!");
1131 bbtkDebugMessage("interpreter",6,"<== InterpreterVirtual::DoInterpretLine(\""
1132 <<line<<"\")"<<std::endl);
1135 //=======================================================================
1141 //=======================================================================
1142 void InterpreterVirtual::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
1144 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::SplitLine(\""<<str<<"\")"<<std::endl);
1146 std::string delimiters = "\"";
1147 std::vector<std::string> quote;
1148 Utilities::SplitString(str,delimiters,quote);
1151 std::vector<std::string>::iterator i;
1152 for (i=quote.begin(); i!=quote.end(); )
1154 Utilities::SplitString(*i,delimiters,tokens);
1158 // bbtkDebugMessage("interpreter",0,"\""<<*i<<"\""<<std::endl);
1159 tokens.push_back(*i);
1164 for (i=tokens.begin(); i!=tokens.end(); ++i)
1166 bbtkDebugMessage("interpreter",9,"--["<<*i<<"]"<<std::endl);
1168 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::SplitLine(\""<<str<<"\")"<<std::endl);
1171 //=======================================================================
1174 //=======================================================================
1175 void InterpreterVirtual::commandReset()
1178 //=======================================================================
1180 //=======================================================================
1185 void InterpreterVirtual::Print( const std::string& str)
1187 if (mVirtualExecuter->GetNoExecMode()) return;
1189 bbtkDebugMessageInc("interpreter",9,"InterpreterVirtual::Print(\""<<str<<"\")"<<std::endl);
1192 // InterpretLine ("load std")
1193 // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande
1194 // InterpretLine("new Print _P_")
1195 // InterpretLine("connect _C_.Out _P_.In")
1199 std::vector<std::string> chains;
1200 std::string delimiters("$");
1202 // Skip delimiters at beginning.
1203 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
1204 bool is_text = true;
1205 if (lastPos>0) is_text = false;
1207 // Find first delimiter.
1208 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
1210 while (std::string::npos != pos || std::string::npos != lastPos)
1214 // Found a text token, add it to the vector.
1215 chains.push_back(str.substr(lastPos, pos - lastPos));
1216 // std::string token = str.substr(lastPos, pos - lastPos)
1217 // InterpretLine("set _C_.In%num% %token%")
1223 // is an output (between $$) : decode
1224 std::string tok,box,output;
1225 tok = str.substr(lastPos, pos - lastPos);
1226 Utilities::SplitAroundFirstDot(tok,box,output);
1227 chains.push_back( mVirtualExecuter->Get(box,output) );
1229 // InterpretLine("connect %tok% _C_.In%num%")
1232 // Skip delimiters. Note the "not_of"
1233 lastPos = str.find_first_not_of(delimiters, pos);
1234 // Find next delimiter
1235 pos = str.find_first_of(delimiters, lastPos);
1240 // InterpretLine("exec _P_")
1241 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
1243 std::vector<std::string>::iterator i;
1244 for (i= chains.begin(); i!=chains.end(); ++i)
1247 Utilities::SubsBackslashN(*i);
1250 std::cout << std::endl;
1251 bbtkDebugDecTab("interpreter",9);
1255 //=======================================================================
1260 // =========================================================================
1261 void InterpreterVirtual::SwitchToFile( const std::string& name , bool source )
1263 // Note : in the following :
1264 // name : the user supplied name
1265 // - abreviated name e.g. scr scr.bbs
1266 // - relative full name e.g. ./scr.bbs ../../scr.bbs
1267 // - absolute full name e.g. /home/usrname/proj/dir/scr.bbs
1268 // same for Windows, with c:, d: ...
1270 // use ./directory/subdir/scrname.bbs
1273 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::SwitchToFile( \""
1274 <<name<<"\")"<<std::endl);
1276 std::vector<std::string> script_paths;
1277 std::string fullPathScriptName; // full path script name
1278 std::string pkgname; // e.g. <scriptname>.bbs
1279 std::vector<std::string> Filenames;
1280 std::string tmpFilenames;
1282 // The following is *NOT* a debug time message :
1283 // It's a user intended message.
1284 // Please don't remove it.
1285 bbtkMessage("interpreter",1,
1286 "look for : [" << name
1287 << "]" << std::endl);
1291 pkgname = Utilities::ExtractScriptName(name,upath);
1293 bbtkMessage("interpreter",3,
1294 "package name:[" << pkgname
1295 << "] path:[" << upath << "]" << std::endl);
1296 bool fullnameGiven = false;
1297 bool foundFile = false;
1299 // ==== "*" provided : load all scripts in given path
1300 // relative (e.g. std/boxes/*) or absolute
1304 std::stringstream* stream = new std::stringstream;
1305 //if (upath.size()!=0) // avoid troubles for "*"
1307 // ==== no path provided : look in root bbs path
1308 if (upath.size()==0)
1310 // bbtkMessage("interpreter",1,
1311 // LG : add all bbs path
1312 // script_paths.push_back( ConfigurationFile::GetInstance().Get_root_bbs_path() );
1313 std::vector<std::string>::const_iterator i;
1314 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1315 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1318 script_paths.push_back(*i);
1321 // ==== absolute path provided
1322 else if (upath[0]=='/' || upath[1] == ':' )
1324 if ( Utilities::IsDirectory( upath ) )
1326 script_paths.push_back(upath);
1330 bbtkError("'"<<upath<<"' : directory does not exist");
1333 // ==== relative path provided : search all bbs path appended with
1334 // the relative path provided
1337 std::vector<std::string>::const_iterator i;
1338 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1339 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1342 std::string full_path(*i);
1343 printf("EED InterpreterVirtual::SwitchToFile 1. >>%s\n", full_path.c_str() );
1344 // we *really* want '.' to be the current working directory
1345 if (full_path == ".")
1347 char buf[2048]; // for getcwd
1348 char * currentDir = getcwd(buf, 2048);
1349 std::string cwd(currentDir);
1350 full_path = currentDir;
1353 full_path += ConfigurationFile::GetInstance().Get_file_separator();
1356 if ( Utilities::IsDirectory( full_path ) )
1358 script_paths.push_back(full_path);
1361 if (script_paths.empty())
1363 bbtkError("no '"<<upath<<"' subdir found in search paths"
1368 // === search paths list complete : now explore it
1370 // ==== relative name, iterate + load all .bbs/.bbp files
1371 std::vector<std::string>::iterator i;
1372 for (i=script_paths.begin();i!=script_paths.end();i++)
1375 printf("EED InterpreterVirtual::SwitchToFile jaja >> %s\n", (*i).c_str() );
1377 bbtkMessage("interpreter",1,
1378 "--> Looking in '" << *i << "'" << std::endl);
1382 Utilities::Explore(*i, false, Filenames);
1384 int iFilesnames,jFilesnames,sizeFilenames;
1385 sizeFilenames=Filenames.size();
1388 // EEDd 30 sept 2012
1389 //Sorting list of files
1390 for (iFilesnames=0;iFilesnames<sizeFilenames; iFilesnames++)
1392 for (jFilesnames=iFilesnames;jFilesnames<sizeFilenames; jFilesnames++)
1394 if ( Filenames[iFilesnames] > Filenames[jFilesnames] )
1396 tmpFilenames = Filenames[iFilesnames];
1397 Filenames[iFilesnames] = Filenames[jFilesnames];
1398 Filenames[jFilesnames] = tmpFilenames;
1400 } // for iFilesnames
1401 } // for iFilesnames
1405 for (std::vector<std::string>::iterator j = Filenames.begin();
1406 j!= Filenames.end(); ++j)
1409 printf("EED InterpreterVirtual::SwitchToFile kkkkk >> %s\n", (*j).c_str() );
1411 int lgr = (*j).size();
1412 if (lgr < 5) continue;
1413 // ignore non .bbp file
1414 if ( (*j).substr(lgr-4, 4) != ".bbp") continue;
1416 (*stream) << "include \"" << *j << "\"\n";
1417 bbtkMessage("interpreter",2," --> Found '" << *j << "'" << std::endl);
1420 } // for (std::vector...
1421 } // for (i=script_...
1426 bbtkMessage("interpreter",1,
1427 " --> No .bbp found"<< std::endl);
1431 bbtkMessage("interpreter",1,
1432 " --> "<<nbBssFiles<<" .bbp found"<< std::endl);
1433 SwitchToStream(stream);
1437 //=============== end pkgname=="*" ===========
1440 // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name
1441 // (not only a plain script name)
1442 // we trust him, and try to expland the directory name
1443 // WARNING : starting from current local directory : ./whatYouWant (./ mandatory!)
1445 if (name[0]=='/' || name[1] == ':' || name[0]=='.') // absolute path (linux/windows) or relative path
1448 // ===========================================================check user supplied location
1449 fullnameGiven = true;
1451 fullPathScriptName = Utilities::ExpandLibName(name, false);
1453 // allow user to always forget ".bbs"
1454 int l = fullPathScriptName.size();
1458 if ((fullPathScriptName.substr(l-4, 4) != ".bbs")&&
1459 (fullPathScriptName.substr(l-4, 4) != ".bbp"))
1461 std::string tfullPathScriptName = fullPathScriptName + ".bbs";
1462 if ( Utilities::FileExists(tfullPathScriptName) )
1464 fullPathScriptName = tfullPathScriptName;
1469 tfullPathScriptName = fullPathScriptName + ".bbp";
1470 if ( Utilities::FileExists(tfullPathScriptName) )
1472 fullPathScriptName = tfullPathScriptName;
1479 if ( Utilities::FileExists(fullPathScriptName) )
1487 // =============================== iterate on the paths
1489 script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
1491 std::vector<std::string>::iterator i;
1492 for (i=script_paths.begin();i!=script_paths.end();++i)
1495 // we *really* want '.' to be the current working directory
1498 char buf[2048]; // for getcwd
1499 char * currentDir = getcwd(buf, 2048);
1500 std::string cwd(currentDir);
1504 std::string tfullPathScriptName = Utilities::MakePkgnameFromPath(path, name, false);
1506 //Addition JCP tfullPathScriptName.size()>=4
1507 if(tfullPathScriptName.size()>=4){
1508 if (tfullPathScriptName.substr(tfullPathScriptName.size()-4, 3)==".bb")
1510 fullPathScriptName = tfullPathScriptName;
1511 if ( ! Utilities::FileExists(fullPathScriptName) )
1513 // The following is *NOT* a debug time message :
1514 // It's a user intended message.
1515 // Please don't remove it.
1516 bbtkMessage("interpreter",2,
1517 " [" <<fullPathScriptName <<"] : does not exist"
1519 continue; // try next path
1521 bbtkMessage("interpreter",2,
1522 " [" <<fullPathScriptName
1523 <<"] : found" <<std::endl);
1525 break; // a script was found; we stop iterating
1529 fullPathScriptName = tfullPathScriptName + ".bbs";
1530 // Check if library exists
1531 if ( ! Utilities::FileExists(fullPathScriptName) )
1533 fullPathScriptName = tfullPathScriptName + ".bbp";
1534 if ( ! Utilities::FileExists(fullPathScriptName) )
1536 // The following is *NOT* a debug time message :
1537 // It's a user intended message.
1538 // Please don't remove it.
1539 bbtkMessage("interpreter",2,
1540 " [" <<tfullPathScriptName <<".bbs/.bbp] : do not exist"
1542 continue; // try next path
1545 bbtkMessage("interpreter",2,
1546 " [" <<fullPathScriptName
1547 <<"] : found" <<std::endl);
1549 break; // a script was found; we stop iterating
1552 } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
1558 if(fullPathScriptName == "")
1559 bbtkError("Path ["<<upath<<"] doesn't exist");
1561 bbtkError("Script ["<<fullPathScriptName<<"] not found");
1563 bbtkError("No ["<<pkgname<<".bbs/.bbp] script found");
1566 //EED printf("EED D. SwitchToFile %s\n", fullPathScriptName.c_str() );
1567 LoadScript(fullPathScriptName,name);
1568 //EED Borrame if (source) GetExecuter()->SetCurrentFileName(fullPathScriptName);
1571 // Over writing the fullpath of the bbp file.
1572 SetCurrentFileName( fullPathScriptName );
1573 SetTypeOfScript_Application();
1579 //=======================================================================
1581 //=======================================================================
1582 void InterpreterVirtual::SetCurrentFileName(const std::string &fullPathScriptName) // virtual
1585 //=======================================================================
1588 //=======================================================================
1589 void InterpreterVirtual::SetTypeOfScript_Application( )
1592 //=======================================================================
1595 //=======================================================================
1596 void InterpreterVirtual::SwitchToStream( std::stringstream* stream )
1598 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::SwitchToStream()"
1600 mFile.push_back(stream);
1601 std::ostringstream buffer_name;
1603 buffer_name << "buffer_" ;
1605 if (mFileName.size()>0 )
1607 buffer_name << mFileName.back() << "_" << mLine.back();
1609 mFileName.push_back(buffer_name.str());
1610 mIncludeFileName.push_back(buffer_name.str());
1613 //=======================================================================
1615 //=======================================================================
1617 void InterpreterVirtual::LoadScript( std::string fullPathScriptName,
1618 std::string includeScriptName)
1620 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::LoadScript("
1621 <<fullPathScriptName<<")"
1624 Utilities::replace( fullPathScriptName ,
1625 INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
1627 if (find(mFileNameHistory.begin(),
1628 mFileNameHistory.end(),
1629 fullPathScriptName)!=mFileNameHistory.end())
1635 s = new std::ifstream;
1636 s->open(fullPathScriptName.c_str());
1639 bbtkError("Could not open file ["<<fullPathScriptName<<"]");
1643 bbtkMessage("interpreter",1," -->[" << fullPathScriptName
1644 << "] found" << std::endl);
1647 mFileName.push_back(fullPathScriptName);
1648 mFileNameHistory.push_back(fullPathScriptName);
1649 mIncludeFileName.push_back(includeScriptName);
1654 //=======================================================================
1656 //=======================================================================
1657 void InterpreterVirtual::CloseCurrentFile()
1659 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::CloseCurrentFile()"
1662 if (mFile.size()==0)
1664 bbtkDebugMessage("interpreter",9," -> no file left open"<<std::endl);
1668 bbtkDebugMessage("interpreter",9," Closing file '"<<mFileName.back()<<"'"<<std::endl);
1670 std::ifstream* file = dynamic_cast<std::ifstream*>(mFile.back());
1671 if (file!=0) file->close();
1673 delete mFile.back();
1675 mFileName.pop_back();
1676 mIncludeFileName.pop_back();
1679 bbtkDebugMessage("interpreter",9," Remains "
1681 <<" open"<<std::endl);
1682 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::CloseCurrentFile()"
1685 //=======================================================================
1687 //=======================================================================
1688 void InterpreterVirtual::CloseAllFiles()
1690 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::CloseAllFiles()"
1693 while (mFile.size() != 0)
1697 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::CloseAllFiles()"
1700 //=======================================================================
1704 //=======================================================================
1705 void InterpreterVirtual::InterpretCommand( const std::vector<std::string>& words,
1706 CommandInfoType& info )
1709 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::InterpretCommand(...)"<<std::endl);
1711 // searches the command keyword
1712 CommandDictType::iterator c;
1713 c = mCommandDict.find(words[0]);
1714 if ( c == mCommandDict.end() ) {
1715 bbtkError(words[0]<<" : unknown command");
1718 // tests the number of args
1719 if ( ( ((int)words.size())-1 < c->second.argmin ) ||
1720 ( ((int)words.size())-1 > c->second.argmax ) )
1723 //EED HelpCommand(words[0]);
1724 commandHelp(words[0]);
1725 bbtkError(words[0]<<" : wrong number of arguments");
1727 //std::cout<<"InterpreterVirtual::InterpretCommand( const std::vector<std::string>& words,"<<std::endl;
1729 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::InterpretCommand(...)"<<std::endl);
1732 //=======================================================================
1735 //=======================================================================
1736 /// Displays help on all the commands
1737 void InterpreterVirtual::commandHelp(const std::vector<std::string>& words)
1740 //=======================================================================
1741 void InterpreterVirtual::commandHelp(const std::string &words)
1744 //=======================================================================
1746 //===================================================================
1747 /// Displays the Configuration
1748 void InterpreterVirtual::commandConfig() const
1751 //===================================================================
1755 //=======================================================================
1756 /// Fills the vector commands with the commands which
1757 /// have the first n chars of buf for prefix
1758 /// TODO : skip initial spaces in buf and also return the position of first
1759 /// non blank char in buf
1760 void InterpreterVirtual::FindCommandsWithPrefix( char* buf,
1762 std::vector<std::string>& commands )
1764 CommandDictType::const_iterator i;
1765 for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
1767 if ((i->first).find(buf,0,n) == 0)
1768 commands.push_back(i->first);
1771 //=======================================================================
1775 //=======================================================================
1776 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1778 inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
1779 inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
1781 // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
1782 // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
1783 // E.G. STORE THIS IN bbtk_config.xml
1784 #define BBTK_UP_ARROW_KBCODE 0x00415B1B
1785 #define BBTK_DOWN_ARROW_KBCODE 0x00425B1B
1786 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
1787 #define BBTK_LEFT_ARROW_KBCODE 0x00445B1B
1788 #define BBTK_BACKSPACE_KBCODE 0x00000008
1789 #define BBTK_DEL_KBCODE 0x0000007F
1790 #define BBTK_SPACE_KBCODE 0x00000020
1792 //=======================================================================
1793 void InterpreterVirtual::GetLineFromPrompt(std::string& s)
1798 unsigned int MAX_LINE_SIZE = 160;
1799 unsigned int MAX_HISTORY_SIZE = 100;
1801 char* newline = new char[MAX_LINE_SIZE];
1802 memset(newline,0,MAX_LINE_SIZE);
1803 char* histline = new char[MAX_LINE_SIZE];
1804 memset(histline,0,MAX_LINE_SIZE);
1806 char* line = newline;
1807 unsigned int hist = mHistory.size();
1813 read ( STDIN_FILENO, &c, 4) ;
1815 bbtkDebugMessage("debug",9,"[0x"<<std::hex<<c<<"]\n");
1817 // Printable character
1818 if ( (ind<MAX_LINE_SIZE-1) &&
1819 ( c >= BBTK_SPACE_KBCODE ) &&
1820 ( c < BBTK_DEL_KBCODE ))
1828 // delete the unused line
1834 // empty lines are not stored in from history
1837 // if history too long : delete oldest command
1838 if (mHistory.size()>MAX_HISTORY_SIZE)
1840 delete mHistory.front();
1841 mHistory.pop_front();
1843 mHistory.push_back(line);
1848 else if ( (ind>0) &&
1849 ((c == BBTK_BACKSPACE_KBCODE) ||
1850 (c == BBTK_DEL_KBCODE)) )
1858 // TODO : Command completion
1859 std::vector<std::string> commands;
1860 FindCommandsWithPrefix( line,ind,commands);
1861 if (commands.size()==1)
1863 std::string com = *commands.begin();
1864 for (; ind<com.size(); ++ind)
1866 PrintChar(com[ind]);
1872 else if (commands.size()>1)
1874 std::vector<std::string>::iterator i;
1876 for (i=commands.begin();i!=commands.end();++i)
1878 write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
1881 write(STDOUT_FILENO,"\n> ",3);
1882 //for (int j=0;j<ind;++j)
1884 write(STDOUT_FILENO,line,ind);
1888 // Arrow up : back in history
1889 else if (c==BBTK_UP_ARROW_KBCODE)
1893 // erase current line
1894 while (ind--) BackSpace();
1898 strcpy(histline,mHistory[hist]);
1902 write(STDOUT_FILENO,line,ind);
1905 // Arrow down : down in history
1906 else if (c==BBTK_DOWN_ARROW_KBCODE)
1908 if (hist<mHistory.size()-1)
1910 // erase current line
1911 while (ind--) BackSpace();
1915 strcpy(histline,mHistory[hist]);
1919 write(STDOUT_FILENO,line,ind);
1921 // end of history : switch back to newline
1922 else if (hist==mHistory.size()-1)
1924 // erase current line
1925 while (ind--) BackSpace();
1932 write(STDOUT_FILENO,line,ind);
1936 else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
1938 PrintChar(line[ind]);
1943 else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
1951 write(STDOUT_FILENO,"\n\r",2);
1959 //=======================================================================
1960 void InterpreterVirtual::GetLineFromPrompt(std::string& s)
1986 //=======================================================================
1992 //=======================================================================
1993 void InterpreterVirtual::CommandLineInterpreter()
1995 bbtkDebugMessageInc("interpreter",9,
1996 "InterpreterVirtual::CommandLineInterpreter()"<<std::endl);
1998 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1999 // Initialise the tty in non canonical mode with no echo
2000 // oter remembers the previous settings to restore them after
2001 struct termios ter,oter;
2004 ter.c_lflag &= ~ECHO;
2005 ter.c_lflag &= ~ICANON;
2008 tcsetattr(0,TCSANOW,&ter);
2011 mCommandLine = true;
2013 // bool insideComment = false; // for multiline comment
2014 mInsideComment = false;
2020 GetLineFromPrompt(line);
2021 DoInterpretLine(line); //, insideComment);
2024 catch (QuitException e)
2026 bbtkMessage("interpreter",1,"Interpreter : Quit"<<std::endl);
2030 catch (bbtk::Exception e)
2034 catch (std::exception& e)
2036 std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
2040 std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
2045 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
2046 tcsetattr(0,TCSANOW,&oter);
2049 std::cout << "Good bye !" << std::endl;
2051 bbtkDebugDecTab("interpreter",9);
2054 //=======================================================================
2055 void InterpreterVirtual::commandGraph(const std::vector<std::string>& words)
2058 //=======================================================================
2061 //=======================================================================
2062 void InterpreterVirtual::commandIndex(const std::string& filename, const std::string& type)
2065 //=======================================================================
2068 //=======================================================================
2069 void InterpreterVirtual::commandNewGUI(const std::string& boxname,const std::string& instanceName)
2072 //=======================================================================
2076 //==========================================================================
2077 void InterpreterVirtual::commandDebug(const std::string& name)
2080 //==========================================================================
2083 //==========================================================================
2084 // Adds a callback when 'break' command issued
2085 void InterpreterVirtual::AddBreakObserver( BreakCallbackType c )
2087 mBreakSignal.connect(c);
2089 //==========================================================================
2092 //==========================================================================
2093 std::string InterpreterVirtual::GetObjectName() const
2095 return std::string("InterpreterVirtual");
2097 //==========================================================================
2099 //==========================================================================
2100 std::string InterpreterVirtual::GetObjectInfo() const
2102 std::stringstream i;
2105 //==========================================================================
2107 //==========================================================================
2108 size_t InterpreterVirtual::GetObjectSize() const
2110 size_t s = Superclass::GetObjectSize();
2111 s += InterpreterVirtual::GetObjectInternalSize();
2114 //==========================================================================
2115 //==========================================================================
2116 size_t InterpreterVirtual::GetObjectInternalSize() const
2118 size_t s = sizeof(InterpreterVirtual);
2121 //==========================================================================
2122 //==========================================================================
2123 size_t InterpreterVirtual::GetObjectRecursiveSize() const
2125 size_t s = Superclass::GetObjectRecursiveSize();
2126 s += InterpreterVirtual::GetObjectInternalSize();
2129 //==========================================================================