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()
80 printf("EED InterpreterVirtual::Init start\n");
85 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);
86 bbtk::MessageManager::RegisterMessageType("Interpreter","Messages of the interpreter",0);
87 bbtkDebugMessageInc("Interpreter",9,"InterpreterVirtual::Interpreter()" <<std::endl);
89 // For the time being, comment out previous line, and
90 // uncomment next line to check Transcriptor
92 //mVirtualExecuter = new bbtk::Transcriptor("GeneratedProgram.txt");
94 // Builds the commands dict
101 info.syntax = "new <type> <name>";
102 info.help = "Creates a new black box of type <type> with name <name>";
103 mCommandDict[info.keyword] = info;
105 info.keyword = "delete";
109 info.syntax = "delete <box>";
110 info.help = "Deletes the black box of name <box>";
111 mCommandDict[info.keyword] = info;
113 info.keyword = "clear";
117 info.syntax = "clear";
118 info.help = "Clears the currently defined complex box (deletes all its boxes and connections)";
119 mCommandDict[info.keyword] = info;
121 info.keyword = "break";
125 info.syntax = "break";
126 info.help = "Breaks the current execution";
127 mCommandDict[info.keyword] = info;
129 info.keyword = "newgui";
133 info.syntax = "newgui <box> <name>";
134 info.help = "Automatically creates a graphical user interface with name <name> for the black box <box> and connects it to the box inputs";
135 mCommandDict[info.keyword] = info;
137 info.keyword = "connect";
140 info.code = cConnect;
141 info.syntax = "connect <box1.output> <box2.input>";
142 info.help = "Connects the ouput <output> of black box <box1> to the input <input> of black box <box2>";
143 mCommandDict[info.keyword] = info;
145 info.keyword = "print";
149 info.syntax = "print <string>";
150 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').";
151 mCommandDict[info.keyword] = info;
153 info.keyword = "exec";
157 info.syntax = "exec <box | 'freeze' | 'unfreeze' | 'freeze_no_error' >";
158 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.";
159 mCommandDict[info.keyword] = info;
161 info.keyword = "package";
164 info.code = cPackage;
165 info.syntax = "package <name>";
166 info.help = "Begins the definition of a package.";
167 mCommandDict[info.keyword] = info;
169 info.keyword = "endpackage";
172 info.code = cEndPackage;
173 info.syntax = "endpackage";
174 info.help = "Ends the definition of a package.";
175 mCommandDict[info.keyword] = info;
177 info.keyword = "define";
181 info.syntax = "define <type> [<package>]";
182 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.";
183 mCommandDict[info.keyword] = info;
185 info.keyword = "endefine";
188 info.code = cEndDefine;
189 info.syntax = "endefine";
190 info.help = "Ends the definition of a new type of complex black box";
191 mCommandDict[info.keyword] = info;
193 info.keyword = "kind";
197 info.syntax = "kind <ADAPTOR|DEFAULT_ADAPTOR|GUI|DEFAULT_GUI>";
198 info.help = "Sets the kind of the currently defined complex black box";
199 mCommandDict[info.keyword] = info;
201 info.keyword = "input";
205 info.syntax = "input <name> <box.input> <help>";
206 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";
207 mCommandDict[info.keyword] = info;
209 info.keyword = "output";
213 info.syntax = "output <name> <box.output> <help>";
214 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";
215 mCommandDict[info.keyword] = info;
217 info.keyword = "set";
221 info.syntax = "set <box.input> <value>";
222 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";
223 mCommandDict[info.keyword] = info;
225 info.keyword = "config"; // JPR
229 info.syntax = "config";
230 info.help = "Prints the value of all configuration parameters";
231 mCommandDict[info.keyword] = info;
233 info.keyword = "index"; // LG
238 info.syntax = "index [<filename> ['Initials'(default)|'Packages'|'Categories'|'Adaptors']]";
239 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.";
240 mCommandDict[info.keyword] = info;
242 info.keyword = "reset";
246 info.syntax = "reset";
247 info.help = "Deletes all boxes and unloads all packages (reset to start state)";
248 mCommandDict[info.keyword] = info;
250 info.keyword = "author";
254 info.syntax = "author <string>";
255 info.help = "Adds the string <string> to the author information of the black box being defined";
256 mCommandDict[info.keyword] = info;
258 info.keyword = "category"; //JP
261 info.code = cCategory;
262 info.syntax = "category <list of items, separated by ;>";
263 info.help = "Adds the string <string> to the category information of the black box being defined";
264 mCommandDict[info.keyword] = info;
266 info.keyword = "description";
269 info.code = cDescription;
270 info.syntax = "description <string>";
271 info.help = "Adds the string <string> to the descriptive information of the black box being defined";
272 mCommandDict[info.keyword] = info;
274 info.keyword = "help";
278 info.syntax = "help";
279 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>";
280 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.";
281 mCommandDict[info.keyword] = info;
283 info.keyword = "message";
286 info.code = cMessage;
287 info.syntax = "message <kind> <level>";
288 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.";
289 mCommandDict[info.keyword] = info;
291 info.keyword = "include";
294 info.code = cInclude;
295 info.syntax = "include <filename> [source]";
296 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).";
297 mCommandDict[info.keyword] = info;
299 info.keyword = "quit";
303 info.syntax = "quit";
304 info.help = "Quits the program (during script execution it stops the complete execution)";
305 mCommandDict[info.keyword] = info;
307 info.keyword = "load";
311 info.syntax = "load <packagename>";
312 info.help = "Loads the black box package <packagename>";
313 mCommandDict[info.keyword] = info;
315 info.keyword = "unload";
319 info.syntax = "unload <packagename>";
320 info.help = "Unloads the black box package <packagename>";
321 mCommandDict[info.keyword] = info;
323 info.keyword = "graph";
327 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 ]]]]]]";
328 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')";
329 mCommandDict[info.keyword] = info;
331 info.keyword = "debug";
335 info.syntax = "debug [expr|-C|-D]";
336 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";
337 mCommandDict[info.keyword] = info;
340 info.keyword = "workspace";
343 info.code = cWorkspace;
344 info.syntax = "workspace < ( freeze | unfreeze ) | ( rename <newname> ) >";
345 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.";
346 mCommandDict[info.keyword] = info;
349 printf("EED InterpreterVirtual::Init end\n");
352 //=======================================================================
356 //=======================================================================
360 InterpreterVirtual::~InterpreterVirtual()
362 bbtkDebugMessage("object",2,"==> ~Interpreter()" <<std::endl);
364 //=======================================================================
367 //=======================================================================
368 InterpreterException::InterpreterException( const std::string& message,
370 const std::string& script_file,
373 : Exception("interpreter",0,message),
374 mInScriptFile(in_script_file),
375 mScriptFile(script_file),
376 mScriptLine(script_line)
379 //=======================================================================
380 //=======================================================================
381 InterpreterException::InterpreterException( const Exception& excep,
383 const std::string& script_file,
387 mInScriptFile(in_script_file),
388 mScriptFile(script_file),
389 mScriptLine(script_line)
392 //=======================================================================
395 //=======================================================================
396 void InterpreterVirtual::CatchInterpreterException( const InterpreterException& e )
398 //EED Borrame if (GetExecuter()->GetNoErrorMode())
400 //EED Borrame bbtkWarning("ERROR :"<<e.GetErrorMessage()
401 //EED Borrame <<" ("<<e.GetScriptFile()<<":"<<e.GetScriptLine()
402 //EED Borrame <<" skipped");
403 //EED Borrame return;
407 if (e.GetErrorMessage()!="break")
409 mStatus = Interpreter_ERROR;
412 throw InterpreterException(e);
414 std::stringstream mess;
415 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
416 if (e.IsInScriptFile())
418 mess << "* FILE : \""<<e.GetScriptFile()<<"\""<<std::endl;
419 mess << "* LINE : "<<e.GetScriptLine()<<std::endl;
422 std::cerr << mess.str();
425 //=======================================================================
427 //=======================================================================
428 void InterpreterVirtual::CatchBbtkException( const bbtk::Exception& e )
430 //EED Borrame if (GetExecuter()->GetNoErrorMode())
432 //EED Borrame std::string file("?");
433 //EED Borrame int line = 0;
434 //EED Borrame if (mFileName.size()) {
435 //EED Borrame file = mFileName.back();
436 //EED Borrame line = mLine.back();
438 //EED Borrame bbtkWarning("ERROR '"<<e.GetErrorMessage()
439 //EED Borrame <<"' ("<<file<<":"<<line<<") skipped");
440 //EED Borrame return;
443 mStatus = Interpreter_ERROR;
446 bool in_script = false;
447 std::string file("");
449 if (mFileName.size())
451 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
452 if (fs!=0) in_script = true;
453 file = mFileName.back();
456 if (e.GetErrorMessage()!="break")
458 throw InterpreterException(e,in_script,file,line);
460 std::stringstream mess;
461 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
462 if (mFileName.size())
464 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
465 mess << "* LINE : "<<mLine.back()<<std::endl;
468 std::cerr << mess.str();
471 //=======================================================================
473 //=======================================================================
474 void InterpreterVirtual::CatchStdException( const std::exception& e )
476 //EED Borrame if (GetExecuter()->GetNoErrorMode())
478 //EED Borrame std::string file("?");
479 //EED Borrame int line = 0;
480 //EED Borrame if (mFileName.size()) {
481 //EED Borrame file = mFileName.back();
482 //EED Borrame line = mLine.back();
484 //EED Borrame bbtkWarning("ERROR '"<<e.what()
485 //EED Borrame <<"' ("<<file<<":"<<line<<") skipped");
486 //EED Borrame return;
489 mStatus = Interpreter_ERROR;
492 bool in_script = false;
493 std::string file("");
495 if (mFileName.size()) {
496 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
497 if (fs!=0) in_script = true;
498 file = mFileName.back();
502 throw InterpreterException(e.what(),in_script,file,line);
504 std::stringstream mess;
505 mess << "* ERROR : "<<e.what()<<std::endl;
506 if (mFileName.size())
508 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
509 mess << "* LINE : "<<mLine.back()<<std::endl;
512 std::cerr << mess.str();
516 //=======================================================================
518 //=======================================================================
519 void InterpreterVirtual::CatchUnknownException()
521 //EED Borrame if (GetExecuter()->GetNoErrorMode())
523 //EED Borrame std::string file("?");
524 //EED Borrame int line = 0;
525 //EED Borrame if (mFileName.size()) {
526 //EED Borrame file = mFileName.back();
527 //EED Borrame line = mLine.back();
529 //EED Borrame bbtkWarning("UNDEFINED ERROR "
530 //EED Borrame <<"("<<file<<":"<<line<<") skipped");
531 //EED Borrame return;
533 mStatus = Interpreter_ERROR;
536 bool in_script = false;
537 std::string file("");
539 if (mFileName.size()) {
540 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
541 if (fs!=0) in_script = true;
542 file = mFileName.back();
546 throw InterpreterException("Unknown exception caught",
547 in_script,file,line);
551 std::stringstream mess;
552 mess << "* UNDEFINED ERROR (not a bbtk nor a std exception)"
554 if (mFileName.size()) {
555 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
556 mess << "* LINE : "<<mLine.back()<<std::endl;
559 std::cerr << mess.str();
562 //=======================================================================
564 //=======================================================================
566 #define CATCH_MACRO \
567 catch (InterpreterException e) \
569 CatchInterpreterException(e); \
571 catch (bbtk::Exception e) \
573 CatchBbtkException(e); \
575 catch (std::exception& e) \
577 CatchStdException(e); \
581 CatchUnknownException(); \
583 //=======================================================================
586 //=======================================================================
587 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretFile( const std::string& filename, bool source )
589 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::InterpretFile(\""<<filename<<"\")"<<std::endl);
591 bool exm = mCommandLine;
592 mCommandLine = false;
596 mStatus = Interpreter_OK;
597 SwitchToFile(filename,source);
598 mInsideComment = false;
599 InterpretCurrentStreams();
603 bbtkDebugMessage("interpreter",4,
604 "<== InterpreterVirtual::InterpretFile(\""
605 <<filename<<"\")"<<std::endl);
612 //=======================================================================
615 //=======================================================================
616 InterpreterVirtual::ExitStatus
617 InterpreterVirtual::InterpretBuffer( std::stringstream* buffer )
619 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::InterpretBuffer()"<<std::endl);
621 bool exm = mCommandLine;
622 mCommandLine = false;
626 mStatus = Interpreter_OK;
627 SwitchToStream(buffer);
628 mInsideComment = false;
629 InterpretCurrentStreams();
634 bbtkDebugMessage("interpreter",4,"<== InterpreterVirtual::InterpretBuffer()"<<std::endl);
640 //=======================================================================
642 //=======================================================================
643 /// Interprets the currently open streams
644 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretCurrentStreams()
646 bbtkDebugMessage("interpreter",4,
647 "==> InterpreterVirtual::InterpretCurrentStreams()"<<std::endl);
649 while (mFile.size()>0)
651 while (!mFile.back()->eof()) {
654 mFile.back()->getline(buf,500);
655 std::string str(buf);
656 //size 0 JCP 21-09-2009
657 int size=str.length();
659 if ( str[ size-1 ]==13 )
665 DoInterpretLine(str);
673 bbtkDebugMessage("interpreter",4,
674 "<== InterpreterVirtual::InterpretCurrentStreams()"<<std::endl);
678 //=======================================================================
680 //=======================================================================
681 /// Runs the interpretation of a command
682 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretLine( const std::string& line )
684 bbtkDebugMessage("interpreter",5,"==> InterpreterVirtual::InterpretLine('"<<line<<"')"<<std::endl);
688 mStatus = Interpreter_OK;
689 mInsideComment = false;
690 //std::cout<<"JCP bbtkInterpreter.cxx InterpreterVirtual::InterpretLine("<<std::endl;
691 DoInterpretLine(line );
696 bbtkDebugMessage("interpreter",5,"<== InterpreterVirtual::InterpretLine('"<<line<<"')"<<std::endl);
700 //=======================================================================
702 void InterpreterVirtual::commandNew(const std::string &boxType, const std::string &boxName) // virtual
706 void InterpreterVirtual::commandDelete(const std::string &boxName)
710 void InterpreterVirtual::commandConnection(const std::string &nodeFrom,const std::string &outputLabel,const std::string &nodeTo,const std::string &inputLabel)
714 void InterpreterVirtual::commandPackage(const std::string &packageName)
718 void InterpreterVirtual::commandEndPackage()
722 void InterpreterVirtual::commandDefine(const std::string &name,const std::string &pack,const std::string &scriptfilename)
726 void InterpreterVirtual::commandEndDefine()
730 void InterpreterVirtual::commandKind(const std::string &kind)
734 void InterpreterVirtual::commandPrint(const std::string &value)
739 void InterpreterVirtual::commandExec(const std::string &word)
744 void InterpreterVirtual::commandInput(const std::string &name,const std::string &box,const std::string &input,const std::string &help)
748 void InterpreterVirtual::commandOutput(const std::string &name,const std::string &box,const std::string &output,const std::string &help)
752 void InterpreterVirtual::commandSet(const std::string &box,const std::string &input,const std::string &value)
756 void InterpreterVirtual::commandAuthor(const std::string &author)
760 void InterpreterVirtual::commandCategory(const std::string &categorytype)
766 void InterpreterVirtual::commandDescription(const std::string &description)
771 void InterpreterVirtual::commandClear()
775 void InterpreterVirtual::commandInclude(const std::string &word, bool ok)
780 void InterpreterVirtual::commandLoad(const std::string &packageName)
784 void InterpreterVirtual::commandUnload(const std::string &packageName)
788 void InterpreterVirtual::commandBreak()
792 void InterpreterVirtual::commandQuit()
796 void InterpreterVirtual::commandMessage()
800 void InterpreterVirtual::commandMessage(const std::string &kind,const std::string &levelstr)
806 //=======================================================================
807 void InterpreterVirtual::DoInterpretLine( const std::string& line )
810 bbtkDebugMessage("interpreter",6,"==> InterpreterVirtual::DoInterpretLine(\""
811 <<line<<"\")"<<std::endl);
812 std::vector<std::string> words;
813 SplitLine(line,words);
820 bbtkDebugDecTab("interpreter",9);
824 // Single line comment : # or //
825 if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') )
827 bbtkDebugDecTab("interpreter",9);
828 bbtkMessage("interpreter",9,"Comment"<<std::endl);
832 // Multi line comment ( /* ... */ ) -delimiters on different lines !-
834 if (words[0][0]=='/' && words[0][1]=='*')
836 bbtkDebugDecTab("interpreter",9);
837 bbtkMessage("interpreter",9,"In multiline comment"<<std::endl);
838 mInsideComment = true;
842 if (words[0][0]=='*' && words[0][1]=='/')
844 bbtkDebugDecTab("interpreter",9);
845 bbtkMessage("interpreter",9,"Out multiline comment"<<std::endl);
846 if ( !mInsideComment ) {
847 bbtkDebugDecTab("interpreter",9);
848 bbtkMessage("interpreter",9,"Comment mismatch : '*/' with no matching '/*'"<<std::endl);
850 mInsideComment = false;
856 bbtkDebugDecTab("interpreter",9);
857 bbtkMessage("interpreter",9,"Multiline Comment"<<std::endl);
863 CommandInfoType command;
864 InterpretCommand(words,command);
865 //std::cout<<"JCP bbtkInterpreter command.keyword ="<<command.keyword<<std::endl;
866 bbtkDebugMessage("interpreter",9,
867 "Command='"<<command.keyword
868 <<"' code="<<command.code<<std::endl);
870 std::string left,right,left2,right2;
871 std::string filename;
874 if (command.code==cMessage)
879 //EED Borrame mVirtualExecuter->HelpMessages();
883 commandMessage(words[1],words[2]);
884 //EED Borrame sscanf(words[2].c_str(),"%d",&level);
885 //EED Borrame mVirtualExecuter->SetMessageLevel(words[1],level);
891 bbtkMessage("echo",2,line<<std::endl);
894 // break and quit commands
895 if ((command.code==cBreak) || (command.code==cQuit))
897 bool in_script = false;
898 std::string file("");
901 if (mFileName.size())
903 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
904 if (fs!=0) in_script = true;
905 file = mFileName.back();
908 if (command.code==cBreak)
911 std::cout << "BreakException("
914 <<line<<")"<<std::endl;
917 //EED Borrame bbtkError("break");//,in_script,file,line);
918 // throw BreakException(in_script,file,line);
923 //EED Borrame bbtkError("quit");//,in_script,file,line);
924 //throw QuitException(in_script,file,line);
928 //std::cout<<" mVirtualExecuter->Create(words[1],words[2]); "<<line<<std::endl;
932 switch (command.code)
935 commandNew(words[1],words[2]);
936 //EED Borrame mVirtualExecuter->Create(words[1],words[2]);
940 commandDelete(words[1]);
941 //EED Borrame mVirtualExecuter->Destroy(words[1]);
945 Utilities::SplitAroundFirstDot(words[1],left,right);
946 Utilities::SplitAroundFirstDot(words[2],left2,right2);
947 commandConnection(left,right,left2,right2);
948 //EED Borrame mVirtualExecuter->Connect(left,right,left2,right2);
952 commandPackage(words[1]);
953 //EED Borrame mVirtualExecuter->BeginPackage(words[1]);
958 //EED Borrame mVirtualExecuter->EndPackage();
962 if (mFileName.size()>0)
964 //??? commandDefine(????);
965 filename = mFileName.back(); //mIncludeFileName.back(); //Utilities::get_file_name(mFileName.back());
969 std::string packTmp = "";
970 commandDefine(words[1],packTmp,filename);
971 //EED Borrame mVirtualExecuter->Define(words[1],"",filename);
975 commandDefine(words[1],words[2],filename);
976 //EED Borrame mVirtualExecuter->Define(words[1],words[2],filename);
982 //EED Borrame mVirtualExecuter->EndDefine();
986 commandKind(words[1]);
987 //EED Borrame mVirtualExecuter->Kind(words[1]);
991 commandPrint(words[1]);
992 //EED Borrame mVirtualExecuter->Print(words[1]);
996 commandExec(words[1]);
997 //EED Borrame if (words[1]=="freeze")
999 //EED Borrame mVirtualExecuter->SetNoExecMode(true);
1000 //EED Borrame mThrow = false;
1002 //EED Borrame else if (words[1]=="freeze_no_error")
1004 //EED Borrame mVirtualExecuter->SetNoExecMode(true);
1005 //EED Borrame mVirtualExecuter->SetNoErrorMode(true);
1006 //EED Borrame mThrow = false;
1008 //EED Borrame else if (words[1]=="unfreeze")
1010 //EED Borrame mVirtualExecuter->SetNoExecMode(false);
1011 //EED Borrame mVirtualExecuter->SetNoErrorMode(false);
1015 //EED Borrame mVirtualExecuter->Execute(words[1]);
1021 Utilities::SplitAroundFirstDot(words[2],left,right);
1022 commandInput(words[1],left,right,words[3]);
1023 //EED Borrame mVirtualExecuter->DefineInput(words[1],left,right,words[3]);
1027 Utilities::SplitAroundFirstDot(words[2],left,right);
1028 commandOutput(words[1],left,right,words[3]);
1029 //EED Borrame mVirtualExecuter->DefineOutput(words[1],left,right,words[3]);
1033 Utilities::SplitAroundFirstDot(words[1],left,right);
1034 commandSet(left,right,words[2]);
1035 //EED Borrame mVirtualExecuter->Set(left,right,words[2]);
1039 commandAuthor(words[1]);
1040 //EED Borrame mVirtualExecuter->Author(words[1]);
1044 commandNewGUI(words[1],words[2]);
1048 commandCategory(words[1]);
1049 //EED Borrame mVirtualExecuter->Category(words[1]);
1053 if (words.size()==1)
1054 commandIndex("tmp_index.html");
1055 else if (words.size()==2)
1056 commandIndex(words[1]);
1057 else if (words.size()==3)
1058 commandIndex(words[1],words[2]);
1062 commandDescription(words[1]);
1063 //EED Borrame mVirtualExecuter->Description(words[1]);
1072 commandGraph(words);
1085 //EED Borrame mVirtualExecuter->Clear();
1089 commandInclude( words[1] , (words.size()==3) );
1090 //EED Borrame // if 'source' was given (words.size()==3) then tell to set the
1091 //EED Borrame // source file name of the current complex box with the full file name included
1092 //EED Borrame if (mCommandLine)
1094 //EED Borrame InterpretFile(words[1],(words.size()==3));
1095 //EED Borrame } else{
1096 //EED Borrame SwitchToFile(words[1],(words.size()==3) );
1101 commandLoad( words[1] );
1102 //EED Borrame GetExecuter()->LoadPackage(words[1]);
1106 commandUnload( words[1] );
1107 //EED Borrame GetExecuter()->UnLoadPackage(words[1]);
1111 if (words.size()==2) commandDebug(words[1]);
1112 else commandDebug("");
1117 if (words.size() == 2)
1119 if (words[1]=="freeze") mVirtualExecuter->SetNoExecMode(true);
1120 else if (words[1]=="unfreeze") mVirtualExecuter->SetNoExecMode(false);
1124 mVirtualExecuter->SetWorkspaceName(words[2]);
1129 bbtkInternalError("should not reach here !!!");
1132 bbtkDebugMessage("interpreter",6,"<== InterpreterVirtual::DoInterpretLine(\""
1133 <<line<<"\")"<<std::endl);
1136 //=======================================================================
1142 //=======================================================================
1143 void InterpreterVirtual::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
1145 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::SplitLine(\""<<str<<"\")"<<std::endl);
1147 std::string delimiters = "\"";
1148 std::vector<std::string> quote;
1149 Utilities::SplitString(str,delimiters,quote);
1152 std::vector<std::string>::iterator i;
1153 for (i=quote.begin(); i!=quote.end(); )
1155 Utilities::SplitString(*i,delimiters,tokens);
1159 // bbtkDebugMessage("interpreter",0,"\""<<*i<<"\""<<std::endl);
1160 tokens.push_back(*i);
1165 for (i=tokens.begin(); i!=tokens.end(); ++i)
1167 bbtkDebugMessage("interpreter",9,"--["<<*i<<"]"<<std::endl);
1169 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::SplitLine(\""<<str<<"\")"<<std::endl);
1172 //=======================================================================
1175 //=======================================================================
1176 void InterpreterVirtual::commandReset()
1179 //=======================================================================
1181 //=======================================================================
1186 void InterpreterVirtual::Print( const std::string& str)
1188 if (mVirtualExecuter->GetNoExecMode()) return;
1190 bbtkDebugMessageInc("interpreter",9,"InterpreterVirtual::Print(\""<<str<<"\")"<<std::endl);
1193 // InterpretLine ("load std")
1194 // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande
1195 // InterpretLine("new Print _P_")
1196 // InterpretLine("connect _C_.Out _P_.In")
1200 std::vector<std::string> chains;
1201 std::string delimiters("$");
1203 // Skip delimiters at beginning.
1204 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
1205 bool is_text = true;
1206 if (lastPos>0) is_text = false;
1208 // Find first delimiter.
1209 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
1211 while (std::string::npos != pos || std::string::npos != lastPos)
1215 // Found a text token, add it to the vector.
1216 chains.push_back(str.substr(lastPos, pos - lastPos));
1217 // std::string token = str.substr(lastPos, pos - lastPos)
1218 // InterpretLine("set _C_.In%num% %token%")
1224 // is an output (between $$) : decode
1225 std::string tok,box,output;
1226 tok = str.substr(lastPos, pos - lastPos);
1227 Utilities::SplitAroundFirstDot(tok,box,output);
1228 chains.push_back( mVirtualExecuter->Get(box,output) );
1230 // InterpretLine("connect %tok% _C_.In%num%")
1233 // Skip delimiters. Note the "not_of"
1234 lastPos = str.find_first_not_of(delimiters, pos);
1235 // Find next delimiter
1236 pos = str.find_first_of(delimiters, lastPos);
1241 // InterpretLine("exec _P_")
1242 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
1244 std::vector<std::string>::iterator i;
1245 for (i= chains.begin(); i!=chains.end(); ++i)
1248 Utilities::SubsBackslashN(*i);
1251 std::cout << std::endl;
1252 bbtkDebugDecTab("interpreter",9);
1256 //=======================================================================
1261 // =========================================================================
1262 void InterpreterVirtual::SwitchToFile( const std::string& name , bool source )
1264 // Note : in the following :
1265 // name : the user supplied name
1266 // - abreviated name e.g. scr scr.bbs
1267 // - relative full name e.g. ./scr.bbs ../../scr.bbs
1268 // - absolute full name e.g. /home/usrname/proj/dir/scr.bbs
1269 // same for Windows, with c:, d: ...
1271 // use ./directory/subdir/scrname.bbs
1274 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::SwitchToFile( \""
1275 <<name<<"\")"<<std::endl);
1277 std::vector<std::string> script_paths;
1278 std::string fullPathScriptName; // full path script name
1279 std::string pkgname; // e.g. <scriptname>.bbs
1280 std::vector<std::string> Filenames;
1281 std::string tmpFilenames;
1283 // The following is *NOT* a debug time message :
1284 // It's a user intended message.
1285 // Please don't remove it.
1286 bbtkMessage("interpreter",1,
1287 "look for : [" << name
1288 << "]" << std::endl);
1292 pkgname = Utilities::ExtractScriptName(name,upath);
1294 bbtkMessage("interpreter",3,
1295 "package name:[" << pkgname
1296 << "] path:[" << upath << "]" << std::endl);
1297 bool fullnameGiven = false;
1298 bool foundFile = false;
1300 // ==== "*" provided : load all scripts in given path
1301 // relative (e.g. std/boxes/*) or absolute
1305 std::stringstream* stream = new std::stringstream;
1306 //if (upath.size()!=0) // avoid troubles for "*"
1308 // ==== no path provided : look in root bbs path
1309 if (upath.size()==0)
1311 // bbtkMessage("interpreter",1,
1312 // LG : add all bbs path
1313 // script_paths.push_back( ConfigurationFile::GetInstance().Get_root_bbs_path() );
1314 std::vector<std::string>::const_iterator i;
1315 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1316 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1319 script_paths.push_back(*i);
1322 // ==== absolute path provided
1323 else if (upath[0]=='/' || upath[1] == ':' )
1325 if ( Utilities::IsDirectory( upath ) )
1327 script_paths.push_back(upath);
1331 bbtkError("'"<<upath<<"' : directory does not exist");
1334 // ==== relative path provided : search all bbs path appended with
1335 // the relative path provided
1338 std::vector<std::string>::const_iterator i;
1339 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1340 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1343 std::string full_path(*i);
1344 printf("EED InterpreterVirtual::SwitchToFile 1. >>%s\n", full_path.c_str() );
1345 // we *really* want '.' to be the current working directory
1346 if (full_path == ".")
1348 char buf[2048]; // for getcwd
1349 char * currentDir = getcwd(buf, 2048);
1350 std::string cwd(currentDir);
1351 full_path = currentDir;
1354 full_path += ConfigurationFile::GetInstance().Get_file_separator();
1357 if ( Utilities::IsDirectory( full_path ) )
1359 script_paths.push_back(full_path);
1362 if (script_paths.empty())
1364 bbtkError("no '"<<upath<<"' subdir found in search paths"
1369 // === search paths list complete : now explore it
1371 // ==== relative name, iterate + load all .bbs/.bbp files
1372 std::vector<std::string>::iterator i;
1373 for (i=script_paths.begin();i!=script_paths.end();i++)
1376 printf("EED InterpreterVirtual::SwitchToFile jaja >> %s\n", (*i).c_str() );
1378 bbtkMessage("interpreter",1,
1379 "--> Looking in '" << *i << "'" << std::endl);
1383 Utilities::Explore(*i, false, Filenames);
1385 int iFilesnames,jFilesnames,sizeFilenames;
1386 sizeFilenames=Filenames.size();
1389 // EEDd 30 sept 2012
1390 //Sorting list of files
1391 for (iFilesnames=0;iFilesnames<sizeFilenames; iFilesnames++)
1393 for (jFilesnames=iFilesnames;jFilesnames<sizeFilenames; jFilesnames++)
1395 if ( Filenames[iFilesnames] > Filenames[jFilesnames] )
1397 tmpFilenames = Filenames[iFilesnames];
1398 Filenames[iFilesnames] = Filenames[jFilesnames];
1399 Filenames[jFilesnames] = tmpFilenames;
1401 } // for iFilesnames
1402 } // for iFilesnames
1406 for (std::vector<std::string>::iterator j = Filenames.begin();
1407 j!= Filenames.end(); ++j)
1410 printf("EED InterpreterVirtual::SwitchToFile kkkkk >> %s\n", (*j).c_str() );
1412 int lgr = (*j).size();
1413 if (lgr < 5) continue;
1414 // ignore non .bbp file
1415 if ( (*j).substr(lgr-4, 4) != ".bbp") continue;
1417 (*stream) << "include \"" << *j << "\"\n";
1418 bbtkMessage("interpreter",2," --> Found '" << *j << "'" << std::endl);
1421 } // for (std::vector...
1422 } // for (i=script_...
1427 bbtkMessage("interpreter",1,
1428 " --> No .bbp found"<< std::endl);
1432 bbtkMessage("interpreter",1,
1433 " --> "<<nbBssFiles<<" .bbp found"<< std::endl);
1434 SwitchToStream(stream);
1438 //=============== end pkgname=="*" ===========
1441 // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name
1442 // (not only a plain script name)
1443 // we trust him, and try to expland the directory name
1444 // WARNING : starting from current local directory : ./whatYouWant (./ mandatory!)
1446 if (name[0]=='/' || name[1] == ':' || name[0]=='.') // absolute path (linux/windows) or relative path
1449 // ===========================================================check user supplied location
1450 fullnameGiven = true;
1452 fullPathScriptName = Utilities::ExpandLibName(name, false);
1454 // allow user to always forget ".bbs"
1455 int l = fullPathScriptName.size();
1459 if ((fullPathScriptName.substr(l-4, 4) != ".bbs")&&
1460 (fullPathScriptName.substr(l-4, 4) != ".bbp"))
1462 std::string tfullPathScriptName = fullPathScriptName + ".bbs";
1463 if ( Utilities::FileExists(tfullPathScriptName) )
1465 fullPathScriptName = tfullPathScriptName;
1470 tfullPathScriptName = fullPathScriptName + ".bbp";
1471 if ( Utilities::FileExists(tfullPathScriptName) )
1473 fullPathScriptName = tfullPathScriptName;
1480 if ( Utilities::FileExists(fullPathScriptName) )
1488 // =============================== iterate on the paths
1490 script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
1492 std::vector<std::string>::iterator i;
1493 for (i=script_paths.begin();i!=script_paths.end();++i)
1496 // we *really* want '.' to be the current working directory
1499 char buf[2048]; // for getcwd
1500 char * currentDir = getcwd(buf, 2048);
1501 std::string cwd(currentDir);
1505 std::string tfullPathScriptName = Utilities::MakePkgnameFromPath(path, name, false);
1507 //Addition JCP tfullPathScriptName.size()>=4
1508 if(tfullPathScriptName.size()>=4){
1509 if (tfullPathScriptName.substr(tfullPathScriptName.size()-4, 3)==".bb")
1511 fullPathScriptName = tfullPathScriptName;
1512 if ( ! Utilities::FileExists(fullPathScriptName) )
1514 // The following is *NOT* a debug time message :
1515 // It's a user intended message.
1516 // Please don't remove it.
1517 bbtkMessage("interpreter",2,
1518 " [" <<fullPathScriptName <<"] : does not exist"
1520 continue; // try next path
1522 bbtkMessage("interpreter",2,
1523 " [" <<fullPathScriptName
1524 <<"] : found" <<std::endl);
1526 break; // a script was found; we stop iterating
1530 fullPathScriptName = tfullPathScriptName + ".bbs";
1531 // Check if library exists
1532 if ( ! Utilities::FileExists(fullPathScriptName) )
1534 fullPathScriptName = tfullPathScriptName + ".bbp";
1535 if ( ! Utilities::FileExists(fullPathScriptName) )
1537 // The following is *NOT* a debug time message :
1538 // It's a user intended message.
1539 // Please don't remove it.
1540 bbtkMessage("interpreter",2,
1541 " [" <<tfullPathScriptName <<".bbs/.bbp] : do not exist"
1543 continue; // try next path
1546 bbtkMessage("interpreter",2,
1547 " [" <<fullPathScriptName
1548 <<"] : found" <<std::endl);
1550 break; // a script was found; we stop iterating
1553 } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
1559 if(fullPathScriptName == "")
1560 bbtkError("Path ["<<upath<<"] doesn't exist");
1562 bbtkError("Script ["<<fullPathScriptName<<"] not found");
1564 bbtkError("No ["<<pkgname<<".bbs/.bbp] script found");
1567 //EED printf("EED D. SwitchToFile %s\n", fullPathScriptName.c_str() );
1568 LoadScript(fullPathScriptName,name);
1569 //EED Borrame if (source) GetExecuter()->SetCurrentFileName(fullPathScriptName);
1572 // Over writing the fullpath of the bbp file.
1573 SetCurrentFileName( fullPathScriptName );
1574 SetTypeOfScript_Application();
1580 //=======================================================================
1582 //=======================================================================
1583 void InterpreterVirtual::SetCurrentFileName(const std::string &fullPathScriptName) // virtual
1586 //=======================================================================
1589 //=======================================================================
1590 void InterpreterVirtual::SetTypeOfScript_Application( )
1593 //=======================================================================
1596 //=======================================================================
1597 void InterpreterVirtual::SwitchToStream( std::stringstream* stream )
1599 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::SwitchToStream()"
1601 mFile.push_back(stream);
1602 std::ostringstream buffer_name;
1604 buffer_name << "buffer_" ;
1606 if (mFileName.size()>0 )
1608 buffer_name << mFileName.back() << "_" << mLine.back();
1610 mFileName.push_back(buffer_name.str());
1611 mIncludeFileName.push_back(buffer_name.str());
1614 //=======================================================================
1616 //=======================================================================
1618 void InterpreterVirtual::LoadScript( std::string fullPathScriptName,
1619 std::string includeScriptName)
1621 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::LoadScript("
1622 <<fullPathScriptName<<")"
1625 Utilities::replace( fullPathScriptName ,
1626 INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
1628 if (find(mFileNameHistory.begin(),
1629 mFileNameHistory.end(),
1630 fullPathScriptName)!=mFileNameHistory.end())
1636 s = new std::ifstream;
1637 s->open(fullPathScriptName.c_str());
1640 bbtkError("Could not open file ["<<fullPathScriptName<<"]");
1644 bbtkMessage("interpreter",1," -->[" << fullPathScriptName
1645 << "] found" << std::endl);
1648 mFileName.push_back(fullPathScriptName);
1649 mFileNameHistory.push_back(fullPathScriptName);
1650 mIncludeFileName.push_back(includeScriptName);
1655 //=======================================================================
1657 //=======================================================================
1658 void InterpreterVirtual::CloseCurrentFile()
1660 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::CloseCurrentFile()"
1663 if (mFile.size()==0)
1665 bbtkDebugMessage("interpreter",9," -> no file left open"<<std::endl);
1669 bbtkDebugMessage("interpreter",9," Closing file '"<<mFileName.back()<<"'"<<std::endl);
1671 std::ifstream* file = dynamic_cast<std::ifstream*>(mFile.back());
1672 if (file!=0) file->close();
1674 delete mFile.back();
1676 mFileName.pop_back();
1677 mIncludeFileName.pop_back();
1680 bbtkDebugMessage("interpreter",9," Remains "
1682 <<" open"<<std::endl);
1683 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::CloseCurrentFile()"
1686 //=======================================================================
1688 //=======================================================================
1689 void InterpreterVirtual::CloseAllFiles()
1691 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::CloseAllFiles()"
1694 while (mFile.size() != 0)
1698 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::CloseAllFiles()"
1701 //=======================================================================
1705 //=======================================================================
1706 void InterpreterVirtual::InterpretCommand( const std::vector<std::string>& words,
1707 CommandInfoType& info )
1710 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::InterpretCommand(...)"<<std::endl);
1712 // searches the command keyword
1713 CommandDictType::iterator c;
1714 c = mCommandDict.find(words[0]);
1715 if ( c == mCommandDict.end() ) {
1716 bbtkError(words[0]<<" : unknown command");
1719 // tests the number of args
1720 if ( ( ((int)words.size())-1 < c->second.argmin ) ||
1721 ( ((int)words.size())-1 > c->second.argmax ) )
1724 //EED HelpCommand(words[0]);
1725 commandHelp(words[0]);
1726 bbtkError(words[0]<<" : wrong number of arguments");
1728 //std::cout<<"InterpreterVirtual::InterpretCommand( const std::vector<std::string>& words,"<<std::endl;
1730 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::InterpretCommand(...)"<<std::endl);
1733 //=======================================================================
1736 //=======================================================================
1737 /// Displays help on all the commands
1738 void InterpreterVirtual::commandHelp(const std::vector<std::string>& words)
1741 //=======================================================================
1742 void InterpreterVirtual::commandHelp(const std::string &words)
1745 //=======================================================================
1747 //===================================================================
1748 /// Displays the Configuration
1749 void InterpreterVirtual::commandConfig() const
1752 //===================================================================
1756 //=======================================================================
1757 /// Fills the vector commands with the commands which
1758 /// have the first n chars of buf for prefix
1759 /// TODO : skip initial spaces in buf and also return the position of first
1760 /// non blank char in buf
1761 void InterpreterVirtual::FindCommandsWithPrefix( char* buf,
1763 std::vector<std::string>& commands )
1765 CommandDictType::const_iterator i;
1766 for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
1768 if ((i->first).find(buf,0,n) == 0)
1769 commands.push_back(i->first);
1772 //=======================================================================
1776 //=======================================================================
1777 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1779 inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
1780 inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
1782 // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
1783 // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
1784 // E.G. STORE THIS IN bbtk_config.xml
1785 #define BBTK_UP_ARROW_KBCODE 0x00415B1B
1786 #define BBTK_DOWN_ARROW_KBCODE 0x00425B1B
1787 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
1788 #define BBTK_LEFT_ARROW_KBCODE 0x00445B1B
1789 #define BBTK_BACKSPACE_KBCODE 0x00000008
1790 #define BBTK_DEL_KBCODE 0x0000007F
1791 #define BBTK_SPACE_KBCODE 0x00000020
1793 //=======================================================================
1794 void InterpreterVirtual::GetLineFromPrompt(std::string& s)
1799 unsigned int MAX_LINE_SIZE = 160;
1800 unsigned int MAX_HISTORY_SIZE = 100;
1802 char* newline = new char[MAX_LINE_SIZE];
1803 memset(newline,0,MAX_LINE_SIZE);
1804 char* histline = new char[MAX_LINE_SIZE];
1805 memset(histline,0,MAX_LINE_SIZE);
1807 char* line = newline;
1808 unsigned int hist = mHistory.size();
1814 read ( STDIN_FILENO, &c, 4) ;
1816 bbtkDebugMessage("debug",9,"[0x"<<std::hex<<c<<"]\n");
1818 // Printable character
1819 if ( (ind<MAX_LINE_SIZE-1) &&
1820 ( c >= BBTK_SPACE_KBCODE ) &&
1821 ( c < BBTK_DEL_KBCODE ))
1829 // delete the unused line
1835 // empty lines are not stored in from history
1838 // if history too long : delete oldest command
1839 if (mHistory.size()>MAX_HISTORY_SIZE)
1841 delete mHistory.front();
1842 mHistory.pop_front();
1844 mHistory.push_back(line);
1849 else if ( (ind>0) &&
1850 ((c == BBTK_BACKSPACE_KBCODE) ||
1851 (c == BBTK_DEL_KBCODE)) )
1859 // TODO : Command completion
1860 std::vector<std::string> commands;
1861 FindCommandsWithPrefix( line,ind,commands);
1862 if (commands.size()==1)
1864 std::string com = *commands.begin();
1865 for (; ind<com.size(); ++ind)
1867 PrintChar(com[ind]);
1873 else if (commands.size()>1)
1875 std::vector<std::string>::iterator i;
1877 for (i=commands.begin();i!=commands.end();++i)
1879 write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
1882 write(STDOUT_FILENO,"\n> ",3);
1883 //for (int j=0;j<ind;++j)
1885 write(STDOUT_FILENO,line,ind);
1889 // Arrow up : back in history
1890 else if (c==BBTK_UP_ARROW_KBCODE)
1894 // erase current line
1895 while (ind--) BackSpace();
1899 strcpy(histline,mHistory[hist]);
1903 write(STDOUT_FILENO,line,ind);
1906 // Arrow down : down in history
1907 else if (c==BBTK_DOWN_ARROW_KBCODE)
1909 if (hist<mHistory.size()-1)
1911 // erase current line
1912 while (ind--) BackSpace();
1916 strcpy(histline,mHistory[hist]);
1920 write(STDOUT_FILENO,line,ind);
1922 // end of history : switch back to newline
1923 else if (hist==mHistory.size()-1)
1925 // erase current line
1926 while (ind--) BackSpace();
1933 write(STDOUT_FILENO,line,ind);
1937 else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
1939 PrintChar(line[ind]);
1944 else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
1952 write(STDOUT_FILENO,"\n\r",2);
1960 //=======================================================================
1961 void InterpreterVirtual::GetLineFromPrompt(std::string& s)
1987 //=======================================================================
1993 //=======================================================================
1994 void InterpreterVirtual::CommandLineInterpreter()
1996 bbtkDebugMessageInc("interpreter",9,
1997 "InterpreterVirtual::CommandLineInterpreter()"<<std::endl);
1999 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
2000 // Initialise the tty in non canonical mode with no echo
2001 // oter remembers the previous settings to restore them after
2002 struct termios ter,oter;
2005 ter.c_lflag &= ~ECHO;
2006 ter.c_lflag &= ~ICANON;
2009 tcsetattr(0,TCSANOW,&ter);
2012 mCommandLine = true;
2014 // bool insideComment = false; // for multiline comment
2015 mInsideComment = false;
2021 GetLineFromPrompt(line);
2022 DoInterpretLine(line); //, insideComment);
2025 catch (QuitException e)
2027 bbtkMessage("interpreter",1,"Interpreter : Quit"<<std::endl);
2031 catch (bbtk::Exception e)
2035 catch (std::exception& e)
2037 std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
2041 std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
2046 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
2047 tcsetattr(0,TCSANOW,&oter);
2050 std::cout << "Good bye !" << std::endl;
2052 bbtkDebugDecTab("interpreter",9);
2055 //=======================================================================
2056 void InterpreterVirtual::commandGraph(const std::vector<std::string>& words)
2059 //=======================================================================
2062 //=======================================================================
2063 void InterpreterVirtual::commandIndex(const std::string& filename, const std::string& type)
2066 //=======================================================================
2069 //=======================================================================
2070 void InterpreterVirtual::commandNewGUI(const std::string& boxname,const std::string& instanceName)
2073 //=======================================================================
2077 //==========================================================================
2078 void InterpreterVirtual::commandDebug(const std::string& name)
2081 //==========================================================================
2084 //==========================================================================
2085 // Adds a callback when 'break' command issued
2086 void InterpreterVirtual::AddBreakObserver( BreakCallbackType c )
2088 mBreakSignal.connect(c);
2090 //==========================================================================
2093 //==========================================================================
2094 std::string InterpreterVirtual::GetObjectName() const
2096 return std::string("InterpreterVirtual");
2098 //==========================================================================
2100 //==========================================================================
2101 std::string InterpreterVirtual::GetObjectInfo() const
2103 std::stringstream i;
2106 //==========================================================================
2108 //==========================================================================
2109 size_t InterpreterVirtual::GetObjectSize() const
2111 size_t s = Superclass::GetObjectSize();
2112 s += InterpreterVirtual::GetObjectInternalSize();
2115 //==========================================================================
2116 //==========================================================================
2117 size_t InterpreterVirtual::GetObjectInternalSize() const
2119 size_t s = sizeof(InterpreterVirtual);
2122 //==========================================================================
2123 //==========================================================================
2124 size_t InterpreterVirtual::GetObjectRecursiveSize() const
2126 size_t s = Superclass::GetObjectRecursiveSize();
2127 s += InterpreterVirtual::GetObjectInternalSize();
2130 //==========================================================================