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