[MOAB-dev] r1250 - MOAB/trunk

kraftche at mcs.anl.gov kraftche at mcs.anl.gov
Thu Aug 23 15:29:07 CDT 2007


Author: kraftche
Date: 2007-08-23 15:29:06 -0500 (Thu, 23 Aug 2007)
New Revision: 1250

Added:
   MOAB/trunk/FileOptions.cpp
   MOAB/trunk/FileOptions.hpp
Modified:
   MOAB/trunk/Makefile.am
Log:
add utility for parsing options passed to FILE IO APIs

Added: MOAB/trunk/FileOptions.cpp
===================================================================
--- MOAB/trunk/FileOptions.cpp	                        (rev 0)
+++ MOAB/trunk/FileOptions.cpp	2007-08-23 20:29:06 UTC (rev 1250)
@@ -0,0 +1,356 @@
+/*
+ * MOAB, a Mesh-Oriented datABase, is a software component for creating,
+ * storing and accessing finite element mesh data.
+ * 
+ * Copyright 2004 Sandia Corporation.  Under the terms of Contract
+ * DE-AC04-94AL85000 with Sandia Coroporation, the U.S. Government
+ * retains certain rights in this software.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ */
+
+/**\file FileOptions.cpp
+ *\author Jason Kraftcheck (kraftche at cae.wisc.edu)
+ *\date 2007-08-21
+ */
+
+#include "FileOptions.hpp"
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+const char DEFAULT_SEPARATOR = ';';
+
+static inline bool strempty( const char* s ) { return !*s; }
+
+FileOptions::FileOptions( const char* str )
+  : mData(0)
+{
+    // if option string is null, just return
+  if (!str)
+    return;
+  
+    // check if alternate separator is specified
+  char separator[2] = { DEFAULT_SEPARATOR, '\0' };
+  if (*str == DEFAULT_SEPARATOR) {
+    ++str;
+    if (strempty(str))
+      return;
+    separator[0] = *str;
+    ++str;
+  }
+  
+    // don't bother allocating copy of input string if
+    // input string is empty.
+  if (!strempty(str))
+  {
+  
+      // tokenize at separator character
+    mData = strdup( str );
+    for (char* i = strtok( mData, separator ); i; i = strtok( 0, separator )) 
+      if (!strempty(i)) // skip empty strings
+        mOptions.push_back( i );
+  }
+  
+  lastOpt = mOptions.end();  
+}
+
+FileOptions::~FileOptions()
+{
+  free( mData );
+}
+
+MBErrorCode FileOptions::get_null_option( const char* name, bool remove )
+{
+  const char* s;
+  MBErrorCode rval = get_option( name, s );
+  if (MB_SUCCESS != rval)
+    return rval;
+  return strempty(s) ? remove_last_option(remove) : MB_TYPE_OUT_OF_RANGE;
+}
+
+MBErrorCode FileOptions::get_int_option( const char* name, int& value, bool remove ) 
+{
+  const char* s;
+  MBErrorCode rval = get_option( name, s );
+  if (MB_SUCCESS != rval)
+    return rval;
+  
+    // empty string
+  if (strempty(s))
+    return MB_TYPE_OUT_OF_RANGE;
+  
+    // parse value
+  char* endptr;
+  long int pval = strtol( s, &endptr, 0 );
+  if (!strempty(endptr)) // syntax error
+    return MB_TYPE_OUT_OF_RANGE;
+  
+    // check for overflow (parsing long int, returning int)
+  value = pval;
+  if (pval != (long int)value)
+    return MB_TYPE_OUT_OF_RANGE;
+  
+  return remove_last_option(remove);
+}
+
+MBErrorCode FileOptions::get_real_option ( const char* name, double& value, bool remove ) 
+{
+  const char* s;
+  MBErrorCode rval = get_option( name, s );
+  if (MB_SUCCESS != rval)
+    return rval;
+  
+    // empty string
+  if (strempty(s))
+    return MB_TYPE_OUT_OF_RANGE;
+  
+    // parse value
+  char* endptr;
+  value = strtod( s, &endptr );
+  if (!strempty(endptr)) // syntax error
+    return MB_TYPE_OUT_OF_RANGE;
+  
+  return remove_last_option(remove);
+}
+
+MBErrorCode FileOptions::get_str_option( const char* name, std::string& value, bool remove )
+{
+  const char* s;
+  MBErrorCode rval = get_option( name, s );
+  if (MB_SUCCESS != rval)
+    return rval;
+  if (strempty(s))
+    return MB_TYPE_OUT_OF_RANGE;
+  value = s;
+  return remove_last_option(remove);
+}
+
+MBErrorCode FileOptions::get_option( const char* name, std::string& value, bool remove )
+{
+  const char* s;
+  MBErrorCode rval = get_option( name, s );
+  if (MB_SUCCESS != rval)
+    return rval;
+  
+  value = s;
+  return remove_last_option(remove);
+}  
+
+MBErrorCode FileOptions::get_option( const char* name, const char*& value )
+{
+  std::vector<const char*>::iterator i;
+  for (i = mOptions.begin(); i != mOptions.end(); ++i) {
+    const char* opt = *i;
+    if (compare( name, opt )) {
+      value = opt + strlen(name);
+        // if compare returned true, next char after option
+        // name must be either the null char or an equals symbol.
+      if (*value == '=') 
+        ++value;
+        
+      lastOpt = i;
+      return MB_SUCCESS;
+    }
+  }
+  
+  lastOpt = mOptions.end();
+  return MB_ENTITY_NOT_FOUND;
+}
+
+bool FileOptions::compare( const char* name, const char* option )
+{
+  while (!strempty(name) && toupper(*name) == toupper(*option)) {
+    ++name;
+    ++option;
+  }
+   // match if name matched option for length of name,
+   // and option either matched entirely or matches up to
+   // and equals sign.
+  return strempty(name) && (strempty(option) || *option == '=');
+}
+
+
+MBErrorCode FileOptions::remove_last_option( bool doit )
+{
+  if (lastOpt == mOptions.end())
+    return MB_FAILURE;
+  if (doit)
+    mOptions.erase( lastOpt );
+  lastOpt = mOptions.end();
+  return MB_SUCCESS;
+}
+
+void FileOptions::get_options( std::vector<std::string>& list ) const
+{
+  list.clear();
+  list.resize( mOptions.size() );
+  std::copy( mOptions.begin(), mOptions.end(), list.begin() );
+}
+
+#ifdef TEST
+
+#include <iostream>
+
+#define CHECK(A) \
+  if (MB_SUCCESS != (A)) { \
+    std::cerr << "Failure at line " << __LINE__ << ": error code " << (A) << std::endl; \
+    return 1; \
+  }
+
+#define EQUAL(A,B) \
+  if (A != B) { \
+    std::cerr << "Failure at line " << __LINE__ << ": expected " << (B) << " but got " << (A) << std::endl; \
+    return 2; \
+  }
+
+int main()
+{
+  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 time;str3==fubar=;;" );
+
+  std::string s;
+  int i;
+  double d;
+  MBErrorCode rval;
+  
+    // test basic get_option method without deleting entry
+  rval = tool.get_option( "STR1", s, false );
+  CHECK(rval);
+  EQUAL( s, "ABC" );
+  
+    // test basic get_option method again, this time deleting the entry
+  rval = tool.get_option( "STR1", s );
+  CHECK(rval);
+  EQUAL( s, "ABC" );
+  
+    // test that the entry was removed
+  rval = tool.get_option( "STR1", s );
+  EQUAL( rval, MB_ENTITY_NOT_FOUND );
+  
+    // test basig get_option method with a null option
+  rval = tool.get_option( "NUL2", s );
+  CHECK( rval );
+  EQUAL( s.empty(), true );
+
+  
+    // test null option
+  rval = tool.get_null_option( "nul1" );
+  CHECK( rval );
+  
+    // try null option method on non-null value
+  rval = tool.get_null_option( "INT1", false) ;
+  EQUAL( rval, MB_TYPE_OUT_OF_RANGE) ;
+  
+
+    // test integer option
+  rval = tool.get_int_option( "int1", i );
+  CHECK( rval );
+  EQUAL( i, 1 );
+  
+  rval = tool.get_int_option( "int2", i );
+  CHECK( rval );
+  EQUAL( i, 2 );
+  
+    // test integer option on non-integer value
+  rval = tool.get_int_option( "dbl2", i, false );
+  EQUAL( rval, MB_TYPE_OUT_OF_RANGE );
+  
+    // test integer option on null value
+  rval = tool.get_int_option( "NUL3", i, false );
+  EQUAL( rval, MB_TYPE_OUT_OF_RANGE );
+  
+    // test double option
+  rval = tool.get_real_option( "dbl1", d );
+  CHECK( rval );
+  EQUAL( d, 1.0 );
+  
+  rval = tool.get_real_option( "dbl2", d );
+  CHECK( rval );
+  EQUAL( d, 2.0 );
+  
+  rval = tool.get_real_option( "int3", d );
+  CHECK( rval );
+  EQUAL( d, 3.0 );
+  
+    // test real option on non-real value
+  rval = tool.get_real_option( "str2", d, false );
+  EQUAL( rval, MB_TYPE_OUT_OF_RANGE );
+  
+  
+    // test real option on null value
+  rval = tool.get_real_option( "NUL3", d, false );
+  EQUAL( rval, MB_TYPE_OUT_OF_RANGE );
+  
+    // test get a simple string option
+  rval = tool.get_str_option( "DBL3", s );
+  CHECK( rval );
+  EQUAL( s, "3.0" );
+  
+    // test get a string with spaces
+  rval = tool.get_str_option("STR2", s );
+  CHECK( rval );
+  EQUAL( s, "once upon a time" );
+  
+    // try to get a string value for a null option
+  rval = tool.get_str_option( "nul3", s, false );
+  EQUAL( rval, MB_TYPE_OUT_OF_RANGE );
+  
+  
+    // should be two options still in list: NUL3 and STR3
+  bool e = tool.empty();
+  EQUAL( e, false );
+  unsigned l = tool.size();
+  EQUAL( l, 2u );
+  std::vector<std::string> list;
+  tool.get_options( list );
+  EQUAL( list[0], "NUL3" );
+  EQUAL( list[1], "str3==fubar=" );
+  
+    // remove remaining options
+  rval = tool.get_option( "NUL3", s );
+  CHECK( rval );
+  EQUAL( s.empty(), true );
+  
+  rval = tool.get_option( "STR3", s );
+  CHECK( rval );
+  EQUAL( s, "=fubar=" );
+  
+    // should be no remaining options
+  e = tool.empty();
+  EQUAL( e, true );
+  l = tool.size();
+  EQUAL( l, 0 );
+  list.clear();
+  tool.get_options( list );
+  e = list.empty();
+  EQUAL( e, true );
+  
+  
+    // test alternate separator
+  
+  FileOptions tool2( ";+OPT1=ABC+OPT2=" );
+  l = tool2.size();
+  EQUAL( l, 2 );
+  
+  rval = tool2.get_option( "opt1", s );
+  CHECK( rval );
+  EQUAL( s, "ABC" );
+  
+  rval = tool2.get_option( "opt2", s );
+  CHECK( rval );
+  e = s.empty();
+  EQUAL( e, true );
+  
+  e = tool2.empty();
+  EQUAL( e, true );
+  
+    
+  return 0;
+}
+
+#endif

