1 /*=========================================================================
3 Module: $RCSfile: bbtkInterpreter.cxx,v $
5 Date: $Date: 2008/11/26 12:36:42 $
6 Version: $Revision: 1.78 $
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 "bbtkInterpreter.h"
37 #include "bbtkExecuter.h"
38 #include "bbtkTranscriptor.h"
39 #include "bbtkMessageManager.h"
40 #include "bbtkConfigurationFile.h"
41 #include "bbtkUtilities.h"
42 #include "bbtkWxBlackBox.h"
45 #ifdef CMAKE_HAVE_TERMIOS_H
47 #define BBTK_USE_TERMIOS_BASED_PROMPT
55 //=======================================================================
56 Interpreter::Pointer Interpreter::New(const std::string& cpp_file)
58 bbtkDebugMessage("Kernel",9,"Interpreter::New('"<<cpp_file<<"')"<<std::endl);
59 return MakePointer(new Interpreter(cpp_file));
61 //=======================================================================
63 //=======================================================================
64 Interpreter::Pointer Interpreter::New(VirtualExec::Pointer e)
66 bbtkDebugMessage("Kernel",9,"Interpreter::New(VirtualExec)"<<std::endl);
67 return MakePointer(new Interpreter(e));
69 //=======================================================================
71 //=======================================================================
72 Interpreter::Interpreter(const std::string& cpp_file)
74 Init(VirtualExec::Pointer(), cpp_file);
76 //=======================================================================
78 //=======================================================================
79 Interpreter::Interpreter(VirtualExec::Pointer e)
83 //=======================================================================
85 //=======================================================================
86 void Interpreter::Init(VirtualExec::Pointer e, const std::string& cpp_file)
92 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);
93 bbtk::MessageManager::RegisterMessageType("Interpreter","Messages of the interpreter",0);
94 bbtkDebugMessageInc("Interpreter",9,"Interpreter::Interpreter()" <<std::endl);
99 else if (cpp_file.size()!=0)
101 mVirtualExecuter = boost::static_pointer_cast<VirtualExec>(bbtk::Transcriptor::New(cpp_file));
105 bbtk::Executer::Pointer exe = bbtk::Executer::New();
107 mVirtualExecuter = boost::static_pointer_cast<VirtualExec>(exe);
110 // Lock this pointer or will auto-destruct !!
111 if (!e) mVirtualExecuter->SetInterpreter(MakePointer(this,true));
113 // For the time being, comment out previous line, and
114 // uncomment next line to check Transcriptor
116 //mVirtualExecuter = new bbtk::Transcriptor("GeneratedProgram.txt");
118 // Builds the commands dict
119 CommandInfoType info;
121 info.keyword = "new";
125 info.syntax = "new <type> <name>";
126 info.help = "Creates a new black box of type <type> with name <name>";
127 mCommandDict[info.keyword] = info;
129 info.keyword = "delete";
133 info.syntax = "delete <box>";
134 info.help = "Deletes the black box of name <box>";
135 mCommandDict[info.keyword] = info;
137 info.keyword = "newgui";
141 info.syntax = "newgui <box> <name>";
142 info.help = "Automatically creates a graphical user interface with name <name> for the black box <box> and connects it to the box inputs";
143 mCommandDict[info.keyword] = info;
145 info.keyword = "connect";
148 info.code = cConnect;
149 info.syntax = "connect <box1.output> <box2.input>";
150 info.help = "Connects the ouput <output> of black box <box1> to the input <input> of black box <box2>";
151 mCommandDict[info.keyword] = info;
153 info.keyword = "print";
157 info.syntax = "print <string>";
158 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').";
159 mCommandDict[info.keyword] = info;
161 info.keyword = "exec";
165 info.syntax = "exec <box | 'freeze' | 'unfreeze' | 'freeze_no_error' >";
166 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.";
167 mCommandDict[info.keyword] = info;
169 info.keyword = "package";
172 info.code = cPackage;
173 info.syntax = "package <name>";
174 info.help = "Begins the definition of a package.";
175 mCommandDict[info.keyword] = info;
177 info.keyword = "endpackage";
180 info.code = cEndPackage;
181 info.syntax = "endpackage";
182 info.help = "Ends the definition of a package.";
183 mCommandDict[info.keyword] = info;
185 info.keyword = "define";
189 info.syntax = "define <type> [<package>]";
190 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.";
191 mCommandDict[info.keyword] = info;
193 info.keyword = "endefine";
196 info.code = cEndDefine;
197 info.syntax = "endefine";
198 info.help = "Ends the definition of a new type of complex black box";
199 mCommandDict[info.keyword] = info;
201 info.keyword = "kind";
205 info.syntax = "kind <ADAPTOR|DEFAULT_ADAPTOR|WIDGET_ADAPTOR|DEFAULT_WIDGET_ADAPTOR>";
206 info.help = "Sets the kind of the currently defined complex black box";
207 mCommandDict[info.keyword] = info;
209 info.keyword = "input";
213 info.syntax = "input <name> <box.input> <help>";
214 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";
215 mCommandDict[info.keyword] = info;
217 info.keyword = "output";
221 info.syntax = "output <name> <box.output> <help>";
222 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";
223 mCommandDict[info.keyword] = info;
225 info.keyword = "set";
229 info.syntax = "set <box.input> <value>";
230 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";
231 mCommandDict[info.keyword] = info;
233 info.keyword = "config"; // JPR
237 info.syntax = "config";
238 info.help = "Prints the value of all configuration parameters";
239 mCommandDict[info.keyword] = info;
241 info.keyword = "index"; // LG
246 info.syntax = "index [<filename> ['Initials'(default)|'Packages'|'Categories'|'Adaptors']]";
247 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.";
248 mCommandDict[info.keyword] = info;
250 info.keyword = "reset";
254 info.syntax = "reset";
255 info.help = "Deletes all boxes and unloads all packages (reset to start state)";
256 mCommandDict[info.keyword] = info;
258 info.keyword = "author";
262 info.syntax = "author <string>";
263 info.help = "Adds the string <string> to the author information of the black box being defined";
264 mCommandDict[info.keyword] = info;
266 info.keyword = "category"; //JP
269 info.code = cCategory;
270 info.syntax = "category <list of items, separated by ;>";
271 info.help = "Adds the string <string> to the category information of the black box being defined";
272 mCommandDict[info.keyword] = info;
274 info.keyword = "description";
277 info.code = cDescription;
278 info.syntax = "description <string>";
279 info.help = "Adds the string <string> to the descriptive information of the black box being defined";
280 mCommandDict[info.keyword] = info;
282 info.keyword = "help";
286 info.syntax = "help";
287 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>";
288 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.";
289 mCommandDict[info.keyword] = info;
291 info.keyword = "message";
294 info.code = cMessage;
295 info.syntax = "message <kind> <level>";
296 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.";
297 mCommandDict[info.keyword] = info;
299 info.keyword = "include";
302 info.code = cInclude;
303 info.syntax = "include <filename> [source]";
304 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).";
305 mCommandDict[info.keyword] = info;
307 info.keyword = "quit";
311 info.syntax = "quit";
312 info.help = "Quits the program (during script execution it stops the complete execution)";
313 mCommandDict[info.keyword] = info;
315 info.keyword = "load";
319 info.syntax = "load <packagename>";
320 info.help = "Loads the black box package <packagename>";
321 mCommandDict[info.keyword] = info;
323 info.keyword = "unload";
327 info.syntax = "unload <packagename>";
328 info.help = "Unloads the black box package <packagename>";
329 mCommandDict[info.keyword] = info;
331 info.keyword = "graph";
335 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 ]]]]]]";
336 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')";
337 mCommandDict[info.keyword] = info;
339 info.keyword = "debug";
343 info.syntax = "debug [expr|-C|-D]";
344 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";
345 mCommandDict[info.keyword] = info;
348 info.keyword = "workspace";
351 info.code = cWorkspace;
352 info.syntax = "workspace < ( freeze | unfreeze ) | ( rename <newname> ) >";
353 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.";
354 mCommandDict[info.keyword] = info;
357 bbtkDebugDecTab("Interpreter",9);
360 //=======================================================================
364 //=======================================================================
368 Interpreter::~Interpreter()
370 bbtkDebugMessageInc("Interpreter",9,"==> Interpreter::~Interpreter()" <<std::endl);
371 mVirtualExecuter = VirtualExec::Pointer();
372 bbtkDebugMessageInc("Interpreter",9,"<== Interpreter::~Interpreter()" <<std::endl);
374 //=======================================================================
377 InterpreterError::InterpreterError( const std::string& message,
379 const std::string& script_file,
382 : Exception("Interpreter",0,message),
383 mInScriptFile(in_script_file),
384 mScriptFile(script_file),
385 mScriptLine(script_line)
388 InterpreterError::InterpreterError( const Exception& excep,
390 const std::string& script_file,
394 mInScriptFile(in_script_file),
395 mScriptFile(script_file),
396 mScriptLine(script_line)
399 //=======================================================================
400 void Interpreter::CatchInterpreterException( const InterpreterError& e )
405 throw InterpreterError(e);
409 std::stringstream mess;
410 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
411 if (e.IsInScriptFile())
413 mess << "* FILE : \""<<e.GetScriptFile()<<"\""<<std::endl;
414 mess << "* LINE : "<<e.GetScriptLine()<<std::endl;
416 std::cerr << mess.str();
419 //=======================================================================
421 //=======================================================================
422 void Interpreter::CatchBbtkException( const bbtk::Exception& e )
426 bool in_script = false;
427 std::string file("");
429 if (mFileName.size()) {
430 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
431 if (fs!=0) in_script = true;
432 file = mFileName.back();
436 throw InterpreterError(e,in_script,file,line);
440 std::stringstream mess;
441 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
442 if (mFileName.size()) {
443 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
444 mess << "* LINE : "<<mLine.back()<<std::endl;
446 std::cerr << mess.str();
449 //=======================================================================
451 //=======================================================================
452 void Interpreter::CatchStdException( const std::exception& e )
456 bool in_script = false;
457 std::string file("");
459 if (mFileName.size()) {
460 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
461 if (fs!=0) in_script = true;
462 file = mFileName.back();
466 throw InterpreterError(e.what(),in_script,file,line);
470 std::stringstream mess;
471 mess << "* ERROR : "<<e.what()<<std::endl;
472 if (mFileName.size()) {
473 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
474 mess << "* LINE : "<<mLine.back()<<std::endl;
476 std::cerr << mess.str();
479 //=======================================================================
481 //=======================================================================
482 void Interpreter::CatchUnknownException()
486 bool in_script = false;
487 std::string file("");
489 if (mFileName.size()) {
490 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
491 if (fs!=0) in_script = true;
492 file = mFileName.back();
496 throw InterpreterError("Unknown exception caught",
497 in_script,file,line);
501 std::stringstream mess;
502 mess << "* UNDEFINED ERROR (not a bbtk nor a std exception)"
504 if (mFileName.size()) {
505 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
506 mess << "* LINE : "<<mLine.back()<<std::endl;
508 std::cerr << mess.str();
511 //=======================================================================
513 //=======================================================================
515 #define CATCH_MACRO \
516 catch (QuitException e) \
518 status = Interpreter_QUIT; \
519 if (mThrow) throw QuitException(); \
521 catch (InterpreterError e) \
523 status = Interpreter_ERROR; \
524 CatchInterpreterException(e); \
526 catch (bbtk::Exception e) \
528 status = Interpreter_ERROR; \
529 CatchBbtkException(e); \
531 catch (std::exception& e) \
533 status = Interpreter_ERROR; \
534 CatchStdException(e); \
538 status = Interpreter_ERROR; \
539 CatchUnknownException(); \
541 //=======================================================================
544 //=======================================================================
548 Interpreter::ExitStatus Interpreter::InterpretFile( const std::string& filename, bool source )
550 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
552 bool exm = mCommandLine;
553 mCommandLine = false;
555 ExitStatus status = Interpreter_OK;
559 SwitchToFile(filename,source);
561 bool insideComment = false; // for multiline comment
562 while (mFile.size()>0)
564 while (!mFile.back()->eof()) {
567 mFile.back()->getline(buf,500);
568 std::string str(buf);
569 int size=str.length();
570 if ( str[ size-1 ]==13 )
576 InterpretLine(str, insideComment);
587 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
588 bbtkDecTab("Interpreter",9);
594 //=======================================================================
597 //=======================================================================
601 Interpreter::ExitStatus
602 Interpreter::InterpretBuffer( std::stringstream* buffer )
604 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretBuffer()"<<std::endl);
606 bool exm = mCommandLine;
607 mCommandLine = false;
609 ExitStatus status = Interpreter_OK;
613 SwitchToStream(buffer);
614 bool insideComment = false; // for multiline comment
615 while (mFile.size()>0)
617 while (!mFile.back()->eof()) {
620 mFile.back()->getline(buf,500);
621 std::string str(buf);
623 int size=str.length();
624 if ( str[ size-1 ]==13 )
630 InterpretLine(str, insideComment);
640 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretBuffer()"<<std::endl);
641 bbtkDecTab("Interpreter",9);
646 //=======================================================================
648 //=======================================================================
649 /// Runs the interpretation of a command
650 Interpreter::ExitStatus Interpreter::InterpretLine( const std::string& line )
652 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretLine('"<<line<<"')"<<std::endl);
654 ExitStatus status = Interpreter_OK;
658 bool insideComment = false;
659 InterpretLine(line, insideComment);
664 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretLine()"
666 bbtkDecTab("Interpreter",9);
672 //=======================================================================
676 void Interpreter::InterpretLine( const std::string& line, bool &insideComment )
678 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretLine(\""<<line<<"\")"<<std::endl);
679 bbtkMessage("echo",2,line<<std::endl);
681 std::vector<std::string> words;
682 SplitLine(line,words);
687 bbtkDebugDecTab("Interpreter",9);
691 // Single line comment : # or //
692 if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') )
694 bbtkDebugDecTab("Interpreter",9);
695 bbtkMessage("Interpreter",9,"Comment"<<std::endl);
699 // Multi line comment ( /* ... */ ) -delimiters on different lines !-
701 if (words[0][0]=='/' && words[0][1]=='*')
703 bbtkDebugDecTab("Interpreter",9);
704 bbtkMessage("Interpreter",9,"In multiline comment"<<std::endl);
705 insideComment = true;
709 if (words[0][0]=='*' && words[0][1]=='/')
711 bbtkDebugDecTab("Interpreter",9);
712 bbtkMessage("Interpreter",9,"Out multiline comment"<<std::endl);
713 if ( !insideComment ) {
714 bbtkDebugDecTab("Interpreter",9);
715 bbtkMessage("Interpreter",9,"Comment mismatch : '*/' with no matching '/*'"<<std::endl);
717 insideComment = false;
723 bbtkDebugDecTab("Interpreter",9);
724 bbtkMessage("Interpreter",9,"Multiline Comment"<<std::endl);
729 CommandInfoType command;
730 InterpretCommand(words,command);
732 bbtkDebugMessage("Interpreter",9,
733 "Command='"<<command.keyword
734 <<"' code="<<command.code<<std::endl);
736 std::string left,right,left2,right2;
737 std::string filename;
738 switch (command.code)
741 mVirtualExecuter->Create(words[1],words[2]);
745 mVirtualExecuter->Destroy(words[1]);
749 Utilities::SplitAroundFirstDot(words[1],left,right);
750 Utilities::SplitAroundFirstDot(words[2],left2,right2);
751 mVirtualExecuter->Connect(left,right,left2,right2);
755 mVirtualExecuter->BeginPackage(words[1]);
759 mVirtualExecuter->EndPackage();
763 if (mFileName.size()>0)
765 filename = mFileName.back(); //mIncludeFileName.back(); //Utilities::get_file_name(mFileName.back());
769 mVirtualExecuter->Define(words[1],"",filename);
773 mVirtualExecuter->Define(words[1],words[2],filename);
778 mVirtualExecuter->EndDefine();
782 mVirtualExecuter->Kind(words[1]);
786 mVirtualExecuter->Print(words[1]);
790 if (words[1]=="freeze")
792 mVirtualExecuter->SetNoExecMode(true);
795 else if (words[1]=="freeze_no_error ")
797 mVirtualExecuter->SetNoExecMode(true);
798 mVirtualExecuter->SetNoErrorMode(true);
801 else if (words[1]=="unfreeze")
803 mVirtualExecuter->SetNoExecMode(false);
804 mVirtualExecuter->SetNoErrorMode(false);
808 mVirtualExecuter->Execute(words[1]);
813 Utilities::SplitAroundFirstDot(words[2],left,right);
814 mVirtualExecuter->DefineInput(words[1],left,right,words[3]);
818 Utilities::SplitAroundFirstDot(words[2],left,right);
819 mVirtualExecuter->DefineOutput(words[1],left,right,words[3]);
823 Utilities::SplitAroundFirstDot(words[1],left,right);
824 mVirtualExecuter->Set(left,right,words[2]);
828 mVirtualExecuter->Author(words[1]);
832 NewGUI(words[1],words[2]);
836 mVirtualExecuter->Category(words[1]);
841 Index("tmp_index.html");
842 else if (words.size()==2)
844 else if (words.size()==3)
845 Index(words[1],words[2]);
849 mVirtualExecuter->Description(words[1]);
859 mVirtualExecuter->HelpMessages();
863 sscanf(words[2].c_str(),"%d",&level);
864 mVirtualExecuter->SetMessageLevel(words[1],level);
881 // if 'source' was given (words.size()==3) then tell to set the
882 // source file name of the current complex box with the full file name included
885 InterpretFile(words[1],(words.size()==3));
889 SwitchToFile(words[1],(words.size()==3) );
894 GetExecuter()->LoadPackage(words[1]);
898 GetExecuter()->UnLoadPackage(words[1]);
902 throw QuitException();
906 if (words.size()==2) Debug(words[1]);
911 if (words.size() == 2)
913 if (words[1]=="freeze") mVirtualExecuter->SetNoExecMode(true);
914 else if (words[1]=="unfreeze") mVirtualExecuter->SetNoExecMode(false);
918 mVirtualExecuter->SetWorkspaceName(words[2]);
923 bbtkInternalError("should not reach here !!!");
926 bbtkDecTab("Interpreter",9);
928 //=======================================================================
934 //=======================================================================
938 void Interpreter::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
940 bbtkDebugMessageInc("Interpreter",9,"Interpreter::SplitLine(\""<<str<<"\")"<<std::endl);
942 std::string delimiters = "\"";
943 std::vector<std::string> quote;
944 Utilities::SplitString(str,delimiters,quote);
947 std::vector<std::string>::iterator i;
948 for (i=quote.begin(); i!=quote.end(); )
950 Utilities::SplitString(*i,delimiters,tokens);
954 // bbtkDebugMessage("Interpreter",0,"\""<<*i<<"\""<<std::endl);
955 tokens.push_back(*i);
960 for (i=tokens.begin(); i!=tokens.end(); ++i)
962 bbtkDebugMessage("Interpreter",9,"["<<*i<<"] ");
964 bbtkDebugMessageCont("Interpreter",9,std::endl);
966 bbtkDebugDecTab("Interpreter",9);
968 //=======================================================================
971 //=======================================================================
972 void Interpreter::Reset()
974 // Cannot close all files if the reset command is read from a file !
976 mFileNameHistory.clear();
977 this->mVirtualExecuter->Reset();
979 //=======================================================================
981 //=======================================================================
986 void Interpreter::Print( const std::string& str)
988 if (mVirtualExecuter->GetNoExecMode()) return;
990 bbtkDebugMessageInc("Interpreter",9,"Interpreter::Print(\""<<str<<"\")"<<std::endl);
993 // InterpretLine ("load std")
994 // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande
995 // InterpretLine("new Print _P_")
996 // InterpretLine("connect _C_.Out _P_.In")
1000 std::vector<std::string> chains;
1001 std::string delimiters("$");
1003 // Skip delimiters at beginning.
1004 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
1005 bool is_text = true;
1006 if (lastPos>0) is_text = false;
1008 // Find first delimiter.
1009 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
1011 while (std::string::npos != pos || std::string::npos != lastPos)
1015 // Found a text token, add it to the vector.
1016 chains.push_back(str.substr(lastPos, pos - lastPos));
1017 // std::string token = str.substr(lastPos, pos - lastPos)
1018 // InterpretLine("set _C_.In%num% %token%")
1024 // is an output (between $$) : decode
1025 std::string tok,box,output;
1026 tok = str.substr(lastPos, pos - lastPos);
1027 Utilities::SplitAroundFirstDot(tok,box,output);
1028 chains.push_back( mVirtualExecuter->Get(box,output) );
1030 // InterpretLine("connect %tok% _C_.In%num%")
1033 // Skip delimiters. Note the "not_of"
1034 lastPos = str.find_first_not_of(delimiters, pos);
1035 // Find next delimiter
1036 pos = str.find_first_of(delimiters, lastPos);
1041 // InterpretLine("exec _P_")
1042 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
1044 std::vector<std::string>::iterator i;
1045 for (i= chains.begin(); i!=chains.end(); ++i)
1048 Utilities::SubsBackslashN(*i);
1051 std::cout << std::endl;
1052 bbtkDebugDecTab("Interpreter",9);
1056 //=======================================================================
1061 // =========================================================================
1062 void Interpreter::SwitchToFile( const std::string& name , bool source )
1064 // Note : in the following :
1065 // name : the user supplied name
1066 // - abreviated name e.g. scr scr.bbs
1067 // - relative full name e.g. ./scr.bbs ../../scr.bbs
1068 // - absolute full name e.g. /home/usrname/proj/dir/scr.bbs
1069 // same for Windows, with c:, d: ...
1071 // use ./directory/subdir/scrname.bbs
1074 bbtkDebugMessageInc("Interpreter",9,"Interpreter::SwitchToFile( \""
1075 <<name<<"\")"<<std::endl);
1077 std::vector<std::string> script_paths;
1078 std::string fullPathScriptName; // full path script name
1079 std::string pkgname; // e.g. <scriptname>.bbs
1080 std::vector<std::string> Filenames;
1082 // The following is *NOT* a debug time message :
1083 // It's a user intended message.
1084 // Please don't remove it.
1085 bbtkMessage("Interpreter",1,
1086 "look for : [" << name
1087 << "]" << std::endl);
1091 pkgname = Utilities::ExtractScriptName(name,upath);
1093 bbtkMessage("Interpreter",3,
1094 "package name:[" << pkgname
1095 << "] path:[" << upath << "]" << std::endl);
1096 bool fullnameGiven = false;
1097 bool foundFile = false;
1099 // ==== "*" provided : load all scripts in given path
1100 // relative (e.g. std/boxes/*) or absolute
1104 std::stringstream* stream = new std::stringstream;
1105 //if (upath.size()!=0) // avoid troubles for "*"
1107 // ==== no path provided : look in root bbs path
1108 if (upath.size()==0)
1110 // bbtkMessage("Interpreter",1,
1111 // LG : add all bbs path
1112 // script_paths.push_back( ConfigurationFile::GetInstance().Get_root_bbs_path() );
1113 std::vector<std::string>::const_iterator i;
1114 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1115 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1118 script_paths.push_back(*i);
1121 // ==== absolute path provided
1122 else if (upath[0]=='/' || upath[1] == ':' )
1124 if ( Utilities::IsDirectory( upath ) )
1126 script_paths.push_back(upath);
1130 bbtkError("'"<<upath<<"' : directory does not exist");
1133 // ==== relative path provided : search all bbs path appended with
1134 // the relative path provided
1137 std::vector<std::string>::const_iterator i;
1138 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1139 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1142 std::string full_path(*i);
1143 // we *really* want '.' to be the current working directory
1144 if (full_path == ".")
1146 char buf[2048]; // for getcwd
1147 char * currentDir = getcwd(buf, 2048);
1148 std::string cwd(currentDir);
1149 full_path = currentDir;
1152 full_path += ConfigurationFile::GetInstance().Get_file_separator();
1155 if ( Utilities::IsDirectory( full_path ) )
1157 script_paths.push_back(full_path);
1160 if (script_paths.empty())
1162 bbtkError("no '"<<upath<<"' subdir found in search paths"
1168 // === search paths list complete : now explore it
1170 // ==== relative name, iterate + load all .bbs/.bbp files
1171 std::vector<std::string>::iterator i;
1172 for (i=script_paths.begin();i!=script_paths.end();i++)
1174 bbtkMessage("Interpreter",1,
1175 "--> Looking in '" << *i << "'" << std::endl);
1179 Utilities::Explore(*i, false, Filenames);
1181 for (std::vector<std::string>::iterator j = Filenames.begin();
1182 j!= Filenames.end(); ++j)
1184 int lgr = (*j).size();
1185 if (lgr < 5) continue;
1186 // ignore non .bbp file
1187 if ( (*j).substr(lgr-4, 4) != ".bbp") continue;
1189 (*stream) << "include \"" << *j << "\"\n";
1190 bbtkMessage("Interpreter",2," --> Found '" << *j << "'" << std::endl);
1193 } // for (std::vector...
1194 } // for (i=script_...
1199 bbtkMessage("Interpreter",1,
1200 " --> No .bbp found"<< std::endl);
1204 bbtkMessage("Interpreter",1,
1205 " --> "<<nbBssFiles<<" .bbp found"<< std::endl);
1206 SwitchToStream(stream);
1210 //=============== end pkgname=="*" ===========
1213 // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name
1214 // (not only a plain script name)
1215 // we trust him, and try to expland the directory name
1216 // WARNING : starting from current local directory : ./whatYouWant (./ mandatory!)
1218 if (name[0]=='/' || name[1] == ':' || name[0]=='.') // absolute path (linux/windows) or relative path
1221 // ===========================================================check user supplied location
1222 fullnameGiven = true;
1224 fullPathScriptName = Utilities::ExpandLibName(name, false);
1226 // allow user to always forget ".bbs"
1227 int l = fullPathScriptName.size();
1231 if ((fullPathScriptName.substr(l-4, 4) != ".bbs")&&
1232 (fullPathScriptName.substr(l-4, 4) != ".bbp"))
1234 std::string tfullPathScriptName = fullPathScriptName + ".bbs";
1235 if ( Utilities::FileExists(tfullPathScriptName) )
1237 fullPathScriptName = tfullPathScriptName;
1242 tfullPathScriptName = fullPathScriptName + ".bbp";
1243 if ( Utilities::FileExists(tfullPathScriptName) )
1245 fullPathScriptName = tfullPathScriptName;
1252 if ( Utilities::FileExists(fullPathScriptName) )
1260 // =============================== iterate on the paths
1262 script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
1264 std::vector<std::string>::iterator i;
1265 for (i=script_paths.begin();i!=script_paths.end();++i)
1268 // we *really* want '.' to be the current working directory
1271 char buf[2048]; // for getcwd
1272 char * currentDir = getcwd(buf, 2048);
1273 std::string cwd(currentDir);
1277 std::string tfullPathScriptName = Utilities::MakePkgnameFromPath(path, name, false);
1278 if (tfullPathScriptName.substr(tfullPathScriptName.size()-4, 3)==".bb")
1280 fullPathScriptName = tfullPathScriptName;
1281 if ( ! Utilities::FileExists(fullPathScriptName) )
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",2,
1287 " [" <<fullPathScriptName <<"] : does not exist"
1289 continue; // try next path
1291 bbtkMessage("Interpreter",2,
1292 " [" <<fullPathScriptName
1293 <<"] : found" <<std::endl);
1295 break; // a script was found; we stop iterating
1299 fullPathScriptName = tfullPathScriptName + ".bbs";
1300 // Check if library exists
1301 if ( ! Utilities::FileExists(fullPathScriptName) )
1303 fullPathScriptName = tfullPathScriptName + ".bbp";
1304 if ( ! Utilities::FileExists(fullPathScriptName) )
1306 // The following is *NOT* a debug time message :
1307 // It's a user intended message.
1308 // Please don't remove it.
1309 bbtkMessage("Interpreter",2,
1310 " [" <<tfullPathScriptName <<".bbs/.bbp] : do not exist"
1312 continue; // try next path
1315 bbtkMessage("Interpreter",2,
1316 " [" <<fullPathScriptName
1317 <<"] : found" <<std::endl);
1319 break; // a script was found; we stop iterating
1321 } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
1327 if(fullPathScriptName == "")
1328 bbtkError("Path ["<<upath<<"] doesn't exist");
1330 bbtkError("Script ["<<fullPathScriptName<<"] not found");
1332 bbtkError("No ["<<pkgname<<".bbs/.bbp] script found");
1337 LoadScript(fullPathScriptName,name);
1338 if (source) GetExecuter()->SetCurrentFileName(fullPathScriptName);
1343 //=======================================================================
1346 //=======================================================================
1347 void Interpreter::SwitchToStream( std::stringstream* stream )
1349 mFile.push_back(stream);
1350 std::ostringstream buffer_name;
1352 buffer_name << "buffer_" ;
1354 if (mFileName.size()>0 )
1356 buffer_name << mFileName.back() << "_" << mLine.back();
1358 mFileName.push_back(buffer_name.str());
1359 mIncludeFileName.push_back(buffer_name.str());
1362 //=======================================================================
1364 //=======================================================================
1366 void Interpreter::LoadScript( std::string fullPathScriptName,
1367 std::string includeScriptName)
1369 Utilities::replace( fullPathScriptName ,
1370 INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
1372 if (find(mFileNameHistory.begin(),
1373 mFileNameHistory.end(),
1374 fullPathScriptName)!=mFileNameHistory.end())
1380 s = new std::ifstream;
1381 s->open(fullPathScriptName.c_str());
1384 bbtkError("Could not open file ["<<fullPathScriptName<<"]");
1388 bbtkMessage("Interpreter",1," -->[" << fullPathScriptName
1389 << "] found" << std::endl);
1392 mFileName.push_back(fullPathScriptName);
1393 mFileNameHistory.push_back(fullPathScriptName);
1394 mIncludeFileName.push_back(includeScriptName);
1400 //=======================================================================
1404 void Interpreter::CloseCurrentFile()
1406 bbtkDebugMessage("Interpreter",9,"Interpreter::CloseCurrentFile()"
1409 if (mFile.size()==0)
1411 bbtkDebugMessage("Interpreter",9," -> no file left open"<<std::endl);
1415 bbtkDebugMessage("Interpreter",9," Closing file '"<<mFileName.back()<<"'"<<std::endl);
1417 std::ifstream* file = dynamic_cast<std::ifstream*>(mFile.back());
1418 if (file!=0) file->close();
1420 delete mFile.back();
1422 mFileName.pop_back();
1423 mIncludeFileName.pop_back();
1426 bbtkDebugMessage("Interpreter",9," Remains "
1428 <<" open"<<std::endl);
1429 bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseCurrentFile()"
1432 //=======================================================================
1434 //=======================================================================
1438 void Interpreter::CloseAllFiles()
1440 bbtkDebugMessage("Interpreter",9,"Interpreter::CloseAllFiles()"
1443 while (mFile.size() != 0)
1447 bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseAllFiles()"
1450 //=======================================================================
1454 //=======================================================================
1458 void Interpreter::InterpretCommand( const std::vector<std::string>& words,
1459 CommandInfoType& info )
1461 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretCommand(...)"<<std::endl);
1463 // searches the command keyword
1464 CommandDictType::iterator c;
1465 c = mCommandDict.find(words[0]);
1466 if ( c == mCommandDict.end() ) {
1467 bbtkError(words[0]<<" : unknown command");
1470 // tests the number of args
1471 if ( ( ((int)words.size())-1 < c->second.argmin ) ||
1472 ( ((int)words.size())-1 > c->second.argmax ) )
1474 HelpCommand(words[0]);
1475 bbtkError(words[0]<<" : wrong number of arguments");
1479 bbtkDecTab("Interpreter",9);
1481 //=======================================================================
1484 //=======================================================================
1485 /// Displays help on all the commands
1486 void Interpreter::Help(const std::vector<std::string>& words)
1488 unsigned int nbarg = words.size()-1;
1496 if (words[1]=="packages")
1498 GetExecuter()->GetFactory()->PrintPackages(true);
1503 HelpCommand(words[1]);
1505 catch (bbtk::Exception e)
1509 GetExecuter()->GetFactory()->HelpPackage(words[1]);
1513 ConfigurationFile::GetInstance().Get_doc_path();
1514 url += "/bbdoc/" + words[1] + "/index.html";
1515 if (Utilities::FileExists(url))
1517 mUser->InterpreterUserViewHtmlPage(url);
1521 catch (bbtk::Exception f)
1525 std::string package;
1526 GetExecuter()->GetFactory()->HelpBlackBox(words[1],package);
1530 ConfigurationFile::GetInstance().Get_doc_path();
1531 url += "/bbdoc/" + package + "/index.html";
1532 if (Utilities::FileExists(url))
1534 url += "#" + words[1];
1535 mUser->InterpreterUserViewHtmlPage(url);
1539 catch (bbtk::Exception g)
1543 GetExecuter()->ShowRelations(words[1],"0","9999");
1545 catch (bbtk::Exception h){
1546 bbtkError("\""<<words[1].c_str()
1547 <<"\" is not a known command, package, black box type or black box name");
1555 if (words[2]=="all")
1557 if ( words[1]=="packages" )
1559 GetExecuter()->GetFactory()->PrintPackages(true,true);
1564 GetExecuter()->GetFactory()->HelpPackage(words[1],true);
1566 catch (bbtk::Exception f)
1572 HelpCommand(words[0]);
1573 bbtkError(words[0]<<" : syntax error");
1578 bbtkError("Should not reach here !!!");
1581 //=======================================================================
1583 //===================================================================
1584 /// Displays the Configuration
1585 void Interpreter::Config() const
1587 ConfigurationFile::GetInstance().GetHelp(1);
1589 //===================================================================
1591 //=======================================================================
1592 /// Displays help on all the commands
1593 void Interpreter::HelpCommands()
1595 std::cout << "Available commands :" << std::endl;
1596 CommandDictType::iterator i;
1597 for ( i = mCommandDict.begin();
1598 i != mCommandDict.end();
1600 std::cout << " " << i->first << std::endl;
1601 // std::cout << " usage : " << i->second.syntax << std::endl;
1602 // std::cout << " " << i->second.help << std::endl;
1606 //=======================================================================
1609 //=======================================================================
1610 /// Displays help on a particular commands
1611 void Interpreter::HelpCommand(const std::string& s)
1613 CommandDictType::iterator c;
1614 c = mCommandDict.find(s);
1615 if ( c == mCommandDict.end() ) {
1616 bbtkError(s<<" : Unknown command");
1618 // std::cout << " " << s << " : "<< std::endl;
1619 // CommandParamDictType::iterator i;
1620 // for ( i = c->second.begin();
1621 // i != c->second.end();
1623 std::cout << " usage : " << c->second.syntax << std::endl;
1624 std::cout << " " << c->second.help << std::endl;
1627 //=======================================================================
1630 //=======================================================================
1631 /// Fills the vector commands with the commands which
1632 /// have the first n chars of buf for prefix
1633 /// TODO : skip initial spaces in buf and also return the position of first
1634 /// non blank char in buf
1635 void Interpreter::FindCommandsWithPrefix( char* buf,
1637 std::vector<std::string>& commands )
1639 CommandDictType::const_iterator i;
1640 for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
1642 if ((i->first).find(buf,0,n) == 0)
1643 commands.push_back(i->first);
1646 //=======================================================================
1650 //=======================================================================
1651 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1653 inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
1654 inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
1656 // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
1657 // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
1658 // E.G. STORE THIS IN bbtk_config.xml
1659 #define BBTK_UP_ARROW_KBCODE 0x00415B1B
1660 #define BBTK_DOWN_ARROW_KBCODE 0x00425B1B
1661 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
1662 #define BBTK_LEFT_ARROW_KBCODE 0x00445B1B
1663 #define BBTK_BACKSPACE_KBCODE 0x00000008
1664 #define BBTK_DEL_KBCODE 0x0000007F
1665 #define BBTK_SPACE_KBCODE 0x00000020
1667 //=======================================================================
1668 void Interpreter::GetLineFromPrompt(std::string& s)
1673 unsigned int MAX_LINE_SIZE = 160;
1674 unsigned int MAX_HISTORY_SIZE = 100;
1676 char* newline = new char[MAX_LINE_SIZE];
1677 memset(newline,0,MAX_LINE_SIZE);
1678 char* histline = new char[MAX_LINE_SIZE];
1679 memset(histline,0,MAX_LINE_SIZE);
1681 char* line = newline;
1682 unsigned int hist = mHistory.size();
1688 read ( STDIN_FILENO, &c, 4) ;
1690 bbtkDebugMessage("debug",9,"[0x"<<std::hex<<c<<"]\n");
1692 // Printable character
1693 if ( (ind<MAX_LINE_SIZE-1) &&
1694 ( c >= BBTK_SPACE_KBCODE ) &&
1695 ( c < BBTK_DEL_KBCODE ))
1703 // delete the unused line
1709 // empty lines are not stored in from history
1712 // if history too long : delete oldest command
1713 if (mHistory.size()>MAX_HISTORY_SIZE)
1715 delete mHistory.front();
1716 mHistory.pop_front();
1718 mHistory.push_back(line);
1723 else if ( (ind>0) &&
1724 ((c == BBTK_BACKSPACE_KBCODE) ||
1725 (c == BBTK_DEL_KBCODE)) )
1733 // TODO : Command completion
1734 std::vector<std::string> commands;
1735 FindCommandsWithPrefix( line,ind,commands);
1736 if (commands.size()==1)
1738 std::string com = *commands.begin();
1739 for (; ind<com.size(); ++ind)
1741 PrintChar(com[ind]);
1747 else if (commands.size()>1)
1749 std::vector<std::string>::iterator i;
1751 for (i=commands.begin();i!=commands.end();++i)
1753 write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
1756 write(STDOUT_FILENO,"\n> ",3);
1757 //for (int j=0;j<ind;++j)
1759 write(STDOUT_FILENO,line,ind);
1763 // Arrow up : back in history
1764 else if (c==BBTK_UP_ARROW_KBCODE)
1768 // erase current line
1769 while (ind--) BackSpace();
1773 strcpy(histline,mHistory[hist]);
1777 write(STDOUT_FILENO,line,ind);
1780 // Arrow down : down in history
1781 else if (c==BBTK_DOWN_ARROW_KBCODE)
1783 if (hist<mHistory.size()-1)
1785 // erase current line
1786 while (ind--) BackSpace();
1790 strcpy(histline,mHistory[hist]);
1794 write(STDOUT_FILENO,line,ind);
1796 // end of history : switch back to newline
1797 else if (hist==mHistory.size()-1)
1799 // erase current line
1800 while (ind--) BackSpace();
1807 write(STDOUT_FILENO,line,ind);
1811 else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
1813 PrintChar(line[ind]);
1818 else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
1826 write(STDOUT_FILENO,"\n\r",2);
1834 //=======================================================================
1835 void Interpreter::GetLineFromPrompt(std::string& s)
1861 //=======================================================================
1867 //=======================================================================
1868 void Interpreter::CommandLineInterpreter()
1870 bbtkDebugMessageInc("Interpreter",9,
1871 "Interpreter::CommandLineInterpreter()"<<std::endl);
1873 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1874 // Initialise the tty in non canonical mode with no echo
1875 // oter remembers the previous settings to restore them after
1876 struct termios ter,oter;
1879 ter.c_lflag &= ~ECHO;
1880 ter.c_lflag &= ~ICANON;
1883 tcsetattr(0,TCSANOW,&ter);
1886 mCommandLine = true;
1888 bool insideComment = false; // for multiline comment
1894 GetLineFromPrompt(line);
1895 InterpretLine(line, insideComment);
1897 catch (QuitException e)
1899 bbtkMessage("Interpreter",1,"Interpreter : Quit"<<std::endl);
1902 catch (bbtk::Exception e)
1906 catch (std::exception& e)
1908 std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
1912 std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
1917 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1918 tcsetattr(0,TCSANOW,&oter);
1921 std::cout << "Good bye !" << std::endl;
1923 bbtkDebugDecTab("Interpreter",9);
1926 //=======================================================================
1927 void Interpreter::Graph(const std::vector<std::string>& words)
1930 bool system_display = true;
1932 if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
1933 system_display = false;
1935 if (words.size()==1)
1937 page = mVirtualExecuter->ShowGraph(".","0","0","","","",system_display);
1939 else if (words.size()==2)
1941 page = mVirtualExecuter->ShowGraph(words[1],"0","0","","","",system_display);
1943 else if (words.size()==3)
1945 page = mVirtualExecuter->ShowGraph(words[1],words[2],"0","","","",system_display);
1947 else if (words.size()==4)
1949 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],"","","",system_display);
1951 else if (words.size()==5)
1953 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],"","",system_display);
1955 else if (words.size()==6)
1957 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],"",system_display);
1959 else if (words.size()==7)
1961 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],words[6],system_display);
1964 if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
1965 mUser->InterpreterUserViewHtmlPage(page);
1968 //=======================================================================
1971 //=======================================================================
1972 void Interpreter::Index(const std::string& filename,
1973 const std::string& type)
1975 Factory::IndexEntryType t;
1976 if (type=="Initials") t = Factory::Initials;
1977 else if (type=="Categories") t = Factory::Categories;
1978 else if (type=="Packages") t = Factory::Packages;
1979 else if (type=="Adaptors") t = Factory::Adaptors;
1981 GetExecuter()->GetFactory()->CreateHtmlIndex(t,filename);
1983 //=======================================================================
1986 //=======================================================================
1987 void Interpreter::NewGUI(const std::string& boxname,
1988 const std::string& instanceName)
1990 if (mRealExecuter.expired())
1992 bbtkError("command 'newgui' cannot be compiled yet");
1995 std::string typeName = instanceName+"Type";
1996 std::stringstream* s = new std::stringstream;
1997 // create the complex box
1998 (*s) << "define "<<typeName<<std::endl;
1999 // (*s) << " description 'Automatically generated user interface for the box "
2000 // << boxname << "'" <<std::endl;
2001 // create the Layout box
2002 (*s) << " load wx"<<std::endl;
2003 (*s) << " new LayoutLine layout"<<std::endl;
2004 // create the output 'Widget'
2005 (*s) << " output Widget layout.Widget Widget"<<std::endl;
2006 // the box change output
2007 (*s) << " new MultipleInputs change"<<std::endl;
2008 (*s) << " output BoxChange change.Out BoxChange"<<std::endl;
2010 // Browse the inputs of the box in order to find which ones are not
2011 // connected and can be adapted from a widget adaptor
2012 // vector which stores the list of inputs of the box which must be connected
2013 std::vector<std::string> in;
2015 Factory::Pointer F = mVirtualExecuter->GetFactory();
2017 Package::Pointer user = F->GetPackage("user");
2019 ComplexBlackBoxDescriptor::Pointer workspace =
2020 mRealExecuter.lock()->GetCurrentDescriptor();
2025 bbtkError("Interpreter::CreateGUI : could not access the executer currently defined complex box");
2030 (ComplexBlackBoxDescriptor::Pointer)(user->GetBlackBoxMap().find("workspace")->second.get());
2033 BlackBox::Pointer box = workspace->GetPrototype()->bbGetBlackBox(boxname);
2034 // BlackBox::InputConnectorMapType incm = box->bbGetInputConnectorMap();
2036 BlackBox::InputConnectorMapType::iterator i;
2037 for (i=box->bbGetInputConnectorMap().begin();
2038 i!=box->bbGetInputConnectorMap().end();
2041 // If the input is connected : continue
2042 if (i->second->IsConnected()) continue;
2043 // Get the input descriptor
2044 const BlackBoxInputDescriptor* d = box->bbGetDescriptor()->GetInputDescriptor(i->first);
2045 // If it is a "system" input : skip it
2046 if ( ( d->GetCreatorTypeInfo() == typeid(AtomicBlackBoxDescriptor)) ||
2047 ( d->GetCreatorTypeInfo() == typeid(WxBlackBoxDescriptor)) )
2050 std::string widget,adaptor;
2051 // try to find a widget adaptor
2052 if (F->FindWidgetAdaptor(DataInfo(d->GetTypeInfo(),""),
2056 // command to create the adaptor
2057 (*s) << " new "<<adaptor<<" "<<i->first<<std::endl;
2058 // Sets the label of the widget adaptor to the name of the input
2059 (*s) << " set "<<i->first<<".Label "<<i->first<<std::endl;
2060 // Sets the initial value of the widget to the value of the input
2061 (*s) << " set "<<i->first<<".In \" "
2062 <<box->bbGetInputAsString(i->first)<<"\""
2064 // store the input name
2065 in.push_back(i->first);
2066 (*s) << " connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2067 //<i->first<<"'"<<std::endl;
2068 (*s) << " connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2070 // try to find a two pieces adaptor
2071 else if (F->FindWidgetAdaptor2(DataInfo(d->GetTypeInfo(),""),
2075 // command to create the widget
2076 (*s) << " new "<<widget<<" "<<i->first<<"Widget"<<std::endl;
2077 // command to create the adaptor
2078 (*s) << " new "<<adaptor<<" "<<i->first<<std::endl;
2080 (*s) << " connect "<<i->first<<"Widget.Out "
2081 <<i->first<<".In"<<std::endl;
2082 // Sets the label of the widget adaptor to the name of the input
2083 (*s) << " set "<<i->first<<"Widget.Label "<<i->first<<std::endl;
2084 // Sets the initial value of the widget to the value of the input
2085 (*s) << " set "<<i->first<<"Widget.In \" "
2086 <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2087 // store the input name
2088 in.push_back(i->first);
2089 (*s) << " connect "<<i->first<<"Widget.Widget layout.Widget"<<in.size()<<std::endl;
2090 //<i->first<<"'"<<std::endl;
2091 (*s) << " connect "<<i->first<<"Widget.BoxChange change.In"<<in.size()<<std::endl;
2094 // try to find an adaptor from string
2095 // If found then can create a text input which
2096 // will be automatically adapted
2097 else if (F->FindAdaptor(DataInfo(typeid(std::string),""),
2101 // command to create the adaptor
2102 (*s) << " new InputText "<<i->first<<std::endl;
2103 // Sets the label of the widget adaptor to the name of the input
2104 (*s) << " set "<<i->first<<".Title "<<i->first<<std::endl;
2105 // Sets the initial value of the widget to the value of the input
2106 (*s) << " set "<<i->first<<".In \" "
2107 <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2108 // store the input name
2109 in.push_back(i->first);
2110 (*s) << " connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2111 //<i->first<<"'"<<std::endl;
2112 (*s) << " connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2121 // command to create the output
2122 (*s) << " output "<<i->first<<" "
2123 <<i->first<<".Out "<<i->first<<std::endl;
2124 // <<" Output of the widget which allows to set "
2128 // Inputs for window properties
2129 (*s) << " input WinTitle layout.WinTitle Title"<<std::endl;
2130 (*s) << " input WinWidth layout.WinWidth Width"<<std::endl;
2131 (*s) << " input WinHeight layout.WinHeight Height"<<std::endl;
2132 (*s) << " input WinDialog layout.WinDialog Dialog"<<std::endl;
2133 (*s) << " input WinHide layout.WinHide Hide"<<std::endl;
2137 // Execute the box executes the layout
2138 (*s) << " exec layout" << std::endl;
2139 (*s) << "endefine" << std::endl;
2140 // (*s) << "help "<< typeName<< std::endl;
2141 // instanciate the box and connect it
2142 (*s) << "new "<<typeName<<" "<<instanceName<<std::endl;
2144 std::vector<std::string>::iterator j;
2145 for (j=in.begin();j!=in.end();++j)
2148 (*s) << "connect "<<instanceName<<"."<<*j<<" "
2149 << boxname<<"."<<*j<<std::endl;
2151 // That's all folks ! now execute the commands :
2154 //=======================================================================
2158 //==========================================================================
2159 void Interpreter::Debug(const std::string& name)
2161 if ((name.length()==2)&&(name[0]=='-'))
2165 bbtk::StaticInitTime::PrintObjectListInfo = true;
2169 // int o = MessageManager::GetMessageLevel("debug");
2170 // if (o<2) MessageManager::SetMessageLevel("debug",2);
2171 mVirtualExecuter->GetFactory()->CheckPackages();
2172 // MessageManager::SetMessageLevel("debug",o);
2177 Object:: PrintObjectListInfo(name);
2180 //==========================================================================
2181 //==========================================================================
2182 std::string Interpreter::GetObjectName() const
2184 return std::string("Interpreter");
2186 //==========================================================================
2188 //==========================================================================
2189 std::string Interpreter::GetObjectInfo() const
2191 std::stringstream i;
2194 //==========================================================================
2196 //==========================================================================
2197 size_t Interpreter::GetObjectSize() const
2199 size_t s = Superclass::GetObjectSize();
2200 s += Interpreter::GetObjectInternalSize();
2203 //==========================================================================
2204 //==========================================================================
2205 size_t Interpreter::GetObjectInternalSize() const
2207 size_t s = sizeof(Interpreter);
2210 //==========================================================================
2211 //==========================================================================
2212 size_t Interpreter::GetObjectRecursiveSize() const
2214 size_t s = Superclass::GetObjectRecursiveSize();
2215 s += Interpreter::GetObjectInternalSize();
2216 s += mVirtualExecuter->GetObjectRecursiveSize();
2219 //==========================================================================