00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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 }
00290
00291 }
00292
00293 #endif // TOOL_TT_OPTIONS_HXX_