Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
parse.cpp File Reference
#include "parse.hpp"
#include <iostream>
#include <cctype>
#include <cstdlib>
#include <cstring>
+ Include dependency graph for parse.cpp:

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)
 

Function Documentation

◆ hexdigit()

int hexdigit ( char  c)
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().

◆ is_platform_little_endian()

static bool is_platform_little_endian ( )
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().

◆ parse_opaque_value()

unsigned char * parse_opaque_value ( const char *  vals,
int  size 
)
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().

◆ parse_tag_create()

int parse_tag_create ( char *  name,
TagSpec result,
Interface iface 
)

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().

◆ parse_tag_spec()

int parse_tag_spec ( char *  name,
TagSpec result,
Interface iface 
)

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().

◆ parse_value()

template<typename T >
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 }

◆ parse_value< double >()

template<>
int parse_value< double > ( const char *&  iter,
double &  value 
)

Definition at line 91 of file parse.cpp.

92 { 93  char* endptr; 94  value = strtod( iter, &endptr ); 95  if( endptr == iter ) return 1; 96  iter = endptr; 97  return 0; 98 }

◆ parse_values()

void * parse_values ( const char *  vals,
DataType  type,
int  size 
)
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().

◆ parse_values_typed()

template<typename T >
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 }

◆ tag_syntax()

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().