DATRW++ library: seismic data I/O with multiple formats
libdatrwxxtests.cc
Go to the documentation of this file.
1 /*! \file libdatrwxxtests.cc
2  * \brief test internal features of the library
3  *
4  * ----------------------------------------------------------------------------
5  *
6  * \author Thomas Forbriger
7  * \date 06/09/2011
8  *
9  * test internal features of the library
10  *
11  * Copyright (c) 2011 by Thomas Forbriger (BFO Schiltach)
12  *
13  * ----
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27  * ----
28  *
29  * REVISIONS and CHANGES
30  * - 06/09/2011 V1.0 Thomas Forbriger
31  * - 11/07/2016 V1.1 provide means to test error message output
32  *
33  * ============================================================================
34  * \example libdatrwxxtests.cc
35  * \brief This program tests some internal features of libdatrwxx and can
36  * serve as an example for using features like datrw::Subformat
37  */
38 #define LIBDATRWXXTESTS_VERSION \
39  "LIBDATRWXXTESTS V1.1 test internal features of the library"
40 
41 #include <iostream>
42 #include <fstream>
43 #include <string>
44 #include <tfxx/commandline.h>
45 #include <datrwxx/debug.h>
46 #include <datrwxx/error.h>
47 #include <datrwxx/util.h>
48 #include <datrwxx/types.h>
49 #include <datrwxx/readany.h>
50 #include <datrwxx/formatmodifier.h>
51 #include <aff/dump.h>
52 
53 using std::cout;
54 using std::cerr;
55 using std::endl;
56 
57 /*----------------------------------------------------------------------*/
58 
59 struct Options {
61  bool testerror;
62  bool debug, verbose;
63  std::string formatstring, readtype;
64  int nerrortest; // select an error function to be tested
65 }; // struct Options
66 
67 /*----------------------------------------------------------------------*/
68 
69 void reportkey(const datrw::Subformat& f,
70  const std::string k,
71  const std::string d)
72 {
73  cout << " " << k << " is ";
74  if (!f.isset(k))
75  {
76  cout << "NOT ";
77  }
78  cout << "set";
79  cout << " and has value " << f.value(k, d) << endl;
80  double a,b;
81  f(k, d) >> a >> b;
82  cout << " reading two doubles from value: " << a << ", " << b;
83  cout << endl;
84  cout << " the given default value is " << d << endl;
85 } // void reportkey(const datrw::Subformat& f, const std::string k)
86 
87 /*----------------------------------------------------------------------*/
88 
89 void reportprovides(const std::string& type, const bool& flag)
90 {
91  cout << "input stream ";
92  if (flag)
93  { cout << "provides"; }
94  else
95  { cout << "doesn't provide"; }
96  cout << " " << type << " type data" << endl;
97 } // void reportprovides(const std::string& type, const bool& flag)
98 
99 /*----------------------------------------------------------------------*/
100 
101 void checkkey(const datrw::Subformat& f, const std::string k)
102 {
103  cout << " " << k << " is ";
104  if (!f.isset(k))
105  {
106  cout << "NOT ";
107  }
108  cout << "set" << endl;
109 } // void checkkey(const datrw::Subformat& f, const std::string k)
110 
111 /*----------------------------------------------------------------------*/
112 
113 int main(int iargc, char* argv[])
114 {
115 
116  // define usage information
117  char usage_text[]=
118  {
120  "usage: libdatrwxxtests [-format s] [-rtest type] [-int] [-single]\n"
121  " [-error[=n]]" "\n"
122  " [-v] [-skip] [-DEBUG] file [file ...]" "\n"
123  " or: libdatrwxxtests --help|-h" "\n"
124  };
125 
126  // define full help text
127  char help_text[]=
128  {
129  "\n"
130  "-v verbose mode\n"
131  "-DEBUG activate debugging output\n"
132  "-format s test datrwxx::Subformat by passing format string s\n"
133  "-rtest type read files of type \"type\" and report content\n"
134  "-int use integer reading\n"
135  "-single use float reading\n"
136  "-skip skip traces\n"
137  "-error[=n] test error report mechanism (n=0: prints available tests)\n"
138  "file file to be read\n"
139  };
140 
141  // define commandline options
142  using namespace tfxx::cmdline;
143  static Declare options[]=
144  {
145  // 0: print help
146  {"help",arg_no,"-"},
147  // 1: verbose mode
148  {"v",arg_no,"-"},
149  // 2: verbose mode
150  {"format",arg_yes,"-"},
151  // 3: perform a read test
152  {"rtest",arg_yes,"-"},
153  // 4: use integer samples
154  {"int",arg_no,"-"},
155  // 5: use single precision samples
156  {"single",arg_no,"-"},
157  // 6: skip samples
158  {"skip",arg_no,"-"},
159  // 7: debug output
160  {"DEBUG",arg_no,"-"},
161  // 8: skip samples
162  {"error",arg_opt,"0"},
163  {NULL}
164  };
165 
166  // no arguments? print usage...
167  if (iargc<2)
168  {
169  cerr << usage_text << endl;
170  exit(0);
171  }
172 
173  // collect options from commandline
174  Commandline cmdline(iargc, argv, options);
175 
176  // help requested? print full help text...
177  if (cmdline.optset(0))
178  {
179  cerr << usage_text << endl;
180  cerr << help_text << endl;
181  exit(0);
182  }
183 
184  Options opt;
185  opt.verbose=cmdline.optset(1);
186  opt.testformat=cmdline.optset(2);
187  opt.formatstring=cmdline.string_arg(2);
188  opt.readtest=cmdline.optset(3);
189  opt.readtype=cmdline.string_arg(3);
190  opt.readint=cmdline.optset(4);
191  opt.readsingle=cmdline.optset(5);
192  opt.skipsamples=cmdline.optset(6);
193  opt.debug=cmdline.optset(7);
194  opt.testerror=cmdline.optset(8);
195  opt.nerrortest=cmdline.int_arg(8);
196 
197  /*======================================================================*/
198 
199  if (opt.testformat)
200  {
201  cout << "Test format modifiers" << endl;
202  cout << "=====================" << endl;
203  std::string format=datrw::util::clipstring(opt.formatstring);
204  datrw::Subformat subformat(opt.formatstring);
205  cout << "data format ID: " << format << endl;
206  reportkey(subformat, "key1", "default1");
207  reportkey(subformat, "key2", "18.,23.6");
208  checkkey(subformat, "key3");
209  checkkey(subformat, "key4");
210  if (subformat.allarechecked())
211  {
212  cout << "All keys have been checked by the program." << endl;
213  }
214  else
215  {
216  DATRW_assert_modifiers_are_recognized(subformat, "libdatrwxxtests");
217  }
218  cout << endl;
219  } // if (opt.testformat)
220 
221  /*======================================================================*/
222 
223  if (opt.readtest)
224  {
225  sff::FREE free;
226  sff::INFO info;
227  sff::SRCE srce;
228  sff::WID2 wid2;
229  cout << "Read input files of type: " << opt.readtype << endl;
230  cout << "=========================" << endl;
231  while (cmdline.extra())
232  {
233  std::string filename=cmdline.next();
234  cout << endl;
235  cout << "read file " << filename << endl;
236 
237  std::ifstream ifs(filename.c_str());
238  datrw::ianystream is(ifs, opt.readtype, opt.debug);
239  if (opt.verbose)
240  {
241  reportprovides("double", is.providesd());
242  reportprovides("float", is.providesf());
243  reportprovides("int", is.providesi());
244  }
245  if (is.hasfree())
246  {
247  if (opt.verbose)
248  {
249  cout << "file FREE block:" << endl;
250  is >> free;
251  ::sff::verbose(std::cout, free);
252  }
253  else
254  {
255  cout << "file has FREE block" << endl;
256  }
257  }
258  else
259  {
260  cout << "file has no FREE block" << endl;
261  }
262  if (is.hassrce())
263  {
264  if (opt.verbose)
265  {
266  cout << "file SRCE line:" << endl;
267  is >> srce;
268  ::sff::verbose(std::cout, srce);
269  }
270  else
271  {
272  cout << "file has SRCE line" << endl;
273  }
274  }
275  else
276  {
277  cout << "file has no SRCE line" << endl;
278  }
279 
280  while (!is.last())
281  {
282  datrw::Tdseries dseries;
283  datrw::Tfseries fseries;
284  datrw::Tiseries iseries;
285 
286  if (opt.skipsamples)
287  {
288  is.skipseries();
289  }
290  else
291  {
292  if (opt.readint)
293  {
294  if (is.providesi())
295  {
296  is >> iseries;
297  }
298  else
299  {
300  cout << "stream does not provide integer data" << endl;
301  is.skipseries();
302  }
303  }
304  else if (opt.readsingle)
305  {
306  if (is.providesf())
307  {
308  is >> fseries;
309  }
310  else
311  {
312  cout << "stream does not provide single data" << endl;
313  is.skipseries();
314  }
315  }
316  else
317  {
318  if (is.providesd())
319  {
320  is >> dseries;
321  }
322  else
323  {
324  cout << "stream does not provide double data" << endl;
325  is.skipseries();
326  }
327  }
328  }
329  if (is.hasfree())
330  {
331  if (opt.verbose)
332  {
333  cout << "trace FREE block:" << endl;
334  is >> free;
335  ::sff::verbose(std::cout, free);
336  }
337  else
338  {
339  cout << "trace has FREE block" << endl;
340  }
341  }
342  else
343  {
344  cout << "trace has no FREE block" << endl;
345  }
346  if (is.hasinfo())
347  {
348  if (opt.verbose)
349  {
350  cout << "trace INFO line:" << endl;
351  is >> info;
352  ::sff::verbose(std::cout, info);
353  }
354  else
355  {
356  cout << "trace has INFO line" << endl;
357  }
358  }
359  else
360  {
361  cout << "trace has no INFO line" << endl;
362  }
363  is >> wid2;
364  ::sff::verbose(std::cout, wid2);
365  if (opt.readint)
366  {
367  if (is.providesi())
368  {
369  if (opt.verbose)
370  {
371  DUMP( iseries );
372  }
373  else
374  {
375  cout << "read " << iseries.size() << " integer samples" << endl;
376  }
377  }
378  else
379  {
380  cout << "stream does not provide integer data" << endl;
381  }
382  }
383  else if (opt.readsingle)
384  {
385  if (is.providesf())
386  {
387  if (opt.verbose)
388  {
389  DUMP( fseries );
390  }
391  else
392  {
393  cout << "read " << fseries.size()
394  << " single precision samples" << endl;
395  }
396  }
397  else
398  {
399  cout << "stream does not provide single precision data" << endl;
400  }
401  }
402  else
403  {
404  if (is.providesd())
405  {
406  if (opt.verbose)
407  {
408  DUMP( dseries );
409  }
410  else
411  {
412  cout << "read " << dseries.size()
413  << " double precision samples" << endl;
414  }
415  }
416  else
417  {
418  cout << "stream does not provide double precision data" << endl;
419  }
420  }
421  if (is.last())
422  {
423  cout << "This was the last trace in file!" << endl;
424  }
425  } // while (!is.last())
426  } // while (cmdline.extra())
427  } // if (opt.readtest)
428 
429  /*======================================================================*/
430 
431  if (opt.testerror)
432  {
433  cout << "Test error reports (formatting of messages)" << endl;
434  cout << "===========================================" << endl;
435  cout << endl;
436  if (opt.nerrortest == 0)
437  {
438  cout << "available tests:" << endl;
439  cout << "1: non-fatal reports" << endl;
440  cout << "2: direct abort" << endl;
441  cout << "3: fatal/non-fatal assert (non-fatal version)" << endl;
442  cout << "4: fatal/non-fatal assert (fatal version)" << endl;
443  cout << "5: standard assertion" << endl;
444  }
445  else if (opt.nerrortest == 1)
446  {
447  cout << "report assert" << endl;
448  cout << "-------------" << endl;
449  DATRW_report_assert(false, "This message is produced after testing"
450  " a condition to report\n"
451  "that the test fails.");
452  cout << "\nwarning" << endl;
453  cout << "-------" << endl;
454  DATRW_warning("main", "This is a warning message from a specific"
455  " function in the library.\n"
456  "The macro takes a multiline message output too.");
457  }
458  else if (opt.nerrortest == 2)
459  {
460  cout << "direct abort" << endl;
461  cout << "------------" << endl;
462  DATRW_abort("Abort program intentionally.\n"
463  "A multi-line message my be passed too in this case.\n"
464  "Pass one of the non-specified values for the error\n"
465  "test to see the output for DATRW_illegal.");
466  }
467  else if ((opt.nerrortest == 3) || (opt.nerrortest == 4))
468  {
469  cout << "fatal/non-fatal assert" << endl;
470  cout << "----------------------" << endl;
472  (opt.nerrortest<=1)||(opt.nerrortest>=6),
473  "This is a test of a fatal/non-fatal assert.\n"
474  "The error is made non-fatal, if the option"
475  "opt.nerrortest equals 3.\n"
476  "Currently " << DATRW_value(opt.nerrortest));
477  }
478  else if (opt.nerrortest == 5)
479  {
480  cout << "standard assertion" << endl;
481  cout << "------------------" << endl;
482  DATRW_assert(false,
483  "This type of error is emitted,"
484  " if an assertion is failed.\n"
485  "Several lines of explanation can be provided"
486  " to the user.\n"
487  "This can include the output of variables like "
488  << DATRW_value(opt.nerrortest));
489  }
490  else
491  {
492  cout << "no test selected by n=" << opt.nerrortest << endl;
494  }
495  cout << "...program did not abort" << endl;
496  } // if (opt.testerror)
497 }
498 
499 /* ----- END OF libdatrwxxtests.cc ----- */
provides all specific data reading classes (prototypes)
std::string readtype
#define DATRW_assert(C, M)
Check an assertion and report by throwing an exception.
Definition: error.h:92
internal data types (prototypes)
provide format modifiers (prototypes)
macro function for debugging output (prototypes)
aff::Series< float > Tfseries
Definition: types.h:46
void reportkey(const datrw::Subformat &f, const std::string k, const std::string d)
void reportprovides(const std::string &type, const bool &flag)
bool allarechecked() const
check if user provided keys not being recognized
bool skipsamples
Definition: binarytest.cc:57
aff::Series< double > Tdseries
Definition: types.h:45
bool testerror
exception class declaration for libdatrwxx (prototypes)
#define LIBDATRWXXTESTS_VERSION
#define DATRW_assert_modifiers_are_recognized(S, F)
abort if user passed unused modifiers
Class to read any type of data file.
Definition: readany.h:82
#define DATRW_warning(N, M)
Report a warning.
Definition: error.h:148
bool debug
Definition: asciitest.cc:52
utilities used by more than one type of data reader (prototypes)
bool verbose
Definition: asciitest.cc:51
#define DATRW_abort(M)
Abort and give a message.
Definition: error.h:101
aff::Series< int > Tiseries
Definition: types.h:47
std::string clipstring(std::string &s, const std::string &delim)
strip substringStrips off first substring up to given delimiter. The string is passed as a reference ...
Definition: util.cc:105
#define DATRW_nonfatal_assert(F, C, M)
Macro to distinguish between fatal and non fatal assertions.
Definition: error.h:138
Class to handle format modifiersThis class is used to parse a format modifier string. Detailed instructions will be given upon request. For some hints have a look at tests/libdatrwxxtests.c.
bool testformat
bool isset(const std::string &k) const
check if user provided this key
int main(int iargc, char *argv[])
bool readsingle
void checkkey(const datrw::Subformat &f, const std::string k)
std::string formatstring
#define DATRW_value(V)
report value
Definition: debug.h:65
std::string value(const std::string &k, const std::string &dev="false") const
function operator returns string
#define DATRW_report_assert(C, M)
Check an assertion and report only.
Definition: error.h:120
#define DATRW_illegal
Definition: error.h:108