Added: MOAB/trunk/FileOptions.hpp
===================================================================
--- MOAB/trunk/FileOptions.hpp	                        (rev 0)
+++ MOAB/trunk/FileOptions.hpp	2007-08-23 20:29:06 UTC (rev 1250)
@@ -0,0 +1,158 @@
+/*
+ * MOAB, a Mesh-Oriented datABase, is a software component for creating,
+ * storing and accessing finite element mesh data.
+ * 
+ * Copyright 2004 Sandia Corporation.  Under the terms of Contract
+ * DE-AC04-94AL85000 with Sandia Coroporation, the U.S. Government
+ * retains certain rights in this software.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ */
+
+/**\file FileOptions.hpp
+ *\author Jason Kraftcheck (kraftche at cae.wisc.edu)
+ *\date 2007-08-21
+ */
+
+#ifndef FILE_OPTIONS_HPP
+#define FILE_OPTIONS_HPP
+
+#include <string>
+#include <vector>
+#include "MBTypes.h"
+
+/**\brief Parse options string passed to file IO routines
+ *
+ * This is a utility class used by file-IO-related code to 
+ * parse the options string passed to MBCore::load_file and
+ * MBCore::write_file
+ */
+class FileOptions {
+public:
+
+  /*\param options_string The concatenation of a list of 
+   *          options, separated either by the default separator
+   *          (semicolon) with a custom separator specified at
+   *          the beginning of the string (semicolon followed by
+   *          destired separator character.)
+   */
+  FileOptions( const char* option_string );
+  
+  ~FileOptions();
+  
+  /**\brief Check for option with no value 
+   *
+   * Check for and remove an option w/out a value.
+   *\param name The option name
+   *\param remove If true (default), remove the option from the list.
+   *\return - MB_SUCCESS if option is found
+   *        - MB_TYPE_OUT_OF_RANGE if options is found, but has value
+   *        - MB_ENTITY_NOT_FOUND if option is not found.
+   */
+  MBErrorCode get_null_option( const char* name, bool remove = true );
+  
+  /**\brief Check for option with an integer value.
+   *
+   * Check for and remove an option with an integer value
+   *\param name The option name
+   *\param value Output. The value.
+   *\param remove If true (default), remove the option from the list.
+   *\return - MB_SUCCESS if option is found
+   *        - MB_TYPE_OUT_OF_RANGE if options is found, but does not have an integer value
+   *        - MB_ENTITY_NOT_FOUND if option is not found.
+   */
+  MBErrorCode get_int_option( const char* name, int& value, bool remove = true );
+  
+  /**\brief Check for option with a double value.
+   *
+   * Check for and remove an option with a double value
+   *\param name The option name
+   *\param value Output. The value.
+   *\param remove If true (default), remove the option from the list.
+   *\return - MB_SUCCESS if option is found
+   *        - MB_TYPE_OUT_OF_RANGE if options is found, but does not have a double value
+   *        - MB_ENTITY_NOT_FOUND if option is not found.
+   */
+  MBErrorCode get_real_option( const char* name, double& value, bool remove = true );
+  
+  /**\brief Check for option with any value.
+   *
+   * Check for and remove an option with any value.
+   *\param name The option name
+   *\param value Output. The value.
+   *\param remove If true (default), remove the option from the list.
+   *\return - MB_SUCCESS if option is found
+   *        - MB_TYPE_OUT_OF_RANGE if options is found, but does not have a value
+   *        - MB_ENTITY_NOT_FOUND if option is not found.
+   */
+  MBErrorCode get_str_option( const char* name, std::string& value, bool remove = true );
+  
+  /**\brief Check for option 
+   *
+   * Check for and remove and option
+   *\param name The option name
+   *\param value The option value, or an empty string if no value.
+   *\param remove If true (default), remove the option from teh list.
+   *\return MB_SUCCESS or MB_ENTITY_NOT_FOUND
+   */
+  MBErrorCode get_option( const char* name, std::string& value, bool remove = true );
+   
+  /**\brief Check for option for which the value is an ID list
+   *
+   * Check for and remove an ID list option.  The value is expected to
+   * be a comma-separated list of ID ranges, where an ID range can be 
+   * either a single integer value or a range of integer values separated
+   * by a dash ('-').
+   *
+   *\param name The option name
+   *\param value Output. The value.
+   *\param remove If true (default), remove the option from the list.
+   *\return - MB_SUCCESS if option is found
+   *        - MB_TYPE_OUT_OF_RANGE if options is found, but does not contain an ID list
+   *        - MB_ENTITY_NOT_FOUND if option is not found.
+   */
+  //MBErrorCode get_id_list_option( const char* name, std::vector<unsigned>& value, bool remove = true );
+  
+  /** number of remaining options */
+  inline unsigned size() const 
+    { return mOptions.size(); }
+  
+  /** true if no remaining options */
+  inline bool empty() const 
+    { return mOptions.empty(); }
+  
+  /** Get list of remaining options by name */
+  void get_options( std::vector<std::string>& list ) const;
+  
+private:
+
+    /* Don't allow copying */
+  FileOptions( const FileOptions& other );
+  void operator=( const FileOptions& other );
+  
+  /**\brief Check for option 
+   *
+   * Check for and remove and option
+   *\param name The option name
+   *\param value The option value, or an empty string if no value.
+   *\param remove If true (default), remove the option from teh list.
+   *\return MB_SUCCESS or MB_ENTITY_NOT_FOUND
+   */
+  MBErrorCode get_option( const char* name, const char*& value);
+
+  MBErrorCode remove_last_option(bool remove_arg);  
+
+  char* mData;
+  std::vector<const char*> mOptions;
+  std::vector<const char*>::iterator lastOpt;
+
+    /** Case-insensitive compare of name with option value. */
+  static bool compare( const char* name, const char* option );
+};
+
+#endif
+

