Go to the source code of this file.
Functions | |
void | tag_syntax (std::ostream &s) |
static bool | is_platform_little_endian () |
static void * | parse_values (const char *vals, DataType type, int size) |
static unsigned char * | parse_opaque_value (const char *vals, int size) |
template<typename T > | |
T * | parse_values_typed (const char *vals, int size) |
template<typename T > | |
int | parse_value (const char *&iter, T &value) |
static int | hexdigit (char c) |
template<> | |
int | parse_value< double > (const char *&iter, double &value) |
int | parse_tag_spec (char *name, TagSpec &result, Interface *iface) |
int | parse_tag_create (char *name, TagSpec &result, Interface *iface) |
|
static |
Definition at line 100 of file parse.cpp.
101 {
102 if( c >= '0' && c <= '9' )
103 return c - '0';
104 else if( c >= 'a' && c <= 'f' )
105 return 10 + c - 'a';
106 else if( c >= 'A' && c <= 'F' )
107 return 10 + c - 'A';
108 else
109 return -1;
110 }
Referenced by parse_opaque_value().
|
inlinestatic |
Definition at line 65 of file parse.cpp.
66 {
67 static const unsigned int one = 1;
68 static const bool little = !*( (char*)&one );
69 return little;
70 }
Referenced by parse_opaque_value().
|
static |
Definition at line 112 of file parse.cpp.
113 {
114 unsigned char* data = (unsigned char*)malloc( size );
115 if( vals[0] && vals[0] == '0' && vals[1] && toupper( vals[1] ) == 'X' )
116 {
117 unsigned char *iter, *end;
118 int step;
119 if( is_platform_little_endian() )
120 {
121 iter = data;
122 end = data + size;
123 step = 1;
124 }
125 else
126 {
127 iter = data + size - 1;
128 end = data - 1;
129 step = -1;
130 }
131
132 const char* vals_end = vals + 1;
133 const char* vals_iter = vals + strlen( vals ) - 1;
134 for( ; iter != end; iter += step )
135 {
136 int less = 0;
137 int most = 0;
138 if( vals_iter != vals_end )
139 {
140 less = hexdigit( *vals_iter );
141 --vals_iter;
142 }
143 if( vals_iter != vals_end )
144 {
145 most = hexdigit( *vals_iter );
146 --vals_iter;
147 }
148 if( less < 0 || most < 0 )
149 {
150 std::cerr << "Error parsing hex value: " << vals << std::endl;
151 free( data );
152 return 0;
153 }
154
155 *iter = 16 * most + less;
156 }
157 }
158 else
159 {
160 memset( data, 0, size );
161 strcpy( (char*)data, vals + 2 );
162 }
163
164 return data;
165 }
References hexdigit(), is_platform_little_endian(), and size.
Referenced by parse_values().
Definition at line 275 of file parse.cpp.
276 {
277 // split at '=' signs
278
279 char* eq1 = strrchr( name, '=' );
280 if( !eq1 )
281 {
282 std::cerr << "Invalid tag specification: " << name << std::endl;
283 return 1;
284 }
285 *eq1 = '\0';
286 ++eq1;
287 char *type_str = eq1, *val = 0;
288
289 char* eq2 = strrchr( name, '=' );
290 if( eq2 )
291 {
292 *eq2 = '\0';
293 ++eq2;
294 val = ( '\0' == eq1[0] ) ? 0 : eq1;
295 type_str = eq2;
296 }
297
298 // parse type data
299 char* size_str = strchr( type_str, ':' );
300 if( !size_str )
301 {
302 std::cerr << "Invalid tag type specification: " << type_str << std::endl;
303 return 1;
304 }
305 *size_str = '\0';
306 ++size_str;
307 DataType type;
308 if( !strcmp( type_str, "int" ) )
309 {
310 type = MB_TYPE_INTEGER;
311 }
312 else if( !strcmp( type_str, "double" ) )
313 {
314 type = MB_TYPE_DOUBLE;
315 }
316 else if( !strcmp( type_str, "bit" ) )
317 {
318 type = MB_TYPE_BIT;
319 }
320 else if( !strcmp( type_str, "handle" ) )
321 {
322 type = MB_TYPE_HANDLE;
323 }
324 else if( !strcmp( type_str, "opaque" ) )
325 {
326 type = MB_TYPE_OPAQUE;
327 }
328 else
329 {
330 std::cerr << "Invalid tag type specification: " << type_str << std::endl;
331 return 1;
332 }
333 char* end_ptr;
334 int count = (int)strtol( size_str, &end_ptr, 0 );
335 if( !*size_str || *end_ptr || count < 1 )
336 {
337 std::cerr << "Invalid tag size specification: " << size_str << std::endl;
338 return 1;
339 }
340
341 // parse default value
342 result.value = 0;
343 if( val )
344 {
345 result.value = parse_values( val, type, count );
346 if( !result.value ) return 1;
347 }
348
349 // check if tag exists
350 if( MB_SUCCESS == iface->tag_get_handle( name, 0, MB_TYPE_OPAQUE, result.handle, MB_TAG_ANY ) )
351 {
352 // make sure it matches
353 DataType etype;
354 int esize;
355 if( MB_SUCCESS != iface->tag_get_data_type( result.handle, etype ) ||
356 MB_SUCCESS != iface->tag_get_length( result.handle, esize ) )
357 {
358 std::cerr << "Error accessing properties of tag: " << name << std::endl;
359 return 3;
360 }
361
362 if( etype != type || esize != count )
363 {
364 std::cerr << "Tag already exists with different type: " << name << std::endl;
365 return 1;
366 }
367
368 std::vector< unsigned char > value( esize );
369 if( result.value )
370 {
371 ErrorCode rval = iface->tag_get_default_value( result.handle, &value[0] );
372 if( rval != MB_ENTITY_NOT_FOUND && rval != MB_SUCCESS )
373 {
374 std::cerr << "Error checking default value of tag: " << name << std::endl;
375 return 3;
376 }
377 else if( rval == MB_ENTITY_NOT_FOUND || memcmp( &value[0], result.value, esize ) )
378 {
379 std::cerr << "Tag already exists and default value doesn't match: " << name << std::endl;
380 return 1;
381 }
382 }
383 }
384 else
385 {
386 ErrorCode rval =
387 iface->tag_get_handle( name, count, type, result.handle, MB_TAG_SPARSE | MB_TAG_CREAT, result.value );
388 if( MB_SUCCESS != rval )
389 {
390 std::cerr << "Failed to create tag: " << name << std::endl;
391 return 3;
392 }
393 }
394
395 return 0;
396 }
References ErrorCode, TagSpec::handle, iface, MB_ENTITY_NOT_FOUND, MB_SUCCESS, MB_TAG_ANY, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TYPE_BIT, MB_TYPE_DOUBLE, MB_TYPE_HANDLE, MB_TYPE_INTEGER, MB_TYPE_OPAQUE, parse_values(), moab::Interface::tag_get_data_type(), moab::Interface::tag_get_default_value(), moab::Interface::tag_get_handle(), moab::Interface::tag_get_length(), and TagSpec::value.
Referenced by main().
Definition at line 218 of file parse.cpp.
219 {
220 // Separate optional tag value from tag name
221 char* val = strrchr( name, '=' );
222 if( val )
223 {
224 // zero-length tag name>
225 if( val == name )
226 {
227 std::cerr << "Cannot create tag w/out name: " << name << std::endl;
228 return 1;
229 }
230 *val = '\0';
231 if( !*++val ) // if name ends with an '=', set val to NULL.
232 val = 0;
233 }
234
235 // Get tag
236 ErrorCode rval = iface->tag_get_handle( name, 0, MB_TYPE_OPAQUE, result.handle, MB_TAG_ANY );
237 if( MB_TAG_NOT_FOUND == rval )
238 {
239 std::cerr << "Tag not found: " << name << std::endl;
240 return 2;
241 }
242 else if( MB_SUCCESS != rval )
243 {
244 std::cerr << "Error retrieving tag handle: " << name << std::endl;
245 return 3;
246 }
247
248 // Parse tag value
249 result.value = 0;
250 if( val )
251 {
252 DataType type;
253 rval = iface->tag_get_data_type( result.handle, type );
254 if( MB_SUCCESS != rval )
255 {
256 std::cerr << "Error retrieving type for tag: " << name << std::endl;
257 return 3;
258 }
259
260 int size;
261 rval = iface->tag_get_length( result.handle, size );
262 if( MB_SUCCESS != rval )
263 {
264 std::cerr << "Error retrieving size for tag: " << name << std::endl;
265 return 3;
266 }
267
268 result.value = parse_values( val, type, size );
269 if( !result.value ) return 1;
270 }
271
272 return 0;
273 }
References ErrorCode, TagSpec::handle, iface, MB_SUCCESS, MB_TAG_ANY, MB_TAG_NOT_FOUND, MB_TYPE_OPAQUE, parse_values(), size, moab::Interface::tag_get_data_type(), moab::Interface::tag_get_handle(), moab::Interface::tag_get_length(), and TagSpec::value.
Referenced by main().
int parse_value | ( | const char *& | iter, |
T & | value | ||
) |
Definition at line 73 of file parse.cpp.
74 {
75 char* endptr;
76 long parsed_val = strtol( iter, &endptr, 0 );
77 if( endptr == iter ) return 1;
78 iter = endptr;
79
80 value = (T)parsed_val;
81 if( (long)value != parsed_val )
82 {
83 std::cerr << "Value too large: " << iter << std::endl;
84 return 2;
85 }
86
87 return 0;
88 }
int parse_value< double > | ( | const char *& | iter, |
double & | value | ||
) |
|
static |
Definition at line 198 of file parse.cpp.
199 {
200 switch( type )
201 {
202 case MB_TYPE_OPAQUE:
203 return parse_opaque_value( vals, size );
204 case MB_TYPE_INTEGER:
205 return parse_values_typed< int >( vals, size );
206 case MB_TYPE_DOUBLE:
207 return parse_values_typed< double >( vals, size );
208 case MB_TYPE_BIT:
209 return parse_values_typed< bittype >( vals, size );
210 case MB_TYPE_HANDLE:
211 return parse_values_typed< EntityHandle >( vals, size );
212 default:
213 std::cerr << "Unknown tag data type: " << (int)type << std::endl;
214 return 0;
215 }
216 }
References MB_TYPE_BIT, MB_TYPE_DOUBLE, MB_TYPE_HANDLE, MB_TYPE_INTEGER, MB_TYPE_OPAQUE, parse_opaque_value(), and size.
Referenced by parse_tag_create(), and parse_tag_spec().
T * parse_values_typed | ( | const char * | vals, |
int | size | ||
) |
Definition at line 168 of file parse.cpp.
169 {
170 if( !count ) return 0;
171
172 T* data = (T*)malloc( count * sizeof( T ) );
173 T* end = data + count;
174 if( parse_value< T >( vals, *data ) )
175 {
176 free( data );
177 return 0;
178 }
179 for( T* ptr = data + 1; ptr != end; ++ptr )
180 {
181 if( *vals != ',' )
182 {
183 std::cerr << "Expected ',' separating tag values: " << vals << std::endl;
184 free( data );
185 return 0;
186 }
187 ++vals;
188 if( parse_value< T >( vals, *ptr ) )
189 {
190 free( data );
191 return 0;
192 }
193 }
194
195 return data;
196 }
void tag_syntax | ( | std::ostream & | s | ) |
Definition at line 10 of file parse.cpp.
11 {
12 s << "Tags are specified as <name>=[value], where the tag value " << std::endl
13 << "is optional." << std::endl
14 << std::endl
15 << "Values of integral types (INTEGER, BIT, and HANDLE) are " << std::endl
16 << "specified using standard C integer notation (a 0x prefix " << std::endl
17 << "for hexidecimal, 0 prefix for octal, and no prefix for " << std::endl
18 << "decimal.) The value of an opaque tag is interpreted as " << std::endl
19 << "either a integral value or a character string. If the tag " << std::endl
20 << "value begins with the prefix 0x it will be interpreted as a " << std::endl
21 << "hexidecimal (base-16) number. If the value does not begin " << std::endl
22 << "with the 0x prefix, it is interpreted as a character string." << std::endl
23 << "Characater strings will be padded with null characters as" << std::endl
24 << "necessary to fill the tag." << std::endl
25 << "Floating-point (real) values must be specified in base-10." << std::endl
26 << "C exponential notation (e.g. 1e-10) is accepted." << std::endl
27 << std::endl
28 << "If the tag is an array of integral or floating-point values " << std::endl
29 << "then the tag value must be specified as a comma-separated " << std::endl
30 << "list, with NO spaces." << std::endl
31 << std::endl
32 << "Tags are created with the syntax name=type:size[=default_value]." << std::endl
33 << "where type is one of {int,double,opaque,handle,bit} and size is " << std::endl
34 << "the number of values of the specified type, or the number of " << std::endl
35 << "bytes if the type is 'opaque', A default value for the tag may " << std::endl
36 << "be specified." << std::endl;
37 }
Referenced by usage().