2 #define _CRT_SECURE_NO_DEPRECATE
12 //==========================================================================
16 bbfyException(const std::string& message) : mMessage(message) {}
20 //==========================================================================
22 const std::string itkImageToImageFilterString = "ITK_ImageToImageFilter";
23 const std::string vtkImageAlgorithmString = "VTK_ImageAlgorithm";
24 const std::string vtkPolyDataAlgorithmString = "VTK_PolyDataAlgorithm";
26 //==========================================================================
30 bbfy(const std::string& filename,
31 const std::string& package = "PACKAGE_NAME",
32 const std::string& output_path = "",
33 bool verbose = false);
35 void CreateBlackBox();
40 void WriteGenericITKFilterHeader();
42 void BeginNamespace();
47 std::string mFilename;
48 std::string mOutputPath;
56 itkImageToImageFilter,
64 std::string mParentBlackBox;
65 std::string mItkParent;
66 std::string mVtkParent;
69 std::string mDescription;
70 std::string mCategory;
72 // bool mIsInNamespace;
73 std::string mNamespace;
74 // int mNbTemplateParam;
75 std::vector<std::string> mTemplateParam;
76 std::string mTemplateDeclaration;
77 std::string mTemplateImplementation;
79 std::vector<std::string> mInclude;
81 std::string mUserConstructor;
82 std::string mUserCopyConstructor;
83 std::string mUserDestructor;
91 std::string generic_type;
95 std::vector<IO> mInput;
96 std::vector<IO> mOutput;
99 std::string mCreateWidget;
104 std::string mCxxName;
107 //==========================================================================
111 //==========================================================================
112 bbfy::bbfy(const std::string& filename,
113 const std::string& package,
114 const std::string& output_path,
119 mFilename = filename;
121 mNamespace = "bb" + mPackage;
123 mOutputPath = output_path;
128 //==========================================================================
130 //==========================================================================
131 void bbfy::CreateBlackBox()
133 // Parse XML input file
135 // Create output files
139 //==========================================================================
142 //==========================================================================
143 void GetTextOrClear(const XMLNode& node, std::string& var)
147 var = node.getText();
149 else if (node.nClear()>0)
151 var = node.getClear().lpszValue;
155 std::string mess("Error : element <");
156 mess += node.getName();
157 mess += "> : no text nor <PRE></PRE> clear tag found";
158 throw bbfyException(mess);
161 //==========================================================================
164 //==========================================================================
165 void bbfy::ParseXML()
167 XMLResults* res = new XMLResults;
168 XMLNode BB = XMLNode::parseFile(mFilename.c_str(),"blackbox",res);
170 if ( res->error != eXMLErrorNone )
172 std::ostringstream str;
173 str << XMLNode::getError(res->error);
174 str << " [line " << res->nLine << ", col "<<res->nColumn<<"]";
176 throw bbfyException(str.str());
181 if (!BB.isAttributeSet("name"))
183 throw bbfyException("Error : <blackbox> tag : no 'name' attribute found (mandatory)");
185 mName = BB.getAttribute("name");
187 if (mVerbose) std::cout << "* Creating BlackBox '"<<mName<<"'"<<std::endl;
194 if (BB.isAttributeSet("type"))
196 std::string bbtype = BB.getAttribute("type");
197 if (bbtype=="standard")
202 else if (bbtype==itkImageToImageFilterString)
204 mType = itkImageToImageFilter;
205 // Looks for <itkparent> tag
206 if (!BB.nChildNode("itkparent"))
208 throw bbfyException("Error : blackbox type '"+itkImageToImageFilterString+"' but no <itkparent> tag found (mandatory)");
210 GetTextOrClear(BB.getChildNode("itkparent"),mItkParent);
213 if (BB.isAttributeSet("generic")) mGeneric=true;
215 else if (bbtype == vtkImageAlgorithmString)
217 mType = vtkImageAlgorithm;
218 // Looks for <vtkparent> tag
219 if (!BB.nChildNode("vtkparent"))
221 throw bbfyException("Error : blackbox type '"
222 +vtkImageAlgorithmString
223 +"' but no <vtkparent> tag found (mandatory)");
225 GetTextOrClear(BB.getChildNode("vtkparent"),mVtkParent);
228 else if (bbtype == vtkPolyDataAlgorithmString )
230 mType = vtkPolyDataAlgorithm;
231 // Looks for <vtkparent> tag
232 if (!BB.nChildNode("vtkparent"))
234 throw bbfyException("Error : blackbox type '"
235 +vtkPolyDataAlgorithmString
236 +"' but no <vtkparent> tag found (mandatory)");
238 GetTextOrClear(BB.getChildNode("vtkparent"),mVtkParent);
243 std::string mess("Error : blackbox type '");
245 mess += "' unknown. Known types :";
246 mess += "'" + itkImageToImageFilterString + "' ";
247 mess += "'" + vtkImageAlgorithmString + "' ";
248 mess += "'" + vtkPolyDataAlgorithmString + "' ";
249 throw bbfyException(mess);
254 if (BB.isAttributeSet("widget"))
257 mParentBlackBox = "bbtk::WxBlackBox";
258 mInclude.push_back("bbtkWxBlackBox.h");
263 mParentBlackBox = "bbtk::AtomicBlackBox";
264 mInclude.push_back("bbtkAtomicBlackBox.h");
269 for (i=0,j=0; i<BB.nChildNode("author"); i++)
272 GetTextOrClear(BB.getChildNode("author",&j),val);
277 for (i=0,j=0; i<BB.nChildNode("description"); i++)
280 GetTextOrClear(BB.getChildNode("description",&j),val);
285 for (i=0,j=0; i<BB.nChildNode("category"); i++)
288 GetTextOrClear(BB.getChildNode("category",&j),val);
293 if (BB.nChildNode("namespace"))
295 GetTextOrClear(BB.getChildNode("namespace"),mNamespace);
298 // UserConstructor body
299 if (BB.nChildNode("constructor"))
301 GetTextOrClear(BB.getChildNode("constructor"),mUserConstructor);
303 // UserCopyConstructor body
304 if (BB.nChildNode("copyconstructor"))
306 GetTextOrClear(BB.getChildNode("copyconstructor"),mUserCopyConstructor);
308 // UserDestructor body
309 if (BB.nChildNode("destructor"))
311 GetTextOrClear(BB.getChildNode("destructor"),mUserDestructor);
314 // Template parameters
315 // mNbTemplateParam = BB.nChildNode("template");
317 if ( BB.nChildNode("template") > 0)
319 mTemplateDeclaration = "<";
320 mTemplateImplementation = "<";
322 for (i=0,j=0; i<BB.nChildNode("template")-1; i++)
324 mTemplateDeclaration += "class ";
326 GetTextOrClear(BB.getChildNode("template",&j),val);
327 mTemplateDeclaration += val;
328 mTemplateDeclaration += ",";
329 mTemplateImplementation += val;
330 mTemplateImplementation += ",";
331 mTemplateParam.push_back(val);
333 mTemplateDeclaration += "class ";
335 GetTextOrClear(BB.getChildNode("template",&j),val);
336 mTemplateDeclaration += val;
337 mTemplateDeclaration += ">";
338 mTemplateImplementation += val;
339 mTemplateImplementation += ">";
340 mTemplateParam.push_back(val);
344 for (i=0,j=0; i<BB.nChildNode("include"); i++)
347 GetTextOrClear(BB.getChildNode("include",&j),val);
348 mInclude.push_back(val);
352 for (i=0,j=0; i<BB.nChildNode("input"); i++)
355 XMLNode n = BB.getChildNode("input",&j);
356 if (!n.isAttributeSet("name"))
358 throw bbfyException("Error : <input> attribute 'name' not found (mandatory)");
360 io.name = n.getAttribute("name");
361 if (!n.isAttributeSet("type"))
363 throw bbfyException("Error : <input name=\""+io.name+"\"> attribute 'type' not found (mandatory)");
365 io.type = n.getAttribute("type");
366 if (!n.isAttributeSet("description"))
368 throw bbfyException("Error : <input name=\""+io.name+"\"> attribute 'description' not found (mandatory)");
370 io.descr = n.getAttribute("description");
372 if (n.isAttributeSet("special"))
374 io.special = n.getAttribute("special");
377 if (n.isAttributeSet("generic_type"))
379 io.generic_type = n.getAttribute("generic_type");
382 mInput.push_back(io);
386 for (i=0,j=0; i<BB.nChildNode("output"); i++)
389 XMLNode n = BB.getChildNode("output",&j);
390 if (!n.isAttributeSet("name"))
392 throw bbfyException("Error : <output> attribute 'name' not found (mandatory)");
394 io.name = n.getAttribute("name");
395 if (!n.isAttributeSet("type"))
397 throw bbfyException("Error : <output name=\""+io.name+"\"> attribute 'type' not found (mandatory)");
399 io.type = n.getAttribute("type");
400 if (!n.isAttributeSet("description"))
402 throw bbfyException("Error : <output name=\""+io.name+"\"> attribute 'description' not found (mandatory)");
404 io.descr = n.getAttribute("description");
406 if (n.isAttributeSet("special"))
408 io.special = n.getAttribute("special");
411 if (n.isAttributeSet("generic_type"))
413 io.generic_type = n.getAttribute("generic_type");
416 mOutput.push_back(io);
421 // process tag given ?
422 if (BB.nChildNode("process"))
424 GetTextOrClear(BB.getChildNode("process"),mProcess);
427 // createwidget tag given ?
428 if (BB.nChildNode("createwidget"))
430 GetTextOrClear(BB.getChildNode("createwidget"),mCreateWidget);
433 //==========================================================================
436 //==========================================================================
437 void bbfy::BeginNamespace()
439 // if (mIsInNamespace)
441 mFile << "namespace "<<mNamespace <<"\n{\n\n";
444 //==========================================================================
446 //==========================================================================
447 void bbfy::EndNamespace()
449 // if (mIsInNamespace)
451 mFile << "}\n// EO namespace "<<mNamespace<<"\n\n";
454 //==========================================================================
457 //==========================================================================
458 void bbfy::CreateHeader()
465 if (mVerbose) std::cout << " - Creating header '"<<mHName<<"'"<<std::endl;
466 std::string fullname = mOutputPath + mHName;
467 mFile.open(fullname.c_str());
470 std::string mess("Error : could not open file \"");
471 mess += fullname + "\"";
472 throw bbfyException(mess);
478 mFile << "#ifdef _USE_WXWIDGETS_\n";
481 // Prevent multiple inclusions
482 std::string included("__bb");
483 included += mPackage + mName + "_h_INCLUDED__";
484 mFile << "#ifndef " << included <<"\n";
485 mFile << "#define " << included <<"\n";
488 // mFile << "#include \"bbtkAtomicBlackBox.h\"\n";
489 std::vector<std::string>::iterator i;
490 for (i=mInclude.begin(); i!=mInclude.end(); ++i)
492 mFile << "#include \"" << *i <<"\"\n";
494 if (mGeneric) mFile << "#include \"bbitkImage.h\"\n";
502 // If it is a template class
503 if (mTemplateParam.size() > 0)
505 mFile << "template " << mTemplateDeclaration <<"\n";
508 // Class declaration and parents
509 mFile << "class /*BBTK_EXPORT*/ "<<mName<<"\n";
511 mFile << " public "<<mParentBlackBox;
514 if (mBB.nChildNode("inherits"))
517 for (i=0,j=0; i<mBB.nChildNode("inherits")-1; i++)
520 << mBB.getChildNode("inherits",&j).getText()
524 << mBB.getChildNode("Inherits",&j).getText()
529 if (mType == itkImageToImageFilter )
531 mFile << ",\n public " << mItkParent <<"\n";
533 else if ( (mType == vtkImageAlgorithm) ||
534 (mType == vtkPolyDataAlgorithm) )
536 mFile << ",\n public " << mVtkParent <<"\n";
546 mFile << " BBTK_USER_BLACK_BOX_INTERFACE("
548 << mParentBlackBox << ");\n";
550 // typedef on itkfilter
551 if (mType == itkImageToImageFilter)
553 mFile << " typedef " <<mItkParent <<" itkParent;"<<std::endl;
554 mFile << " void bbDelete() { itkParent::UnRegister(); }"<<std::endl;
556 // typedef on itkfilter
557 if ( (mType == vtkImageAlgorithm) ||
558 (mType == vtkPolyDataAlgorithm) )
560 mFile << " typedef " <<mVtkParent <<" vtkParent;"<<std::endl;
561 mFile << " void bbDelete() { vtkParent::Delete(); }"<<std::endl;
564 // Declare user constructor / copy cons /destr
565 mFile << "//=================================================================="<<std::endl;
566 mFile << "/// User callback called in the box contructor"<<std::endl;
568 mFile << "virtual void bbUserConstructor();"<<std::endl;
569 mFile << "/// User callback called in the box copy constructor"<<std::endl;
570 mFile << "virtual void bbUserCopyConstructor();"<<std::endl;
571 mFile << "/// User callback called in the box destructor"<<std::endl;
572 mFile << "virtual void bbUserDestructor();"<<std::endl;
573 mFile << "//=================================================================="<<std::endl;
578 std::vector<IO>::iterator ioi;
579 for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi)
581 if (ioi->special=="")
583 mFile << " BBTK_DECLARE_INPUT("
589 else if (ioi->special=="itk input")
591 mFile << " BBTK_DECLARE_ITK_INPUT("
598 else if (ioi->special=="vtk input")
600 if (mType == vtkImageAlgorithm) {
601 mFile << " BBTK_DECLARE_VTK_IMAGE_ALGORITHM_INPUT("
608 else if (mType == vtkPolyDataAlgorithm) {
609 mFile << " BBTK_DECLARE_POLY_DATA_ALGORITHM_INPUT("
617 else if (ioi->special=="itk parameter")
619 mFile << " BBTK_DECLARE_ITK_PARAM("
626 else if (ioi->special=="vtk parameter")
628 mFile << " BBTK_DECLARE_VTK_PARAM("
637 std::string mess("Error : input '");
639 mess += "', 'special' attribute '";
640 mess += ioi->special;
642 throw bbfyException(mess);
647 for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi)
649 if (ioi->special=="")
651 mFile << " BBTK_DECLARE_OUTPUT("
657 else if (ioi->special=="itk output")
659 mFile << " BBTK_DECLARE_ITK_OUTPUT("
666 else if (ioi->special=="vtk output")
668 mFile << " BBTK_DECLARE_VTK_OUTPUT("
677 std::string mess("Error : output '");
679 mess += "', 'special' attribute '";
680 mess += ioi->special;
682 throw bbfyException(mess);
688 if ((mType == STD)||(mProcess.size()))
690 mFile << " BBTK_PROCESS(DoProcess);\n" ;
691 mFile << " void DoProcess();\n";
693 else if (mType == itkImageToImageFilter)
695 mFile << " BBTK_PROCESS(itkParent::Update);\n" ;
697 else if ((mType == vtkImageAlgorithm) ||
698 (mType == vtkPolyDataAlgorithm) )
701 mFile << " BBTK_PROCESS(vtkParent::Update);\n" ;
707 mFile << " BBTK_CREATE_WIDGET(DoCreateWidget);\n" ;
708 mFile << " void DoCreateWidget();\n";
712 // EO black box declaration
717 // BO black box description
718 if (mTemplateParam.size()==0)
720 mFile << "BBTK_BEGIN_DESCRIBE_BLACK_BOX("
722 << mParentBlackBox << ");\n";
723 mFile << "BBTK_NAME(\"" << mName <<"\");\n";
725 else if (mTemplateParam.size()==1)
727 mFile << "BBTK_BEGIN_DESCRIBE_TEMPLATE_BLACK_BOX("
729 //<< mParentBlackBox //<< ","
730 // << mTemplateParam[0]
732 mFile << "BBTK_NAME(\"" << mName
733 << "<\"+bbtk::TypeName<" << mTemplateParam[0]
738 throw bbfyException("template bb with more than 1 templ param not impl");
742 mFile << "BBTK_AUTHOR(\""<<mAuthor<< "\");\n";
745 mFile << "BBTK_DESCRIPTION(\""<<mDescription<< "\");\n";
748 mFile << "BBTK_CATEGORY(\""<<mCategory<< "\");\n";
751 for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi)
753 if (mTemplateParam.size()>0)
755 mFile << "BBTK_TEMPLATE_INPUT(";
759 mFile << "BBTK_INPUT(";
761 mFile << mName << "," << ioi->name << ",\""
762 << ioi->descr << "\"," << ioi->type <<");\n";
766 for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi)
768 if (mTemplateParam.size()>0)
770 mFile << "BBTK_TEMPLATE_OUTPUT(";
774 mFile << "BBTK_OUTPUT(";
776 mFile << mName << "," << ioi->name << ",\""
777 << ioi->descr << "\"," << ioi->type <<");\n";
780 // EO black box description
781 if (mTemplateParam.size()==0)
783 mFile << "BBTK_END_DESCRIBE_BLACK_BOX("
786 else if (mTemplateParam.size()==1)
788 mFile << "BBTK_END_DESCRIBE_TEMPLATE_BLACK_BOX("
790 // << mTemplateParam[0]
795 throw bbfyException("template bb with more than 1 templ param not impl");
799 // Untemplatization of itk filters
802 WriteGenericITKFilterHeader();
809 // Prevent multiple inclusions
810 mFile << "#endif // " << included <<"\n";
814 mFile << "#endif // _USE_WXWIDGETS_\n";
822 //==========================================================================
826 //==========================================================================
827 void bbfy::WriteGenericITKFilterHeader()
829 mFile << "\n//===================================================\n";
830 mFile << "// Generic \"untemplatized\" filter\n";
831 mFile << "//===================================================\n";
833 // Class declaration and parents
834 mFile << "class /*BBTK_EXPORT*/ "<<mName<<"Generic\n";
836 mFile << " public bbtk::AtomicBlackBox\n";
840 mFile << " BBTK_USER_BLACK_BOX_INTERFACE("
841 << mName << "Generic,bbtk::AtomicBlackBox);\n";
844 std::vector<IO>::iterator ioi;
845 for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi)
847 mFile << " BBTK_DECLARE_INPUT("
855 for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi)
857 mFile << " BBTK_DECLARE_OUTPUT("
865 mFile << " BBTK_PROCESS(ProcessSwitch);\n";
866 mFile << " private :\n";
867 mFile << " inline void ProcessSwitch();\n";
868 mFile << " template <class T, unsigned int D> void Process();\n";
869 // EO black box declaration
874 // BO black box description
875 mFile << "BBTK_BEGIN_DESCRIBE_BLACK_BOX("
876 << mName << "Generic,bbtk::AtomicBlackBox);\n";
877 mFile << "BBTK_NAME(\"" << mName <<"\");\n";
880 mFile << "BBTK_AUTHOR(\""<<mAuthor<< "\");\n";
883 mFile << "BBTK_DESCRIPTION(\""<<mDescription<< "\");\n";
886 for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi)
888 mFile << "BBTK_INPUT(";
889 mFile << mName << "Generic," << ioi->name << ",\""
890 << ioi->descr << "\"," << ioi->generic_type <<");\n";
894 for (ioi=mOutput.begin(); ioi!=mOutput.end(); ++ioi)
896 mFile << "BBTK_OUTPUT(";
897 mFile << mName << "Generic," << ioi->name << ",\""
898 << ioi->descr << "\"," << ioi->generic_type <<");\n";
901 // EO black box description
902 mFile << "BBTK_END_DESCRIBE_BLACK_BOX("
903 << mName << "Generic);\n";
906 //=================================================================
907 // ProcessSwitch implementation
908 mFile << "void "<< mName <<"Generic::ProcessSwitch()\n"
910 << "CALL_FOR_ALL_TYPES_AND_DIM(bbGetInputIn()->GetType(),\n"
911 << " bbGetInputIn()->GetDimension(),\n"
914 //=================================================================
917 //=================================================================
918 // Template process implementation
919 mFile << "template <class T, unsigned int D>\n"
920 << "void "<<mName<<"Generic::Process()\n"
922 << " bbtkDebugMessageInc(\"Kernel\",9,\n"
924 << "Generic::Process<\"<<TypeName<T>()<<\",\"<<D<<\">()\"<<std::endl);\n"
926 << " typedef itk::Image<T,D> ImageType;\n"
927 << " typedef "<<mName<<"<ImageType> FilterType;\n"
929 << " FilterType* f = new FilterType(\"Temp\");\n"
931 << " f->bbSetInputIn( this->bbGetInputIn()->GetImage<T,D>() );\n";
933 for (ioi=mInput.begin(); ioi!=mInput.end(); ++ioi)
935 if (ioi->name == "In") continue;
936 mFile << " f->bbSetInput"<<ioi->name<<" ( this->bbGetInput"
937 << ioi->name << "() );\n";
940 mFile << " f->bbUpdate();\n"
941 << " this->bbSetOutputOut( new itkImage( f->bbGetOutputOut() ) );\n"
942 << " f->UnRegister();\n"
943 << " bbtkDebugDecTab(\"Kernel\",9);\n"
945 //=================================================================
949 //==========================================================================
952 //==========================================================================
953 void bbfy::CreateCode()
956 mCxxName += mPackage;
959 if (mVerbose) std::cout << " - Creating code '"<<mCxxName<<"'"<<std::endl;
960 std::string fullname = mOutputPath + mCxxName;
961 mFile.open(fullname.c_str());
964 std::string mess("Error : could not open file \"");
967 throw bbfyException(mess);
971 // Header of the class
972 mFile << "#include \"" << mHName << "\"\n";
974 // Include Package header
975 mFile << "#include \"bb"<<mPackage << "Package.h\"\n";
982 if (mTemplateParam.size()>0)
985 mFile << "BBTK_USER_BLACK_BOX_TEMPLATE_IMPLEMENTATION("
987 << mParentBlackBox << ");\n";
992 mFile << "BBTK_USER_BLACK_BOX_IMPLEMENTATION("
993 << mName << "Generic,bbtk::AtomicBlackBox);\n";
995 mFile << "BBTK_ADD_BLACK_BOX_TO_PACKAGE("
997 << mName << "Generic)\n";
1002 // Non template class
1004 mFile << "BBTK_ADD_BLACK_BOX_TO_PACKAGE("
1009 mFile << "BBTK_USER_BLACK_BOX_IMPLEMENTATION("
1011 << mParentBlackBox << ");\n";
1014 if ((mType == STD)||(mProcess.size()))
1016 mFile << "void "<<mName<<"::DoProcess()\n{\n";
1017 mFile << mProcess << "\n";
1023 mFile << "void "<<mName<<"::DoCreateWidget()\n{\n";
1024 mFile << mCreateWidget << "\n";
1029 // User constr / copy constr / destr implementation
1030 mFile <<"void "<<mName<<"::bbUserConstructor()"<<std::endl;
1031 mFile << "{"<<std::endl;
1032 //mFile<<"bbtkDebugMessage(\"Kernel\",9,\""<<mName<<::bbUserConstructor()"<<std::endl);"<<std::endl;
1033 mFile << mUserConstructor << std::endl;
1034 mFile << "}" << std::endl;
1036 mFile <<"void "<<mName<<"::bbUserCopyConstructor()"<<std::endl;
1037 mFile << "{"<<std::endl;
1038 //mFile<<"bbtkDebugMessage(\"Kernel\",9,\""<<mName<<::bbUserCopyConstructor()"<<std::endl);"<<std::endl;
1039 mFile << mUserCopyConstructor << std::endl;
1040 mFile << "}" << std::endl;
1042 mFile <<"void "<<mName<<"::bbUserDestructor()"<<std::endl;
1043 mFile << "{"<<std::endl;
1044 //mFile<<"bbtkDebugMessage(\"Kernel\",9,\""<<mName<<::bbUserDestructor()"<<std::endl);"<<std::endl;
1045 mFile << mUserDestructor << std::endl;
1046 mFile << "}" << std::endl;
1058 //==========================================================================
1064 //==========================================================================
1065 int main(int argc, char **argv)
1068 if (argc<2 || argc>5)
1070 std::cerr << "usage : "<< argv[0] <<" xml_file [package_name] [output_path] [-q]" << std::endl;
1076 std::string package("PACKAGE_NAME");
1077 std::string output_path("");
1078 bool verbose = true;
1079 if (argc>2) package = argv[2];
1080 if (argc>3) output_path = argv[3];
1081 if (argc>4) verbose = false;
1083 bbfy B(argv[1],package,output_path,verbose);
1085 catch (bbfyException e)
1087 std::cerr << argv[0] << " " << argv[1] << std::endl
1088 << e.mMessage << std::endl;
1093 //==========================================================================