Menu

CommandLineParameterGenerator.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002  *
00003  * Copyright (c) 2008-2010 Michael Schulze <mschulze@ivs.cs.uni-magdeburg.de>
00004  * All rights reserved.
00005  *
00006  *    Redistribution and use in source and binary forms, with or without
00007  *    modification, are permitted provided that the following conditions
00008  *    are met:
00009  *
00010  *    * Redistributions of source code must retain the above copyright
00011  *      notice, this list of conditions and the following disclaimer.
00012  *
00013  *    * Redistributions in binary form must reproduce the above copyright
00014  *      notice, this list of conditions and the following disclaimer in
00015  *      the documentation and/or other materials provided with the
00016  *      distribution.
00017  *
00018  *    * Neither the name of the copyright holders nor the names of
00019  *      contributors may be used to endorse or promote products derived
00020  *      from this software without specific prior written permission.
00021  *
00022  *
00023  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00024  *    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00025  *    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00026  *    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00027  *    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00028  *    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00029  *    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00030  *    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00031  *    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032  *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00033  *    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034  *
00035  *
00036  * $Id$
00037  *
00038  ******************************************************************************/
00039 
00040 #ifndef __CommandLineParameterGenerator_h__
00041 #define __CommandLineParameterGenerator_h__
00042 
00043 #include <stdlib.h>
00044 #include <iostream>
00045 #include <vector>
00046 #include <boost/tokenizer.hpp>
00047 #include "util/CommandLineParameterProvider.h"
00048 
00049 #define GENERATE_STRUCT_PARAMETER_HEAD struct Parameter {
00050 #define GENERATE_STRUCT_PARAMETER_PARAM(TYPE, VARIABLE) TYPE VARIABLE;
00051 #define GENERATE_STRUCT_PARAMETER_TAIL };
00052 
00053 #define CLP_CLASS_START(class_name, desc, option_name, option_desc, pd1, pd2, pd3, pd4, pd5) \
00054             class CLP::config::class_name {\
00055                 typedef boost::details::pool::singleton_default<class_name> class_name##__;\
00056                 bool _used;\
00057                 std::vector<std::string> ips;\
00058                 boost::program_options::options_description options;\
00059               public: \
00060                 class_name() : _used(false), options(desc" Options") {\
00061                     options.add_options() (option_name,\
00062                         boost::program_options::value<std::vector<std::string> >(&ips)->composing(),\
00063                         option_desc); \
00064                     famouso::util::cmdline_options::instance().add(options);\
00065                 }\
00066                 struct Parameter; \
00067                 static inline class_name& instance() { \
00068                     return class_name##__::instance();\
00069                 }\
00070                 bool used() {\
00071                     bool u=_used;\
00072                     _used=true;\
00073                     return u;\
00074                 }
00075 
00076 #define CLP_CLASS_TRANSFORM_START \
00077                 void getParameter(Parameter& param) {
00078 
00079 #define CLP_CLASS_TRANSFORM_MIDDLE \
00080                     try {\
00081                         if ( !ips.empty() ) {\
00082                             used();\
00083                             typedef boost::tokenizer<boost::char_separator<char> > tokenizer;\
00084                             boost::char_separator<char> sep(":");\
00085                             std::string str(ips.back());\
00086                             ips.pop_back();\
00087                             tokenizer tokens(str, sep);\
00088                             tokenizer::iterator tok_iter = tokens.begin(); \
00089                             try { \
00090 
00091 #define CLP_CLASS_TRANSFORM_OPTION(desc, option_type, option_variable) \
00092                                 if (tok_iter!=tokens.end()) {\
00093                                     param.option_variable=boost::lexical_cast<option_type>(*tok_iter); \
00094                                     ++tok_iter; \
00095                                 } else { \
00096                                     throw desc": invalid or incomplete arguments"; \
00097                                 }
00098 
00099 #define CLP_CLASS_TRANSFORM_END(desc) \
00100                              } catch(boost::bad_lexical_cast &) { \
00101                                  throw desc": invalid or incomplete arguments";\
00102                              } \
00103                          } else {\
00104                             if (used()) \
00105                                 throw desc": to few command line arguments";\
00106                         }\
00107                     } catch (const char *c) {\
00108                         std::cout << c << std::endl << std::endl << options << std::endl; \
00109                         exit(0);\
00110                     }\
00111                 }\
00112            }
00113 
00114 #define NAMESPACE(class_name) \
00115     namespace CLP { \
00116         namespace config { \
00117             class class_name; \
00118         } \
00119     }
00120 
00121 #define CLP1(class_name, desc, option_name, option_desc, pt1, pv1, pd1) \
00122     NAMESPACE(class_name) \
00123     CLP_CLASS_START(class_name,desc,option_name,option_desc, pd1, "", "", "", "") \
00124     GENERATE_STRUCT_PARAMETER_HEAD \
00125     GENERATE_STRUCT_PARAMETER_PARAM(pt1, pv1) \
00126     GENERATE_STRUCT_PARAMETER_TAIL \
00127     CLP_CLASS_TRANSFORM_START \
00128         param.pv1=pd1;\
00129     CLP_CLASS_TRANSFORM_MIDDLE \
00130             CLP_CLASS_TRANSFORM_OPTION(desc, pt1, pv1) \
00131     CLP_CLASS_TRANSFORM_END(desc) \
00132 
00133 #define CLP2(class_name, desc, option_name, option_desc, pt1, pv1, pd1, pt2, pv2, pd2) \
00134     NAMESPACE(class_name) \
00135     CLP_CLASS_START(class_name,desc,option_name,option_desc, pd1, pd2, "", "", "") \
00136     GENERATE_STRUCT_PARAMETER_HEAD \
00137     GENERATE_STRUCT_PARAMETER_PARAM(pt1, pv1) \
00138     GENERATE_STRUCT_PARAMETER_PARAM(pt2, pv2) \
00139     GENERATE_STRUCT_PARAMETER_TAIL \
00140     CLP_CLASS_TRANSFORM_START \
00141             param.pv1=pd1;\
00142             param.pv2=pd2;\
00143     CLP_CLASS_TRANSFORM_MIDDLE \
00144             CLP_CLASS_TRANSFORM_OPTION(desc, pt1, pv1) \
00145             CLP_CLASS_TRANSFORM_OPTION(desc, pt2, pv2) \
00146     CLP_CLASS_TRANSFORM_END(desc)
00147 
00148 #define CLP3(class_name, desc, option_name, option_desc, pt1, pv1, pd1, pt2, pv2, pd2, pt3, pv3, pd3) \
00149     NAMESPACE(class_name) \
00150     CLP_CLASS_START(class_name,desc,option_name,option_desc, pd1, pd2, pd3, "", "") \
00151     GENERATE_STRUCT_PARAMETER_HEAD \
00152     GENERATE_STRUCT_PARAMETER_PARAM(pt1, pv1) \
00153     GENERATE_STRUCT_PARAMETER_PARAM(pt2, pv2) \
00154     GENERATE_STRUCT_PARAMETER_PARAM(pt3, pv3) \
00155     GENERATE_STRUCT_PARAMETER_TAIL \
00156     CLP_CLASS_TRANSFORM_START \
00157             param.pv1=pd1;\
00158             param.pv2=pd2;\
00159             param.pv3=pd3;\
00160     CLP_CLASS_TRANSFORM_MIDDLE \
00161             CLP_CLASS_TRANSFORM_OPTION(desc, pt1, pv1) \
00162             CLP_CLASS_TRANSFORM_OPTION(desc, pt2, pv2) \
00163             CLP_CLASS_TRANSFORM_OPTION(desc, pt3, pv3) \
00164     CLP_CLASS_TRANSFORM_END(desc)
00165 
00166 #define CLP4(class_name, desc, option_name, option_desc, pt1, pv1, pd1, pt2, pv2, pd2, pt3, pv3, pd3, pt4, pv4, pd4) \
00167     NAMESPACE(class_name) \
00168     CLP_CLASS_START(class_name,desc,option_name,option_desc, pd1, pd2, pd3, pd4, "") \
00169     GENERATE_STRUCT_PARAMETER_HEAD \
00170     GENERATE_STRUCT_PARAMETER_PARAM(pt1, pv1) \
00171     GENERATE_STRUCT_PARAMETER_PARAM(pt2, pv2) \
00172     GENERATE_STRUCT_PARAMETER_PARAM(pt3, pv3) \
00173     GENERATE_STRUCT_PARAMETER_PARAM(pt4, pv4) \
00174     GENERATE_STRUCT_PARAMETER_TAIL \
00175     CLP_CLASS_TRANSFORM_START \
00176             param.pv1=pd1;\
00177             param.pv2=pd2;\
00178             param.pv3=pd3;\
00179             param.pv4=pd4;\
00180     CLP_CLASS_TRANSFORM_MIDDLE \
00181             CLP_CLASS_TRANSFORM_OPTION(desc, pt1, pv1) \
00182             CLP_CLASS_TRANSFORM_OPTION(desc, pt2, pv2) \
00183             CLP_CLASS_TRANSFORM_OPTION(desc, pt3, pv3) \
00184             CLP_CLASS_TRANSFORM_OPTION(desc, pt4, pv4) \
00185     CLP_CLASS_TRANSFORM_END(desc)
00186 
00187 #define CLP5(class_name, desc, option_name, option_desc, pt1, pv1, pd1, pt2, pv2, pd2, pt3, pv3, pd3, pt4, pv4, pd4, pt5, pv5, pd5) \
00188     NAMESPACE(class_name) \
00189     CLP_CLASS_START(class_name,desc,option_name,option_desc, pd1, pd2, pd3, pd4, pd5) \
00190     GENERATE_STRUCT_PARAMETER_HEAD \
00191     GENERATE_STRUCT_PARAMETER_PARAM(pt1, pv1) \
00192     GENERATE_STRUCT_PARAMETER_PARAM(pt2, pv2) \
00193     GENERATE_STRUCT_PARAMETER_PARAM(pt3, pv3) \
00194     GENERATE_STRUCT_PARAMETER_PARAM(pt4, pv4) \
00195     GENERATE_STRUCT_PARAMETER_PARAM(pt5, pv5) \
00196     GENERATE_STRUCT_PARAMETER_TAIL \
00197     CLP_CLASS_TRANSFORM_START \
00198             param.pv1=pd1;\
00199             param.pv2=pd2;\
00200             param.pv3=pd3;\
00201             param.pv4=pd4;\
00202             param.pv5=pd5;\
00203     CLP_CLASS_TRANSFORM_MIDDLE \
00204             CLP_CLASS_TRANSFORM_OPTION(desc, pt1, pv1) \
00205             CLP_CLASS_TRANSFORM_OPTION(desc, pt2, pv2) \
00206             CLP_CLASS_TRANSFORM_OPTION(desc, pt3, pv3) \
00207             CLP_CLASS_TRANSFORM_OPTION(desc, pt4, pv4) \
00208             CLP_CLASS_TRANSFORM_OPTION(desc, pt5, pv5) \
00209     CLP_CLASS_TRANSFORM_END(desc)
00210 
00211 #endif
00212