Branch data Line data Source code
1 : : /*
2 : : * MOAB, a Mesh-Oriented datABase, is a software component for creating,
3 : : * storing and accessing finite element mesh data.
4 : : *
5 : : * Copyright 2004 Sandia Corporation. Under the terms of Contract
6 : : * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
7 : : * retains certain rights in this software.
8 : : *
9 : : * This library is free software; you can redistribute it and/or
10 : : * modify it under the terms of the GNU Lesser General Public
11 : : * License as published by the Free Software Foundation; either
12 : : * version 2.1 of the License, or (at your option) any later version.
13 : : *
14 : : */
15 : :
16 : : /**\file FileOptions.cpp
17 : : *\author Jason Kraftcheck ([email protected])
18 : : *\date 2007-08-21
19 : : */
20 : :
21 : : #include "moab/FileOptions.hpp"
22 : :
23 : : #include <ctype.h>
24 : : #include <stdlib.h>
25 : : #include <string.h>
26 : : #include <algorithm>
27 : :
28 : : namespace moab
29 : : {
30 : :
31 : : const char DEFAULT_SEPARATOR = ';';
32 : :
33 : 19978 : static inline bool strempty( const char* s )
34 : : {
35 : 19978 : return !*s;
36 : : }
37 : :
38 [ + - ]: 494 : FileOptions::FileOptions( const char* str ) : mData( 0 )
39 : : {
40 : : // if option string is null, just return
41 [ + + ]: 371 : if( !str ) return;
42 : :
43 : : // check if alternate separator is specified
44 : 124 : char separator[2] = { DEFAULT_SEPARATOR, '\0' };
45 [ + + ]: 124 : if( *str == DEFAULT_SEPARATOR )
46 : : {
47 : 3 : ++str;
48 [ - + ]: 3 : if( strempty( str ) ) return;
49 : 3 : separator[0] = *str;
50 : 3 : ++str;
51 : : }
52 : :
53 : : // don't bother allocating copy of input string if
54 : : // input string is empty.
55 [ + + ]: 124 : if( !strempty( str ) )
56 : : {
57 : : // tokenize at separator character
58 : 34 : mData = strdup( str );
59 [ + + ]: 178 : for( char* i = strtok( mData, separator ); i; i = strtok( 0, separator ) )
60 [ + - ]: 144 : if( !strempty( i ) ) // skip empty strings
61 [ + - ]: 144 : mOptions.push_back( i );
62 : : }
63 : :
64 [ + - ]: 124 : mSeen.resize( mOptions.size(), false );
65 : : }
66 : :
67 [ + - ][ + - ]: 6 : FileOptions::FileOptions( const FileOptions& copy ) : mData( 0 ), mOptions( copy.mOptions.size() )
68 : : {
69 [ + + ]: 3 : if( !copy.mOptions.empty() )
70 : : {
71 [ + - ]: 2 : const char* last = copy.mOptions.back();
72 : 2 : const char* endptr = last + strlen( last ) + 1;
73 : 2 : size_t len = endptr - copy.mData;
74 : 2 : mData = (char*)malloc( len );
75 : 2 : memcpy( mData, copy.mData, len );
76 [ + + ]: 6 : for( size_t i = 0; i < mOptions.size(); ++i )
77 [ + - ][ + - ]: 4 : mOptions[i] = mData + ( copy.mOptions[i] - copy.mData );
78 : : }
79 [ + - ]: 3 : mSeen = copy.mSeen;
80 : 3 : }
81 : :
82 : 2 : FileOptions& FileOptions::operator=( const FileOptions& copy )
83 : : {
84 : : // Check for self-assignment
85 [ - + ]: 2 : if( this == © ) return *this;
86 : :
87 : 2 : free( mData );
88 : 2 : mData = 0;
89 : 2 : mOptions.resize( copy.mOptions.size() );
90 : :
91 [ + - ]: 2 : if( !copy.mOptions.empty() )
92 : : {
93 : 2 : const char* last = copy.mOptions.back();
94 : 2 : const char* endptr = last + strlen( last ) + 1;
95 : 2 : size_t len = endptr - copy.mData;
96 : 2 : mData = (char*)malloc( len );
97 : 2 : memcpy( mData, copy.mData, len );
98 [ + + ]: 22 : for( size_t i = 0; i < mOptions.size(); ++i )
99 : 20 : mOptions[i] = mData + ( copy.mOptions[i] - copy.mData );
100 : : }
101 : :
102 : 2 : mSeen = copy.mSeen;
103 : 2 : return *this;
104 : : }
105 : :
106 : 500 : FileOptions::~FileOptions()
107 : : {
108 : 250 : free( mData );
109 : 250 : }
110 : :
111 : 750 : ErrorCode FileOptions::get_null_option( const char* name ) const
112 : : {
113 : : const char* s;
114 [ + - ]: 750 : ErrorCode rval = get_option( name, s );
115 [ + + ]: 750 : if( MB_SUCCESS != rval ) return rval;
116 [ + + ]: 750 : return strempty( s ) ? MB_SUCCESS : MB_TYPE_OUT_OF_RANGE;
117 : : }
118 : :
119 : 303 : ErrorCode FileOptions::get_int_option( const char* name, int& value ) const
120 : : {
121 : : const char* s;
122 [ + - ]: 303 : ErrorCode rval = get_option( name, s );
123 [ + + ]: 303 : if( MB_SUCCESS != rval ) return rval;
124 : :
125 : : // empty string
126 [ + + ]: 55 : if( strempty( s ) ) return MB_TYPE_OUT_OF_RANGE;
127 : :
128 : : // parse value
129 : : char* endptr;
130 : 54 : long int pval = strtol( s, &endptr, 0 );
131 [ + + ]: 54 : if( !strempty( endptr ) ) // syntax error
132 : 1 : return MB_TYPE_OUT_OF_RANGE;
133 : :
134 : : // check for overflow (parsing long int, returning int)
135 : 53 : value = pval;
136 [ - + ]: 53 : if( pval != (long int)value ) return MB_TYPE_OUT_OF_RANGE;
137 : :
138 : 303 : return MB_SUCCESS;
139 : : }
140 : :
141 : 134 : ErrorCode FileOptions::get_int_option( const char* name, int default_val, int& value ) const
142 : : {
143 : : const char* s;
144 [ + - ]: 134 : ErrorCode rval = get_option( name, s );
145 [ + - ]: 134 : if( MB_SUCCESS != rval ) return rval;
146 : :
147 : : // empty string
148 [ # # ]: 0 : if( strempty( s ) )
149 : : {
150 : 0 : value = default_val;
151 : 0 : return MB_SUCCESS;
152 : : }
153 : :
154 : : // parse value
155 : : char* endptr;
156 : 0 : long int pval = strtol( s, &endptr, 0 );
157 [ # # ]: 0 : if( !strempty( endptr ) ) // syntax error
158 : 0 : return MB_TYPE_OUT_OF_RANGE;
159 : :
160 : : // check for overflow (parsing long int, returning int)
161 : 0 : value = pval;
162 [ # # ]: 0 : if( pval != (long int)value ) return MB_TYPE_OUT_OF_RANGE;
163 : :
164 : 134 : return MB_SUCCESS;
165 : : }
166 : :
167 : 23 : ErrorCode FileOptions::get_ints_option( const char* name, std::vector< int >& values ) const
168 : : {
169 : : const char* s;
170 [ + - ]: 23 : ErrorCode rval = get_option( name, s );
171 [ + + ]: 23 : if( MB_SUCCESS != rval ) return rval;
172 : :
173 : : // empty string
174 [ - + ]: 1 : if( strempty( s ) ) return MB_TYPE_OUT_OF_RANGE;
175 : :
176 : : // parse values
177 [ + + ]: 4 : while( !strempty( s ) )
178 : : {
179 : : char* endptr;
180 : 3 : long int sval = strtol( s, &endptr, 0 );
181 : :
182 : : #define EATSPACE( a ) \
183 : : while( ( *a == ' ' || *a == ',' ) && !strempty( a ) ) \
184 : : a++;
185 [ + - ][ + + ]: 4 : EATSPACE( endptr );
[ + - ][ + + ]
186 : 3 : long int eval = sval;
187 [ + + ]: 3 : if( *endptr == '-' )
188 : : {
189 : 1 : endptr++;
190 : 1 : s = endptr;
191 : 1 : eval = strtol( s, &endptr, 0 );
192 [ + - ][ + + ]: 2 : EATSPACE( endptr );
[ + - ][ + + ]
193 : : }
194 : :
195 : : // check for overflow (parsing long int, returning int)
196 : 3 : int value = sval;
197 [ - + ]: 3 : if( sval != (long int)value ) return MB_TYPE_OUT_OF_RANGE;
198 : 3 : value = eval;
199 [ - + ]: 3 : if( eval != (long int)value ) return MB_TYPE_OUT_OF_RANGE;
200 : :
201 [ + + ]: 8 : for( int i = sval; i <= eval; i++ )
202 [ + - ]: 5 : values.push_back( i );
203 : :
204 : 3 : s = endptr;
205 : : }
206 : :
207 : 23 : return MB_SUCCESS;
208 : : }
209 : :
210 : 2 : ErrorCode FileOptions::get_reals_option( const char* name, std::vector< double >& values ) const
211 : : {
212 : : const char* s;
213 [ + - ]: 2 : ErrorCode rval = get_option( name, s );
214 [ + + ]: 2 : if( MB_SUCCESS != rval ) return rval;
215 : :
216 : : // empty string
217 [ - + ]: 1 : if( strempty( s ) ) return MB_TYPE_OUT_OF_RANGE;
218 : :
219 : : // parse values
220 [ + + ]: 4 : while( !strempty( s ) )
221 : : {
222 : : char* endptr;
223 : 3 : double sval = strtod( s, &endptr );
224 : :
225 [ + + ][ + + ]: 6 : EATSPACE( endptr );
[ + - ][ + + ]
226 [ + - ]: 3 : values.push_back( sval );
227 : :
228 : 3 : s = endptr;
229 : : }
230 : :
231 : 2 : return MB_SUCCESS;
232 : : }
233 : :
234 : 650 : ErrorCode FileOptions::get_real_option( const char* name, double& value ) const
235 : : {
236 : : const char* s;
237 [ + - ]: 650 : ErrorCode rval = get_option( name, s );
238 [ + + ]: 650 : if( MB_SUCCESS != rval ) return rval;
239 : :
240 : : // empty string
241 [ + + ]: 9 : if( strempty( s ) ) return MB_TYPE_OUT_OF_RANGE;
242 : :
243 : : // parse value
244 : : char* endptr;
245 : 8 : value = strtod( s, &endptr );
246 [ + + ]: 8 : if( !strempty( endptr ) ) // syntax error
247 : 1 : return MB_TYPE_OUT_OF_RANGE;
248 : :
249 : 650 : return MB_SUCCESS;
250 : : }
251 : :
252 : 3 : ErrorCode FileOptions::get_strs_option( const char* name, std::vector< std::string >& values ) const
253 : : {
254 : : const char* s;
255 [ + - ]: 3 : ErrorCode rval = get_option( name, s );
256 [ + + ]: 3 : if( MB_SUCCESS != rval ) return rval;
257 : :
258 : : // empty string
259 [ + + ]: 2 : if( strempty( s ) ) return MB_TYPE_OUT_OF_RANGE;
260 : :
261 : : // parse values
262 : 1 : char separator[3] = { ' ', ',', '\0' };
263 : 1 : char* tmp_str = strdup( s );
264 [ + + ]: 3 : for( char* i = strtok( tmp_str, separator ); i; i = strtok( 0, separator ) )
265 [ + - ]: 2 : if( !strempty( i ) ) // skip empty strings
266 [ + - ][ + - ]: 2 : values.push_back( std::string( i ) );
267 : 1 : free( tmp_str );
268 : :
269 : 3 : return MB_SUCCESS;
270 : : }
271 : :
272 : 82 : ErrorCode FileOptions::get_str_option( const char* name, std::string& value ) const
273 : : {
274 : : const char* s;
275 [ + - ]: 82 : ErrorCode rval = get_option( name, s );
276 [ + + ]: 82 : if( MB_SUCCESS != rval ) return rval;
277 [ + + ]: 24 : if( strempty( s ) ) return MB_TYPE_OUT_OF_RANGE;
278 [ + - ]: 2 : value = s;
279 : 82 : return MB_SUCCESS;
280 : : }
281 : :
282 : 181 : ErrorCode FileOptions::get_option( const char* name, std::string& value ) const
283 : : {
284 : : const char* s;
285 [ + - ]: 181 : ErrorCode rval = get_option( name, s );
286 [ + + ]: 181 : if( MB_SUCCESS != rval ) return rval;
287 : :
288 [ + - ]: 53 : value = s;
289 : 181 : return MB_SUCCESS;
290 : : }
291 : :
292 : 2492 : ErrorCode FileOptions::get_option( const char* name, const char*& value ) const
293 : : {
294 : 2492 : std::vector< const char* >::const_iterator i;
295 [ + - ][ + - ]: 7233 : for( i = mOptions.begin(); i != mOptions.end(); ++i )
[ + + ]
296 : : {
297 [ + - ]: 4952 : const char* opt = *i;
298 [ + - ][ + + ]: 4952 : if( compare( name, opt ) )
299 : : {
300 : 211 : value = opt + strlen( name );
301 : : // if compare returned true, next char after option
302 : : // name must be either the null char or an equals symbol.
303 [ + + ]: 211 : if( *value == '=' ) ++value;
304 : :
305 [ + - ][ + - ]: 211 : mSeen[i - mOptions.begin()] = true;
306 : 211 : return MB_SUCCESS;
307 : : }
308 : : }
309 : :
310 : 2492 : return MB_ENTITY_NOT_FOUND;
311 : : }
312 : :
313 : 73 : ErrorCode FileOptions::match_option( const char* name, const char* value ) const
314 : : {
315 : : int idx;
316 : 73 : const char* array[] = { value, NULL };
317 [ + - ]: 73 : return match_option( name, array, idx );
318 : : }
319 : :
320 : 364 : ErrorCode FileOptions::match_option( const char* name, const char* const* values, int& index ) const
321 : : {
322 : : const char* optval;
323 [ + - ]: 364 : ErrorCode rval = get_option( name, optval );
324 [ + + ]: 364 : if( MB_SUCCESS != rval ) return rval;
325 : :
326 [ + + ]: 170 : for( index = 0; values[index]; ++index )
327 [ + - ][ + + ]: 151 : if( compare( optval, values[index] ) ) return MB_SUCCESS;
328 : :
329 : 19 : index = -1;
330 : 364 : return MB_FAILURE;
331 : : }
332 : :
333 : 228 : ErrorCode FileOptions::get_toggle_option( const char* name, bool default_value, bool& value ) const
334 : : {
335 : : static const char* values[] = { "true", "yes", "1", "on", "false", "no", "0", "off", 0 };
336 : 228 : const int num_true = 4;
337 : :
338 : : int index;
339 [ + - ]: 228 : ErrorCode result = match_option( name, values, index );
340 [ - + ]: 228 : if( result == MB_SUCCESS ) { value = index < num_true; }
341 [ + - ]: 228 : else if( result == MB_ENTITY_NOT_FOUND )
342 : : {
343 : 228 : value = default_value;
344 : 228 : result = MB_SUCCESS;
345 : : }
346 : : else
347 : : {
348 : 0 : result = MB_TYPE_OUT_OF_RANGE;
349 : : }
350 : :
351 : 228 : return result;
352 : : }
353 : :
354 : 5103 : bool FileOptions::compare( const char* name, const char* option )
355 : : {
356 [ + + ][ + + ]: 14063 : while( !strempty( name ) && toupper( *name ) == toupper( *option ) )
[ + + ]
357 : : {
358 : 8960 : ++name;
359 : 8960 : ++option;
360 : : }
361 : : // match if name matched option for length of name,
362 : : // and option either matched entirely or matches up to
363 : : // and equals sign.
364 [ + + ][ + + ]: 5103 : return strempty( name ) && ( strempty( option ) || *option == '=' );
[ + + ]
365 : : }
366 : :
367 : 0 : void FileOptions::get_options( std::vector< std::string >& list ) const
368 : : {
369 : 0 : list.clear();
370 : 0 : list.resize( mOptions.size() );
371 : 0 : std::copy( mOptions.begin(), mOptions.end(), list.begin() );
372 : 0 : }
373 : :
374 : 184 : bool FileOptions::all_seen() const
375 : : {
376 [ + - ][ + - ]: 184 : return std::find( mSeen.begin(), mSeen.end(), false ) == mSeen.end();
377 : : }
378 : :
379 : 1 : void FileOptions::mark_all_seen() const
380 : : {
381 : 1 : mSeen.clear();
382 : 1 : mSeen.resize( mOptions.size(), true );
383 : 1 : }
384 : :
385 : 4 : ErrorCode FileOptions::get_unseen_option( std::string& name ) const
386 : : {
387 [ + - ]: 4 : std::vector< bool >::iterator i = std::find( mSeen.begin(), mSeen.end(), false );
388 [ + - ][ + + ]: 4 : if( i == mSeen.end() )
389 : : {
390 : 2 : name.clear();
391 : 2 : return MB_ENTITY_NOT_FOUND;
392 : : }
393 : :
394 [ + - ][ + - ]: 2 : const char* opt = mOptions[i - mSeen.begin()];
395 : 2 : const char* end = strchr( opt, '=' );
396 [ + - ][ + - ]: 2 : name = end ? std::string( opt, end - opt ) : std::string( opt );
[ # # ][ + - ]
[ - + ][ + - ]
[ # # # # ]
397 : 4 : return MB_SUCCESS;
398 : : }
399 : :
400 : : } // namespace moab
401 : :
402 : : #ifdef TEST
403 : :
404 : : using namespace moab;
405 : :
406 : : #include <iostream>
407 : :
408 : : #define CHECK( A ) \
409 : : if( MB_SUCCESS != ( A ) ) \
410 : : { \
411 : : std::cerr << "Failure at line " << __LINE__ << ": error code " << ( A ) << std::endl; \
412 : : return 1; \
413 : : }
414 : :
415 : : #define EQUAL( A, B ) \
416 : : if( A != B ) \
417 : : { \
418 : : std::cerr << "Failure at line " << __LINE__ << ": expected " << ( B ) << " but got " << ( A ) << std::endl; \
419 : : return 2; \
420 : : }
421 : :
422 : : int main()
423 : : {
424 : : FileOptions tool( "INT1=1;NUL1;STR1=ABC;DBL1=1.0;dbl2=2.0;DBL3=3.0;INT2=2;nul2;NUL3;INT3=3;str2=once upon a "
425 : : "time;str3==fubar=;;INTS=1-3,5,6;DBLS=1.0,2.0, 3.0;STRS=var1, var2_var2;STRS2=" );
426 : :
427 : : std::string s;
428 : : int i;
429 : : double d;
430 : : ErrorCode rval;
431 : :
432 : : // test basic get_option method without deleting entry
433 : : rval = tool.get_option( "STR1", s );
434 : : CHECK( rval );
435 : : EQUAL( s, "ABC" );
436 : :
437 : : // test basic get_option method again, this time deleting the entry
438 : : rval = tool.get_option( "STR1", s );
439 : : CHECK( rval );
440 : : EQUAL( s, "ABC" );
441 : :
442 : : // test basig get_option method with a null option
443 : : rval = tool.get_option( "NUL2", s );
444 : : CHECK( rval );
445 : : EQUAL( s.empty(), true );
446 : :
447 : : // test null option
448 : : rval = tool.get_null_option( "nul1" );
449 : : CHECK( rval );
450 : :
451 : : // try null option method on non-null value
452 : : rval = tool.get_null_option( "INT1" );
453 : : EQUAL( rval, MB_TYPE_OUT_OF_RANGE );
454 : :
455 : : // test integer option
456 : : rval = tool.get_int_option( "int1", i );
457 : : CHECK( rval );
458 : : EQUAL( i, 1 );
459 : :
460 : : rval = tool.get_int_option( "int2", i );
461 : : CHECK( rval );
462 : : EQUAL( i, 2 );
463 : :
464 : : // test integer option on non-integer value
465 : : rval = tool.get_int_option( "dbl2", i );
466 : : EQUAL( rval, MB_TYPE_OUT_OF_RANGE );
467 : :
468 : : // test integer option on null value
469 : : rval = tool.get_int_option( "NUL3", i );
470 : : EQUAL( rval, MB_TYPE_OUT_OF_RANGE );
471 : :
472 : : // test double option
473 : : rval = tool.get_real_option( "dbl1", d );
474 : : CHECK( rval );
475 : : EQUAL( d, 1.0 );
476 : :
477 : : rval = tool.get_real_option( "dbl2", d );
478 : : CHECK( rval );
479 : : EQUAL( d, 2.0 );
480 : :
481 : : rval = tool.get_real_option( "int3", d );
482 : : CHECK( rval );
483 : : EQUAL( d, 3.0 );
484 : :
485 : : // test real option on non-real value
486 : : rval = tool.get_real_option( "str2", d );
487 : : EQUAL( rval, MB_TYPE_OUT_OF_RANGE );
488 : :
489 : : // test real option on null value
490 : : rval = tool.get_real_option( "NUL3", d );
491 : : EQUAL( rval, MB_TYPE_OUT_OF_RANGE );
492 : :
493 : : // test get a simple string option
494 : : rval = tool.get_str_option( "DBL3", s );
495 : : CHECK( rval );
496 : : EQUAL( s, "3.0" );
497 : :
498 : : // test get a string with spaces
499 : : rval = tool.get_str_option( "STR2", s );
500 : : CHECK( rval );
501 : : EQUAL( s, "once upon a time" );
502 : :
503 : : // try to get a string value for a null option
504 : : rval = tool.get_str_option( "nul3", s );
505 : : EQUAL( rval, MB_TYPE_OUT_OF_RANGE );
506 : :
507 : : // We haven't looked at all of the options yet
508 : : EQUAL( false, tool.all_seen() );
509 : : rval = tool.get_unseen_option( s );
510 : : CHECK( rval );
511 : : EQUAL( s, "str3" );
512 : :
513 : : // test options using generic get_option method
514 : :
515 : : rval = tool.get_option( "NUL3", s );
516 : : CHECK( rval );
517 : : EQUAL( s.empty(), true );
518 : :
519 : : rval = tool.get_option( "STR3", s );
520 : : CHECK( rval );
521 : : EQUAL( s, "=fubar=" );
522 : :
523 : : // test size of options string
524 : : unsigned l = tool.size();
525 : : EQUAL( l, 16u );
526 : :
527 : : // test ints option
528 : : std::vector< int > ivals;
529 : : rval = tool.get_ints_option( "INTS", ivals );
530 : : CHECK( rval );
531 : : EQUAL( 5, ivals.size() );
532 : : EQUAL( 1, ivals[0] );
533 : : EQUAL( 2, ivals[1] );
534 : : EQUAL( 3, ivals[2] );
535 : : EQUAL( 5, ivals[3] );
536 : : EQUAL( 6, ivals[4] );
537 : :
538 : : // test dbls option
539 : : std::vector< double > vals;
540 : : rval = tool.get_reals_option( "DBLS", vals );
541 : : CHECK( rval );
542 : : EQUAL( 3, vals.size() );
543 : : EQUAL( 1.0, vals[0] );
544 : : EQUAL( 2.0, vals[1] );
545 : : EQUAL( 3.0, vals[2] );
546 : :
547 : : // test strs option
548 : : std::vector< std::string > svals;
549 : : rval = tool.get_strs_option( "STRS", svals );
550 : : CHECK( rval );
551 : : EQUAL( 2, svals.size() );
552 : : EQUAL( "var1", svals[0] );
553 : : EQUAL( "var2_var2", svals[1] );
554 : :
555 : : svals.clear();
556 : : rval = tool.get_strs_option( "STRS2", svals );
557 : : EQUAL( MB_TYPE_OUT_OF_RANGE, rval );
558 : :
559 : : // We requested every option
560 : : EQUAL( true, tool.all_seen() );
561 : : rval = tool.get_unseen_option( s );
562 : : EQUAL( MB_ENTITY_NOT_FOUND, rval );
563 : :
564 : : // test alternate separator
565 : :
566 : : FileOptions tool2( ";+OPT1=ABC+OPT2=" );
567 : : l = tool2.size();
568 : : EQUAL( l, 2 );
569 : :
570 : : // We haven't looked at all of the options yet
571 : : EQUAL( false, tool2.all_seen() );
572 : : rval = tool2.get_unseen_option( s );
573 : : CHECK( rval );
574 : : EQUAL( s, "OPT1" );
575 : :
576 : : rval = tool2.get_option( "opt1", s );
577 : : CHECK( rval );
578 : : EQUAL( s, "ABC" );
579 : :
580 : : rval = tool2.get_option( "opt2", s );
581 : : CHECK( rval );
582 : : bool e = s.empty();
583 : : EQUAL( e, true );
584 : :
585 : : l = tool2.size();
586 : : EQUAL( l, 2 );
587 : :
588 : : // We requested every option
589 : : EQUAL( true, tool2.all_seen() );
590 : : rval = tool2.get_unseen_option( s );
591 : : EQUAL( MB_ENTITY_NOT_FOUND, rval );
592 : :
593 : : // test empty options string
594 : :
595 : : FileOptions tool3( ";;;;" );
596 : : e = tool3.empty();
597 : : EQUAL( e, true );
598 : : l = tool3.size();
599 : : EQUAL( l, 0 );
600 : : EQUAL( true, tool3.all_seen() );
601 : :
602 : : FileOptions tool4( NULL );
603 : : e = tool4.empty();
604 : : EQUAL( e, true );
605 : : l = tool4.size();
606 : : EQUAL( l, 0 );
607 : : EQUAL( true, tool4.all_seen() );
608 : :
609 : : FileOptions tool5( ";+" );
610 : : e = tool5.empty();
611 : : EQUAL( e, true );
612 : : l = tool5.size();
613 : : EQUAL( l, 0 );
614 : : EQUAL( true, tool5.all_seen() );
615 : :
616 : : // test copy constructor
617 : :
618 : : FileOptions tool6( tool2 );
619 : :
620 : : rval = tool6.get_option( "opt1", s );
621 : : CHECK( rval );
622 : : EQUAL( s, "ABC" );
623 : :
624 : : rval = tool6.get_option( "opt2", s );
625 : : CHECK( rval );
626 : : e = s.empty();
627 : : EQUAL( e, true );
628 : :
629 : : l = tool6.size();
630 : : EQUAL( l, 2 );
631 : :
632 : : FileOptions tool7( tool5 );
633 : : e = tool7.empty();
634 : : EQUAL( e, true );
635 : : l = tool7.size();
636 : : EQUAL( l, 0 );
637 : :
638 : : // test assignment operator
639 : :
640 : : FileOptions tool8( tool2 );
641 : : tool8 = tool;
642 : : EQUAL( tool8.size(), tool.size() );
643 : :
644 : : return 0;
645 : : }
646 : :
647 : : #endif
|