]> Creatis software - bbtk.git/blob - kernel/appli/bbfy/bbfy.cpp
64120471d5fa2883012204fa218108a190ee9356
[bbtk.git] / kernel / appli / bbfy / bbfy.cpp
1 #ifdef WIN32
2 #define _CRT_SECURE_NO_DEPRECATE
3 #endif
4
5 #include <stdio.h>
6 #include "xmlParser.h"
7 #include <iostream>
8 #include <fstream>
9 #include <sstream>
10 #include <vector>
11
12 //==========================================================================
13 class bbfyException
14 {
15 public: 
16   bbfyException(const std::string& message) : mMessage(message) {}
17
18   std::string mMessage;
19 };
20 //==========================================================================
21
22 //==========================================================================
23 class bbfy
24 {
25 public:
26   bbfy(const std::string& filename, 
27        const std::string& package = "PACKAGE_NAME",
28        const std::string& output_path = "",
29        bool verbose = false);
30   
31   void CreateBlackBox();
32   void ParseXML();
33   void CreateHeader();
34   void CreateCode();
35
36   void WriteGenericITKFilterHeader();
37
38   void BeginNamespace();
39   void EndNamespace();
40
41 private:
42   //
43   std::string mFilename;
44   std::string mOutputPath;
45   bool mVerbose;
46
47   //
48   std::string mName;
49   typedef enum 
50     {
51       STD,
52       itkImageToImageFilter,
53       vtkImageAlgorithm,
54       vtkPolyDataAlgorithm,
55     }
56     BoxType;
57   BoxType mType;
58   bool mIsWidget;
59   std::string mParentBlackBox;
60   std::string mItkParent;
61   std::string mVtkParent;
62   bool mGeneric;
63   std::string mAuthor;
64   std::string mDescription;
65   std::string mCategory;
66   std::string mPackage;
67   // bool mIsInNamespace;
68   std::string mNamespace;
69   // int mNbTemplateParam;
70   std::vector<std::string> mTemplateParam;
71   std::string mTemplateDeclaration;
72   std::string mTemplateImplementation;
73
74   std::vector<std::string> mInclude;
75
76   std::string mUserConstructor;
77   std::string mUserCopyConstructor;
78   std::string mUserDestructor;
79
80   typedef struct
81   {
82     std::string name;
83     std::string type;
84     std::string help;
85     std::string special;
86     std::string generic_type;
87   }
88     IO;
89   
90   std::vector<IO> mInput;
91   std::vector<IO> mOutput;
92
93   std::string mProcess;
94   std::string mCreateWidget;
95
96   //
97   std::ofstream mFile;
98   std::string mHName;
99   std::string mCxxName;
100
101 };
102 //==========================================================================
103
104
105
106 //==========================================================================
107 bbfy::bbfy(const std::string& filename, 
108            const std::string& package,
109            const std::string& output_path,
110            bool verbose)
111 {
112   mFilename = filename;
113   mPackage = package;
114   mNamespace = "bb" + mPackage;
115
116   mOutputPath = output_path;
117   mVerbose = verbose;
118
119   CreateBlackBox();
120 }
121 //==========================================================================
122
123 //==========================================================================
124 void bbfy::CreateBlackBox()
125 {
126   // Parse XML input file
127   ParseXML();
128   // Create output files
129   CreateHeader();
130   CreateCode();
131 }
132 //==========================================================================
133
134
135 //==========================================================================
136 void GetTextOrClear(const XMLNode& node, std::string& var) 
137 {
138   if (node.nText()>0) 
139     {
140       var = node.getText();
141     }
142   else if (node.nClear()>0) 
143     {
144       var = node.getClear().lpszValue;
145     }
146   else 
147     {
148       std::string mess("Error : element <");
149       mess += node.getName();
150       mess += "> : no text nor <PRE></PRE> clear tag found";
151       throw bbfyException(mess);
152     }
153 }
154 //==========================================================================
155
156
157 //==========================================================================
158 void bbfy::ParseXML()
159 {
160   XMLResults* res = new XMLResults;
161   XMLNode BB = XMLNode::parseFile(mFilename.c_str(),"blackbox",res);
162
163   if ( res->error != eXMLErrorNone ) 
164     {
165       std::ostringstream str;
166       str << XMLNode::getError(res->error);
167       str << " [line " << res->nLine << ", col "<<res->nColumn<<"]"; 
168       delete res;
169       throw bbfyException(str.str());
170     }
171   delete res;
172
173   // Name
174   if (!BB.isAttributeSet("name")) 
175     {
176       throw bbfyException("Error : no 'name' attribute found (mandatory)");
177     }
178   mName = BB.getAttribute("name");
179
180   if (mVerbose) std::cout << "* Creating BlackBox '"<<mName<<"'"<<std::endl;
181
182   // Type 
183   mGeneric = false;
184   mType = STD;
185
186
187   if (BB.isAttributeSet("type")) 
188     {
189       std::string bbtype = BB.getAttribute("type");
190       if (bbtype=="standard")
191         {
192           mGeneric = false;
193           mType = STD;
194         }
195       else if (bbtype=="itkImageToImageFilter")
196         {
197           mType = itkImageToImageFilter;
198           // Looks for <itkparent> tag
199           if (!BB.nChildNode("itkparent")) 
200             {
201               throw bbfyException("Error : blackbox type 'itkImageToImageFilter' but no <itkparent> tag found (mandatory)");
202             }
203           GetTextOrClear(BB.getChildNode("itkparent"),mItkParent);
204           // 
205           mGeneric = false;
206           if (BB.isAttributeSet("generic")) mGeneric=true;
207         }
208       else if ((bbtype=="vtkImageAlgorithm") || (bbtype=="vtkPolyDataAlgorithm"))
209         {
210           mType = vtkImageAlgorithm;
211           // Looks for <vtkparent> tag
212           if (!BB.nChildNode("vtkparent")) 
213             {
214               throw bbfyException("Error : blackbox type 'vtkImageAlgorithm' but no <vtkparent> tag found (mandatory)");
215             }
216           GetTextOrClear(BB.getChildNode("vtkparent"),mVtkParent);
217           // 
218         }
219       else 
220         {
221           std::string mess("Error : blackbox type '");
222           mess += bbtype;
223           mess += "' unknown (types are 'standard','itkfilter')";
224           throw bbfyException(mess);
225         }
226     }
227
228   // Is a widget box ?
229   if (BB.isAttributeSet("widget")) 
230     {
231       mIsWidget = true;
232       mParentBlackBox = "bbtk::WxBlackBox";
233       mInclude.push_back("bbtkWxBlackBox.h");
234     }
235   else 
236     {
237       mIsWidget = false;
238       mParentBlackBox = "bbtk::AtomicBlackBox";
239       mInclude.push_back("bbtkAtomicBlackBox.h");
240     }
241
242   /*
243   // Parent black box
244   if (!BB.nChildNode("parentblackbox")) 
245     {
246       throw bbfyException("Error : no <parentblackbox> tag found (mandatory)");
247    }
248   GetTextOrClear(BB.getChildNode("parentblackbox"),mParentBlackBox);
249
250   // Package
251   if (!BB.nChildNode("package")) 
252     {
253       throw bbfyException("Error : no <package> tag found (mandatory)");
254    }
255   GetTextOrClear(BB.getChildNode("package"),mPackage);
256   */
257
258   // Author
259   int i,j;
260   for (i=0,j=0; i<BB.nChildNode("author"); i++) 
261     {
262       std::string val;
263       GetTextOrClear(BB.getChildNode("author",&j),val);
264       mAuthor += val;
265     }
266
267   // Description
268   for (i=0,j=0; i<BB.nChildNode("description"); i++) 
269     {
270       std::string val;
271       GetTextOrClear(BB.getChildNode("description",&j),val);
272       mDescription += val;
273     }
274   
275   // Category
276   for (i=0,j=0; i<BB.nChildNode("category"); i++) 
277     {
278       std::string val;
279       GetTextOrClear(BB.getChildNode("category",&j),val);
280       mCategory += val;
281     }
282
283   // Namespace
284   /*
285   mIsInNamespace = false;
286   if (BB.nChildNode("namespace"))
287     {
288       mIsInNamespace = true;
289       GetTextOrClear(BB.getChildNode("namespace"),mNamespace);
290     }
291   */
292
293   // UserConstructor body
294   if (BB.nChildNode("constructor"))
295     {
296       GetTextOrClear(BB.getChildNode("constructor"),mUserConstructor);
297     }
298   // UserCopyConstructor body
299   if (BB.nChildNode("copyconstructor"))
300     {
301       GetTextOrClear(BB.getChildNode("copyconstructor"),mUserCopyConstructor);
302     }
303   // UserDestructor body
304   if (BB.nChildNode("destructor"))
305     {
306       GetTextOrClear(BB.getChildNode("destructor"),mUserDestructor);
307     }
308  
309     // Template parameters
310   //  mNbTemplateParam = BB.nChildNode("template");
311
312   if ( BB.nChildNode("template") > 0)
313     {
314       mTemplateDeclaration = "<";
315       mTemplateImplementation = "<";
316       
317       for (i=0,j=0; i<BB.nChildNode("template")-1; i++) 
318         {
319           mTemplateDeclaration += "class ";
320           std::string val;
321           GetTextOrClear(BB.getChildNode("template",&j),val);
322           mTemplateDeclaration += val;
323           mTemplateDeclaration +=  ",";
324           mTemplateImplementation += val;
325           mTemplateImplementation +=  ",";
326           mTemplateParam.push_back(val);
327         }
328       mTemplateDeclaration += "class ";
329       std::string val;
330       GetTextOrClear(BB.getChildNode("template",&j),val);
331       mTemplateDeclaration += val;
332       mTemplateDeclaration +=  ">";
333       mTemplateImplementation += val;
334       mTemplateImplementation +=  ">";
335       mTemplateParam.push_back(val);
336     }
337
338   // Includes 
339   for (i=0,j=0; i<BB.nChildNode("include"); i++) 
340     {
341       std::string val;
342       GetTextOrClear(BB.getChildNode("include",&j),val);
343       mInclude.push_back(val);
344     }
345   
346   // Inputs
347   for (i=0,j=0; i<BB.nChildNode("input"); i++) 
348     {
349       XMLNode n = BB.getChildNode("input",&j); 
350       if (!n.isAttributeSet("name"))
351         {
352           throw bbfyException("Error : <input> attribute 'name' not found (mandatory)");
353         }
354       if (!n.isAttributeSet("type"))
355         {
356           throw bbfyException("Error : <input> attribute 'type' not found (mandatory)");
357         }
358
359       IO io;
360       io.name = n.getAttribute("name");
361       io.type = n.getAttribute("type"); 
362       GetTextOrClear(n,io.help);
363
364       if (n.isAttributeSet("special")) 
365         {
366           io.special =  n.getAttribute("special");  
367         }
368
369       if (n.isAttributeSet("generic_type")) 
370         {
371           io.generic_type =  n.getAttribute("generic_type");  
372         }
373
374       mInput.push_back(io);
375     }
376   
377   // Outputs
378   for (i=0,j=0; i<BB.nChildNode("output"); i++) 
379     {
380       XMLNode n = BB.getChildNode("output",&j); 
381       if (!n.isAttributeSet("name"))
382         {
383           throw bbfyException("Error : <output> attribute 'name' not found (mandatory)");
384         }
385       if (!n.isAttributeSet("type"))
386         {
387           throw bbfyException("Error : <output> attribute 'type' not found (mandatory)");
388         }
389
390       IO io;
391       io.name = n.getAttribute("name"); 
392       io.type = n.getAttribute("type"); 
393       GetTextOrClear(n,io.help);
394
395       if (n.isAttributeSet("special")) 
396         {
397           io.special =  n.getAttribute("special");  
398         }
399
400       if (n.isAttributeSet("generic_type")) 
401         {
402           io.generic_type =  n.getAttribute("generic_type");  
403         }
404
405       mOutput.push_back(io);
406     }
407
408
409   // Process
410   // process tag given ?
411    if (BB.nChildNode("process"))
412      {
413        GetTextOrClear(BB.getChildNode("process"),mProcess);
414      }
415   // CreateWidget
416   // createwidget tag given ?
417    if (BB.nChildNode("createwidget"))
418      {
419        GetTextOrClear(BB.getChildNode("createwidget"),mCreateWidget);
420      }
421 }
422 //==========================================================================
423
424
425 //==========================================================================
426 void bbfy::BeginNamespace()
427 {
428   //  if (mIsInNamespace)
429   // {
430   mFile << "namespace "<<mNamespace <<"\n{\n\n";
431   //  }
432 }
433 //==========================================================================
434
435 //==========================================================================
436 void bbfy::EndNamespace()
437 {
438   // if (mIsInNamespace)
439   //  {
440   mFile << "}\n// EO namespace "<<mNamespace<<"\n\n";
441   //  }
442 }
443 //==========================================================================
444
445
446 //==========================================================================
447 void bbfy::CreateHeader()
448 {
449
450   mHName = "bb";
451   mHName += mPackage;
452   mHName += mName;
453   mHName += ".h";
454   if (mVerbose) std::cout << " - Creating header '"<<mHName<<"'"<<std::endl;
455   std::string fullname = mOutputPath + mHName;
456   mFile.open(fullname.c_str());
457   if (!mFile.good())
458     {
459       std::string mess("Error : could not open file \"");
460       mess += fullname + "\"";
461       throw bbfyException(mess);
462     }
463   
464   // If is widget 
465   mFile << "#ifdef _USE_WXWIDGETS_\n";
466
467   // Prevent multiple inclusions
468   std::string included("__bb");
469   included += mPackage + mName + "_h_INCLUDED__";
470   mFile << "#ifndef " << included <<"\n";
471   mFile << "#define " << included <<"\n";
472
473   // Includes 
474   //  mFile << "#include \"bbtkAtomicBlackBox.h\"\n";
475   std::vector<std::string>::iterator i;
476   for (i=mInclude.begin(); i!=mInclude.end(); ++i) 
477     {
478       mFile << "#include \"" << *i <<"\"\n";
479     }
480   if (mGeneric) mFile << "#include \"bbitkImage.h\"\n";
481   mFile << "\n";
482
483   // Namespace
484   BeginNamespace();
485
486   // Interface
487
488   // If it is a template class
489   if (mTemplateParam.size() > 0)
490     {
491       mFile << "template " << mTemplateDeclaration <<"\n";
492     }
493   
494   // Class declaration and parents
495   mFile << "class /*BBTK_EXPORT*/ "<<mName<<"\n";
496   mFile << " : \n";
497   mFile << "   public "<<mParentBlackBox;
498
499   /*
500   if (mBB.nChildNode("inherits"))
501     {
502       mFile << ",\n";
503       for (i=0,j=0; i<mBB.nChildNode("inherits")-1; i++) 
504         {
505           mFile << "   public " 
506                 << mBB.getChildNode("inherits",&j).getText()
507                 << ",\n";
508         }
509       mFile << "   public " 
510             << mBB.getChildNode("Inherits",&j).getText()
511             <<"\n";
512     }
513   */
514
515   if (mType == itkImageToImageFilter )
516     {
517       mFile << ",\n   public " << mItkParent <<"\n";
518     }
519   else if ( (mType == vtkImageAlgorithm) ||
520             (mType == vtkPolyDataAlgorithm) )
521     {
522       mFile << ",\n   public " << mVtkParent <<"\n";
523     }
524   else 
525     {
526       mFile << "\n";
527     }
528
529   mFile << "{\n";
530
531   // Interface
532   mFile << "  BBTK_USER_BLACK_BOX_INTERFACE("
533         << mName << ","
534         << mParentBlackBox << ");\n";
535
536   // typedef on itkfilter
537   if (mType == itkImageToImageFilter)
538     {
539       mFile << "  typedef " <<mItkParent <<" itkParent;"<<std::endl;
540       mFile << "  void bbDelete() { itkParent::UnRegister(); }"<<std::endl;
541     }
542   // typedef on itkfilter
543   if ( (mType == vtkImageAlgorithm) ||
544        (mType == vtkPolyDataAlgorithm) )
545     {
546       mFile << "  typedef " <<mVtkParent <<" vtkParent;"<<std::endl;
547       mFile << "  void bbDelete() { vtkParent::Delete(); }"<<std::endl;
548     }
549
550   // Declare user constructor / copy cons /destr 
551   mFile << "//=================================================================="<<std::endl;
552   mFile << "/// User callback called in the box contructor"<<std::endl;
553
554   mFile << "virtual void bbUserConstructor();"<<std::endl;
555   mFile << "/// User callback called in the box copy constructor"<<std::endl;
556   mFile << "virtual void bbUserCopyConstructor();"<<std::endl;
557   mFile << "/// User callback called in the box destructor"<<std::endl;
558   mFile << "virtual void bbUserDestructor();"<<std::endl;
559   mFile << "//=================================================================="<<std::endl; 
560
561
562
563   // Inputs
564   std::vector<IO>::iterator ioi;
565   for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) 
566     {
567       if (ioi->special=="") 
568         {
569           mFile << "  BBTK_DECLARE_INPUT(" 
570                 << ioi->name
571                 << ","
572                 << ioi->type
573                 << ");\n";
574         }
575       else if (ioi->special=="itk input")
576         {
577           mFile << "  BBTK_DECLARE_ITK_INPUT(" 
578                 << "itkParent,"
579                 << ioi->name
580                 << ","
581                 << ioi->type
582                 << ");\n";
583         }
584       else if (ioi->special=="vtk input")
585         {
586           if (mType == vtkImageAlgorithm) {
587           mFile << "  BBTK_DECLARE_VTK_IMAGE_ALGORITHM_INPUT(" 
588                 << "vtkParent,"
589                 << ioi->name
590                 << ","
591                 << ioi->type
592                 << ");\n";
593           } 
594           else if (mType == vtkPolyDataAlgorithm) {
595           mFile << "  BBTK_DECLARE_POLY_DATA_ALGORITHM_INPUT(" 
596                 << "vtkParent,"
597                 << ioi->name
598                 << ","
599                 << ioi->type
600                 << ");\n";
601           }
602         }
603       else if (ioi->special=="itk parameter")
604         {
605           mFile << "  BBTK_DECLARE_ITK_PARAM(" 
606                 << "itkParent,"
607                 << ioi->name
608                 << ","
609                 << ioi->type
610                 << ");\n";
611         }
612       else if (ioi->special=="vtk parameter")
613         {
614           mFile << "  BBTK_DECLARE_VTK_PARAM(" 
615                 << "vtkParent,"
616                 << ioi->name
617                 << ","
618                 << ioi->type
619                 << ");\n";
620         }
621       else 
622         {
623           std::string mess("Error : input '");
624           mess += ioi->name;
625           mess += "', 'special' attribute '";
626           mess += ioi->special;
627           mess += "' unknown";
628           throw bbfyException(mess);
629         }
630     }
631   
632   // Outputs
633   for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi) 
634     {
635       if (ioi->special=="") 
636         {
637           mFile << "  BBTK_DECLARE_OUTPUT(" 
638                 << ioi->name
639                 << ","
640                 << ioi->type
641                 << ");\n";
642         }
643       else if (ioi->special=="itk output")
644         {
645           mFile << "  BBTK_DECLARE_ITK_OUTPUT(" 
646                 << "itkParent,"
647                 << ioi->name
648                 << ","
649                 << ioi->type
650                 << ");\n";
651         }  
652       else if (ioi->special=="vtk output")
653         {
654           mFile << "  BBTK_DECLARE_VTK_OUTPUT(" 
655                 << "vtkParent,"
656                 << ioi->name
657                 << ","
658                 << ioi->type
659                 << ");\n";
660         }  
661       else 
662         {
663           std::string mess("Error : output '");
664           mess += ioi->name;
665           mess += "', 'special' attribute '";
666           mess += ioi->special;
667           mess += "' unknown";
668           throw bbfyException(mess);
669         }
670     }
671   
672
673   // Process
674   if ((mType == STD)||(mProcess.size()))
675     {
676       mFile << "  BBTK_PROCESS(DoProcess);\n" ;
677       mFile << "  void DoProcess();\n";
678     }
679   else if (mType == itkImageToImageFilter)
680     {   
681       mFile << "  BBTK_PROCESS(itkParent::Update);\n" ;
682     }
683   else if ((mType == vtkImageAlgorithm) ||
684            (mType == vtkPolyDataAlgorithm) )
685
686     {   
687       mFile << "  BBTK_PROCESS(vtkParent::Update);\n" ;
688     }
689
690   // CreateWidget
691   if (mIsWidget) 
692     {
693        mFile << "  BBTK_CREATE_WIDGET(DoCreateWidget);\n" ;
694        mFile << "  void DoCreateWidget();\n";
695     }
696
697
698   // EO black box declaration
699   mFile << "};\n\n";
700
701
702
703   // BO black box description
704   if (mTemplateParam.size()==0)
705     {
706       mFile << "BBTK_BEGIN_DESCRIBE_BLACK_BOX("
707             << mName << ","
708             << mParentBlackBox << ");\n";
709       mFile << "BBTK_NAME(\"" << mName <<"\");\n";
710     }
711   else if (mTemplateParam.size()==1)
712     {
713       mFile << "BBTK_BEGIN_DESCRIBE_TEMPLATE_BLACK_BOX("
714             << mName //<< ","
715         //<< mParentBlackBox //<< ","
716         //   << mTemplateParam[0] 
717             << ");\n";
718       mFile << "BBTK_NAME(\"" << mName 
719             << "<\"+bbtk::TypeName<" << mTemplateParam[0]
720             <<">()+\">\");\n";
721     }
722  else 
723     {
724       throw bbfyException("template bb with more than 1 templ param not impl");
725     } 
726   
727   // Author
728   mFile << "BBTK_AUTHOR(\""<<mAuthor<< "\");\n";
729
730   // Description
731   mFile << "BBTK_DESCRIPTION(\""<<mDescription<< "\");\n"; 
732   
733   // Category
734   mFile << "BBTK_CATEGORY(\""<<mCategory<< "\");\n"; 
735   
736   // Inputs
737   for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) 
738     {
739       if (mTemplateParam.size()>0)
740         {
741           mFile << "BBTK_TEMPLATE_INPUT(";
742         } 
743       else 
744         {
745           mFile << "BBTK_INPUT(";
746         } 
747       mFile << mName << "," << ioi->name << ",\""
748             << ioi->help << "\"," <<  ioi->type <<");\n";
749     }
750   
751   // Outputs
752   for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi) 
753     {
754       if (mTemplateParam.size()>0)
755         {
756           mFile << "BBTK_TEMPLATE_OUTPUT(";
757         } 
758       else 
759         {
760           mFile << "BBTK_OUTPUT(";
761         } 
762       mFile << mName << "," << ioi->name << ",\""
763             << ioi->help << "\"," <<  ioi->type <<");\n";
764     }
765   
766   // EO black box description
767   if (mTemplateParam.size()==0)
768     {
769       mFile << "BBTK_END_DESCRIBE_BLACK_BOX("
770             << mName << ");\n";
771     }
772   else if (mTemplateParam.size()==1)
773     {
774       mFile << "BBTK_END_DESCRIBE_TEMPLATE_BLACK_BOX("
775             << mName //<< ","
776         // << mTemplateParam[0] 
777             << ");\n";
778     }
779   else 
780     {
781       throw bbfyException("template bb with more than 1 templ param not impl");
782      
783     } 
784   
785   // Untemplatization of itk filters
786   if ( mGeneric )
787     {
788       WriteGenericITKFilterHeader();
789     }
790
791
792   // EO namespace
793   EndNamespace();
794   
795   // Prevent multiple inclusions
796   mFile << "#endif // " << included <<"\n";
797   // If is widget 
798   mFile << "#endif // _USE_WXWIDGETS_\n";
799
800   // EOF
801   mFile << "\n";
802
803   mFile.close();
804 }
805 //==========================================================================
806
807
808
809 //==========================================================================
810 void bbfy::WriteGenericITKFilterHeader()
811 {
812   mFile << "\n//===================================================\n";
813   mFile << "// Generic \"untemplatized\" filter\n";
814   mFile << "//===================================================\n";
815
816   // Class declaration and parents
817   mFile << "class /*BBTK_EXPORT*/ "<<mName<<"Generic\n";
818   mFile << " : \n";
819   mFile << "   public bbtk::AtomicBlackBox\n";
820   mFile << "{\n";
821
822   // Interface
823   mFile << "  BBTK_USER_BLACK_BOX_INTERFACE("
824         << mName << "Generic,bbtk::AtomicBlackBox);\n";
825
826   // Inputs
827   std::vector<IO>::iterator ioi;
828   for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) 
829     {
830       mFile << "  BBTK_DECLARE_INPUT(" 
831             << ioi->name
832             << ","
833             << ioi->generic_type
834             << ");\n";
835     }
836   
837   // Outputs
838   for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi) 
839     {
840       mFile << "  BBTK_DECLARE_OUTPUT(" 
841             << ioi->name
842             << ","
843             << ioi->generic_type
844             << ");\n";
845     }
846     
847   // Process
848   mFile << "  BBTK_PROCESS(ProcessSwitch);\n";
849   mFile << "  private :\n";
850   mFile << "    inline void ProcessSwitch();\n";
851   mFile << "    template <class T, unsigned int D> void Process();\n";
852   // EO black box declaration
853   mFile << "};\n\n";
854
855
856
857   // BO black box description
858   mFile << "BBTK_BEGIN_DESCRIBE_BLACK_BOX("
859         << mName << "Generic,bbtk::AtomicBlackBox);\n";
860   mFile << "BBTK_NAME(\"" << mName <<"\");\n";
861
862   // Author
863   mFile << "BBTK_AUTHOR(\""<<mAuthor<< "\");\n";
864
865   // Description
866   mFile << "BBTK_DESCRIPTION(\""<<mDescription<< "\");\n"; 
867   
868   // Inputs
869   for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) 
870     {
871       mFile << "BBTK_INPUT(";
872       mFile << mName << "Generic," << ioi->name << ",\""
873             << ioi->help << "\"," <<  ioi->generic_type <<");\n";
874     }
875   
876   // Outputs
877   for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi) 
878     {
879       mFile << "BBTK_OUTPUT(";
880       mFile << mName << "Generic," << ioi->name << ",\""
881             << ioi->help << "\"," <<  ioi->generic_type <<");\n";
882     }
883   
884   // EO black box description
885   mFile << "BBTK_END_DESCRIBE_BLACK_BOX("
886         << mName << "Generic);\n";
887
888
889   //=================================================================
890   // ProcessSwitch implementation
891   mFile << "void "<< mName <<"Generic::ProcessSwitch()\n"
892         << "{\n"
893         << "CALL_FOR_ALL_TYPES_AND_DIM(bbGetInputIn()->GetType(),\n"
894         << "                           bbGetInputIn()->GetDimension(),\n"
895         << "                           Process);\n"
896         << "}\n";
897   //=================================================================
898
899
900   //=================================================================
901   // Template process implementation
902   mFile << "template <class T, unsigned int D>\n"
903         << "void "<<mName<<"Generic::Process()\n"
904         << "{\n"
905         << "  bbtkDebugMessageInc(\"Kernel\",9,\n"
906         << "      \""<<mName 
907         << "Generic::Process<\"<<TypeName<T>()<<\",\"<<D<<\">()\"<<std::endl);\n"
908     
909         << "  typedef itk::Image<T,D> ImageType;\n"
910         << "  typedef "<<mName<<"<ImageType> FilterType;\n"
911     
912         << "  FilterType* f = new FilterType(\"Temp\");\n"
913     
914         << "  f->bbSetInputIn( this->bbGetInputIn()->GetImage<T,D>() );\n";
915   
916   for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi) 
917     {
918       if (ioi->name == "In") continue;
919       mFile << "  f->bbSetInput"<<ioi->name<<" ( this->bbGetInput" 
920             << ioi->name << "() );\n";
921     }
922   
923   mFile << "  f->bbUpdate();\n"
924         << "  this->bbSetOutputOut( new itkImage( f->bbGetOutputOut() ) );\n"
925         << "  f->UnRegister();\n"
926         << "  bbtkDebugDecTab(\"Kernel\",9);\n"
927         << "}\n\n";
928   //=================================================================
929
930
931 }
932 //==========================================================================
933
934
935 //==========================================================================
936 void bbfy::CreateCode()
937 {
938   mCxxName = "bb";
939   mCxxName += mPackage;
940   mCxxName += mName;
941   mCxxName += ".cxx";
942   if (mVerbose) std::cout << " - Creating code   '"<<mCxxName<<"'"<<std::endl;
943   std::string fullname = mOutputPath + mCxxName;
944   mFile.open(fullname.c_str());
945   if (!mFile.good()) 
946     {
947       std::string mess("Error : could not open file \"");
948       mess += fullname;
949       mess += "\"";
950       throw bbfyException(mess);
951     }
952   
953   // Includes
954   // Header of the class
955   mFile << "#include \"" << mHName << "\"\n";
956
957   // Include Package header
958   mFile << "#include \"bb"<<mPackage << "Package.h\"\n";
959
960   // BO namespace
961   BeginNamespace();
962  
963   
964   // Template class ?
965   if (mTemplateParam.size()>0) 
966     {
967       // Implementation
968       mFile << "BBTK_USER_BLACK_BOX_TEMPLATE_IMPLEMENTATION("
969             << mName << ","  
970             << mParentBlackBox << ");\n";
971      
972       if (mGeneric) 
973         {       
974           // Implementation
975           mFile << "BBTK_USER_BLACK_BOX_IMPLEMENTATION("
976                 << mName << "Generic,bbtk::AtomicBlackBox);\n";
977           // Package
978           mFile << "BBTK_ADD_BLACK_BOX_TO_PACKAGE("
979                 << mPackage << ","
980                 << mName << "Generic)\n";
981         }
982     }
983   else 
984     {
985       // Non template class
986       // Package
987       mFile << "BBTK_ADD_BLACK_BOX_TO_PACKAGE("
988             << mPackage << ","
989             << mName << ")\n";
990
991       // Implementation
992       mFile << "BBTK_USER_BLACK_BOX_IMPLEMENTATION("
993             << mName << ","  
994             << mParentBlackBox << ");\n"; 
995     }
996   // Process
997   if ((mType == STD)||(mProcess.size()))
998     {
999       mFile << "void "<<mName<<"::DoProcess()\n{\n";
1000       mFile << mProcess << "\n";
1001       mFile << "}\n";
1002     }
1003   // CreateWidget
1004   if (mIsWidget)
1005     {
1006       mFile << "void "<<mName<<"::DoCreateWidget()\n{\n";
1007       mFile << mCreateWidget << "\n";
1008       mFile << "}\n";
1009     }
1010   
1011
1012   // User constr / copy constr / destr implementation
1013   mFile <<"void "<<mName<<"::bbUserConstructor()"<<std::endl;
1014   mFile << "{"<<std::endl;
1015   //mFile<<"bbtkDebugMessage(\"Kernel\",9,\""<<mName<<::bbUserConstructor()"<<std::endl);"<<std::endl;
1016   mFile << mUserConstructor << std::endl;
1017   mFile << "}" << std::endl;
1018
1019   mFile <<"void "<<mName<<"::bbUserCopyConstructor()"<<std::endl;
1020   mFile << "{"<<std::endl;
1021   //mFile<<"bbtkDebugMessage(\"Kernel\",9,\""<<mName<<::bbUserCopyConstructor()"<<std::endl);"<<std::endl;
1022   mFile << mUserCopyConstructor << std::endl;
1023   mFile << "}" << std::endl;
1024
1025   mFile <<"void "<<mName<<"::bbUserDestructor()"<<std::endl;
1026   mFile << "{"<<std::endl;
1027   //mFile<<"bbtkDebugMessage(\"Kernel\",9,\""<<mName<<::bbUserDestructor()"<<std::endl);"<<std::endl;
1028   mFile << mUserDestructor << std::endl;
1029   mFile << "}" << std::endl;
1030
1031
1032   // EO namespace
1033   EndNamespace();
1034
1035   mFile << "\n";
1036   
1037   // EOF
1038   mFile.close();
1039   
1040 }
1041 //==========================================================================
1042  
1043
1044
1045
1046
1047 //==========================================================================
1048 int main(int argc, char **argv)
1049 {
1050   
1051   if (argc<2 || argc>5) 
1052     {
1053       std::cerr << "usage : "<< argv[0] <<" xml_file [package_name] [output_path] [-q]" << std::endl;
1054       return 1;
1055     }
1056
1057   try 
1058     {
1059       std::string package("PACKAGE_NAME");
1060       std::string output_path("");
1061       bool verbose = true;
1062       if (argc>2) package = argv[2];
1063       if (argc>3) output_path = argv[3];
1064       if (argc>4) verbose = false;
1065       
1066       bbfy B(argv[1],package,output_path,verbose);
1067     }
1068   catch (bbfyException e)
1069     {
1070       std::cerr << e.mMessage << std::endl;
1071       return 1;
1072     }
1073   return 0;
1074 }
1075 //==========================================================================
1076
1077