1 /*=========================================================================
4 Module: $RCSfile: bbtkInterpreter.cxx,v $ $
6 Date: $Date: 2008/04/08 06:59:30 $
7 Version: $Revision: 1.58 $
9 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10 l'Image). All rights reserved. See Doc/License.txt or
11 http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
13 This software is distributed WITHOUT ANY WARRANTY; without even
14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 PURPOSE. See the above copyright notices for more information.
17 =========================================================================*/
20 * \brief class Interpreter :
23 #include "bbtkInterpreter.h"
24 #include "bbtkExecuter.h"
25 #include "bbtkTranscriptor.h"
26 #include "bbtkMessageManager.h"
27 #include "bbtkConfigurationFile.h"
28 #include "bbtkUtilities.h"
29 #include "bbtkWxBlackBox.h"
32 #ifdef CMAKE_HAVE_TERMIOS_H
34 #define BBTK_USE_TERMIOS_BASED_PROMPT
42 //Interpreter* Interpreter::mGlobalInterpreter = NULL;
44 //=======================================================================
48 Interpreter::Interpreter(const std::string& cpp_file)
55 bbtk::MessageManager::RegisterMessageType("Echo","Level>0 : Prints the 'echo' commands of the user.\n\tLevel>1 : Prints the command being interpreted",1);
56 bbtk::MessageManager::RegisterMessageType("Interpreter","Messages of the interpreter",0);
57 bbtkDebugMessageInc("Interpreter",9,"Interpreter::Interpreter()" <<std::endl);
59 if (cpp_file.size()!=0)
61 mExecuter = new bbtk::Transcriptor(cpp_file);
65 mExecuter = new bbtk::Executer();
67 mExecuter->SetInterpreter(this);
69 // For the time being, comment out previous line, and
70 // uncomment next line to check Transcriptor
72 //mExecuter = new bbtk::Transcriptor("GeneratedProgram.txt");
74 // Builds the commands dict
81 info.syntax = "new <type> <name>";
82 info.help = "Creates a new black box of type <type> with name <name>";
83 mCommandDict[info.keyword] = info;
85 info.keyword = "delete";
89 info.syntax = "delete <box>";
90 info.help = "Deletes the black box of name <box>";
91 mCommandDict[info.keyword] = info;
93 info.keyword = "newgui";
97 info.syntax = "newgui <box> <name>";
98 info.help = "Automatically creates a graphical user interface with name <name> for the black box <box> and connects it to the box inputs";
99 mCommandDict[info.keyword] = info;
101 info.keyword = "connect";
104 info.code = cConnect;
105 info.syntax = "connect <box1.output> <box2.input>";
106 info.help = "Connects the ouput <output> of black box <box1> to the input <input> of black box <box2>";
107 mCommandDict[info.keyword] = info;
109 info.keyword = "print";
113 info.syntax = "print <string>";
114 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').";
115 mCommandDict[info.keyword] = info;
117 info.keyword = "exec";
121 info.syntax = "exec <box | 'freeze' | 'unfreeze' >";
122 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.";
123 mCommandDict[info.keyword] = info;
125 info.keyword = "package";
128 info.code = cPackage;
129 info.syntax = "package <name>";
130 info.help = "Begins the definition of a package.";
131 mCommandDict[info.keyword] = info;
133 info.keyword = "endpackage";
136 info.code = cEndPackage;
137 info.syntax = "endpackage";
138 info.help = "Ends the definition of a package.";
139 mCommandDict[info.keyword] = info;
141 info.keyword = "define";
145 info.syntax = "define <type> [<package>]";
146 info.help = "Begins the definition of a new type of complex black box called <type>. If <package> if provided will create it in the given package.";
147 mCommandDict[info.keyword] = info;
149 info.keyword = "endefine";
152 info.code = cEndDefine;
153 info.syntax = "endefine";
154 info.help = "Ends the definition of a new type of complex black box";
155 mCommandDict[info.keyword] = info;
157 info.keyword = "kind";
161 info.syntax = "kind <ADAPTOR|DEFAULT_ADAPTOR|WIDGET_ADAPTOR|DEFAULT_WIDGET_ADAPTOR>";
162 info.help = "Sets the kind of the currently defined complex black box";
163 mCommandDict[info.keyword] = info;
165 info.keyword = "input";
169 info.syntax = "input <name> <box.input> <help>";
170 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";
171 mCommandDict[info.keyword] = info;
173 info.keyword = "output";
177 info.syntax = "output <name> <box.output> <help>";
178 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";
179 mCommandDict[info.keyword] = info;
181 info.keyword = "set";
185 info.syntax = "set <box.input> <value>";
186 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";
187 mCommandDict[info.keyword] = info;
189 info.keyword = "config"; // JPR
193 info.syntax = "config";
194 info.help = "Prints the value of all configuration parameters";
195 mCommandDict[info.keyword] = info;
197 info.keyword = "index"; // LG
202 info.syntax = "index [<filename> ['Initials'(default)|'Packages'|'Categories'|'Adaptors']]";
203 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.";
204 mCommandDict[info.keyword] = info;
206 info.keyword = "reset";
210 info.syntax = "reset";
211 info.help = "Deletes all boxes and unloads all packages (bbi is reset to its start state)";
212 mCommandDict[info.keyword] = info;
214 info.keyword = "author";
218 info.syntax = "author <string>";
219 info.help = "Adds the string <string> to the author information of the black box being defined";
220 mCommandDict[info.keyword] = info;
222 info.keyword = "category"; //JP
225 info.code = cCategory;
226 info.syntax = "category <list of items, separated by ;>";
227 info.help = "Adds the string <string> to the category information of the black box being defined";
228 mCommandDict[info.keyword] = info;
230 info.keyword = "description";
233 info.code = cDescription;
234 info.syntax = "description <string>";
235 info.help = "Adds the string <string> to the descriptive information of the black box being defined";
236 mCommandDict[info.keyword] = info;
238 info.keyword = "help";
242 info.syntax = "help";
243 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>";
244 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.";
245 mCommandDict[info.keyword] = info;
247 info.keyword = "message";
250 info.code = cMessage;
251 info.syntax = "message <kind> <level>";
252 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."; mCommandDict[info.keyword] = info;
254 info.keyword = "include";
257 info.code = cInclude;
258 info.syntax = "include <filename> [source]";
259 info.help = "Includes the file <filename>.\n 'source' : If the keyword 'source' is provided then informs bbi 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).";
260 mCommandDict[info.keyword] = info;
262 info.keyword = "quit";
266 info.syntax = "quit";
267 info.help = "Quits the program (during script execution it stops the complete execution)";
268 mCommandDict[info.keyword] = info;
270 info.keyword = "load";
274 info.syntax = "load <packagename>";
275 info.help = "Loads the black box package <packagename>";
276 mCommandDict[info.keyword] = info;
278 info.keyword = "unload";
282 info.syntax = "unload <packagename>";
283 info.help = "Unloads the black box package <packagename>";
284 mCommandDict[info.keyword] = info;
286 info.keyword = "graph";
290 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 ]]]]]]";
291 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')";
292 mCommandDict[info.keyword] = info;
295 info.keyword = "workspace";
298 info.code = cWorkspace;
299 info.syntax = "workspace < ( freeze | unfreeze ) | ( rename <newname> ) >";
300 info.help = "Configures the workspace.\n 'freeze' allow 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.";
301 mCommandDict[info.keyword] = info;
304 bbtkDebugDecTab("Interpreter",9);
307 //=======================================================================
311 //=======================================================================
315 Interpreter::~Interpreter()
317 bbtkDebugMessageInc("Interpreter",9,"Interpreter::~Interpreter()" <<std::endl);
320 bbtkDebugDecTab("Interpreter",9);
322 //=======================================================================
325 InterpreterError::InterpreterError( const std::string& message,
327 const std::string& script_file,
330 : Exception("Interpreter",0,message),
331 mInScriptFile(in_script_file),
332 mScriptFile(script_file),
333 mScriptLine(script_line)
336 InterpreterError::InterpreterError( const Exception& excep,
338 const std::string& script_file,
342 mInScriptFile(in_script_file),
343 mScriptFile(script_file),
344 mScriptLine(script_line)
347 //=======================================================================
348 void Interpreter::CatchBbtkException( const bbtk::Exception& e )
352 bool in_script = false;
353 std::string file("");
355 if (mFileName.size()) {
356 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
357 if (fs!=0) in_script = true;
358 file = mFileName.back();
362 throw InterpreterError(e,in_script,file,line);
366 std::stringstream mess;
367 mess << "* ERROR : "<<e.GetMessage()<<std::endl;
368 if (mFileName.size()) {
369 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
370 mess << "* LINE : "<<mLine.back()<<std::endl;
372 std::cerr << mess.str();
375 //=======================================================================
377 //=======================================================================
378 void Interpreter::CatchStdException( const std::exception& e )
382 bool in_script = false;
383 std::string file("");
385 if (mFileName.size()) {
386 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
387 if (fs!=0) in_script = true;
388 file = mFileName.back();
392 throw InterpreterError(e.what(),in_script,file,line);
396 std::stringstream mess;
397 mess << "* ERROR : "<<e.what()<<std::endl;
398 if (mFileName.size()) {
399 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
400 mess << "* LINE : "<<mLine.back()<<std::endl;
402 std::cerr << mess.str();
405 //=======================================================================
407 //=======================================================================
408 void Interpreter::CatchUnknownException()
412 bool in_script = false;
413 std::string file("");
415 if (mFileName.size()) {
416 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
417 if (fs!=0) in_script = true;
418 file = mFileName.back();
422 throw InterpreterError("Unknown exception caught",
423 in_script,file,line);
427 std::stringstream mess;
428 mess << "* UNDEFINED ERROR (not a bbtk nor a std exception)"
430 if (mFileName.size()) {
431 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
432 mess << "* LINE : "<<mLine.back()<<std::endl;
434 std::cerr << mess.str();
437 //=======================================================================
439 //=======================================================================
441 #define CATCH_MACRO \
442 catch (QuitException e) \
444 status = Interpreter_QUIT; \
445 if (mThrow) throw QuitException(); \
447 catch (bbtk::Exception e) \
449 status = Interpreter_ERROR; \
450 CatchBbtkException(e); \
452 catch (std::exception& e) \
454 status = Interpreter_ERROR; \
455 CatchStdException(e); \
459 status = Interpreter_ERROR; \
460 CatchUnknownException(); \
462 //=======================================================================
465 //=======================================================================
469 Interpreter::ExitStatus Interpreter::InterpretFile( const std::string& filename )
471 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
473 bool exm = mCommandLine;
474 mCommandLine = false;
476 ExitStatus status = Interpreter_OK;
480 SwitchToFile(filename);
482 bool insideComment = false; // for multiline comment
483 while (mFile.size()>0)
485 while (!mFile.back()->eof()) {
488 mFile.back()->getline(buf,500);
489 std::string str(buf);
490 int size=str.length();
491 if ( str[ size-1 ]==13 )
496 InterpretLine(str, insideComment);
505 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
506 bbtkDecTab("Interpreter",9);
512 //=======================================================================
515 //=======================================================================
519 Interpreter::ExitStatus
520 Interpreter::InterpretBuffer( std::stringstream* buffer )
522 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretBuffer()"<<std::endl);
524 bool exm = mCommandLine;
525 mCommandLine = false;
527 ExitStatus status = Interpreter_OK;
531 SwitchToStream(buffer);
532 bool insideComment = false; // for multiline comment
533 while (mFile.size()>0)
535 while (!mFile.back()->eof()) {
538 mFile.back()->getline(buf,500);
539 std::string str(buf);
541 int size=str.length();
542 if ( str[ size-1 ]==13 )
547 InterpretLine(str, insideComment);
557 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretBuffer()"<<std::endl);
558 bbtkDecTab("Interpreter",9);
563 //=======================================================================
565 //=======================================================================
566 /// Runs the interpretation of a command
567 Interpreter::ExitStatus Interpreter::InterpretLine( const std::string& line )
569 printf("EED Interpreter::InterpretLine %s \n", line.c_str() );
570 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretLine('"<<line<<"')"<<std::endl);
572 ExitStatus status = Interpreter_OK;
576 bool insideComment = false;
577 InterpretLine(line, insideComment);
581 catch (QuitException e)
583 status = Interpreter_QUIT;
585 catch (bbtk::Exception e)
587 std::cerr << "* ERROR : "<<e.GetMessage()<<std::endl;
588 status = Interpreter_ERROR;
590 catch (std::exception& e)
592 std::cerr << "* ERROR : "<<e.what()<<" (not in bbtk)"<<std::endl;
593 status = Interpreter_ERROR;
598 << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
599 status = Interpreter_ERROR;
603 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretLine()"
605 bbtkDecTab("Interpreter",9);
611 //=======================================================================
615 void Interpreter::InterpretLine( const std::string& line, bool &insideComment )
617 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretLine(\""<<line<<"\")"<<std::endl);
618 bbtkMessage("Echo",2,"\""<<line<<"\""<<std::endl);
620 std::vector<std::string> words;
621 SplitLine(line,words);
626 bbtkDebugDecTab("Interpreter",9);
630 // Single line comment : # or //
631 if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') )
633 bbtkDebugDecTab("Interpreter",9);
634 bbtkMessage("Interpreter",9,"Comment"<<std::endl);
638 // Multi line comment ( /* ... */ ) -delimiters on different lines !-
640 if (words[0][0]=='/' && words[0][1]=='*')
642 bbtkDebugDecTab("Interpreter",9);
643 bbtkMessage("Interpreter",9,"In multiline comment"<<std::endl);
644 insideComment = true;
648 if (words[0][0]=='*' && words[0][1]=='/')
650 bbtkDebugDecTab("Interpreter",9);
651 bbtkMessage("Interpreter",9,"Out multiline comment"<<std::endl);
652 if ( !insideComment ) {
653 bbtkDebugDecTab("Interpreter",9);
654 bbtkMessage("Interpreter",9,"Comment mismatch : '*/' with no matching '/*'"<<std::endl);
656 insideComment = false;
662 bbtkDebugDecTab("Interpreter",9);
663 bbtkMessage("Interpreter",9,"Multiline Comment"<<std::endl);
668 CommandInfoType command;
669 InterpretCommand(words,command);
671 bbtkDebugMessage("Interpreter",9,
672 "Command='"<<command.keyword
673 <<"' code="<<command.code<<std::endl);
675 std::string left,right,left2,right2;
676 std::string filename;
677 switch (command.code)
680 mExecuter->Create(words[1],words[2]);
684 mExecuter->Destroy(words[1]);
688 Utilities::SplitAroundFirstDot(words[1],left,right);
689 Utilities::SplitAroundFirstDot(words[2],left2,right2);
690 mExecuter->Connect(left,right,left2,right2);
694 mExecuter->BeginPackage(words[1]);
698 mExecuter->EndPackage();
702 if (mFileName.size()>0)
704 filename = mIncludeFileName.back(); //Utilities::get_file_name(mFileName.back());
708 mExecuter->Define(words[1],"",filename);
712 mExecuter->Define(words[1],words[2],filename);
717 mExecuter->EndDefine();
721 mExecuter->Kind(words[1]);
725 mExecuter->Print(words[1]);
729 if (words[1]=="freeze")
730 mExecuter->SetNoExecMode(true);
731 else if (words[1]=="unfreeze")
732 mExecuter->SetNoExecMode(false);
734 mExecuter->Execute(words[1]);
738 Utilities::SplitAroundFirstDot(words[2],left,right);
739 mExecuter->DefineInput(words[1],left,right,words[3]);
743 Utilities::SplitAroundFirstDot(words[2],left,right);
744 mExecuter->DefineOutput(words[1],left,right,words[3]);
748 Utilities::SplitAroundFirstDot(words[1],left,right);
749 mExecuter->Set(left,right,words[2]);
753 mExecuter->Author(words[1]);
757 NewGUI(words[1],words[2]);
761 mExecuter->Category(words[1]);
766 Index("tmp_index.html");
767 else if (words.size()==2)
769 else if (words.size()==3)
770 Index(words[1],words[2]);
774 mExecuter->Description(words[1]);
784 mExecuter->HelpMessages();
788 sscanf(words[2].c_str(),"%d",&level);
789 mExecuter->SetMessageLevel(words[1],level);
802 this->mExecuter->Reset();
808 InterpretFile(words[1]);
812 SwitchToFile(words[1]);
814 // if 'source' was given
817 GetExecuter()->SetCurrentFileName(words[1]);
822 GetExecuter()->LoadPackage(words[1]);
826 GetExecuter()->UnLoadPackage(words[1]);
831 throw QuitException();
835 if (words.size() == 2)
837 if (words[1]=="freeze") mExecuter->SetNoExecMode(true);
838 else if (words[1]=="unfreeze") mExecuter->SetNoExecMode(false);
842 mExecuter->SetWorkspaceName(words[2]);
847 bbtkInternalError("should not reach here !!!");
850 bbtkDecTab("Interpreter",9);
852 //=======================================================================
858 //=======================================================================
862 void Interpreter::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
864 bbtkDebugMessageInc("Interpreter",9,"Interpreter::SplitLine(\""<<str<<"\")"<<std::endl);
866 std::string delimiters = "\"";
867 std::vector<std::string> quote;
868 Utilities::SplitString(str,delimiters,quote);
871 std::vector<std::string>::iterator i;
872 for (i=quote.begin(); i!=quote.end(); )
874 Utilities::SplitString(*i,delimiters,tokens);
878 // bbtkDebugMessage("Interpreter",0,"\""<<*i<<"\""<<std::endl);
879 tokens.push_back(*i);
884 for (i=tokens.begin(); i!=tokens.end(); ++i)
886 bbtkDebugMessage("Interpreter",9,"["<<*i<<"] ");
888 bbtkDebugMessageCont("Interpreter",9,std::endl);
890 bbtkDebugDecTab("Interpreter",9);
892 //=======================================================================
897 //=======================================================================
902 void Interpreter::Print( const std::string& str)
904 if (mExecuter->GetNoExecMode()) return;
906 bbtkDebugMessageInc("Interpreter",9,"Interpreter::Print(\""<<str<<"\")"<<std::endl);
909 // InterpretLine ("load std")
910 // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande
911 // InterpretLine("new Print _P_")
912 // InterpretLine("connect _C_.Out _P_.In")
916 std::vector<std::string> chains;
917 std::string delimiters("$");
919 // Skip delimiters at beginning.
920 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
922 if (lastPos>0) is_text = false;
924 // Find first delimiter.
925 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
927 while (std::string::npos != pos || std::string::npos != lastPos)
931 // Found a text token, add it to the vector.
932 chains.push_back(str.substr(lastPos, pos - lastPos));
933 // std::string token = str.substr(lastPos, pos - lastPos)
934 // InterpretLine("set _C_.In%num% %token%")
940 // is an output (between $$) : decode
941 std::string tok,box,output;
942 tok = str.substr(lastPos, pos - lastPos);
943 Utilities::SplitAroundFirstDot(tok,box,output);
944 chains.push_back( mExecuter->Get(box,output) );
946 // InterpretLine("connect %tok% _C_.In%num%")
949 // Skip delimiters. Note the "not_of"
950 lastPos = str.find_first_not_of(delimiters, pos);
951 // Find next delimiter
952 pos = str.find_first_of(delimiters, lastPos);
957 // InterpretLine("exec _P_")
958 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
960 std::vector<std::string>::iterator i;
961 for (i= chains.begin(); i!=chains.end(); ++i)
963 // bbtkMessage("Echo",1,*i);
964 Utilities::SubsBackslashN(*i);
967 std::cout << std::endl;
968 bbtkDebugDecTab("Interpreter",9);
972 //=======================================================================
977 // ===================================================================================
979 void Interpreter::SwitchToFile( const std::string& name )
981 // Note : in the following :
982 // name : the user supplied name
983 // - abreviated name e.g. scr scr.bbs
984 // - relative full name e.g. ./scr.bbs ../../scr.bbs
985 // - absolute full name e.g. /home/usrname/proj/dir/scr.bbs
986 // same for Windows, with c:, d: ...
988 // use ./directory/subdir/scrname.bbs
991 bbtkDebugMessageInc("Interpreter",9,"Interpreter::SwitchToFile( \""
992 <<name<<"\")"<<std::endl);
994 std::vector<std::string> script_paths;
995 std::string fullPathScriptName; // full path script name
996 std::string pkgname; // e.g. <scriptname>.bbs
997 std::vector<std::string> Filenames;
999 // The following is *NOT* a debug time message :
1000 // It's a user intended message.
1001 // Please don't remove it.
1002 bbtkMessage("Interpreter",1,
1003 "look for : [" << name
1004 << "]" << std::endl);
1008 pkgname = Utilities::ExtractScriptName(name,upath);
1010 bbtkMessage("Interpreter",3,
1011 "extract : pkgname [" << pkgname
1012 << "] upath [" << upath << "]" << std::endl);
1013 bool fullnameGiven = false;
1014 bool foundFile = false;
1016 // ==== "*" provided : load all scripts in given path
1017 // relative (e.g. std/boxes/*) or absolute
1022 std::stringstream* stream = new std::stringstream;
1023 //if (upath.size()!=0) // avoid troubles for "*"
1025 // ==== no path provided : look in root bbs path
1026 if (upath.size()==0)
1028 // bbtkMessage("Interpreter",1,
1029 script_paths.push_back( ConfigurationFile::GetInstance().Get_root_bbs_path() );
1031 // ==== absolute path provided
1032 else if (upath[0]=='/' || upath[1] == ':' )
1034 if ( Utilities::IsDirectory( upath ) )
1036 script_paths.push_back(upath);
1040 bbtkError("'"<<upath<<"' : directory does not exist");
1043 // ==== relative path provided : search all bbs path appended with
1044 // the relative path provided
1047 std::vector<std::string>::const_iterator i;
1048 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1049 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1052 std::string full_path(*i);
1053 // we *really* want '.' to be the current working directory
1054 if (full_path == ".") {
1055 char buf[2048]; // for getcwd
1056 char * currentDir = getcwd(buf, 2048);
1057 std::string cwd(currentDir);
1058 full_path = currentDir;
1061 full_path += ConfigurationFile::GetInstance().Get_file_separator();
1064 if ( Utilities::IsDirectory( full_path ) )
1066 script_paths.push_back(full_path);
1069 if (script_paths.empty())
1071 bbtkError("no '"<<upath<<"' subdir found in search paths"
1076 // === search paths list complete : now explore it
1079 std::vector<std::string>::iterator i;
1080 for (i=script_paths.begin();i!=script_paths.end();i++)// ==== relative name, iterate + load all .bbs files
1082 bbtkMessage("Interpreter",1,
1083 "--> Looking in '" << *i << "'" << std::endl);
1087 int nbFiles = Utilities::Explore(*i, false, Filenames);
1090 for (std::vector<std::string>::iterator j = Filenames.begin();
1091 j!= Filenames.end(); ++j)
1093 int lgr = (*j).size();
1095 continue; // ignore non .bbs file
1096 if ((*j).substr(lgr-4, 4) != ".bbs")
1099 (*stream) << "include \"" << *j << "\"\n";
1100 bbtkMessage("Interpreter",2,
1101 " --> Found '" << *j << "'" << std::endl);
1108 bbtkMessage("Interpreter",1,
1109 " --> No .bbs found"<< std::endl);
1113 bbtkMessage("Interpreter",1,
1114 " --> "<<nbBssFiles<<" .bbs found"<< std::endl);
1115 SwitchToStream(stream);
1118 //break; // a directory was found; we stop iterating
1119 // LG : No! We want all files included !
1123 //=============== end pkgname=="*" ===========
1126 // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name
1127 // (not only a plain script name)
1128 // we trust him, and try to expland the directory name
1129 // WARNING : starting from current local directory : ./whatYouWant (./ mandatory!)
1131 if (name[0]=='/' || name[1] == ':' || name[0]=='.') // absolute path (linux/windows) or relative path
1134 // ===========================================================check user supplied location
1135 fullnameGiven = true;
1137 fullPathScriptName = Utilities::ExpandLibName(name, false);
1139 // allow user to always forget ".bbs"
1140 int l = fullPathScriptName.size();
1146 if (fullPathScriptName.substr(l-4, 4) != ".bbs")
1148 fullPathScriptName = fullPathScriptName + ".bbs";
1153 fullPathScriptName = fullPathScriptName + ".bbs";
1156 if ( Utilities::FileExists(fullPathScriptName))
1163 // =============================== iterate on the paths
1165 script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
1167 std::vector<std::string>::iterator i;
1168 for (i=script_paths.begin();i!=script_paths.end();++i)
1171 // we *really* want '.' to be the current working directory
1173 char buf[2048]; // for getcwd
1174 char * currentDir = getcwd(buf, 2048);
1175 std::string cwd(currentDir);
1179 fullPathScriptName = Utilities::MakePkgnameFromPath(path, name, true);
1181 // Check if library exists
1182 if ( ! Utilities::FileExists(fullPathScriptName) )
1184 // The following is *NOT* a debug time message :
1185 // It's a user intended message.
1186 // Please don't remove it.
1187 bbtkMessage("Interpreter",2,
1188 " [" <<fullPathScriptName <<"] : doesn't exist"
1190 continue; // try next path
1192 bbtkMessage("Interpreter",2,
1193 " [" <<fullPathScriptName
1194 <<"] : found" <<std::endl);
1196 break; // a script was found; we stop iterating
1198 } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
1204 if(fullPathScriptName == "")
1205 bbtkError("Path ["<<upath<<"] doesn't exist");
1207 bbtkError("Script ["<<fullPathScriptName<<"] not found");
1209 bbtkError("No ["<<pkgname<<".bbs] script found");
1213 LoadScript(fullPathScriptName,name);
1217 //=======================================================================
1220 //=======================================================================
1221 void Interpreter::SwitchToStream( std::stringstream* stream )
1223 mFile.push_back(stream);
1224 std::ostringstream buffer_name;
1226 buffer_name << "buffer_" ;
1228 if (mFileName.size()>0 )
1230 buffer_name << mFileName.back() << "_" << mLine.back();
1232 mFileName.push_back(buffer_name.str());
1233 mIncludeFileName.push_back(buffer_name.str());
1236 //=======================================================================
1238 //=======================================================================
1240 void Interpreter::LoadScript( std::string fullPathScriptName,
1241 std::string includeScriptName)
1243 Utilities::replace( fullPathScriptName , INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
1245 bool okScriptExist=false;
1246 int iStrScript,sizeVecStricpt=mFileName.size();
1247 for ( iStrScript=0;iStrScript<sizeVecStricpt;iStrScript++)
1249 if (mFileName[iStrScript] == fullPathScriptName )
1255 if (find(mFileName.begin(),mFileName.end(),fullPathScriptName)!=mFileName.end())
1256 // if (okScriptExist==true)
1258 bbtkMessage("Interpreter",1,"file '"<<fullPathScriptName
1259 <<"' already open : I do not open it once more to prevent recursive inclusion"<<std::endl);
1264 s = new std::ifstream;
1265 s->open(fullPathScriptName.c_str());
1268 bbtkError("Could not open file ["<<fullPathScriptName<<"]");
1272 bbtkMessage("Interpreter",1," -->[" << fullPathScriptName
1273 << "] found" << std::endl);
1276 mFileName.push_back(fullPathScriptName);
1277 mIncludeFileName.push_back(includeScriptName);
1283 //=======================================================================
1287 void Interpreter::CloseCurrentFile()
1289 bbtkDebugMessage("Interpreter",9,"Interpreter::CloseCurrentFile()"
1292 if (mFile.size()==0)
1294 bbtkDebugMessage("Interpreter",9," -> no file left open"<<std::endl);
1298 bbtkDebugMessage("Interpreter",9," Closing file '"<<mFileName.back()<<"'"<<std::endl);
1300 std::ifstream* file = dynamic_cast<std::ifstream*>(mFile.back());
1301 if (file!=0) file->close();
1303 delete mFile.back();
1305 mFileName.pop_back();
1306 mIncludeFileName.pop_back();
1309 bbtkDebugMessage("Interpreter",9," Remains "
1311 <<" open"<<std::endl);
1312 bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseCurrentFile()"
1315 //=======================================================================
1317 //=======================================================================
1321 void Interpreter::CloseAllFiles()
1323 bbtkDebugMessage("Interpreter",9,"Interpreter::CloseAllFiles()"
1326 while (mFile.size() != 0)
1330 mFile.back()->close();
1331 delete mFile.back();
1333 bbtkDebugMessage("Interpreter",9,
1334 " Closing file '"<<mFileName.back()<<"'"<<std::endl);
1335 mFileName.pop_back();
1336 mIncludeFileName.pop_back();
1340 bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseAllFiles()"
1343 //=======================================================================
1347 //=======================================================================
1351 void Interpreter::InterpretCommand( const std::vector<std::string>& words,
1352 CommandInfoType& info )
1354 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretCommand(...)"<<std::endl);
1356 // searches the command keyword
1357 CommandDictType::iterator c;
1358 c = mCommandDict.find(words[0]);
1359 if ( c == mCommandDict.end() ) {
1360 bbtkError(words[0]<<" : unknown command");
1363 // tests the number of args
1364 if ( ( words.size()-1 < c->second.argmin ) ||
1365 ( words.size()-1 > c->second.argmax ) )
1367 HelpCommand(words[0]);
1368 bbtkError(words[0]<<" : wrong number of arguments");
1372 bbtkDecTab("Interpreter",9);
1374 //=======================================================================
1377 //=======================================================================
1378 /// Displays help on all the commands
1379 void Interpreter::Help(const std::vector<std::string>& words)
1381 unsigned int nbarg = words.size()-1;
1389 if (words[1]=="packages")
1391 GetExecuter()->GetFactory()->PrintPackages(true);
1396 HelpCommand(words[1]);
1398 catch (bbtk::Exception e)
1402 GetExecuter()->GetFactory()->HelpPackage(words[1]);
1406 ConfigurationFile::GetInstance().Get_doc_path();
1407 url += "/bbdoc/" + words[1] + "/index.html";
1408 if (Utilities::FileExists(url))
1410 mUser->InterpreterUserViewHtmlPage(url);
1414 catch (bbtk::Exception f)
1418 std::string package;
1419 GetExecuter()->GetFactory()->HelpBlackBox(words[1],package);
1423 ConfigurationFile::GetInstance().Get_doc_path();
1424 url += "/bbdoc/" + package + "/index.html";
1425 if (Utilities::FileExists(url))
1427 url += "#" + words[1];
1428 mUser->InterpreterUserViewHtmlPage(url);
1432 catch (bbtk::Exception g)
1436 GetExecuter()->ShowRelations(words[1],"0","9999");
1438 catch (bbtk::Exception h){
1439 bbtkError("\""<<words[1].c_str()
1440 <<"\" is not a known command, package, black box type or black box name");
1448 if (words[2]=="all")
1450 if ( words[1]=="packages" )
1452 GetExecuter()->GetFactory()->PrintPackages(true,true);
1457 GetExecuter()->GetFactory()->HelpPackage(words[1],true);
1459 catch (bbtk::Exception f)
1465 HelpCommand(words[0]);
1466 bbtkError(words[0]<<" : syntax error");
1471 bbtkError("Should not reach here !!!");
1474 //=======================================================================
1476 //===================================================================
1477 /// Displays the Configuration
1478 void Interpreter::Config() const
1480 ConfigurationFile::GetInstance().GetHelp(1);
1482 //===================================================================
1484 //=======================================================================
1485 /// Displays help on all the commands
1486 void Interpreter::HelpCommands()
1488 std::cout << "Available commands :" << std::endl;
1489 CommandDictType::iterator i;
1490 for ( i = mCommandDict.begin();
1491 i != mCommandDict.end();
1493 std::cout << " " << i->first << std::endl;
1494 // std::cout << " usage : " << i->second.syntax << std::endl;
1495 // std::cout << " " << i->second.help << std::endl;
1499 //=======================================================================
1502 //=======================================================================
1503 /// Displays help on a particular commands
1504 void Interpreter::HelpCommand(const std::string& s)
1506 CommandDictType::iterator c;
1507 c = mCommandDict.find(s);
1508 if ( c == mCommandDict.end() ) {
1509 bbtkError(s<<" : Unknown command");
1511 // std::cout << " " << s << " : "<< std::endl;
1512 // CommandParamDictType::iterator i;
1513 // for ( i = c->second.begin();
1514 // i != c->second.end();
1516 std::cout << " usage : " << c->second.syntax << std::endl;
1517 std::cout << " " << c->second.help << std::endl;
1520 //=======================================================================
1523 //=======================================================================
1524 /// Fills the vector commands with the commands which
1525 /// have the first n chars of buf for prefix
1526 /// TODO : skip initial spaces in buf and also return the position of first
1527 /// non blank char in buf
1528 void Interpreter::FindCommandsWithPrefix( char* buf,
1530 std::vector<std::string>& commands )
1532 CommandDictType::const_iterator i;
1533 for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
1535 if ((i->first).find(buf,0,n) == 0)
1536 commands.push_back(i->first);
1539 //=======================================================================
1543 //=======================================================================
1544 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1546 inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
1547 inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
1549 // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
1550 // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
1551 // E.G. STORE THIS IN bbtk_config.xml
1552 #define BBTK_UP_ARROW_KBCODE 0x00415B1B
1553 #define BBTK_DOWN_ARROW_KBCODE 0x00425B1B
1554 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
1555 #define BBTK_LEFT_ARROW_KBCODE 0x00445B1B
1556 #define BBTK_BACKSPACE_KBCODE 0x00000008
1557 #define BBTK_DEL_KBCODE 0x0000007F
1558 #define BBTK_SPACE_KBCODE 0x00000020
1560 //=======================================================================
1561 void Interpreter::GetLineFromPrompt(std::string& s)
1566 int MAX_LINE_SIZE = 160;
1567 int MAX_HISTORY_SIZE = 100;
1569 char* newline = new char[MAX_LINE_SIZE];
1570 memset(newline,0,MAX_LINE_SIZE);
1571 char* histline = new char[MAX_LINE_SIZE];
1572 memset(histline,0,MAX_LINE_SIZE);
1574 char* line = newline;
1575 int hist = mHistory.size();
1581 read ( STDIN_FILENO, &c, 4) ;
1583 bbtkDebugMessage("Debug",9,"[0x"<<std::hex<<c<<"]\n");
1585 // Printable character
1586 if ( (ind<MAX_LINE_SIZE-1) &&
1587 ( c >= BBTK_SPACE_KBCODE ) &&
1588 ( c < BBTK_DEL_KBCODE ))
1596 // delete the unused line
1602 // empty lines are not stored in from history
1605 // if history too long : delete oldest command
1606 if (mHistory.size()>MAX_HISTORY_SIZE)
1608 delete mHistory.front();
1609 mHistory.pop_front();
1611 mHistory.push_back(line);
1616 else if ( (ind>0) &&
1617 ((c == BBTK_BACKSPACE_KBCODE) ||
1618 (c == BBTK_DEL_KBCODE)) )
1626 // TODO : Command completion
1627 std::vector<std::string> commands;
1628 FindCommandsWithPrefix( line,ind,commands);
1629 if (commands.size()==1)
1631 std::string com = *commands.begin();
1632 for (; ind<com.size(); ++ind)
1634 PrintChar(com[ind]);
1640 else if (commands.size()>1)
1642 std::vector<std::string>::iterator i;
1644 for (i=commands.begin();i!=commands.end();++i)
1646 write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
1649 write(STDOUT_FILENO,"\n> ",3);
1650 //for (int j=0;j<ind;++j)
1652 write(STDOUT_FILENO,line,ind);
1656 // Arrow up : back in history
1657 else if (c==BBTK_UP_ARROW_KBCODE)
1661 // erase current line
1662 while (ind--) BackSpace();
1666 strcpy(histline,mHistory[hist]);
1670 write(STDOUT_FILENO,line,ind);
1673 // Arrow down : down in history
1674 else if (c==BBTK_DOWN_ARROW_KBCODE)
1676 if (hist<mHistory.size()-1)
1678 // erase current line
1679 while (ind--) BackSpace();
1683 strcpy(histline,mHistory[hist]);
1687 write(STDOUT_FILENO,line,ind);
1689 // end of history : switch back to newline
1690 else if (hist==mHistory.size()-1)
1692 // erase current line
1693 while (ind--) BackSpace();
1700 write(STDOUT_FILENO,line,ind);
1704 else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
1706 PrintChar(line[ind]);
1711 else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
1719 write(STDOUT_FILENO,"\n\r",2);
1727 //=======================================================================
1728 void Interpreter::GetLineFromPrompt(std::string& s)
1754 //=======================================================================
1760 //=======================================================================
1761 void Interpreter::CommandLineInterpreter()
1763 bbtkDebugMessageInc("Interpreter",9,
1764 "Interpreter::CommandLineInterpreter()"<<std::endl);
1766 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1767 // Initialise the tty in non canonical mode with no echo
1768 // oter remembers the previous settings to restore them after
1769 struct termios ter,oter;
1772 ter.c_lflag &= ~ECHO;
1773 ter.c_lflag &= ~ICANON;
1776 tcsetattr(0,TCSANOW,&ter);
1779 mCommandLine = true;
1781 bool insideComment = false; // for multiline comment
1787 GetLineFromPrompt(line);
1788 InterpretLine(line, insideComment);
1790 catch (QuitException e)
1792 bbtkMessage("Interpreter",1,"Interpreter : Quit"<<std::endl);
1795 catch (bbtk::Exception e)
1799 catch (std::exception& e)
1801 std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
1805 std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
1810 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1811 tcsetattr(0,TCSANOW,&oter);
1814 std::cout << "Good bye !" << std::endl;
1816 bbtkDebugDecTab("Interpreter",9);
1819 //=======================================================================
1820 void Interpreter::Graph(const std::vector<std::string>& words)
1823 bool system_display = true;
1825 if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
1826 system_display = false;
1828 if (words.size()==1)
1830 page = mExecuter->ShowGraph(".","0","0","","","",system_display);
1832 else if (words.size()==2)
1834 page = mExecuter->ShowGraph(words[1],"0","0","","","",system_display);
1836 else if (words.size()==3)
1838 page = mExecuter->ShowGraph(words[1],words[2],"0","","","",system_display);
1840 else if (words.size()==4)
1842 page = mExecuter->ShowGraph(words[1],words[2],words[3],"","","",system_display);
1844 else if (words.size()==5)
1846 page = mExecuter->ShowGraph(words[1],words[2],words[3],words[4],"","",system_display);
1848 else if (words.size()==6)
1850 page = mExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],"",system_display);
1852 else if (words.size()==7)
1854 page = mExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],words[6],system_display);
1857 if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
1858 mUser->InterpreterUserViewHtmlPage(page);
1861 //=======================================================================
1864 //=======================================================================
1865 void Interpreter::Index(const std::string& filename,
1866 const std::string& type)
1868 Factory::IndexEntryType t;
1869 if (type=="Initials") t = Factory::Initials;
1870 else if (type=="Categories") t = Factory::Categories;
1871 else if (type=="Packages") t = Factory::Packages;
1872 else if (type=="Adaptors") t = Factory::Adaptors;
1874 GetExecuter()->GetFactory()->CreateHtmlIndex(t,filename);
1876 //=======================================================================
1879 //=======================================================================
1880 void Interpreter::NewGUI(const std::string& boxname,
1881 const std::string& instanceName)
1883 std::string typeName = instanceName+"Type";
1884 std::stringstream* s = new std::stringstream;
1885 // create the complex box
1886 (*s) << "define "<<typeName<<std::endl;
1887 // (*s) << " description 'Automatically generated user interface for the box "
1888 // << boxname << "'" <<std::endl;
1889 // create the Layout box
1890 (*s) << " load wx"<<std::endl;
1891 (*s) << " new LayoutLine layout"<<std::endl;
1892 // create the output 'Widget'
1893 (*s) << " output Widget layout.Widget Widget"<<std::endl;
1894 // the box change output
1895 (*s) << " new MultipleInputs change"<<std::endl;
1896 (*s) << " output BoxChange change.Out BoxChange"<<std::endl;
1898 // Browse the inputs of the box in order to find which ones are not
1899 // connected and can be adapted from a widget adaptor
1900 // vector which stores the list of inputs of the box which must be connected
1901 std::vector<std::string> in;
1902 Factory* F = mExecuter->GetFactory();
1906 bbtkError("Interpreter::CreateGUI : could not access the executer factory");
1908 Package* user = F->GetPackage("user");
1909 ComplexBlackBoxDescriptor* workspace
1910 = (ComplexBlackBoxDescriptor*)user->GetBlackBoxMap().find("workspace")->second;
1912 BlackBox* box = workspace->GetPrototype()->bbGetBlackBox(boxname);
1913 // BlackBox::InputConnectorMapType incm = box->bbGetInputConnectorMap();
1915 BlackBox::InputConnectorMapType::iterator i;
1916 for (i=box->bbGetInputConnectorMap().begin();
1917 i!=box->bbGetInputConnectorMap().end();
1920 // If the input is connected : continue
1921 if (i->second->IsConnected()) continue;
1922 // Get the input descriptor
1923 const BlackBoxInputDescriptor* d = box->bbGetDescriptor()->GetInputDescriptor(i->first);
1924 // If it is a "system" input : skip it
1925 if ( ( d->GetCreatorTypeInfo() == typeid(AtomicBlackBoxDescriptor)) ||
1926 ( d->GetCreatorTypeInfo() == typeid(WxBlackBoxDescriptor)) )
1928 // try to find a widget adaptor
1929 std::string adaptor;
1930 if (F->FindWidgetAdaptor(DataInfo(typeid(Void),""),
1934 // store the input name
1935 in.push_back(i->first);
1936 // command to create the adaptor
1937 (*s) << " new "<<adaptor<<" "<<i->first<<std::endl;
1938 // command to create the output
1939 (*s) << " output "<<i->first<<" "
1940 <<i->first<<".Out "<<i->first<<std::endl;
1941 // <<" Output of the widget which allows to set "
1942 //<i->first<<"'"<<std::endl;
1943 // Sets the label of the widget adaptor to the name of the input
1944 (*s) << " set "<<i->first<<".Label "<<i->first<<std::endl;
1945 (*s) << " connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
1946 (*s) << " connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
1948 // try to find an adaptor from string
1949 // If found then can create a text input which
1950 // will be automatically adapted
1951 else if (F->FindAdaptor(DataInfo(typeid(std::string),""),
1955 // store the input name
1956 in.push_back(i->first);
1957 // command to create the adaptor
1958 (*s) << " new InputText "<<i->first<<std::endl;
1959 // command to create the output
1960 (*s) << " output "<<i->first<<" "
1961 <<i->first<<".Out "<<i->first<<std::endl;
1962 // <<" Output of the widget which allows to set "
1963 //<i->first<<"'"<<std::endl;
1964 // Sets the label of the widget adaptor to the name of the input
1965 (*s) << " set "<<i->first<<".Title "<<i->first<<std::endl;
1966 (*s) << " connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
1967 (*s) << " connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
1971 // Inputs for window properties
1972 (*s) << " input WinTitle layout.WinTitle Title"<<std::endl;
1973 (*s) << " input WinWidth layout.WinWidth Width"<<std::endl;
1974 (*s) << " input WinHeight layout.WinHeight Height"<<std::endl;
1975 (*s) << " input WinDialog layout.WinDialog Dialog"<<std::endl;
1976 (*s) << " input WinHide layout.WinHide Hide"<<std::endl;
1980 // Execute the box executes the layout
1981 (*s) << " exec layout" << std::endl;
1982 (*s) << "endefine" << std::endl;
1983 // (*s) << "help "<< typeName<< std::endl;
1984 // instanciate the box and connect it
1985 (*s) << "new "<<typeName<<" "<<instanceName<<std::endl;
1987 std::vector<std::string>::iterator j;
1988 for (j=in.begin();j!=in.end();++j)
1991 (*s) << "connect "<<instanceName<<"."<<*j<<" "
1992 << boxname<<"."<<*j<<std::endl;
1994 // That's all folks ! now execute the commands :
1997 //=======================================================================