Modified: MOAB/trunk/Makefile.am
===================================================================
--- MOAB/trunk/Makefile.am	2007-08-23 15:33:18 UTC (rev 1249)
+++ MOAB/trunk/Makefile.am	2007-08-23 20:29:06 UTC (rev 1250)
@@ -22,7 +22,8 @@
         xform_test \
         obb_test \
 	vtk_test \
-	adaptive_kd_tree_tests
+	adaptive_kd_tree_tests \
+	file_options_test 
 #                 merge_test \         # input files no longer exist?
 #                 test_tag_server \    # fails
 
@@ -95,6 +96,8 @@
   EntitySequenceManager.hpp \
   ExoIIUtil.cpp \
   ExoIIUtil.hpp \
+  FileOptions.cpp \
+  FileOptions.hpp \
   FileTokenizer.cpp \
   FileTokenizer.hpp \
   GeomTopoTool.cpp \
@@ -293,6 +296,9 @@
 kd_tree_time_LDADD = $(top_builddir)/libMOAB.la
 kd_tree_time_DEPENDENCIES = $(kd_tree_time_LDADD)
 
+file_options_test_SOURCES = FileOptions.cpp 
+file_options_test_CPPFLAGS = -DTEST
+
 # Other files to clean up (e.g. output from tests)
 MOSTLYCLEANFILES = dumped_acis.sat
 




More information about the moab-dev mailing list