1 /*=========================================================================
3 Module: $RCSfile: bbtkInterpreter.cxx,v $
5 Date: $Date: 2010/09/14 07:18:46 $
6 Version: $Revision: 1.88 $
7 =========================================================================*/
9 /* ---------------------------------------------------------------------
11 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
12 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
14 * This software is governed by the CeCILL-B license under French law and
15 * abiding by the rules of distribution of free software. You can use,
16 * modify and/ or redistribute the software under the terms of the CeCILL-B
17 * license as circulated by CEA, CNRS and INRIA at the following URL
18 * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
19 * or in the file LICENSE.txt.
21 * As a counterpart to the access to the source code and rights to copy,
22 * modify and redistribute granted by the license, users are provided only
23 * with a limited warranty and the software's author, the holder of the
24 * economic rights, and the successive licensors have only limited
27 * The fact that you are presently reading this means that you have had
28 * knowledge of the CeCILL-B license and that you accept its terms.
29 * ------------------------------------------------------------------------ */
33 * \brief class Interpreter :
36 #include "bbtkInterpreterVirtual.h"
37 //#include "bbtkTranscriptor.h"
38 #include "bbtkConfigurationFile.h"
39 #include "bbtkUtilities.h"
40 //#include "bbtkAtomicBlackBox.h"
41 //#include "bbtkWxBlackBox.h"
44 #ifdef CMAKE_HAVE_TERMIOS_H
46 #define BBTK_USE_TERMIOS_BASED_PROMPT
54 //=======================================================================
55 InterpreterVirtual::Pointer InterpreterVirtual::New()
57 bbtkDebugMessage("kernel",9,"InterpreterVirtual::New()"<<std::endl);
58 return MakePointer( new InterpreterVirtual() );
60 //=======================================================================
62 //=======================================================================
63 InterpreterVirtual::InterpreterVirtual()
67 //=======================================================================
70 //=======================================================================
71 void InterpreterVirtual::Init()
77 bbtk::MessageManager::RegisterMessageType("echo","Level>0 : Prints the output of the 'print' commands of the user.\n\tLevel>1 : Prints the command being interpreted",1);
78 bbtk::MessageManager::RegisterMessageType("Interpreter","Messages of the interpreter",0);
79 bbtkDebugMessageInc("Interpreter",9,"InterpreterVirtual::Interpreter()" <<std::endl);
81 // For the time being, comment out previous line, and
82 // uncomment next line to check Transcriptor
84 //mVirtualExecuter = new bbtk::Transcriptor("GeneratedProgram.txt");
86 // Builds the commands dict
93 info.syntax = "new <type> <name>";
94 info.help = "Creates a new black box of type <type> with name <name>";
95 mCommandDict[info.keyword] = info;
97 info.keyword = "delete";
101 info.syntax = "delete <box>";
102 info.help = "Deletes the black box of name <box>";
103 mCommandDict[info.keyword] = info;
105 info.keyword = "clear";
109 info.syntax = "clear";
110 info.help = "Clears the currently defined complex box (deletes all its boxes and connections)";
111 mCommandDict[info.keyword] = info;
113 info.keyword = "break";
117 info.syntax = "break";
118 info.help = "Breaks the current execution";
119 mCommandDict[info.keyword] = info;
121 info.keyword = "newgui";
125 info.syntax = "newgui <box> <name>";
126 info.help = "Automatically creates a graphical user interface with name <name> for the black box <box> and connects it to the box inputs";
127 mCommandDict[info.keyword] = info;
129 info.keyword = "connect";
132 info.code = cConnect;
133 info.syntax = "connect <box1.output> <box2.input>";
134 info.help = "Connects the ouput <output> of black box <box1> to the input <input> of black box <box2>";
135 mCommandDict[info.keyword] = info;
137 info.keyword = "print";
141 info.syntax = "print <string>";
142 info.help = "Prints the string. Substitutes any token of the form '$box.output$' by the string adaptation of the output of the box (requires the right adaptor). No carriage return is issued at the end, use '\\n' to add carriage returns. The level of 'echo' messages must be greater than 1 (see the command 'message').";
143 mCommandDict[info.keyword] = info;
145 info.keyword = "exec";
149 info.syntax = "exec <box | 'freeze' | 'unfreeze' | 'freeze_no_error' >";
150 info.help = "Executes the black box of name <box> (and connected boxes if needed). If the special keyword 'freeze' is given then freezes any further execution command. 'unfreeze' reverts to normal execution mode. 'freeze_no_error' is like freeze but also skips any error.";
151 mCommandDict[info.keyword] = info;
153 info.keyword = "package";
156 info.code = cPackage;
157 info.syntax = "package <name>";
158 info.help = "Begins the definition of a package.";
159 mCommandDict[info.keyword] = info;
161 info.keyword = "endpackage";
164 info.code = cEndPackage;
165 info.syntax = "endpackage";
166 info.help = "Ends the definition of a package.";
167 mCommandDict[info.keyword] = info;
169 info.keyword = "define";
173 info.syntax = "define <type> [<package>]";
174 info.help = "Begins the definition of a new type of complex black box called <type>. If <package> is provided will create it in the given package.";
175 mCommandDict[info.keyword] = info;
177 info.keyword = "endefine";
180 info.code = cEndDefine;
181 info.syntax = "endefine";
182 info.help = "Ends the definition of a new type of complex black box";
183 mCommandDict[info.keyword] = info;
185 info.keyword = "kind";
189 info.syntax = "kind <ADAPTOR|DEFAULT_ADAPTOR|GUI|DEFAULT_GUI>";
190 info.help = "Sets the kind of the currently defined complex black box";
191 mCommandDict[info.keyword] = info;
193 info.keyword = "input";
197 info.syntax = "input <name> <box.input> <help>";
198 info.help = "Defines the input <name> of the current working black box as being an alias for the input <input> of the black box <box>. <help> defines the help string for the newly created input";
199 mCommandDict[info.keyword] = info;
201 info.keyword = "output";
205 info.syntax = "output <name> <box.output> <help>";
206 info.help = "Defines the output <name> of the current working black box as being an alias for the output <output> of the black box <box>. <help> defines the help string for the newly created output";
207 mCommandDict[info.keyword] = info;
209 info.keyword = "set";
213 info.syntax = "set <box.input> <value>";
214 info.help = "Sets the value of the input <input> of the black box <box> to <value>. There must exist a string to the value type adaptor";
215 mCommandDict[info.keyword] = info;
217 info.keyword = "config"; // JPR
221 info.syntax = "config";
222 info.help = "Prints the value of all configuration parameters";
223 mCommandDict[info.keyword] = info;
225 info.keyword = "index"; // LG
230 info.syntax = "index [<filename> ['Initials'(default)|'Packages'|'Categories'|'Adaptors']]";
231 info.help = "Creates an html index of known boxes. If filename is provided then save it to the file 'filename'. The default index entries are the initial letters of the names of the boxes. If 'Packages' or 'Categories' is provided then the entries are either the packages names or the categories. If 'Adaptors' is provided then an alphabetical index of all adaptors is created.";
232 mCommandDict[info.keyword] = info;
234 info.keyword = "reset";
238 info.syntax = "reset";
239 info.help = "Deletes all boxes and unloads all packages (reset to start state)";
240 mCommandDict[info.keyword] = info;
242 info.keyword = "author";
246 info.syntax = "author <string>";
247 info.help = "Adds the string <string> to the author information of the black box being defined";
248 mCommandDict[info.keyword] = info;
250 info.keyword = "category"; //JP
253 info.code = cCategory;
254 info.syntax = "category <list of items, separated by ;>";
255 info.help = "Adds the string <string> to the category information of the black box being defined";
256 mCommandDict[info.keyword] = info;
258 info.keyword = "description";
261 info.code = cDescription;
262 info.syntax = "description <string>";
263 info.help = "Adds the string <string> to the descriptive information of the black box being defined";
264 mCommandDict[info.keyword] = info;
266 info.keyword = "help";
270 info.syntax = "help";
271 info.syntax = "\n (1) help \n (2) help <command name> \n (3) help packages [all]\n (4) help <package name> [all]\n (5) help <black box type> \n (6) help <black box name>";
272 info.help = "Effect :\n (1) Lists all available commands;\n (2) Prints help on a particular command; \n (3) Lists the packages loaded and their black boxes.\n Add 'all' to list adaptors; \n (4) Prints short help on the black boxes of a package.\n Add 'all' to include adaptors; \n (5) Prints full help on a black box type; \n (6) Prints information on the inputs, outputs and connections of a black box instance.";
273 mCommandDict[info.keyword] = info;
275 info.keyword = "message";
278 info.code = cMessage;
279 info.syntax = "message <kind> <level>";
280 info.help = "Sets the level of the kind of messages <kind> to <level>.\n If kind='All' then sets the level for all kinds. If no kind nor level is passed then prints info on available kinds of messages and their current level.";
281 mCommandDict[info.keyword] = info;
283 info.keyword = "include";
286 info.code = cInclude;
287 info.syntax = "include <filename> [source]";
288 info.help = "Includes the file <filename>.\n 'source' : If the keyword 'source' is provided then informs the interpreter that the included file is the source of the current box definition (Advanced; used to get the right 'Include' field in html doc of packages 'appli' scripts).";
289 mCommandDict[info.keyword] = info;
291 info.keyword = "quit";
295 info.syntax = "quit";
296 info.help = "Quits the program (during script execution it stops the complete execution)";
297 mCommandDict[info.keyword] = info;
299 info.keyword = "load";
303 info.syntax = "load <packagename>";
304 info.help = "Loads the black box package <packagename>";
305 mCommandDict[info.keyword] = info;
307 info.keyword = "unload";
311 info.syntax = "unload <packagename>";
312 info.help = "Unloads the black box package <packagename>";
313 mCommandDict[info.keyword] = info;
315 info.keyword = "graph";
319 info.syntax = "graph [ BlackBoxName [ Detail 0..1 [ Level 0..99999 [ Output html file [ Custom header [ Custom title ]]]]]] \n graph [ BlackBoxNameType [ Detail 0..1 [ Level 0..99999 [ Output html file [ Custom header [ Custom title ]]]]]]";
320 info.help = "Shows a graphical view of a bbtk pipeline.\n- BlackBoxName : name of the box to view. Default '.' : current box.\n- BlackBoxNameType : name of the type of box to view, ex : 'workspace')";
321 mCommandDict[info.keyword] = info;
323 info.keyword = "debug";
327 info.syntax = "debug [expr|-C|-D]";
328 info.help = "Prints debug info on living bbtk objects containing the string 'expr' (default expr=''). -C checks the factory integrity. -D turns on objects debug info after main ends";
329 mCommandDict[info.keyword] = info;
332 info.keyword = "workspace";
335 info.code = cWorkspace;
336 info.syntax = "workspace < ( freeze | unfreeze ) | ( rename <newname> ) >";
337 info.help = "Configures the workspace.\n 'freeze' allows to block execution commands while keeping definition commands active. 'unfreeze' turns back the worspace in 'normal' mode.\n 'rename' allow to set a new name to the workspace.";
338 mCommandDict[info.keyword] = info;
344 //=======================================================================
348 //=======================================================================
352 InterpreterVirtual::~InterpreterVirtual()
354 bbtkDebugMessage("object",2,"==> ~Interpreter()" <<std::endl);
356 //=======================================================================
359 //=======================================================================
360 InterpreterException::InterpreterException( const std::string& message,
362 const std::string& script_file,
365 : Exception("interpreter",0,message),
366 mInScriptFile(in_script_file),
367 mScriptFile(script_file),
368 mScriptLine(script_line)
371 //=======================================================================
372 //=======================================================================
373 InterpreterException::InterpreterException( const Exception& excep,
375 const std::string& script_file,
379 mInScriptFile(in_script_file),
380 mScriptFile(script_file),
381 mScriptLine(script_line)
384 //=======================================================================
387 //=======================================================================
388 void InterpreterVirtual::CatchInterpreterException( const InterpreterException& e )
390 //EED Borrame if (GetExecuter()->GetNoErrorMode())
392 //EED Borrame bbtkWarning("ERROR :"<<e.GetErrorMessage()
393 //EED Borrame <<" ("<<e.GetScriptFile()<<":"<<e.GetScriptLine()
394 //EED Borrame <<" skipped");
395 //EED Borrame return;
399 if (e.GetErrorMessage()!="break")
401 mStatus = Interpreter_ERROR;
404 throw InterpreterException(e);
406 std::stringstream mess;
407 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
408 if (e.IsInScriptFile())
410 mess << "* FILE : \""<<e.GetScriptFile()<<"\""<<std::endl;
411 mess << "* LINE : "<<e.GetScriptLine()<<std::endl;
414 std::cerr << mess.str();
417 //=======================================================================
419 //=======================================================================
420 void InterpreterVirtual::CatchBbtkException( const bbtk::Exception& e )
422 //EED Borrame if (GetExecuter()->GetNoErrorMode())
424 //EED Borrame std::string file("?");
425 //EED Borrame int line = 0;
426 //EED Borrame if (mFileName.size()) {
427 //EED Borrame file = mFileName.back();
428 //EED Borrame line = mLine.back();
430 //EED Borrame bbtkWarning("ERROR '"<<e.GetErrorMessage()
431 //EED Borrame <<"' ("<<file<<":"<<line<<") skipped");
432 //EED Borrame return;
435 mStatus = Interpreter_ERROR;
438 bool in_script = false;
439 std::string file("");
441 if (mFileName.size())
443 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
444 if (fs!=0) in_script = true;
445 file = mFileName.back();
448 if (e.GetErrorMessage()!="break")
450 throw InterpreterException(e,in_script,file,line);
452 std::stringstream mess;
453 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
454 if (mFileName.size())
456 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
457 mess << "* LINE : "<<mLine.back()<<std::endl;
460 std::cerr << mess.str();
463 //=======================================================================
465 //=======================================================================
466 void InterpreterVirtual::CatchStdException( const std::exception& e )
468 //EED Borrame if (GetExecuter()->GetNoErrorMode())
470 //EED Borrame std::string file("?");
471 //EED Borrame int line = 0;
472 //EED Borrame if (mFileName.size()) {
473 //EED Borrame file = mFileName.back();
474 //EED Borrame line = mLine.back();
476 //EED Borrame bbtkWarning("ERROR '"<<e.what()
477 //EED Borrame <<"' ("<<file<<":"<<line<<") skipped");
478 //EED Borrame return;
481 mStatus = Interpreter_ERROR;
484 bool in_script = false;
485 std::string file("");
487 if (mFileName.size()) {
488 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
489 if (fs!=0) in_script = true;
490 file = mFileName.back();
494 throw InterpreterException(e.what(),in_script,file,line);
496 std::stringstream mess;
497 mess << "* ERROR : "<<e.what()<<std::endl;
498 if (mFileName.size())
500 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
501 mess << "* LINE : "<<mLine.back()<<std::endl;
504 std::cerr << mess.str();
508 //=======================================================================
510 //=======================================================================
511 void InterpreterVirtual::CatchUnknownException()
513 //EED Borrame if (GetExecuter()->GetNoErrorMode())
515 //EED Borrame std::string file("?");
516 //EED Borrame int line = 0;
517 //EED Borrame if (mFileName.size()) {
518 //EED Borrame file = mFileName.back();
519 //EED Borrame line = mLine.back();
521 //EED Borrame bbtkWarning("UNDEFINED ERROR "
522 //EED Borrame <<"("<<file<<":"<<line<<") skipped");
523 //EED Borrame return;
525 mStatus = Interpreter_ERROR;
528 bool in_script = false;
529 std::string file("");
531 if (mFileName.size()) {
532 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
533 if (fs!=0) in_script = true;
534 file = mFileName.back();
538 throw InterpreterException("Unknown exception caught",
539 in_script,file,line);
543 std::stringstream mess;
544 mess << "* UNDEFINED ERROR (not a bbtk nor a std exception)"
546 if (mFileName.size()) {
547 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
548 mess << "* LINE : "<<mLine.back()<<std::endl;
551 std::cerr << mess.str();
554 //=======================================================================
556 //=======================================================================
558 #define CATCH_MACRO \
559 catch (InterpreterException e) \
561 CatchInterpreterException(e); \
563 catch (bbtk::Exception e) \
565 CatchBbtkException(e); \
567 catch (std::exception& e) \
569 CatchStdException(e); \
573 CatchUnknownException(); \
575 //=======================================================================
578 //=======================================================================
579 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretFile( const std::string& filename, bool source )
582 printf("EED InterpreterVirtual::InterpretFile 1\n");
583 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::InterpretFile(\""<<filename<<"\")"<<std::endl);
585 bool exm = mCommandLine;
586 mCommandLine = false;
590 mStatus = Interpreter_OK;
591 SwitchToFile(filename,source);
592 mInsideComment = false;
593 InterpretCurrentStreams();
597 bbtkDebugMessage("interpreter",4,
598 "<== InterpreterVirtual::InterpretFile(\""
599 <<filename<<"\")"<<std::endl);
604 printf("EED InterpreterVirtual::InterpretFile 2\n");
608 //=======================================================================
611 //=======================================================================
612 InterpreterVirtual::ExitStatus
613 InterpreterVirtual::InterpretBuffer( std::stringstream* buffer )
615 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::InterpretBuffer()"<<std::endl);
617 bool exm = mCommandLine;
618 mCommandLine = false;
622 mStatus = Interpreter_OK;
623 SwitchToStream(buffer);
624 mInsideComment = false;
625 InterpretCurrentStreams();
630 bbtkDebugMessage("interpreter",4,"<== InterpreterVirtual::InterpretBuffer()"<<std::endl);
636 //=======================================================================
638 //=======================================================================
639 /// Interprets the currently open streams
640 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretCurrentStreams()
642 bbtkDebugMessage("interpreter",4,
643 "==> InterpreterVirtual::InterpretCurrentStreams()"<<std::endl);
645 while (mFile.size()>0)
647 while (!mFile.back()->eof()) {
650 mFile.back()->getline(buf,500);
651 std::string str(buf);
652 //size 0 JCP 21-09-2009
653 int size=str.length();
655 if ( str[ size-1 ]==13 )
661 DoInterpretLine(str);
669 bbtkDebugMessage("interpreter",4,
670 "<== InterpreterVirtual::InterpretCurrentStreams()"<<std::endl);
674 //=======================================================================
676 //=======================================================================
677 /// Runs the interpretation of a command
678 InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretLine( const std::string& line )
680 bbtkDebugMessage("interpreter",5,"==> InterpreterVirtual::InterpretLine('"<<line<<"')"<<std::endl);
684 mStatus = Interpreter_OK;
685 mInsideComment = false;
686 //std::cout<<"JCP bbtkInterpreter.cxx InterpreterVirtual::InterpretLine("<<std::endl;
687 DoInterpretLine(line );
692 bbtkDebugMessage("interpreter",5,"<== InterpreterVirtual::InterpretLine('"<<line<<"')"<<std::endl);
696 //=======================================================================
698 void InterpreterVirtual::commandNew(std::string boxType, std::string boxName) // virtual
700 printf("EED %p InterpreterVirtual::commandNew 1 %s %s\n", this, boxType.c_str(),boxName.c_str() );
703 void InterpreterVirtual::commandDelete(std::string boxName)
707 void InterpreterVirtual::commandConnection(std::string nodeFrom, std::string outputLabel, std::string nodeTo, std::string inputLabel)
711 void InterpreterVirtual::commandPackage(std::string packageName)
715 void InterpreterVirtual::commandEndPackage()
719 void InterpreterVirtual::commandDefine(std::string name, std::string pack, std::string scriptfilename)
723 void InterpreterVirtual::commandEndDefine()
727 void InterpreterVirtual::commandKind(std::string kind)
731 void InterpreterVirtual::commandPrint(std::string value)
736 void InterpreterVirtual::commandExec(std::string word)
741 void InterpreterVirtual::commandInput(std::string name, std::string box, std::string input,std::string help)
745 void InterpreterVirtual::commandOutput(std::string name, std::string box, std::string output,std::string help)
749 void InterpreterVirtual::commandSet(std::string box, std::string input, std::string value)
753 void InterpreterVirtual::commandAuthor(std::string author)
757 void InterpreterVirtual::commandCategory(std::string categorytype)
763 void InterpreterVirtual::commandDescription(std::string description)
768 void InterpreterVirtual::commandClear()
772 void InterpreterVirtual::commandInclude(std::string word, bool ok)
777 void InterpreterVirtual::commandLoad(std::string packageName)
781 void InterpreterVirtual::commandUnload(std::string packageName)
785 void InterpreterVirtual::commandBreak()
789 void InterpreterVirtual::commandQuit()
793 void InterpreterVirtual::commandMessage()
798 void InterpreterVirtual::commandMessage(std::string kind, std::string levelstr)
804 //=======================================================================
805 void InterpreterVirtual::DoInterpretLine( const std::string& line )
808 printf("EED %p InterpreterVirtual::DoInterpretLine 0 \n", this);
809 printf("EED %p InterpreterVirtual::DoInterpretLine line=%s \n", this, line.c_str() );
810 bbtkDebugMessage("interpreter",6,"==> InterpreterVirtual::DoInterpretLine(\""
811 <<line<<"\")"<<std::endl);
812 std::vector<std::string> words;
813 SplitLine(line,words);
815 printf("EED %p InterpreterVirtual::DoInterpretLine word.size %d \n", this, (int)words.size() );
821 bbtkDebugDecTab("interpreter",9);
825 // Single line comment : # or //
826 if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') )
828 bbtkDebugDecTab("interpreter",9);
829 bbtkMessage("interpreter",9,"Comment"<<std::endl);
833 // Multi line comment ( /* ... */ ) -delimiters on different lines !-
835 if (words[0][0]=='/' && words[0][1]=='*')
837 bbtkDebugDecTab("interpreter",9);
838 bbtkMessage("interpreter",9,"In multiline comment"<<std::endl);
839 mInsideComment = true;
843 if (words[0][0]=='*' && words[0][1]=='/')
845 bbtkDebugDecTab("interpreter",9);
846 bbtkMessage("interpreter",9,"Out multiline comment"<<std::endl);
847 if ( !mInsideComment ) {
848 bbtkDebugDecTab("interpreter",9);
849 bbtkMessage("interpreter",9,"Comment mismatch : '*/' with no matching '/*'"<<std::endl);
851 mInsideComment = false;
857 bbtkDebugDecTab("interpreter",9);
858 bbtkMessage("interpreter",9,"Multiline Comment"<<std::endl);
862 printf("EED %p InterpreterVirtual::DoInterpretLine word.size %d \n", this, (int)words.size() );
865 CommandInfoType command;
866 InterpretCommand(words,command);
867 //std::cout<<"JCP bbtkInterpreter command.keyword ="<<command.keyword<<std::endl;
868 bbtkDebugMessage("interpreter",9,
869 "Command='"<<command.keyword
870 <<"' code="<<command.code<<std::endl);
872 std::string left,right,left2,right2;
873 std::string filename;
877 if (command.code==cMessage)
882 //EED Borrame mVirtualExecuter->HelpMessages();
886 commandMessage(words[1],words[2]);
887 //EED Borrame sscanf(words[2].c_str(),"%d",&level);
888 //EED Borrame mVirtualExecuter->SetMessageLevel(words[1],level);
894 bbtkMessage("echo",2,line<<std::endl);
897 // break and quit commands
898 if ((command.code==cBreak) || (command.code==cQuit))
900 bool in_script = false;
901 std::string file("");
904 if (mFileName.size())
906 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
907 if (fs!=0) in_script = true;
908 file = mFileName.back();
911 if (command.code==cBreak)
914 std::cout << "BreakException("
917 <<line<<")"<<std::endl;
920 //EED Borrame bbtkError("break");//,in_script,file,line);
921 // throw BreakException(in_script,file,line);
926 //EED Borrame bbtkError("quit");//,in_script,file,line);
927 //throw QuitException(in_script,file,line);
931 //std::cout<<" mVirtualExecuter->Create(words[1],words[2]); "<<line<<std::endl;
934 printf("EED %p InterpreterVirtual::DoInterpretLine 4 command.code=%d\n", this, (int)command.code);
936 switch (command.code)
939 printf("EED %p InterpreterVirtual::DoInterpretLine 5 %s %s\n", this, words[1].c_str() , words[2].c_str() );
940 commandNew(words[1],words[2]);
941 //EED Borrame mVirtualExecuter->Create(words[1],words[2]);
945 commandDelete(words[1]);
946 //EED Borrame mVirtualExecuter->Destroy(words[1]);
950 Utilities::SplitAroundFirstDot(words[1],left,right);
951 Utilities::SplitAroundFirstDot(words[2],left2,right2);
952 commandConnection(left,right,left2,right2);
953 //EED Borrame mVirtualExecuter->Connect(left,right,left2,right2);
957 commandPackage(words[1]);
958 //EED Borrame mVirtualExecuter->BeginPackage(words[1]);
963 //EED Borrame mVirtualExecuter->EndPackage();
967 if (mFileName.size()>0)
969 //??? commandDefine(????);
970 filename = mFileName.back(); //mIncludeFileName.back(); //Utilities::get_file_name(mFileName.back());
974 commandDefine(words[1],"",filename);
975 //EED Borrame mVirtualExecuter->Define(words[1],"",filename);
979 commandDefine(words[1],words[2],filename);
980 //EED Borrame mVirtualExecuter->Define(words[1],words[2],filename);
986 //EED Borrame mVirtualExecuter->EndDefine();
990 commandKind(words[1]);
991 //EED Borrame mVirtualExecuter->Kind(words[1]);
995 commandPrint(words[1]);
996 //EED Borrame mVirtualExecuter->Print(words[1]);
1000 commandExec(words[1]);
1001 //EED Borrame if (words[1]=="freeze")
1003 //EED Borrame mVirtualExecuter->SetNoExecMode(true);
1004 //EED Borrame mThrow = false;
1006 //EED Borrame else if (words[1]=="freeze_no_error")
1008 //EED Borrame mVirtualExecuter->SetNoExecMode(true);
1009 //EED Borrame mVirtualExecuter->SetNoErrorMode(true);
1010 //EED Borrame mThrow = false;
1012 //EED Borrame else if (words[1]=="unfreeze")
1014 //EED Borrame mVirtualExecuter->SetNoExecMode(false);
1015 //EED Borrame mVirtualExecuter->SetNoErrorMode(false);
1019 //EED Borrame mVirtualExecuter->Execute(words[1]);
1025 Utilities::SplitAroundFirstDot(words[2],left,right);
1026 commandInput(words[1],left,right,words[3]);
1027 //EED Borrame mVirtualExecuter->DefineInput(words[1],left,right,words[3]);
1031 Utilities::SplitAroundFirstDot(words[2],left,right);
1032 commandOutput(words[1],left,right,words[3]);
1033 //EED Borrame mVirtualExecuter->DefineOutput(words[1],left,right,words[3]);
1037 Utilities::SplitAroundFirstDot(words[1],left,right);
1038 commandSet(left,right,words[2]);
1039 //EED Borrame mVirtualExecuter->Set(left,right,words[2]);
1043 commandAuthor(words[1]);
1044 //EED Borrame mVirtualExecuter->Author(words[1]);
1048 commandNewGUI(words[1],words[2]);
1052 commandCategory(words[1]);
1053 //EED Borrame mVirtualExecuter->Category(words[1]);
1057 if (words.size()==1)
1058 commandIndex("tmp_index.html");
1059 else if (words.size()==2)
1060 commandIndex(words[1]);
1061 else if (words.size()==3)
1062 commandIndex(words[1],words[2]);
1066 commandDescription(words[1]);
1067 //EED Borrame mVirtualExecuter->Description(words[1]);
1076 commandGraph(words);
1089 //EED Borrame mVirtualExecuter->Clear();
1093 commandInclude( words[1] , (words.size()==3) );
1094 //EED Borrame // if 'source' was given (words.size()==3) then tell to set the
1095 //EED Borrame // source file name of the current complex box with the full file name included
1096 //EED Borrame if (mCommandLine)
1098 //EED Borrame InterpretFile(words[1],(words.size()==3));
1099 //EED Borrame } else{
1100 //EED Borrame SwitchToFile(words[1],(words.size()==3) );
1105 commandLoad( words[1] );
1106 //EED Borrame GetExecuter()->LoadPackage(words[1]);
1110 commandUnload( words[1] );
1111 //EED Borrame GetExecuter()->UnLoadPackage(words[1]);
1115 if (words.size()==2) commandDebug(words[1]);
1116 else commandDebug("");
1121 if (words.size() == 2)
1123 if (words[1]=="freeze") mVirtualExecuter->SetNoExecMode(true);
1124 else if (words[1]=="unfreeze") mVirtualExecuter->SetNoExecMode(false);
1128 mVirtualExecuter->SetWorkspaceName(words[2]);
1133 bbtkInternalError("should not reach here !!!");
1136 bbtkDebugMessage("interpreter",6,"<== InterpreterVirtual::DoInterpretLine(\""
1137 <<line<<"\")"<<std::endl);
1139 printf("EED %p InterpreterVirtual::DoInterpretLine 10\n", this);
1143 //=======================================================================
1149 //=======================================================================
1150 void InterpreterVirtual::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
1152 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::SplitLine(\""<<str<<"\")"<<std::endl);
1154 std::string delimiters = "\"";
1155 std::vector<std::string> quote;
1156 Utilities::SplitString(str,delimiters,quote);
1159 std::vector<std::string>::iterator i;
1160 for (i=quote.begin(); i!=quote.end(); )
1162 Utilities::SplitString(*i,delimiters,tokens);
1166 // bbtkDebugMessage("interpreter",0,"\""<<*i<<"\""<<std::endl);
1167 tokens.push_back(*i);
1172 for (i=tokens.begin(); i!=tokens.end(); ++i)
1174 bbtkDebugMessage("interpreter",9,"--["<<*i<<"]"<<std::endl);
1176 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::SplitLine(\""<<str<<"\")"<<std::endl);
1179 //=======================================================================
1182 //=======================================================================
1183 void InterpreterVirtual::commandReset()
1186 //=======================================================================
1188 //=======================================================================
1193 void InterpreterVirtual::Print( const std::string& str)
1195 if (mVirtualExecuter->GetNoExecMode()) return;
1197 bbtkDebugMessageInc("interpreter",9,"InterpreterVirtual::Print(\""<<str<<"\")"<<std::endl);
1200 // InterpretLine ("load std")
1201 // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande
1202 // InterpretLine("new Print _P_")
1203 // InterpretLine("connect _C_.Out _P_.In")
1207 std::vector<std::string> chains;
1208 std::string delimiters("$");
1210 // Skip delimiters at beginning.
1211 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
1212 bool is_text = true;
1213 if (lastPos>0) is_text = false;
1215 // Find first delimiter.
1216 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
1218 while (std::string::npos != pos || std::string::npos != lastPos)
1222 // Found a text token, add it to the vector.
1223 chains.push_back(str.substr(lastPos, pos - lastPos));
1224 // std::string token = str.substr(lastPos, pos - lastPos)
1225 // InterpretLine("set _C_.In%num% %token%")
1231 // is an output (between $$) : decode
1232 std::string tok,box,output;
1233 tok = str.substr(lastPos, pos - lastPos);
1234 Utilities::SplitAroundFirstDot(tok,box,output);
1235 chains.push_back( mVirtualExecuter->Get(box,output) );
1237 // InterpretLine("connect %tok% _C_.In%num%")
1240 // Skip delimiters. Note the "not_of"
1241 lastPos = str.find_first_not_of(delimiters, pos);
1242 // Find next delimiter
1243 pos = str.find_first_of(delimiters, lastPos);
1248 // InterpretLine("exec _P_")
1249 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
1251 std::vector<std::string>::iterator i;
1252 for (i= chains.begin(); i!=chains.end(); ++i)
1255 Utilities::SubsBackslashN(*i);
1258 std::cout << std::endl;
1259 bbtkDebugDecTab("interpreter",9);
1263 //=======================================================================
1268 // =========================================================================
1269 void InterpreterVirtual::SwitchToFile( const std::string& name , bool source )
1271 printf("EED InterpreterVirtual::SwitchToFile 1\n");
1272 printf("EED InterpreterVirtual::SwitchToFile name=%s\n", name.c_str() );
1274 // Note : in the following :
1275 // name : the user supplied name
1276 // - abreviated name e.g. scr scr.bbs
1277 // - relative full name e.g. ./scr.bbs ../../scr.bbs
1278 // - absolute full name e.g. /home/usrname/proj/dir/scr.bbs
1279 // same for Windows, with c:, d: ...
1281 // use ./directory/subdir/scrname.bbs
1284 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::SwitchToFile( \""
1285 <<name<<"\")"<<std::endl);
1287 std::vector<std::string> script_paths;
1288 std::string fullPathScriptName; // full path script name
1289 std::string pkgname; // e.g. <scriptname>.bbs
1290 std::vector<std::string> Filenames;
1292 // The following is *NOT* a debug time message :
1293 // It's a user intended message.
1294 // Please don't remove it.
1295 bbtkMessage("interpreter",1,
1296 "look for : [" << name
1297 << "]" << std::endl);
1301 pkgname = Utilities::ExtractScriptName(name,upath);
1303 bbtkMessage("interpreter",3,
1304 "package name:[" << pkgname
1305 << "] path:[" << upath << "]" << std::endl);
1306 bool fullnameGiven = false;
1307 bool foundFile = false;
1309 // ==== "*" provided : load all scripts in given path
1310 // relative (e.g. std/boxes/*) or absolute
1314 std::stringstream* stream = new std::stringstream;
1315 //if (upath.size()!=0) // avoid troubles for "*"
1317 printf("EED InterpreterVirtual::SwitchToFile 2\n");
1319 // ==== no path provided : look in root bbs path
1320 if (upath.size()==0)
1322 // bbtkMessage("interpreter",1,
1323 // LG : add all bbs path
1324 // script_paths.push_back( ConfigurationFile::GetInstance().Get_root_bbs_path() );
1325 std::vector<std::string>::const_iterator i;
1326 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1327 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1330 script_paths.push_back(*i);
1333 // ==== absolute path provided
1334 else if (upath[0]=='/' || upath[1] == ':' )
1336 if ( Utilities::IsDirectory( upath ) )
1338 script_paths.push_back(upath);
1342 bbtkError("'"<<upath<<"' : directory does not exist");
1345 // ==== relative path provided : search all bbs path appended with
1346 // the relative path provided
1349 std::vector<std::string>::const_iterator i;
1350 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1351 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1354 std::string full_path(*i);
1355 // we *really* want '.' to be the current working directory
1356 if (full_path == ".")
1358 char buf[2048]; // for getcwd
1359 char * currentDir = getcwd(buf, 2048);
1360 std::string cwd(currentDir);
1361 full_path = currentDir;
1364 full_path += ConfigurationFile::GetInstance().Get_file_separator();
1367 if ( Utilities::IsDirectory( full_path ) )
1369 script_paths.push_back(full_path);
1372 if (script_paths.empty())
1374 bbtkError("no '"<<upath<<"' subdir found in search paths"
1379 printf("EED InterpreterVirtual::SwitchToFile 3\n");
1381 // === search paths list complete : now explore it
1383 // ==== relative name, iterate + load all .bbs/.bbp files
1384 std::vector<std::string>::iterator i;
1385 for (i=script_paths.begin();i!=script_paths.end();i++)
1387 bbtkMessage("interpreter",1,
1388 "--> Looking in '" << *i << "'" << std::endl);
1392 Utilities::Explore(*i, false, Filenames);
1394 for (std::vector<std::string>::iterator j = Filenames.begin();
1395 j!= Filenames.end(); ++j)
1397 int lgr = (*j).size();
1398 if (lgr < 5) continue;
1399 // ignore non .bbp file
1400 if ( (*j).substr(lgr-4, 4) != ".bbp") continue;
1402 (*stream) << "include \"" << *j << "\"\n";
1403 bbtkMessage("interpreter",2," --> Found '" << *j << "'" << std::endl);
1406 } // for (std::vector...
1407 } // for (i=script_...
1412 bbtkMessage("interpreter",1,
1413 " --> No .bbp found"<< std::endl);
1417 bbtkMessage("interpreter",1,
1418 " --> "<<nbBssFiles<<" .bbp found"<< std::endl);
1419 SwitchToStream(stream);
1423 //=============== end pkgname=="*" ===========
1426 // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name
1427 // (not only a plain script name)
1428 // we trust him, and try to expland the directory name
1429 // WARNING : starting from current local directory : ./whatYouWant (./ mandatory!)
1431 if (name[0]=='/' || name[1] == ':' || name[0]=='.') // absolute path (linux/windows) or relative path
1434 // ===========================================================check user supplied location
1435 fullnameGiven = true;
1437 fullPathScriptName = Utilities::ExpandLibName(name, false);
1439 // allow user to always forget ".bbs"
1440 int l = fullPathScriptName.size();
1444 if ((fullPathScriptName.substr(l-4, 4) != ".bbs")&&
1445 (fullPathScriptName.substr(l-4, 4) != ".bbp"))
1447 std::string tfullPathScriptName = fullPathScriptName + ".bbs";
1448 if ( Utilities::FileExists(tfullPathScriptName) )
1450 fullPathScriptName = tfullPathScriptName;
1455 tfullPathScriptName = fullPathScriptName + ".bbp";
1456 if ( Utilities::FileExists(tfullPathScriptName) )
1458 fullPathScriptName = tfullPathScriptName;
1465 if ( Utilities::FileExists(fullPathScriptName) )
1473 // =============================== iterate on the paths
1475 script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
1477 std::vector<std::string>::iterator i;
1478 for (i=script_paths.begin();i!=script_paths.end();++i)
1481 // we *really* want '.' to be the current working directory
1484 char buf[2048]; // for getcwd
1485 char * currentDir = getcwd(buf, 2048);
1486 std::string cwd(currentDir);
1490 std::string tfullPathScriptName = Utilities::MakePkgnameFromPath(path, name, false);
1491 //Addition JCP tfullPathScriptName.size()>=4
1492 if(tfullPathScriptName.size()>=4){
1493 if (tfullPathScriptName.substr(tfullPathScriptName.size()-4, 3)==".bb")
1495 fullPathScriptName = tfullPathScriptName;
1496 if ( ! Utilities::FileExists(fullPathScriptName) )
1498 // The following is *NOT* a debug time message :
1499 // It's a user intended message.
1500 // Please don't remove it.
1501 bbtkMessage("interpreter",2,
1502 " [" <<fullPathScriptName <<"] : does not exist"
1504 continue; // try next path
1506 bbtkMessage("interpreter",2,
1507 " [" <<fullPathScriptName
1508 <<"] : found" <<std::endl);
1510 break; // a script was found; we stop iterating
1514 fullPathScriptName = tfullPathScriptName + ".bbs";
1515 // Check if library exists
1516 if ( ! Utilities::FileExists(fullPathScriptName) )
1518 fullPathScriptName = tfullPathScriptName + ".bbp";
1519 if ( ! Utilities::FileExists(fullPathScriptName) )
1521 // The following is *NOT* a debug time message :
1522 // It's a user intended message.
1523 // Please don't remove it.
1524 bbtkMessage("interpreter",2,
1525 " [" <<tfullPathScriptName <<".bbs/.bbp] : do not exist"
1527 continue; // try next path
1530 bbtkMessage("interpreter",2,
1531 " [" <<fullPathScriptName
1532 <<"] : found" <<std::endl);
1534 break; // a script was found; we stop iterating
1537 } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
1543 if(fullPathScriptName == "")
1544 bbtkError("Path ["<<upath<<"] doesn't exist");
1546 bbtkError("Script ["<<fullPathScriptName<<"] not found");
1548 bbtkError("No ["<<pkgname<<".bbs/.bbp] script found");
1551 LoadScript(fullPathScriptName,name);
1552 //EED Borrame if (source) GetExecuter()->SetCurrentFileName(fullPathScriptName);
1553 if (source) SetCurrentFileName(fullPathScriptName);
1556 printf("EED InterpreterVirtual::SwitchToFile 4\n");
1560 //=======================================================================
1562 //=======================================================================
1563 void InterpreterVirtual::SetCurrentFileName(std::string fullPathScriptName) // virtual
1565 printf("EED InterpreterVirtual::SetCurrentFileName 1\n");
1567 //=======================================================================
1569 //=======================================================================
1570 void InterpreterVirtual::SwitchToStream( std::stringstream* stream )
1572 printf("EED InterpreterVirtual::SwitchToStream 1\n");
1574 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::SwitchToStream()"
1576 mFile.push_back(stream);
1577 std::ostringstream buffer_name;
1579 buffer_name << "buffer_" ;
1581 if (mFileName.size()>0 )
1583 buffer_name << mFileName.back() << "_" << mLine.back();
1585 mFileName.push_back(buffer_name.str());
1586 mIncludeFileName.push_back(buffer_name.str());
1589 //=======================================================================
1591 //=======================================================================
1593 void InterpreterVirtual::LoadScript( std::string fullPathScriptName,
1594 std::string includeScriptName)
1596 bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::LoadScript("
1597 <<fullPathScriptName<<")"
1600 Utilities::replace( fullPathScriptName ,
1601 INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
1603 if (find(mFileNameHistory.begin(),
1604 mFileNameHistory.end(),
1605 fullPathScriptName)!=mFileNameHistory.end())
1611 s = new std::ifstream;
1612 s->open(fullPathScriptName.c_str());
1615 bbtkError("Could not open file ["<<fullPathScriptName<<"]");
1619 bbtkMessage("interpreter",1," -->[" << fullPathScriptName
1620 << "] found" << std::endl);
1623 mFileName.push_back(fullPathScriptName);
1624 mFileNameHistory.push_back(fullPathScriptName);
1625 mIncludeFileName.push_back(includeScriptName);
1630 //=======================================================================
1632 //=======================================================================
1633 void InterpreterVirtual::CloseCurrentFile()
1635 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::CloseCurrentFile()"
1638 if (mFile.size()==0)
1640 bbtkDebugMessage("interpreter",9," -> no file left open"<<std::endl);
1644 bbtkDebugMessage("interpreter",9," Closing file '"<<mFileName.back()<<"'"<<std::endl);
1646 std::ifstream* file = dynamic_cast<std::ifstream*>(mFile.back());
1647 if (file!=0) file->close();
1649 delete mFile.back();
1651 mFileName.pop_back();
1652 mIncludeFileName.pop_back();
1655 bbtkDebugMessage("interpreter",9," Remains "
1657 <<" open"<<std::endl);
1658 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::CloseCurrentFile()"
1661 //=======================================================================
1663 //=======================================================================
1664 void InterpreterVirtual::CloseAllFiles()
1666 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::CloseAllFiles()"
1669 while (mFile.size() != 0)
1673 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::CloseAllFiles()"
1676 //=======================================================================
1680 //=======================================================================
1681 void InterpreterVirtual::InterpretCommand( const std::vector<std::string>& words,
1682 CommandInfoType& info )
1685 printf("EED InterpreterVirtual::InterpretCommand 1 \n");
1686 bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::InterpretCommand(...)"<<std::endl);
1688 // searches the command keyword
1689 CommandDictType::iterator c;
1690 c = mCommandDict.find(words[0]);
1691 if ( c == mCommandDict.end() ) {
1692 printf("EED InterpreterVirtual::InterpretCommand 2 \n");
1693 bbtkError(words[0]<<" : unknown command");
1696 // tests the number of args
1697 if ( ( ((int)words.size())-1 < c->second.argmin ) ||
1698 ( ((int)words.size())-1 > c->second.argmax ) )
1701 //EED HelpCommand(words[0]);
1702 commandHelp(words[0]);
1703 printf("EED InterpreterVirtual::InterpretCommand 3 \n");
1705 bbtkError(words[0]<<" : wrong number of arguments");
1707 //std::cout<<"InterpreterVirtual::InterpretCommand( const std::vector<std::string>& words,"<<std::endl;
1710 printf("EED InterpreterVirtual::InterpretCommand 4 \n" );
1711 bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::InterpretCommand(...)"<<std::endl);
1714 //=======================================================================
1717 //=======================================================================
1718 /// Displays help on all the commands
1719 void InterpreterVirtual::commandHelp(const std::vector<std::string>& words)
1722 //=======================================================================
1723 void InterpreterVirtual::commandHelp(const std::string words)
1726 //=======================================================================
1728 //===================================================================
1729 /// Displays the Configuration
1730 void InterpreterVirtual::commandConfig() const
1733 //===================================================================
1737 //=======================================================================
1738 /// Fills the vector commands with the commands which
1739 /// have the first n chars of buf for prefix
1740 /// TODO : skip initial spaces in buf and also return the position of first
1741 /// non blank char in buf
1742 void InterpreterVirtual::FindCommandsWithPrefix( char* buf,
1744 std::vector<std::string>& commands )
1746 CommandDictType::const_iterator i;
1747 for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
1749 if ((i->first).find(buf,0,n) == 0)
1750 commands.push_back(i->first);
1753 //=======================================================================
1757 //=======================================================================
1758 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1760 inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
1761 inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
1763 // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
1764 // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
1765 // E.G. STORE THIS IN bbtk_config.xml
1766 #define BBTK_UP_ARROW_KBCODE 0x00415B1B
1767 #define BBTK_DOWN_ARROW_KBCODE 0x00425B1B
1768 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
1769 #define BBTK_LEFT_ARROW_KBCODE 0x00445B1B
1770 #define BBTK_BACKSPACE_KBCODE 0x00000008
1771 #define BBTK_DEL_KBCODE 0x0000007F
1772 #define BBTK_SPACE_KBCODE 0x00000020
1774 //=======================================================================
1775 void InterpreterVirtual::GetLineFromPrompt(std::string& s)
1780 unsigned int MAX_LINE_SIZE = 160;
1781 unsigned int MAX_HISTORY_SIZE = 100;
1783 char* newline = new char[MAX_LINE_SIZE];
1784 memset(newline,0,MAX_LINE_SIZE);
1785 char* histline = new char[MAX_LINE_SIZE];
1786 memset(histline,0,MAX_LINE_SIZE);
1788 char* line = newline;
1789 unsigned int hist = mHistory.size();
1795 read ( STDIN_FILENO, &c, 4) ;
1797 bbtkDebugMessage("debug",9,"[0x"<<std::hex<<c<<"]\n");
1799 // Printable character
1800 if ( (ind<MAX_LINE_SIZE-1) &&
1801 ( c >= BBTK_SPACE_KBCODE ) &&
1802 ( c < BBTK_DEL_KBCODE ))
1810 // delete the unused line
1816 // empty lines are not stored in from history
1819 // if history too long : delete oldest command
1820 if (mHistory.size()>MAX_HISTORY_SIZE)
1822 delete mHistory.front();
1823 mHistory.pop_front();
1825 mHistory.push_back(line);
1830 else if ( (ind>0) &&
1831 ((c == BBTK_BACKSPACE_KBCODE) ||
1832 (c == BBTK_DEL_KBCODE)) )
1840 // TODO : Command completion
1841 std::vector<std::string> commands;
1842 FindCommandsWithPrefix( line,ind,commands);
1843 if (commands.size()==1)
1845 std::string com = *commands.begin();
1846 for (; ind<com.size(); ++ind)
1848 PrintChar(com[ind]);
1854 else if (commands.size()>1)
1856 std::vector<std::string>::iterator i;
1858 for (i=commands.begin();i!=commands.end();++i)
1860 write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
1863 write(STDOUT_FILENO,"\n> ",3);
1864 //for (int j=0;j<ind;++j)
1866 write(STDOUT_FILENO,line,ind);
1870 // Arrow up : back in history
1871 else if (c==BBTK_UP_ARROW_KBCODE)
1875 // erase current line
1876 while (ind--) BackSpace();
1880 strcpy(histline,mHistory[hist]);
1884 write(STDOUT_FILENO,line,ind);
1887 // Arrow down : down in history
1888 else if (c==BBTK_DOWN_ARROW_KBCODE)
1890 if (hist<mHistory.size()-1)
1892 // erase current line
1893 while (ind--) BackSpace();
1897 strcpy(histline,mHistory[hist]);
1901 write(STDOUT_FILENO,line,ind);
1903 // end of history : switch back to newline
1904 else if (hist==mHistory.size()-1)
1906 // erase current line
1907 while (ind--) BackSpace();
1914 write(STDOUT_FILENO,line,ind);
1918 else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
1920 PrintChar(line[ind]);
1925 else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
1933 write(STDOUT_FILENO,"\n\r",2);
1941 //=======================================================================
1942 void InterpreterVirtual::GetLineFromPrompt(std::string& s)
1968 //=======================================================================
1974 //=======================================================================
1975 void InterpreterVirtual::CommandLineInterpreter()
1977 bbtkDebugMessageInc("interpreter",9,
1978 "InterpreterVirtual::CommandLineInterpreter()"<<std::endl);
1980 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1981 // Initialise the tty in non canonical mode with no echo
1982 // oter remembers the previous settings to restore them after
1983 struct termios ter,oter;
1986 ter.c_lflag &= ~ECHO;
1987 ter.c_lflag &= ~ICANON;
1990 tcsetattr(0,TCSANOW,&ter);
1993 mCommandLine = true;
1995 // bool insideComment = false; // for multiline comment
1996 mInsideComment = false;
2002 GetLineFromPrompt(line);
2003 DoInterpretLine(line); //, insideComment);
2006 catch (QuitException e)
2008 bbtkMessage("interpreter",1,"Interpreter : Quit"<<std::endl);
2012 catch (bbtk::Exception e)
2016 catch (std::exception& e)
2018 std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
2022 std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
2027 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
2028 tcsetattr(0,TCSANOW,&oter);
2031 std::cout << "Good bye !" << std::endl;
2033 bbtkDebugDecTab("interpreter",9);
2036 //=======================================================================
2037 void InterpreterVirtual::commandGraph(const std::vector<std::string>& words)
2040 //=======================================================================
2043 //=======================================================================
2044 void InterpreterVirtual::commandIndex(const std::string& filename, const std::string& type)
2047 //=======================================================================
2050 //=======================================================================
2051 void InterpreterVirtual::commandNewGUI(const std::string& boxname,const std::string& instanceName)
2054 //=======================================================================
2058 //==========================================================================
2059 void InterpreterVirtual::commandDebug(const std::string& name)
2062 //==========================================================================
2065 //==========================================================================
2066 // Adds a callback when 'break' command issued
2067 void InterpreterVirtual::AddBreakObserver( BreakCallbackType c )
2069 mBreakSignal.connect(c);
2071 //==========================================================================
2074 //==========================================================================
2075 std::string InterpreterVirtual::GetObjectName() const
2077 return std::string("InterpreterVirtual");
2079 //==========================================================================
2081 //==========================================================================
2082 std::string InterpreterVirtual::GetObjectInfo() const
2084 std::stringstream i;
2087 //==========================================================================
2089 //==========================================================================
2090 size_t InterpreterVirtual::GetObjectSize() const
2092 size_t s = Superclass::GetObjectSize();
2093 s += InterpreterVirtual::GetObjectInternalSize();
2096 //==========================================================================
2097 //==========================================================================
2098 size_t InterpreterVirtual::GetObjectInternalSize() const
2100 size_t s = sizeof(InterpreterVirtual);
2103 //==========================================================================
2104 //==========================================================================
2105 size_t InterpreterVirtual::GetObjectRecursiveSize() const
2107 size_t s = Superclass::GetObjectRecursiveSize();
2108 s += InterpreterVirtual::GetObjectInternalSize();
2111 //==========================================================================