00001
00002
00003
00004 #include <stdio.h>
00005 #include <string.h>
00006 #include <stdlib.h>
00007
00008 #include <iostream>
00009 #include "tclap/CmdLine.h"
00010 #include "ModuleProcessInformation.h"
00011 #include <itksys/ios/sstream>
00012
00013 void
00014 splitString (std::string &text,
00015 std::string &separators,
00016 std::vector<std::string> &words)
00017 {
00018 const std::string::size_type n = text.length();
00019 std::string::size_type start = text.find_first_not_of(separators);
00020 while (start < n)
00021 {
00022 std::string::size_type stop = text.find_first_of(separators, start);
00023 if (stop > n) stop = n;
00024 words.push_back(text.substr(start, stop - start));
00025 start = text.find_first_not_of(separators, stop+1);
00026 }
00027 }
00028
00029 #ifdef main
00030 #ifdef WIN32
00031 #define Slicer_EXPORT __declspec(dllexport)
00032 #else
00033 #define Slicer_EXPORT
00034 #endif
00035
00036 extern "C" {
00037 Slicer_EXPORT char *GetXMLModuleDescription();
00038 Slicer_EXPORT int SlicerModuleEntryPoint(int, char*[]);
00039 }
00040 #endif
00041
00042 char *GetXMLModuleDescription()
00043 {
00044 std::string xml;
00045 xml += "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
00046 xml += "<executable>\n";
00047 xml += " <category>utility</category>\n";
00048 xml += " <title>NAMIC Command Line Processing Code Generator</title>\n";
00049 xml += " <description>Generates C++ code that will parse command lines</description>\n";
00050 xml += " <version>1.0</version>\n";
00051 xml += " <documentation-url></documentation-url>\n";
00052 xml += " <license></license>\n";
00053 xml += " <contributor>Bill Lorensen</contributor>\n";
00054 xml += "\n";
00055 xml += " <parameters>\n";
00056 xml += " <label>Parameters</label>\n";
00057 xml += " <description>Parameters used for command line processing</description>\n";
00058 xml += " <boolean>\n";
00059 xml += " <name>UseTCLAP</name>\n";
00060 xml += " <longflag>--TCLAP</longflag>\n";
00061 xml += " <description>Generate TCLAP Code</description>\n";
00062 xml += " <label>Generate TCLAP Code</label>\n";
00063 xml += " <default>true</default>\n";
00064 xml += " </boolean>\n";
00065 xml += " </parameters>\n";
00066 xml += " <parameters>\n";
00067 xml += " <label>IO</label>\n";
00068 xml += " <description>Input/Output parameters</description>\n";
00069 xml += " <file multiple=\"true\">\n";
00070 xml += " <name>logoFiles</name>\n";
00071 xml += " <label>Logo Files XML</label>\n";
00072 xml += " <longflag>--logoFiles</longflag>\n";
00073 xml += " <description>Logo files</description>\n";
00074 xml += " </file>\n";
00075 xml += " <file>\n";
00076 xml += " <name>InputXML</name>\n";
00077 xml += " <label>Input XML</label>\n";
00078 xml += " <channel>input</channel>\n";
00079 xml += " <longflag>--InputXML</longflag>\n";
00080 xml += " <description>XML description of interface</description>\n";
00081 xml += " </file>\n";
00082 xml += " <file>\n";
00083 xml += " <name>OutputCxx</name>\n";
00084 xml += " <label>Output C++</label>\n";
00085 xml += " <channel>output</channel>\n";
00086 xml += " <longflag>--OutputCxx</longflag>\n";
00087 xml += " <description>C++ Code to process command line arguments</description>\n";
00088 xml += " </file>\n";
00089 xml += " </parameters>\n";
00090 xml += "</executable>\n";
00091 xml += "\n";
00092 xml += "\n";
00093 char *xmlChar = new char[xml.size()+1];
00094 memcpy (xmlChar, xml.c_str(), xml.size());
00095 xmlChar[xml.size()] = '\0';
00096 return xmlChar;
00097 }
00098 #define GENERATE_XML \
00099 if (argc >= 2 && (strcmp(argv[1],"--xml") == 0)) \
00100 { \
00101 std::cout << GetXMLModuleDescription(); \
00102 return EXIT_SUCCESS; \
00103 }
00104 #define GENERATE_TCLAP \
00105 bool UseTCLAP = false; \
00106 std::vector<std::string> logoFilesTemp; \
00107 std::vector<std::string> logoFiles; \
00108 std::string InputXML; \
00109 std::string OutputCxx; \
00110 bool echoSwitch = false; \
00111 bool xmlSwitch = false; \
00112 std::string processInformationAddressString = "0"; \
00113 try \
00114 { \
00115 TCLAP::CmdLine commandLine ( \
00116 "Generates C++ code that will parse command lines", \
00117 ' ', \
00118 "1.0" ); \
00119 \
00120 itksys_ios::ostringstream msg; \
00121 msg.str("");msg << "Generate TCLAP Code (default: " << UseTCLAP << ")"; \
00122 TCLAP::SwitchArg UseTCLAPArg("", "TCLAP", msg.str(), commandLine, UseTCLAP); \
00123 \
00124 msg.str("");msg << "Logo files"; TCLAP::MultiArg<std::string > logoFilesArg("", "logoFiles", msg.str(), 0, "std::vector<std::string>", commandLine); \
00125 \
00126 msg.str("");msg << "XML description of interface"; TCLAP::ValueArg<std::string> InputXMLArg("", "InputXML", msg.str(), 0, InputXML, "std::string", commandLine); \
00127 \
00128 msg.str("");msg << "C++ Code to process command line arguments"; TCLAP::ValueArg<std::string> OutputCxxArg("", "OutputCxx", msg.str(), 0, OutputCxx, "std::string", commandLine); \
00129 \
00130 msg.str("");msg << "Echo the command line arguments (default: " << echoSwitch << ")"; \
00131 TCLAP::SwitchArg echoSwitchArg("", "echo", msg.str(), commandLine, echoSwitch); \
00132 \
00133 msg.str("");msg << "Produce xml description of command line arguments (default: " << xmlSwitch << ")"; \
00134 TCLAP::SwitchArg xmlSwitchArg("", "xml", msg.str(), commandLine, xmlSwitch); \
00135 \
00136 msg.str("");msg << "Address of a structure to store process information (progress, abort, etc.). (default: " << processInformationAddressString << ")"; \
00137 TCLAP::ValueArg<std::string > processInformationAddressStringArg("", "processinformationaddress", msg.str(), 0, processInformationAddressString, "std::string", commandLine); \
00138 \
00139 commandLine.parse ( argc, (char**) argv ); \
00140 UseTCLAP = UseTCLAPArg.getValue(); \
00141 logoFilesTemp = logoFilesArg.getValue(); \
00142 InputXML = InputXMLArg.getValue(); \
00143 OutputCxx = OutputCxxArg.getValue(); \
00144 echoSwitch = echoSwitchArg.getValue(); \
00145 xmlSwitch = xmlSwitchArg.getValue(); \
00146 processInformationAddressString = processInformationAddressStringArg.getValue(); \
00147 { \
00148 for (unsigned int _i = 0; _i < (unsigned int)logoFilesTemp.size(); _i++) \
00149 { \
00150 std::vector<std::string> words; \
00151 std::vector<std::string> elements; \
00152 words.clear(); \
00153 std::string sep(","); \
00154 splitString(logoFilesTemp[_i], sep, words); \
00155 for (unsigned int _j= 0; _j < (unsigned int)words.size(); _j++) \
00156 { \
00157 logoFiles.push_back((words[_j].c_str())); \
00158 } \
00159 } \
00160 } \
00161 } \
00162 catch ( TCLAP::ArgException e ) \
00163 { \
00164 std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl; \
00165 return ( EXIT_FAILURE ); \
00166 }
00167 #define GENERATE_ECHOARGS \
00168 if (echoSwitch) \
00169 { \
00170 std::cout << "Command Line Arguments" << std::endl; \
00171 std::cout << " UseTCLAP: " << UseTCLAP << std::endl; \
00172 for (unsigned int _i= 0; _i < (unsigned int)logoFilesTemp.size(); _i++) \
00173 { \
00174 std::cout << "logoFiles[" << _i << "]: "; \
00175 std::vector<std::string> words; \
00176 words.clear(); \
00177 std::string sep(","); \
00178 splitString(logoFilesTemp[_i], sep, words); \
00179 for (unsigned int _j= 0; _j < (unsigned int)words.size(); _j++) \
00180 { \
00181 std::cout << words[_j] << " "; \
00182 } \
00183 std::cout << std::endl; \
00184 } \
00185 std::cout << " InputXML: " << InputXML << std::endl; \
00186 std::cout << " OutputCxx: " << OutputCxx << std::endl; \
00187 std::cout << " echoSwitch: " << echoSwitch << std::endl; \
00188 std::cout << " xmlSwitch: " << xmlSwitch << std::endl; \
00189 std::cout << " processInformationAddressString: " << processInformationAddressString << std::endl; \
00190 }
00191 #define GENERATE_ProcessInformationAddressDecoding \
00192 ModuleProcessInformation *CLPProcessInformation = 0; \
00193 if (processInformationAddressString != "") \
00194 { \
00195 sscanf(processInformationAddressString.c_str(), "%p", &CLPProcessInformation); \
00196 }
00197 #define PARSE_ARGS GENERATE_XML;GENERATE_TCLAP;GENERATE_ECHOARGS;GENERATE_ProcessInformationAddressDecoding;