include/wipal/tool/tt_options.hxx

00001 /*
00002  * WiPal - A library and a set of tools to manipulate wireless traces.
00003  * Copyright (C) 2007  Universite Pierre et Marie Curie - Paris 6
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00018  * MA  02110-1301  USA
00019  *
00020  * Author: Thomas Claveirole <thomas.claveirole@lip6.fr>
00021  */
00022 #ifndef TOOL_TT_OPTIONS_HXX_
00023 # define TOOL_TT_OPTIONS_HXX_
00024 
00025 # include <boost/algorithm/string/classification.hpp>
00026 # include <boost/algorithm/string/split.hpp>
00027 # include <boost/lexical_cast.hpp>
00028 
00029 # include <cassert>
00030 # include <unistd.h>
00031 
00032 # include "tt_options.hh"
00033 
00034 namespace tool
00035 {
00036 
00037   namespace opt
00038   {
00039 
00040     namespace internals
00041     {
00042 
00043       inline
00044       void
00045       usage(const std::string& progname,
00046             const std::string& available_options,
00047             unsigned ninputs, unsigned noutputs)
00048       {
00049         std::cerr << "Invocation:\n\t" << progname << " [options]";
00050         switch (ninputs)
00051           {
00052           case 0:                                       break;
00053           case 1:  std::cerr << " <input>";             break;
00054           case 2:  std::cerr << " <input-1> <input-2>"; break;
00055           default: std::cerr << " <inputs...>";         break;
00056           }
00057         switch (noutputs)
00058           {
00059           case 0:                                       break;
00060           case 1:  std::cerr << " <output>";            break;
00061           default: std::cerr << " <outputs...>";        break;
00062           }
00063         std::cerr << "\n\nOptions:\n";
00064 
00065 # define tt_help_print_(OptName) OptName
00066 # define tt_help_print(OptName)                                         \
00067         if (available_options.find(tt_opt_  ## OptName) <               \
00068             available_options.size())                                   \
00069           std::cerr << tt_help_print_(tt_help_ ## OptName)
00070 
00071         tt_help_print(802cmp);
00072         tt_help_print(attr);
00073         tt_help_print(bytescmp);
00074         tt_help_print(colheads);
00075         tt_help_print(defaultcmp);
00076         tt_help_print(errs);
00077         tt_help_print(help);
00078         tt_help_print(mapping);
00079         tt_help_print(endianness);
00080         tt_help_print(prism_noise);
00081         tt_help_print(quiet);
00082         tt_help_print(ignore_ref);
00083         tt_help_print(usec);
00084         tt_help_print(timecmp);
00085         tt_help_print(version);
00086 
00087 # undef tt_help_print
00088 
00089         if (available_options.find(tt_opt_attr) < available_options.size())
00090           std::cerr << "\nAvailable attributes:\n"
00091             "  " tt_attr_tmp "\n"
00092             "  " tt_attr_dst_tmp "\n"
00093             "  " tt_attr_src_tmp "\n"
00094             "  " tt_attr_bss_tmp "\n"
00095             "  " tt_attr_src_bss_tmp "\n"
00096             "  " tt_attr_seq_tmp "\n"
00097             "  " tt_attr_seq_bss_tmp "\n"
00098             "  " tt_attr_seq_dst_bss_tmp "\n"
00099             "  " tt_attr_seq_src_bss_tmp "\n";
00100       }
00101 
00102       inline
00103       void
00104       version(const std::string& progname)
00105       {
00106         std::cerr << progname << "\n"
00107           "Trace Tools, version " << PACKAGE_VERSION << '.' << std::endl;
00108       }
00109 
00110       inline
00111       std::pair<unsigned, unsigned>
00112       make_reference(const std::string& s)
00113       {
00114         static const std::string err = ("Invalid reference frame format. "
00115                                         "Format is ``<unsigned>-<unsigned>''");
00116 
00117         std::vector<std::string>        v;
00118 
00119         boost::split(v, s, boost::is_any_of("-"));
00120         if (v.size() != 2)
00121           throw std::invalid_argument (err);
00122         try
00123           {
00124             return std::make_pair(boost::lexical_cast<unsigned> (v[0]),
00125                                   boost::lexical_cast<unsigned> (v[1]));
00126           }
00127         catch (const boost::bad_lexical_cast&)
00128           {
00129             throw std::invalid_argument (err);
00130           }
00131       }
00132 
00133     }
00134 
00135     inline
00136     options
00137     parse_args(int argc, char* const* argv,
00138                const std::string& available_options,
00139                int ninputs, int noutputs)
00140     {
00141       const std::string optstring =
00142         available_options + tt_opt_help tt_opt_version;
00143 
00144       options   r;
00145       int       o;
00146 
00147       r.mapping = tt_mapping_default;
00148       r.attributes = tt_attr_default;
00149       r.endianness = endian::guess;
00150 
00151       r.cmp = options::cmp_default;
00152       r.prism_noise_means_error = false;
00153       r.print_errors = false;
00154       r.print_frame_indices = true;
00155       r.print_column_headers = isatty(STDOUT_FILENO);
00156       r.print_microseconds = false;
00157       r.print_summary = true;
00158 
00159       while ((o = getopt(argc, argv, optstring.c_str())) != -1)
00160         switch (o)
00161           {
00162           case '8':
00163             r.cmp = options::cmp_802;
00164             break;
00165 
00166           case 'a':
00167             r.attributes = optarg;
00168             break;
00169 
00170           case 'b':
00171             r.cmp = options::cmp_bytes;
00172             break;
00173 
00174           case 'c':
00175             r.print_column_headers = false;
00176             break;
00177 
00178           case 'C':
00179             r.print_column_headers = true;
00180             break;
00181 
00182           case 'd':
00183             r.cmp = options::cmp_default;
00184             break;
00185 
00186           case 'e':
00187             r.print_errors = false;
00188             break;
00189 
00190           case 'E':
00191             r.print_errors = true;
00192             break;
00193 
00194           case 'h':
00195             internals::usage(argv[0], optstring, ninputs, noutputs);
00196             exit(EXIT_SUCCESS);
00197             break;
00198 
00199           case 'i':
00200             r.print_frame_indices = false;
00201             break;
00202 
00203           case 'I':
00204             r.print_frame_indices = true;
00205             break;
00206 
00207           case 'm':
00208             r.mapping = optarg;
00209             break;
00210 
00211           case 'n':
00212             r.endianness = endian::little;
00213             break;
00214 
00215           case 'N':
00216             r.endianness = endian::big;
00217             break;
00218 
00219           case 'p':
00220             r.prism_noise_means_error = false;
00221             break;
00222 
00223           case 'P':
00224             r.prism_noise_means_error = true;
00225             break;
00226 
00227           case 'q':
00228             r.print_errors = false;
00229             r.print_frame_indices = false;
00230             r.print_column_headers = false;
00231             r.print_microseconds = false;
00232             r.print_summary = false;
00233             break;
00234 
00235           case 'r':
00236             try
00237               {
00238                 r.ref_blacklist.insert(internals::make_reference(optarg));
00239               }
00240             catch (const std::invalid_argument& i)
00241               {
00242                 std::cerr << "ERROR: " << i.what() << '.' << std::endl;
00243                 exit(EXIT_FAILURE);
00244               }
00245             break;
00246 
00247           case 't':
00248             r.cmp = options::cmp_time;
00249             break;
00250 
00251           case 'u':
00252             r.print_microseconds = false;
00253             break;
00254 
00255           case 'U':
00256               r.print_microseconds = true;
00257               break;
00258 
00259           case 'v':
00260             internals::version(argv[0]);
00261             exit(EXIT_SUCCESS);
00262 
00263           default: /* '?' */
00264             internals::usage(argv[0], optstring, ninputs, noutputs);
00265             exit(EXIT_FAILURE);
00266           }
00267 
00268       assert(ninputs  != options::arbitrary_number_of_inputs or
00269              noutputs != options::arbitrary_number_of_outputs);
00270 
00271       if (ninputs == options::arbitrary_number_of_inputs)
00272         ninputs = argc - optind - noutputs;
00273       if (noutputs == options::arbitrary_number_of_outputs)
00274         noutputs = argc - optind - ninputs;
00275       if (ninputs < 0 or noutputs < 0 or optind + ninputs + noutputs != argc)
00276         {
00277           std::cerr << "ERROR: Wrong number of arguments." << std::endl;
00278           internals::usage(argv[0], optstring, ninputs, noutputs);
00279           exit(EXIT_FAILURE);
00280         }
00281       for (int i = 0; i < ninputs; ++i)
00282         r.input.push_back(argv[optind + i]);
00283       for (int i = 0; i < noutputs; ++i)
00284         r.output.push_back(argv[optind + ninputs + i]);
00285 
00286       return r;
00287     }
00288 
00289   } // End of namespace tool::opt.
00290 
00291 } // End of namespace tool.
00292 
00293 #endif // TOOL_TT_OPTIONS_HXX_

Generated on Tue Jan 15 19:32:31 2008 for wipal by  doxygen 1.5.4