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