]> Creatis software - bbtk.git/blob - kernel/src/bbtkExecuter.cxx
*** empty log message ***
[bbtk.git] / kernel / src / bbtkExecuter.cxx
1 /*=========================================================================                                                                               
2   Program:   bbtk
3   Module:    $RCSfile: bbtkExecuter.cxx,v $
4   Language:  C++
5   Date:      $Date: 2009/01/13 08:45:27 $
6   Version:   $Revision: 1.26 $
7 =========================================================================*/
8
9 /* ---------------------------------------------------------------------
10
11 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
12 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
13 *
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.
20 *
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
25 *  liability. 
26 *
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 * ------------------------------------------------------------------------ */                                                                         
30
31 /**
32  *  \file 
33  *  \brief class Executer: level 0 of script execution (code)
34  */
35
36 #include "bbtkExecuter.h"
37 #include "bbtkMessageManager.h"
38 #include "bbtkFactory.h"
39 #include "bbtkUtilities.h"
40 #include <fstream>
41
42 #ifdef USE_WXWIDGETS
43 #include <wx/textdlg.h>
44 #endif
45
46 #include "bbtkWxBlackBox.h"
47
48 #include "bbtkConfigurationFile.h"
49
50 namespace bbtk
51 {
52   //=======================================================================
53   Executer::Pointer Executer::New()
54   {
55     bbtkDebugMessage("Kernel",9,"Executer::New()"<<std::endl);
56     return MakePointer(new Executer());
57   }
58   //=======================================================================
59
60   //=======================================================================
61   Executer::Executer()
62     : 
63     mFactory(),
64     mRootPackage(),
65     mRootCBB(),
66     mNoExecMode(false),
67     mDialogMode(NoDialog)
68   {
69     bbtkDebugMessageInc("Kernel",9,"Executer::Executer()" <<std::endl);
70     mFactory = Factory::New();
71     // The smart pointer on this is not made yet (is made by New) 
72     // -> create it to pass it to the factory
73     // We have to "lock" the smart pointer because the factory
74     // only keeps a weak pointer on the executer
75     // -> this would auto-destroy !!
76     mFactory->SetExecuter(MakePointer(this,true));
77     Reset();
78     bbtkDebugDecTab("Kernel",9);
79   }
80   //=======================================================================
81
82   //=======================================================================
83   Executer::~Executer()
84   {
85      bbtkDebugMessageInc("Kernel",9,"==> Executer::~Executer()" <<std::endl);
86      mOpenDefinition.clear();
87      mOpenPackage.clear();
88      mFactory->Reset();
89      mFactory.reset();
90      bbtkDebugDecTab("Kernel",9);
91   }
92   //=======================================================================
93
94   //=======================================================================
95    /// Loads a package
96     void Executer::LoadPackage(const std::string &name )
97    {
98      GetFactory()->LoadPackage(name);
99    }
100   //=======================================================================
101
102   //=======================================================================
103     /// Unloads a package
104     void Executer::UnLoadPackage(const std::string &name )
105     {
106       GetFactory()->UnLoadPackage(name);
107     }
108   //=======================================================================
109
110   //=======================================================================
111   void Executer::Reset()
112   {
113     bbtkDebugMessageInc("Kernel",9,"Executer::Reset()" <<std::endl);
114
115     GetFactory()->CheckPackages();
116  
117     mOpenDefinition.clear();
118     mOpenPackage.clear();
119     GetFactory()->Reset();
120
121     // Create user package
122     Package::Pointer p =
123       Package::New("user","internal","User defined black boxes","");
124     // Insert the user package in the factory
125     GetFactory()->InsertPackage(p);
126     // And in the list of open packages
127     mOpenPackage.push_back(p);
128     mRootPackage = p;
129
130     // Create user workspace
131     ComplexBlackBoxDescriptor::Pointer r = 
132       ComplexBlackBoxDescriptor::New("workspace"); 
133     //    mRootCBB->Reference();
134     r->SetFactory(GetFactory());
135     r->AddToAuthor("bbtk");
136     r->AddToDescription("User's workspace");
137     mOpenDefinition.push_back(CBBDefinition(r,"user"));
138     // Register it into the user package
139     p->RegisterBlackBox(r);
140     mRootCBB = r;
141
142     //    Object::PrintObjectListInfo();
143     //  GetFactory()->CheckPackages();
144
145     bbtkDebugDecTab("Kernel",9);
146   }
147   //=======================================================================
148
149
150   //=======================================================================
151   /// changes the workspace name
152   void Executer::SetWorkspaceName( const std::string& n )
153   {
154     GetUserPackage()->ChangeBlackBoxName( GetWorkspace()->GetTypeName(), n );
155   }
156   //=======================================================================
157
158   //=======================================================================
159   void Executer::BeginPackage (const std::string &name)
160   {
161      bbtkDebugMessageInc("Kernel",9,"Executer::BeginPackage(\""<<name<<"\")"
162                         <<std::endl);
163      Package::Pointer p;
164      try 
165       {
166          p = GetFactory()->GetPackage(name);
167       }
168     catch (Exception e)
169       {
170         p = Package::New(name,"","","");
171         GetFactory()->InsertPackage(p);
172       }
173      mOpenPackage.push_back(p);
174   }
175   //=======================================================================
176
177   //=======================================================================
178   void Executer::EndPackage()
179   {
180     if (mOpenPackage.size()>1) mOpenPackage.pop_back();
181   }
182   //=======================================================================
183
184   //=======================================================================
185   void Executer::Define (const std::string &name,
186                          const std::string &pack,
187                          const std::string &scriptfilename)
188   {
189     bbtkDebugMessageInc("Kernel",9,"Executer::Define(\""<<name<<
190                         ","<<pack<<"\")"
191                         <<std::endl);
192
193     ComplexBlackBoxDescriptor::Pointer b 
194       = ComplexBlackBoxDescriptor::New(name);
195     b->SetFactory(GetFactory());
196     b->SetScriptFileName(scriptfilename);
197     mOpenDefinition.push_back( CBBDefinition( b, pack ) );
198     
199     bbtkDebugDecTab("Kernel",9);
200   }
201   //=======================================================================
202
203   //=======================================================================
204   /// Sets the file name to use for the current definition
205   /// (Used to set it after the Define command)
206   void Executer::SetCurrentFileName (const std::string &name )
207   {
208     mOpenDefinition.back().box->SetScriptFileName(name);
209   }
210   //=======================================================================
211
212   //=======================================================================
213   void Executer::Clear()
214   {
215     bbtkDebugMessageInc("Kernel",9,"Executer::Clear()" <<std::endl);
216     GetCurrentDescriptor()->GetPrototype()->Clear();
217
218   }
219   //=======================================================================
220
221   //=======================================================================
222   void Executer::EndDefine ()
223   {
224     bbtkDebugMessageInc("Kernel",9,"Executer::EndDefine(\""
225                         <<GetCurrentDescriptor()->GetTypeName()<<"\")" 
226                         <<std::endl);
227     // Does current package exist ?
228     Package::Pointer p;
229     std::string pname(mOpenDefinition.back().package);
230     if (pname.size()>0)
231       {
232         try
233           {
234             p = GetFactory()->GetPackage(pname);
235           }
236         catch (Exception e)
237           {
238             p = Package::New(pname,"","","");
239             GetFactory()->InsertPackage(p);
240           }
241       }
242     else
243       {
244         p = mOpenPackage.back().lock();
245       }
246     p->RegisterBlackBox(GetCurrentDescriptor());
247     
248     mOpenDefinition.pop_back();
249   }
250   //======================================================================= 
251
252   //=======================================================================  
253   void Executer::Kind(const std::string& kind)
254   {
255     if (kind=="ADAPTOR")
256       {
257         GetCurrentDescriptor()->AddToCategory("adaptor");
258         GetCurrentDescriptor()->SetKind(bbtk::BlackBoxDescriptor::ADAPTOR);
259       }
260     else if (kind=="DEFAULT_ADAPTOR")
261       {
262         GetCurrentDescriptor()->AddToCategory("adaptor");
263         GetCurrentDescriptor()->SetKind(bbtk::BlackBoxDescriptor::DEFAULT_ADAPTOR);
264       }
265     if (kind=="GUI")
266       {
267         GetCurrentDescriptor()->AddToCategory("gui");
268         GetCurrentDescriptor()->SetKind(bbtk::BlackBoxDescriptor::GUI);
269       }
270     else if (kind=="DEFAULT_GUI")
271       {
272         GetCurrentDescriptor()->AddToCategory("gui");
273         GetCurrentDescriptor()->SetKind(bbtk::BlackBoxDescriptor::DEFAULT_GUI);
274       }
275     else
276       {
277         bbtkError("Unknown box kind : '"<<kind<<"'. "
278                   <<"Valid kinds are 'ADAPTOR','DEFAULT_ADAPTOR',"
279                   <<"'GUI','DEFAULT_GUI'");
280       }
281   }
282   //=======================================================================
283
284   //=======================================================================
285   void Executer::Create ( const std::string& nodeType, 
286                           const std::string& nodeName)
287   {
288      GetCurrentDescriptor()->Add(nodeType,nodeName);
289   }
290   //=======================================================================
291
292   //=======================================================================
293   void Executer::Destroy(const std::string &boxName)
294   {
295     GetCurrentDescriptor()->Remove(boxName,true);
296   }
297   //=======================================================================
298
299   //=======================================================================
300   void Executer::Connect (const std::string &nodeFrom,
301                           const std::string &outputLabel,
302                           const std::string &nodeTo, 
303                           const std::string &inputLabel)
304   {
305     GetCurrentDescriptor()->Connect(nodeFrom, outputLabel, nodeTo, inputLabel);
306   }
307   //=======================================================================
308
309   //=======================================================================
310   void Executer::Execute (const std::string &nodeName) 
311   {
312     // if in root
313     if (GetCurrentDescriptor()==GetWorkspace()) 
314      {
315         if (!mNoExecMode) 
316         {
317            GetCurrentDescriptor()->GetPrototype()->bbGetBlackBox(nodeName)->bbExecute(true);
318         }
319      }
320      else 
321      {
322         GetCurrentDescriptor()->AddToExecutionList(nodeName) ;
323      }
324   }
325   //=======================================================================
326
327   //=======================================================================
328   void Executer::DefineInput ( const std::string &name,
329                                const std::string &box,
330                                const std::string &input,
331                                const std::string& help)
332   {
333     // If the input is defined in the Root box
334     if (GetCurrentDescriptor()==GetWorkspace()) 
335       {
336       // If the dialog mode is set to NoDialog
337       // and the user passed the name in the Inputs map 
338       // then the associated value is set to the box.input
339       // This is the way command line parameters are passed to the Root box
340          if (mDialogMode == NoDialog) 
341          {
342          // find if name is in mInputs
343             std::map<std::string,std::string>::iterator i;
344             i = mInputs.find(name);
345             if (i!=mInputs.end()) {
346                Set(box,input,(*i).second);
347             }
348          }
349         // If the dialog mode is set to TextDialog
350         // The user is prompted for the value
351         else if (mDialogMode == TextDialog) 
352         {
353            std::cout << name << "=";
354            std::string ans;
355            std::cin >> ans;
356            Set(box,input,ans);
357         }
358 #ifdef USE_WXWIDGETS
359        // If the dialog mode is set to GraphicalDialog
360        // A dialog box is pop up
361        else if (mDialogMode == GraphicalDialog) 
362        {
363           std::string mess("Enter the value of '");
364           mess += name;
365           mess += "' (";
366           mess += help;
367           mess += ")";
368           std::string title(name);
369           title += " ?";
370           std::string ans = wx2std ( wxGetTextFromUser( std2wx (mess), std2wx(title)));
371           Set(box,input,ans); 
372        }
373 #endif
374     }
375
376     GetCurrentDescriptor()->DefineInput(name,box,input,help);
377
378   }
379   //=======================================================================
380
381   //=======================================================================
382    void Executer::DefineOutput ( const std::string &name,
383                                  const std::string &box,
384                                  const std::string &output,
385                                  const std::string& help)
386   {
387     GetCurrentDescriptor()->DefineOutput(name,box,output,help);
388   }
389   //=======================================================================
390
391   //=======================================================================
392   void Executer::Set (const std::string &box,
393                       const std::string &input,
394                       const std::string &value)
395   {
396     BlackBox::Pointer b = GetCurrentDescriptor()->GetPrototype()->bbGetBlackBox(box);
397     // Looks for the adaptor
398
399     if ( b->bbGetInputType(input) !=  typeid(std::string) ) 
400       {
401         BlackBox::Pointer a =
402            GetFactory()->NewAdaptor(typeid(std::string),
403                                     b->bbGetInputType(input),
404                                     "tmp");
405          if (!a) 
406            {
407              bbtkError("No <"<<
408                        TypeName(b->bbGetInputType(input))
409                        <<"> to <std::string> found");
410            }
411          std::string v(value);
412          a->bbSetInput("In",v);
413          a->bbExecute();
414          b->bbSetInput(input,a->bbGetOutput("Out"));
415          //         a->Delete();
416       }
417     else 
418       {
419       std::string v(value);
420       b->bbSetInput(input,v);
421       }
422   }
423   //=======================================================================
424
425   //=======================================================================
426   std::string Executer::Get(const std::string &box,
427                             const std::string &output)
428   {
429     BlackBox::Pointer b = GetCurrentDescriptor()->GetPrototype()->bbGetBlackBox(box);
430     // Looks for the adaptor
431     if (b->bbGetOutputType(output) != typeid(std::string)) 
432       {
433         BlackBox::Pointer a =
434           GetFactory()->NewAdaptor(
435                                    b->bbGetOutputType(output),
436                                    typeid(std::string),
437                                    "tmp");
438         if (!a) 
439           {
440             bbtkError("No <"<<
441                       TypeName(b->bbGetOutputType(output))
442                       <<"> to <std::string> found");
443           }
444         b->bbExecute();
445         
446         a->bbSetInput("In",b->bbGetOutput(output));
447         a->bbExecute();
448         std::string r = a->bbGetOutput("Out").unsafe_get<std::string>();
449         //std::string v = *((std::string*)a->bbGetOutput("Out")) ;
450         //   std::cout << a->bbGetOutput("Out").unsafe_get<std::string>() 
451         //             << std::endl;
452         //std::string v(value);
453         //b->bbSetInput(input,a->bbGetOutput("Out"));
454         //        a->bbDelete();
455         return r;
456       }
457     else
458       {
459         b->bbExecute();
460         return b->bbGetOutput(output).unsafe_get<std::string>();
461         // std::string v = *((std::string*)b->bbGetOutput(output)) ;
462         // std::cout << b->bbGetOutput("Out").unsafe_get<std::string>() 
463         //   << std::endl;
464         // b->bbSetInput(input,&v);
465       }
466   }
467   //=======================================================================
468
469   //=======================================================================
470   void Executer::Author(const std::string &authorName)
471   {
472     GetCurrentDescriptor()->AddToAuthor(authorName,GetCurrentDescriptor()==GetWorkspace());
473   }
474   //=======================================================================
475
476   //=======================================================================
477   void Executer::Category(const std::string &category)
478   {
479     GetCurrentDescriptor()->AddToCategory(category,GetCurrentDescriptor()==GetWorkspace());
480   }
481   //=======================================================================
482
483   //=======================================================================
484   void Executer::Description(const std::string &d)
485   {
486     GetCurrentDescriptor()->AddToDescription(d,GetCurrentDescriptor()==GetWorkspace());
487   }
488   //=======================================================================
489
490   //=======================================================================
491   /// prints the list of the boxes of the current descriptor
492   void Executer::PrintBoxes()
493   {
494     bbtkMessageInc("Help",1,"The black box descriptor \""
495                    <<GetCurrentDescriptor()->GetTypeName()<<"\" contains : "<<std::endl);
496     GetCurrentDescriptor()->PrintBlackBoxes();
497     bbtkDecTab("Help",1);
498  }
499   //=======================================================================
500
501   //=======================================================================
502   std::string Executer::ShowGraph(const std::string &nameblackbox, 
503                                   const std::string &detailStr, 
504                                   const std::string &levelStr,
505                                   const std::string &output_html,
506                                   const std::string &custom_header,
507                                   const std::string &custom_title,
508                                   bool system_display )
509   {
510     int detail  =       atoi(detailStr.c_str());
511     int level   =       atoi(levelStr.c_str());
512
513     std::string filename_rootHtml (output_html) ;
514     std::string simplefilename_rootHtml ( Utilities::get_file_name(output_html));
515
516     bool relative_link = true;
517
518     // No output provided : automatic generation
519     if (output_html.length() == 0)
520       {
521                 // Don't pollute the file store with  "temp_dir" directories ...    
522                 std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
523         
524                 char c = default_doc_dir.c_str()[strlen(default_doc_dir.c_str())-1];
525         
526                 std::string directory = default_doc_dir; 
527                 if (c != '/' && c !='\\') directory = directory + "/";
528                 directory = directory +  "temp_dir";    
529         
530                 filename_rootHtml = directory + "/" + "User.html";
531                 simplefilename_rootHtml = "User.html" ;
532
533                 // Creating directory
534                 std::string command0("mkdir \"" +directory + "\"");
535                 system( command0.c_str() );
536
537                 relative_link = false;
538       }
539
540     Package::Pointer p;
541     try
542     {
543        p = GetFactory()->GetPackage(nameblackbox);
544     }
545     catch (Exception e)
546     {
547       p = GetUserPackage();
548     }
549     // Generating documentation-help of workspace
550     p->SetDocURL(filename_rootHtml);
551     p->SetDocRelativeURL(simplefilename_rootHtml);
552
553     p->CreateHtmlPage(filename_rootHtml,"bbtk","user package",custom_header,custom_title,detail,level,relative_link);
554
555     std::string page = filename_rootHtml;
556     /*
557     try 
558     {
559        ShowGraphTypes(nameblackbox);
560     }
561     catch (bbtk::Exception a)
562     {
563        std::cout <<"EXC"<<std::endl;
564        page = ShowGraphInstances(nameblackbox,detail,level,system_display);
565     }
566     */
567     return page;
568   }
569   //=======================================================================
570
571   //=======================================================================
572   /// Generate a png file with the actual pipeline (Graphviz-dot needed)
573   std::string Executer::ShowGraphInstances(const std::string &nameblackbox, int detail, int level,
574                                            bool system_display)
575   {
576
577     BlackBox::Pointer blackbox;
578     if (nameblackbox==".")
579     {
580        blackbox = GetCurrentDescriptor()->GetPrototype();
581     }
582     else
583     {
584        blackbox = GetCurrentDescriptor()->GetPrototype()->bbFindBlackBox(nameblackbox);
585     }
586     
587     std::string page;
588
589     if (blackbox)
590       {      
591         // Don't pollute the file store with  "temp_dir" directories ...
592         std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
593         char c = default_doc_dir.c_str()[strlen(default_doc_dir.c_str())-1];
594
595         std::string directory = default_doc_dir; 
596         if (c != '/' && c !='\\') directory = directory + "/";
597
598         directory = directory +  "temp_dir";
599         //std::string directory("temp_dir");
600         std::string filename(directory + "/" + "bbtk_graph_pipeline");
601         std::string filename_html(filename+".html");
602         std::string command0("mkdir \""+directory + "\"");
603
604 #if defined(_WIN32)
605         std::string command2("start ");
606 #else 
607         std::string command2("gnome-open ");
608 #endif
609
610         command2=command2+filename_html;
611         page = filename_html;
612         // 1. Generate Html Diagram
613         std::ofstream s;
614         s.open(filename_html.c_str());
615         if (s.good()) 
616           {
617             s << "<html><head><title>BBtk graph diagram</title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\"></head>\n";
618             s << "<body bgcolor=\"#FFFFFF\" text=\"#000000\"> \n\n";
619             if ( blackbox->bbGetName()=="workspacePrototype" )
620               {
621                 s << "<center>Current workspace</center>";
622               } else {
623               s << "<center>" << blackbox->bbGetName()<< "</center>";
624             } 
625
626             blackbox->bbInsertHTMLGraph( s, detail, level, true, directory, false );
627             s << "</body></html>\n";
628           }
629         s.close();
630         
631         // 2. Starting Browser
632         if (system_display) system( command2.c_str() );      
633       } 
634     else 
635       {
636         bbtkMessageInc("Help",1,"No black box: \""
637                        <<nameblackbox<<"\" " <<std::endl);
638       }
639     return page;
640   }
641   //=======================================================================
642
643   //=======================================================================
644   void Executer::ShowRelations(const std::string &nameblackbox, 
645                                const std::string &detailStr, 
646                                const std::string &levelStr)
647   {
648     bool found=false;
649     
650     int detail = atoi(detailStr.c_str());
651     int level  = atoi(levelStr.c_str());
652     BlackBox::Pointer blackbox;
653     if (nameblackbox.compare(".")==0)
654       {
655         blackbox=GetCurrentDescriptor()->GetPrototype();
656       } 
657     else 
658       {
659         blackbox = GetCurrentDescriptor()->GetPrototype()->bbFindBlackBox(nameblackbox);
660       }
661     
662     if (blackbox)
663       {
664         found=true;
665         blackbox->bbShowRelations(blackbox,detail,level); //,mFactory);
666       }
667     
668     if (!found) 
669       {
670         bbtkError("Blackbox Name not found.. <"  <<nameblackbox<<">");
671       }
672   }
673   //=======================================================================
674
675   //=======================================================================
676   /// sets the level of message
677   void Executer::SetMessageLevel(const std::string &kind,
678                                  int level)
679   {
680     bbtk::MessageManager::SetMessageLevel(kind,level);
681   }
682   //=======================================================================
683
684   //=======================================================================
685   /// Prints help on the messages
686   void  Executer::HelpMessages()
687   {
688     bbtk::MessageManager::PrintInfo();
689   }
690   //=======================================================================
691
692   //=======================================================================
693   ///
694   void Executer::Print(const std::string &str)
695   {  
696     if (GetNoExecMode() &&  (GetCurrentDescriptor()==GetWorkspace()) ) return;
697     if (GetCurrentDescriptor()!=GetWorkspace()) return;
698
699     bbtkDebugMessageInc("Interpreter",9,"Interpreter::Print(\""<<str<<"\")"<<std::endl);
700
701  // TO DO :
702  // InterpretLine ("load std")
703  // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande 
704  // InterpretLine("new Print _P_") 
705  // InterpretLine("connect _C_.Out _P_.In")
706  // int num = 1
707  
708
709     std::vector<std::string> chains;
710     std::string delimiters("$");
711
712     // Skip delimiters at beginning.
713     std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
714     bool is_text = true;
715     if (lastPos>0) is_text = false;
716
717     // Find first delimiter.
718     std::string::size_type pos     = str.find_first_of(delimiters, lastPos);
719
720     while (std::string::npos != pos || std::string::npos != lastPos)
721     {
722        if (is_text) 
723        {
724           // Found a text token, add it to the vector.
725           chains.push_back(str.substr(lastPos, pos - lastPos));
726  // std::string token = str.substr(lastPos, pos - lastPos)
727  // InterpretLine("set _C_.In%num% %token%")
728  
729        }
730        else 
731        {
732
733        // is an output (between $$) : decode 
734          std::string tok,box,output;
735          tok = str.substr(lastPos, pos - lastPos);
736          Utilities::SplitAroundFirstDot(tok,box,output);
737          chains.push_back( Get(box,output) );
738
739 // InterpretLine("connect %tok% _C_.In%num%") 
740
741        }
742         // Skip delimiters.  Note the "not_of"
743        lastPos = str.find_first_not_of(delimiters, pos);
744         // Find next delimiter
745        pos = str.find_first_of(delimiters, lastPos);
746     //
747        is_text = !is_text;
748 // num ++;
749      }
750 // InterpretLine("exec _P_")
751 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
752
753     std::vector<std::string>::iterator i;
754     for (i= chains.begin(); i!=chains.end(); ++i) 
755       {
756         Utilities::SubsBackslashN(*i);
757         bbtkMessage("Output",1,*i);
758       }
759     bbtkMessage("Output",1,std::endl);
760   }
761   //==========================================================================
762
763   //==========================================================================
764   std::string Executer::GetObjectName() const
765   {
766     return std::string("Executer");
767   }
768   //==========================================================================
769   
770   //==========================================================================
771   std::string  Executer::GetObjectInfo() const 
772   {
773     std::stringstream i;
774     return i.str();
775   }
776   //==========================================================================
777   //==========================================================================
778 size_t  Executer::GetObjectSize() const 
779 {
780   size_t s = Superclass::GetObjectSize();
781   s += Executer::GetObjectInternalSize();
782   return s;
783   }
784   //==========================================================================
785   //==========================================================================
786 size_t  Executer::GetObjectInternalSize() const 
787 {
788   size_t s = sizeof(Executer);
789   return s;
790   }
791   //==========================================================================
792   //==========================================================================
793   size_t  Executer::GetObjectRecursiveSize() const 
794   {
795     size_t s = Superclass::GetObjectRecursiveSize();
796     s += Executer::GetObjectInternalSize();
797     s += mFactory->GetObjectRecursiveSize();
798     return s;
799   }
800   //==========================================================================
801 }//namespace