]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Convert from libg++'s String to the standard's string class. Whoop, this was a large...
authorWolfgang Bangerth <bangerth@math.tamu.edu>
Mon, 18 May 1998 08:31:25 +0000 (08:31 +0000)
committerWolfgang Bangerth <bangerth@math.tamu.edu>
Mon, 18 May 1998 08:31:25 +0000 (08:31 +0000)
git-svn-id: https://svn.dealii.org/trunk@299 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/base/include/base/parameter_handler.h
deal.II/base/source/parameter_handler.cc

index 58790dbfcb441f516d57237c3596d4f89d10708d..cc2f52c8b6e950caa47fa4597291879897b164de 100644 (file)
@@ -12,19 +12,9 @@ class MultipleParameterLoop;
 
 #include <map>
 #include <vector>
+#include <string>
 #include <base/exceptions.h>
 
-
-#ifdef DEBUG
-#  define _G_NO_NRV     // don't use GNU's named return values in debug modes
-#  include <String.h>   // because if we did we'd harvest tons of warnings.
-#  undef _G_NO_NRV
-#else
-#  include <String.h>
-#endif
-
-
-
 class istream;
 class ostream;
 
@@ -39,6 +29,103 @@ enum OutputStyle {
 
 
 
+/**
+ * Declare some regexps which
+ * may be used to define patterns.
+ */ 
+struct Patterns {
+  public:
+                                    /**
+                                     * Base class to declare common
+                                     * interface.
+                                     */
+    class PatternBase {
+      public:
+                                        /**
+                                         * Make destructor of this and all
+                                         * derived classes virtual.
+                                         */
+       virtual ~PatternBase () {};
+       
+                                        /**
+                                         * Return true if the given string
+                                         * matches the pattern.
+                                         */
+       virtual bool match (const string &test_string) const = 0;
+       
+                                        /**
+                                         * Return a string describing the
+                                         * pattern.
+                                         */
+       virtual string description () const = 0;
+       
+                                        /**
+                                         * Return a pointer to an exact
+                                         * copy of the object. This is
+                                         * necessary since we want to store
+                                         * objects of this type in
+                                         * containers.
+                                         */
+       virtual PatternBase * clone () const = 0;
+    };
+    
+                                    /**
+                                     * Test for the string being an
+                                     * integer.
+                                     */
+    class Integer : public PatternBase {
+      public:
+       virtual bool match (const string &test_string) const;
+       virtual string description () const;
+       virtual PatternBase * clone () const;
+    };
+    
+                                    /**
+                                     * Test for the string being a double.
+                                     */
+    class Double : public PatternBase {
+      public:
+       virtual bool match (const string &test_string) const;
+       virtual string description () const;
+       virtual PatternBase * clone () const;
+    };
+    
+                                    /**
+                                     * Test for the string being one of
+                                     * a sequence of values given like a
+                                     * regular expression. For example, if
+                                     * the string given to the constructor
+                                     * is "red|blue|black", then the #match#
+                                     * function returns #true# exactly if
+                                     * the string is either "red" or "blue"
+                                     * or "black". Spaces around the pipe
+                                     * signs do not matter and are
+                                     * eliminated.
+                                     */
+    class Sequence : public PatternBase {
+      public:
+       Sequence (const string &seq);
+       virtual bool match (const string &test_string) const;
+       virtual string description () const;
+       virtual PatternBase * clone () const;
+      private:
+       string sequence;
+    };
+    
+                                    /**
+                                     * Always returns true when testing a
+                                     * string.
+                                     */
+    class Anything : public PatternBase {
+      public:
+       virtual bool match (const string &test_string) const;
+       virtual string description () const;
+       virtual PatternBase * clone () const;
+    };
+};
+
+
+
       
 
 /**
@@ -64,17 +151,17 @@ enum OutputStyle {
  *     ParameterHandler prm;
  *     prm.declare_entry ("Time step size",
  *                       "0.2",
- *                       ParameterHandler::RegularExpressions::Double);
+ *                       Patterns::Double());
  *     prm.declare_entry ("Geometry",
  *                       "[0,1]x[0,1]",
- *                       ".*");
+ *                       Patterns::Anything());
  *     ...
  *   \end{verbatim}
  *   Each entry is declared using the function #declare_entry#. The first parameter is
  *   the name of the entry (in short: the entry). The second is the default answer to
  *   be taken in case the entry is not specified in the input file. The third parameter
  *   is a regular expression which the input (and the default answer) has to match.
- *   Several such regular expressions are defined in #ParameterHandler::RegularExpressions#.
+ *   Several such regular expressions are defined in #Patterns#.
  *
  *   Entries may be located in subsections which form a kind of input tree. For example
  *   input parameters for linear solver routines should be classified in a subsection
@@ -88,14 +175,14 @@ enum OutputStyle {
  *
  *     void LinEq::declare_parameters (ParameterHandler &prm) {
  *       prm.enter_subsection("Linear solver");
- *prm.declare_entry ("Solver",
- *                  "CG",
- *               "CG\\|GMRES\\|GaussElim");
- *prm.declare_entry ("Maximum number of iterations",
- *                  "20",
- *               ParameterHandler::RegularExpressions::Integer);
- *...
- *prm.leave_subsection ();
+ *       prm.declare_entry ("Solver",
+ *                          "CG",
+ *                         Patterns::Sequence("CG|GMRES|GaussElim"));
+ *       prm.declare_entry ("Maximum number of iterations",
+ *                          "20",
+ *                         ParameterHandler::RegularExpressions::Integer());
+ *       ...
+ *       prm.leave_subsection ();
  *     };
  *   \end{verbatim}
  *
@@ -106,8 +193,8 @@ enum OutputStyle {
  *     void NonLinEq::declare_parameters (ParameterHandler &prm) {
  *       prm.enter_subsection ("Nonlinear solver");
  *       prm.declare_entry ("Nonlinear method",
- *                  "Newton-Raphson",
- *               ParameterHandler::RegularExpressions::AlphaNum);
+ *                          "Newton-Raphson",
+ *                         ParameterHandler::RegularExpressions::Anything());
  *       eq.declare_parameters (prm);
  *       prm.leave_subsection ();
  *     };
@@ -124,13 +211,13 @@ enum OutputStyle {
  *     void NonLinEq::declare_parameters (ParameterHandler &prm) {
  *       prm.enter_subsection ("Nonlinear solver");
  *       prm.enter_subsection ("Linear solver 1");
- *eq1.declare_parameters (prm);
- *prm.leave_subsection ();
+ *       eq1.declare_parameters (prm);
+ *       prm.leave_subsection ();
  *
- *prm.enter_subsection ("Linear solver 2");
- *eq2.declare_parameters (prm);
- *prm.leave_subsection ();
- *prm.leave_subsection ();
+ *       prm.enter_subsection ("Linear solver 2");
+ *       eq2.declare_parameters (prm);
+ *       prm.leave_subsection ();
+ *       prm.leave_subsection ();
  *     };      
  *   \end{verbatim}
  *
@@ -142,10 +229,10 @@ enum OutputStyle {
  *     ...
  *     subsection Nonlinear solver
  *       set Nonlinear method = Gradient
- *subsection Linear solver
- *  set Solver                        = CG
- *  set Maxmimum number of iterations = 30
- *end
+ *       subsection Linear solver
+ *         set Solver                        = CG
+ *         set Maxmimum number of iterations = 30
+ *       end
  *     end
  *     ...                       # other stuff
  *   \end{verbatim}
@@ -201,7 +288,7 @@ enum OutputStyle {
  *   \begin{verbatim}
  *      void NonLinEq::get_parameters (ParameterHandler &prm) {
  *       prm.enter_subsection ("Nonlinear solver");
- *       String method = prm.get ("Nonlinear method");
+ *       string method = prm.get ("Nonlinear method");
  *       eq.get_parameters (prm);
  *       prm.leave_subsection ();
  *     };
@@ -263,7 +350,7 @@ enum OutputStyle {
  *         static void declare_parameters (ParameterHandler &prm);
  *         void get_parameters (ParameterHandler &prm);
  *       private:
- *         String Method;
+ *         string Method;
  *         int    MaxIterations;
  *     };
  *     
@@ -271,8 +358,8 @@ enum OutputStyle {
  *     class Problem {
  *       private:
  *         LinEq eq1, eq2;
- *         String Matrix1, Matrix2;
- *         String outfile;
+ *         string Matrix1, Matrix2;
+ *         string outfile;
  *       public:
  *         static void declare_parameters (ParameterHandler &prm);
  *         void get_parameters (ParameterHandler &prm);
@@ -286,10 +373,10 @@ enum OutputStyle {
  *       prm.enter_subsection ("Linear solver");
  *       prm.declare_entry ("Solver",
  *                          "CG",
- *                          "\\(CG\\|BiCGStab\\|GMRES\\)");
+ *                          Patterns::Sequence("CG|BiCGStab|GMRES"));
  *       prm.declare_entry ("Maximum number of iterations",
  *                          "20",
- *                          ParameterHandler::RegularExpressions::Integer);
+ *                          Patterns::Integer());
  *       prm.leave_subsection ();
  *     };
  *           
@@ -308,21 +395,20 @@ enum OutputStyle {
  *                                        // first some global parameter entries
  *       prm.declare_entry ("Output file",
  *                          "out",
- *                          ".*");
- *       
+ *                          Patterns::Anything());
  *       prm.declare_entry ("Equation 1",
  *                          "Laplace",
- *                          ".*");
+ *                          Patterns::Anything());
  *       prm.declare_entry ("Equation 2",
  *                          "Elasticity",
- *                          ".*");
+ *                          Patterns::Anything());
  *     
  *                                        // declare parameters for the
  *                                        // first equation
  *       prm.enter_subsection ("Equation 1");
  *       prm.declare_entry ("Matrix type",
  *                          "Sparse",
- *                          "\\(Full\\|Sparse\\|Diagonal\\)");
+ *                          Patterns::Sequence("Full|Sparse|Diagonal"));
  *       LinEq::declare_parameters (prm);  // for eq1
  *       prm.leave_subsection ();
  *           
@@ -331,7 +417,7 @@ enum OutputStyle {
  *       prm.enter_subsection ("Equation 2");
  *       prm.declare_entry ("Matrix type",
  *                          "Sparse",
- *                          "\\(Full\\|Sparse\\|Diagonal\\)");
+ *                          Patterns::Sequence("Full|Sparse|Diagonal"));
  *       LinEq::declare_parameters (prm);  // for eq2
  *       prm.leave_subsection ();
  *     };
@@ -341,7 +427,7 @@ enum OutputStyle {
  *                                        // entries of the problem class
  *       outfile = prm.get ("Output file");
  *     
- *       String equation1 = prm.get ("Equation 1"),
+ *       string equation1 = prm.get ("Equation 1"),
  *              equation2 = prm.get ("Equation 2");
  *       
  *                                        // get parameters for the
@@ -419,7 +505,7 @@ enum OutputStyle {
  *         for the entry named
  *             Solver
  *         does not match the given regular expression
- *             \(CG\|BiCGStab\|GMRES\)
+ *             CG|BiCGStab|GMRES
  *
  *
  *     Listing of Parameters
@@ -488,7 +574,7 @@ class ParameterHandler {
                                      *
                                      * Return whether the read was successful.
                                      */
-    virtual bool read_input (const String &filename);
+    virtual bool read_input (const string &filename);
     
                                     /**
                                      * Read input from a string in memory. The
@@ -520,15 +606,16 @@ class ParameterHandler {
                                      * default value does not match the regular
                                      * expression; #true# otherwise.
                                      */
-    bool declare_entry    (const String &entry,
-                          const String &default_value,
-                          const String &pattern = ".*");
+    bool declare_entry    (const string &entry,
+                          const string &default_value,
+                          const Patterns::PatternBase &pattern
+                          = Patterns::Anything());
     
                                     /**
                                      * Enter a subsection; if not yet
                                      * existent, declare it.
                                      */
-    void enter_subsection (const String &subsection);
+    void enter_subsection (const string &subsection);
     
                                     /**
                                      * Leave present subsection.
@@ -547,19 +634,19 @@ class ParameterHandler {
                                      * was declared (therefore an exception may be
                                      * thrown).
                                      */
-    const String & get (const String &entry_string) const;
+    const string & get (const string &entry_string) const;
     
                                     /**
                                      * Return value of entry #entry_string# as
                                      * long integer.
                                      */
-    long int       get_integer (const String &entry_string) const;
+    long int       get_integer (const string &entry_string) const;
     
                                     /**
                                      * Return value of entry #entry_string# as
                                      * double.
                                      */
-    double         get_double (const String &entry_string) const;
+    double         get_double (const string &entry_string) const;
 
                                     /**
                                      * Print all parameters with the given style
@@ -577,57 +664,21 @@ class ParameterHandler {
                                   const OutputStyle Style,
                                   const unsigned int indent_level);
     
-                                    /**
-                                     * Declare some regexps which
-                                     * may be used to define patterns.
-                                     */ 
-    struct RegularExpressions {
-                                        /**
-                                         * #[ \n\t]+#
-                                         */
-       static const String WhiteSpace;
-       
-                                        /**
-                                         * #\\(-?[0-9]+[ \n\t]*\\)#
-                                         */
-       static const String Integer;
-       
-                                        /**
-                                         * #\\(#
-                                         * #  -?#
-                                         * #  \\(#
-                                         * #       \\([0-9]+\\.[0-9]*\\)#
-                                         * #     \\|#
-                                         * #       \\([0-9]+\\)#
-                                         * #     \\|#
-                                         * #       \\(\\.[0-9]+\\)#
-                                         * #  \\)#
-                                         * #  \\([eE][---+]?[0-9]+\\)?#
-                                         * #  [ \n\t]*#
-                                         * #\\)#
-                                         */
-       static const String Double;
-       
-                                        /**
-                                         * #"\\([0-9A-Za-z]+[ \n\t]*\\)"#
-                                         */
-       static const String AlphaNum;
-    };
                                   
 
                                     /**
                                      * Exception
                                      */
     DeclException1 (ExcEntryAlreadyExists,
-                   String,
+                   string,
                    << "The following entry already exists: " << arg1);
                                     /**
                                      * Exception
                                      */
-    DeclException2 (ExcDefaultDoesNotMatchRegex,
-                   String, String,
+    DeclException2 (ExcDefaultDoesNotMatchPattern,
+                   string, string,
                    << "The default string <" << arg1
-                   << "> does not match the given regex <" << arg2 << ">");  
+                   << "> does not match the given pattern <" << arg2 << ">");  
                                     /**
                                      * Exception
                                      */
@@ -636,19 +687,22 @@ class ParameterHandler {
                                      * Exception
                                      */
     DeclException1 (ExcEntryUndeclared,
-                   String,
+                   string,
                    << "You cant ask for entry <" << arg1 << "> you have not yet declared");  
                                     /**
                                      * Exception
                                      */
     DeclException1 (ExcConversionError,
-                   String,
+                   string,
                    << "Error when trying to convert the following string: " << arg1);
                                     /**
                                      * Exception
                                      */
     DeclException0 (ExcNotImplemented);
-    
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcInternalError);
 
     
   private:
@@ -665,16 +719,18 @@ class ParameterHandler {
                                      */
     struct Section {
        ~Section ();
+
+       typedef map<string, pair<string,Patterns::PatternBase*> > EntryType;
        
-       map<String, pair<String,String>, less<String> >  entries;
-       map<String, Section*, less<String> >             subsections;
+       EntryType             entries;
+       map<string, Section*> subsections;
     };
 
                                     /**
                                      * Path of presently selected subsections;
                                      * empty list means top level
                                      */
-    vector<String> subsection_path;
+    vector<string> subsection_path;
 
                                     /**
                                      * List of default values organized as a
@@ -704,7 +760,7 @@ class ParameterHandler {
                                      * match the regular expression. #true#
                                      * otherwise
                                      */
-    bool scan_line (String line, const unsigned int lineno);
+    bool scan_line (string line, const unsigned int lineno);
 
                                     /**
                                      * Get a pointer to the #Section# structure
@@ -1010,7 +1066,7 @@ class MultipleParameterLoop : public ParameterHandler {
                                      * Read input from a file the name of which
                                      * is given.
                                      */
-    virtual bool read_input (const String &FileName);
+    virtual bool read_input (const string &FileName);
     
                                     /**
                                      * Read input from a string in memory. The
@@ -1050,7 +1106,7 @@ class MultipleParameterLoop : public ParameterHandler {
                                          * into the different variants is done
                                          * later by #split_different_values.
                                          */
-       Entry (const vector<String> &Path, const String &Name, const String &Value);
+       Entry (const vector<string> &Path, const string &Name, const string &Value);
 
                                         /**
                                          * Split the entry value into the different
@@ -1061,24 +1117,24 @@ class MultipleParameterLoop : public ParameterHandler {
                                         /**
                                          * Path to variant entry.
                                          */
-       vector<String> subsection_path;
+       vector<string> subsection_path;
 
                                         /**
                                          * Name of entry.
                                          */
-       String         entry_name;
+       string         entry_name;
 
                                         /**
                                          * Original variant value.
                                          */
-       String         entry_value;
+       string         entry_value;
        
                                         /**
                                          * List of entry values constructed out of
                                          * what was given in the input file (that
                                          * is stored in #EntryValue#.
                                          */
-       vector<String> different_values;
+       vector<string> different_values;
 
                                         /**
                                          * Store whether this entry is a variant
index f796c14c2ab402c588ad43dacbe8915b5b4c228b..53a329c944e93f122333a15c0618d07c7ee334d4 100644 (file)
 #include <basic/parameter_handler.h>
 #include <fstream>
 #include <iomanip>
+#include <strstream>
 #include <cstdlib>
+#include <algorithm>
 
 
+bool Patterns::Integer::match (const string &test_string) const {
+  istrstream str(test_string.c_str());
+  int i;
+  if (str >> i) return true;
+  return false;
+};
+
+
+string Patterns::Integer::description () const {
+  return "[Integer]";
+};
+
+
+Patterns::PatternBase *
+Patterns::Integer::clone () const {
+  return new Patterns::Integer();
+};
+
+
+bool Patterns::Double::match (const string &test_string) const {
+  istrstream str(test_string.c_str());
+  double d;
+  if (str >> d) return true;
+  return false;
+};
+
+
+string Patterns::Double::description () const {
+  return "[Integer]";
+};
+
+
+Patterns::PatternBase *
+Patterns::Double::clone () const {
+  return new Patterns::Double();
+};
+
+
+
+Patterns::Sequence::Sequence (const string &seq) {
+  sequence = seq;
+  while (sequence.find(" |") != string::npos)
+    sequence.replace (sequence.find(" |"), 2, '|');
+  while (sequence.find("| ") != string::npos)
+    sequence.replace (sequence.find("| "), 2, '|');
+};
+
+
+bool Patterns::Sequence::match (const string &test_string) const {
+  vector<string> choices;
+  string tmp(sequence);
+                                  // check the different possibilities
+  while (tmp.find('|') != string::npos) 
+    {
+      if (test_string == string(tmp, 0, tmp.find('|')))
+       return true;
+      
+      tmp.erase (0, tmp.find('|')+1);
+    };
+                                  // check last choice, not finished by |
+  if (test_string == tmp)
+    return true;
+
+                                  // not found
+  return false;
+};
+
+
+string Patterns::Sequence::description () const {
+  return sequence;
+};
+
+
+Patterns::PatternBase *
+Patterns::Sequence::clone () const {
+  return new Patterns::Sequence(sequence);
+};
+
+
+
+bool Patterns::Anything::match (const string &) const {
+  return true;
+};
+
+
+string Patterns::Anything::description () const {
+  return "[Anything]";
+};
+
+
+Patterns::PatternBase *
+Patterns::Anything::clone () const {
+  return new Patterns::Anything();
+};
+
 
 
-const String ParameterHandler::RegularExpressions::WhiteSpace = "[ \n\t]+",
-            ParameterHandler::RegularExpressions::Integer    = "\\(-?[0-9]+[ \n\t]*\\)",
-            ParameterHandler::RegularExpressions::Double     = "\\("
-                                                                   "-?"
-                                                                   "\\("
-                                                                       "\\([0-9]+\\.[0-9]*\\)"
-                                                                       "\\|"
-                                                                       "\\([0-9]+\\)"
-                                                                       "\\|"
-                                                                       "\\(\\.[0-9]+\\)"
-                                                                       "\\)"
-                                                                   "\\([eE][---+]?[0-9]+\\)?"
-                                                                   "[ \n\t]*"
-                                                                   "\\)",
-            ParameterHandler::RegularExpressions::AlphaNum   = "\\([0-9A-Za-z]+[ \n\t]*\\)";
 
 
 
@@ -35,17 +117,12 @@ ParameterHandler::~ParameterHandler () {};
 
 
 bool ParameterHandler::read_input (istream &input) {
-  String line;
+  string line;
   int lineno=0;
   while (input) 
     {
       ++lineno;
-                                      // get one line; limit of 10000
-                                      // chars is arbitrary but should
-                                      // be enough
-      char c[10000];
-      input.getline (&c[0], 10000);
-      line = c;
+      getline (input, line);
       if (!scan_line (line, lineno)) 
        status = false;
     };
@@ -54,8 +131,8 @@ bool ParameterHandler::read_input (istream &input) {
 };
 
 
-bool ParameterHandler::read_input (const String &filename) {
-  ifstream input (filename);
+bool ParameterHandler::read_input (const string &filename) {
+  ifstream input (filename.c_str());
   if (!input) 
     {
       cerr << "ParameterHandler::read_input: could not open file <"
@@ -73,8 +150,8 @@ bool ParameterHandler::read_input_from_string (const char *s) {
                                   // with success
   if ((s == 0) || ((*s) == 0)) return true;
   
-  String line;
-  String input (s);
+  string line;
+  string input (s);
   int    lineno=0;
 
                                   // if necessary append a newline char
@@ -82,14 +159,13 @@ bool ParameterHandler::read_input_from_string (const char *s) {
   if (input[input.length()-1] != '\n')
     input += '\n';
   
-  while (input) 
+  while (input.size() != 0
     {
                                       // get one line from Input (=s)
-      line = input.before ('\n');
+      line.assign (input, 0, input.find('\n'));
                                       // delete this part including
                                       // the backspace
-      input.del (line);
-      input.del (input[0]);
+      input.erase (0, input.find('\n')+1);
       ++lineno;
       
       if (!scan_line (line, lineno)) 
@@ -105,29 +181,30 @@ bool ParameterHandler::read_input_from_string (const char *s) {
 void ParameterHandler::clear () {
   status = true;
 
-  subsection_path.erase       (subsection_path.begin(), subsection_path.end());
-
-  defaults.entries.erase     (defaults.entries.begin(), defaults.entries.end());
-  changed_entries.entries.erase (changed_entries.entries.begin(),
-                                changed_entries.entries.end());
+  subsection_path.clear ();
+  defaults.entries.clear ();
+  changed_entries.entries.clear ();
 
-  map<String, Section*>::iterator p;
+  map<string, Section*>::iterator p;
 
   for (p=defaults.subsections.begin(); p!=defaults.subsections.end(); ++p)
     delete p->second;
   for (p=changed_entries.subsections.begin(); p!=changed_entries.subsections.end(); ++p)
-    delete p->second;
+    if (p->second) 
+      {
+       delete p->second;
+       Assert (false, ExcInternalError());
+      };
 
-  defaults.subsections.erase (defaults.subsections.begin(), defaults.subsections.end());
-  changed_entries.subsections.erase (changed_entries.subsections.begin(),
-                                    changed_entries.subsections.end());
+  defaults.subsections.clear ();
+  changed_entries.subsections.clear ();
 };
 
 
 
-bool ParameterHandler::declare_entry    (const String &entry,
-                                        const String &default_value,
-                                        const String &pattern) {
+bool ParameterHandler::declare_entry (const string &entry,
+                                     const string &default_value,
+                                     const Patterns::PatternBase &pattern) {
   Section* p = get_present_defaults_subsection ();
 
                                   // assertions:
@@ -135,18 +212,18 @@ bool ParameterHandler::declare_entry    (const String &entry,
   Assert (p->entries.find (entry) == p->entries.end(),
          ExcEntryAlreadyExists (entry));
                                   // Default must match Pattern
-  Assert (default_value.matches (Regex(pattern)),
-         ExcDefaultDoesNotMatchRegex(default_value, pattern));
+  Assert (pattern.match (default_value),
+         ExcDefaultDoesNotMatchPattern(default_value, pattern.description()));
   
                                   // does entry already exist?
   if (p->entries.find (entry) != p->entries.end())
     return false;
 
-  p->entries[entry] = make_pair(default_value, pattern);
+  p->entries[entry] = make_pair(default_value, pattern.clone());
 
                                   // check whether default answer matches
                                   // the pattern
-  if (!default_value.matches (Regex(pattern)))
+  if (!pattern.match(default_value))
     return false;
 
   return true;
@@ -155,7 +232,7 @@ bool ParameterHandler::declare_entry    (const String &entry,
   
 
 
-void ParameterHandler::enter_subsection (const String &subsection) {
+void ParameterHandler::enter_subsection (const string &subsection) {
   Section* pd = get_present_defaults_subsection ();
 
                                   // does subsection already exist?
@@ -194,7 +271,7 @@ bool ParameterHandler::leave_subsection () {
 
 
 
-const String & ParameterHandler::get (const String &entry_string) const {
+const string & ParameterHandler::get (const string &entry_string) const {
   const Section* pd = get_present_defaults_subsection ();
   const Section* pc = get_present_changed_subsection ();
 
@@ -205,14 +282,14 @@ const String & ParameterHandler::get (const String &entry_string) const {
   
   if (pd->entries.find (entry_string) == pd->entries.end()) 
     {
-      static const String empty_string;
+      static const string empty_string;
       return empty_string;
     };
 
 
                                   // entry exists; now find out whether
                                   // it was changed:
-  map<String, pair<String,String> >::const_iterator ptr;
+  Section::EntryType::const_iterator ptr;
   ptr = pc->entries.find (entry_string);
   if (ptr != pc->entries.end())
     return ptr->second.first;
@@ -224,12 +301,12 @@ const String & ParameterHandler::get (const String &entry_string) const {
 
 
 
-long int ParameterHandler::get_integer (const String &entry_string) const {
-  String s = get (entry_string);
+long int ParameterHandler::get_integer (const string &entry_string) const {
+  string s = get (entry_string);
   char *endptr;
-  long int i = strtol (s.chars(), &endptr, 10);
+  long int i = strtol (s.c_str(), &endptr, 10);
                                   // assert there was no error
-  Assert ((s.chars()!='\0') || (*endptr == '\0'),
+  Assert ((s.c_str()!='\0') || (*endptr == '\0'),
          ExcConversionError(s));
 
   return i;
@@ -237,12 +314,12 @@ long int ParameterHandler::get_integer (const String &entry_string) const {
 
 
 
-double ParameterHandler::get_double (const String &entry_string) const {
-  String s = get (entry_string);
+double ParameterHandler::get_double (const string &entry_string) const {
+  string s = get (entry_string);
   char *endptr;
-  double d = strtod (s.chars(), &endptr);
+  double d = strtod (s.c_str(), &endptr);
                                   // assert there was no error
-  Assert ((s.chars()!='\0') || (*endptr == '\0'),
+  Assert ((s.c_str()!='\0') || (*endptr == '\0'),
          ExcConversionError(s));
 
   return d;
@@ -302,7 +379,7 @@ void ParameterHandler::print_parameters_section (ostream &out,
   Section *pc = get_present_changed_subsection ();
 
                                   // traverse entry list
-  map<String, pair<String,String> >::const_iterator ptr;
+  Section::EntryType::const_iterator ptr;
 
                                   // first find out the longest entry name
   unsigned int longest_entry = 0;
@@ -361,7 +438,7 @@ void ParameterHandler::print_parameters_section (ostream &out,
   
 
                                   // now transverse subsections tree
-  map<String, Section*>::const_iterator ptrss;
+  map<string, Section*>::const_iterator ptrss;
   for (ptrss = pd->subsections.begin(); ptrss != pd->subsections.end(); ++ptrss)
     {
       switch (style) 
@@ -399,46 +476,35 @@ void ParameterHandler::print_parameters_section (ostream &out,
 };
 
 
-         
   
 
-bool ParameterHandler::scan_line (String line, const unsigned int lineno) {
+bool ParameterHandler::scan_line (string line, const unsigned int lineno) {
                                   // if there is a comment, delete it
-  if (line.contains ('#'))
-    line = line.before ("#");
+  if (line.find('#') != string::npos)
+    line.erase (line.find("#"), string::npos);
                                   // replace every whitespace sequence
                                   // by ' '
-  line.gsub (Regex(RegularExpressions::WhiteSpace), ' ');
-                                  // now every existing whitespace
+  while (line.find('\t') != string::npos)
+    line.replace (line.find('\t'), 1, ' ');
+  while (line.find("  ") != string::npos)
+    line.erase (line.find("  "), 1);
+                                  // now every existing whitespace
                                   // should be exactly one ' ';
                                   // if at end or beginning: delete
-  if ((line.length() != 0) && (line[0] == ' '))  line.del (' ');
+  if ((line.length() != 0) && (line[0] == ' '))  line.erase (line[0]);
                                   // if line is now empty: leave
   if (line.length() == 0) return true;
 
-  if (line[line.length()-1] == ' ')  line.at (' ', -1) = "";
-
-  static Regex re_enter_subsection ("\\(SUBSECTION\\|subsection\\)"
-                                   "[ \n\t]+"
-                                   "\\(.*\\)");
-  static Regex re_entry           ("\\(SET\\|set\\)"   // "set" command
-                                  "[ \n\t]+"
-                                  "\\(.*[^ \t\n]\\)"   // 2: entry name
-                                  "[ \n\t]*"
-                                  "="
-                                  "[ \n\t]*"
-                                  "\\(.*\\)");        // 3: entry value
-  static Regex re_exit_subsection  ("\\(END\\|end\\)");
+  if (line[line.length()-1] == ' ')  line.erase (line[line.size()-1]);
 
                                   // enter subsection
-  if (line.matches (re_enter_subsection)) 
+  if ((line.find ("SUBSECTION") != string::npos) ||
+      (line.find ("subsection") != string::npos))
     {
-                                      // first find out name of subsection
-      int start, len;
-      re_enter_subsection.match (line, line.length());
-      re_enter_subsection.match_info (start, len, 2);
-      
-      String SecName = line.at (start, len);
+                                      // delete this prefix
+      line.erase (0, string("subsection").length()+1);
+
+      string SecName = line;
       Section* pc = get_present_changed_subsection ();
                                       // check whether subsection exists
       if (pc->subsections.find(SecName) == pc->subsections.end()) 
@@ -459,7 +525,8 @@ bool ParameterHandler::scan_line (String line, const unsigned int lineno) {
   
 
                                   // exit subsection
-  if (line.matches (re_exit_subsection)) 
+  if ((line.find ("END") != string::npos) ||
+      (line.find ("end") != string::npos))
     if (subsection_path.size() == 0) 
       {
        cerr << "Line " << lineno << ": There is no subsection to leave here!" << endl;
@@ -470,18 +537,18 @@ bool ParameterHandler::scan_line (String line, const unsigned int lineno) {
 
 
                                   // regular entry
-  if (line.matches (re_entry)) 
+  if ((line.find ("SET") != string::npos) ||
+      (line.find ("set") != string::npos)) 
     {
-      int start, end;
-      re_entry.match (line, line.length());
-
-                                      // extract entry name
-      re_entry.match_info (start, end, 2);
-      String entry_name = line.at (start, end);
+                                      // erase "set" statement and eliminate
+                                      // spaces around the '='
+      line.erase (0, 4);
+      line.replace (line.find(" ="), 2, "=");
+      line.replace (line.find("= "), 2, "=");
 
-                                      // extract entry value
-      re_entry.match_info (start, end, 3);
-      String entry_value = line.at (start, end);
+                                      // extract entry name and value
+      string entry_name  (line, 0, line.find('='));
+      string entry_value (line, line.find('=')+1, string::npos);
 
       Section* pd = get_present_defaults_subsection ();
 
@@ -506,24 +573,28 @@ bool ParameterHandler::scan_line (String line, const unsigned int lineno) {
                                       // exception: if it contains characters
                                       // which specify it as a multiple loop
                                       // entry, then ignore content
-      if (!entry_value.contains ('{'))
-       if (!entry_value.matches (Regex(pd->entries[entry_name].second)))
+      if (entry_value.find ('{') == string::npos)
+       if (!pd->entries[entry_name].second->match(entry_value))
          {
            cerr << "Line " << lineno << ":" << endl
                 << "    The entry value" << endl
                 << "        " << entry_value << endl
                 << "    for the entry named" << endl
                 << "        " << entry_name << endl
-                << "    does not match the given regular expression" << endl
-                << "        " << pd->entries[entry_name].second << endl;
+                << "    does not match the given pattern" << endl
+                << "        " << pd->entries[entry_name].second->description() << endl;
            return false;
          };
       
       Section* pc = get_present_changed_subsection ();
                                       // the following line declares this entry
                                       // if not yet existent and overwrites it
-                                      // otherwise
-      pc->entries[entry_name] = make_pair(entry_value, String(""));
+                                      // otherwise (the pattern is set to a null
+                                      // pointer, since we don't need the
+                                      // pattern in the entries section -- only
+                                      // in the defaults section)
+      pc->entries[entry_name] = make_pair(entry_value,
+                                         static_cast<Patterns::PatternBase*>(0));
 
       return true;
     };
@@ -538,7 +609,7 @@ bool ParameterHandler::scan_line (String line, const unsigned int lineno) {
 
 ParameterHandler::Section* ParameterHandler::get_present_defaults_subsection () {
   Section* sec = &defaults;
-  vector<String>::const_iterator SecName = subsection_path.begin();
+  vector<string>::const_iterator SecName = subsection_path.begin();
     
   while (SecName != subsection_path.end()) 
     {
@@ -554,7 +625,7 @@ ParameterHandler::Section* ParameterHandler::get_present_defaults_subsection ()
 const ParameterHandler::Section* ParameterHandler::get_present_defaults_subsection () const {
   Section* sec = const_cast<Section*>(&defaults); // not nice, but needs to be and
                                   // after all: we do not change #sec#
-  vector<String>::const_iterator SecName = subsection_path.begin();
+  vector<string>::const_iterator SecName = subsection_path.begin();
     
   while (SecName != subsection_path.end()) 
     {
@@ -569,7 +640,7 @@ const ParameterHandler::Section* ParameterHandler::get_present_defaults_subsecti
 
 ParameterHandler::Section* ParameterHandler::get_present_changed_subsection () {
   Section* sec = &changed_entries;
-  vector<String>::iterator SecName = subsection_path.begin();
+  vector<string>::iterator SecName = subsection_path.begin();
     
   while (SecName != subsection_path.end()) 
     {
@@ -584,7 +655,7 @@ ParameterHandler::Section* ParameterHandler::get_present_changed_subsection () {
 
 const ParameterHandler::Section* ParameterHandler::get_present_changed_subsection () const {
   Section* sec = const_cast<Section*>(&changed_entries); // same as in get_present_default_s...
-  vector<String>::const_iterator SecName = subsection_path.begin();
+  vector<string>::const_iterator SecName = subsection_path.begin();
     
   while (SecName != subsection_path.end()) 
     {
@@ -598,15 +669,15 @@ const ParameterHandler::Section* ParameterHandler::get_present_changed_subsectio
 
 
 ParameterHandler::Section::~Section () {
-  entries.erase (entries.begin(), entries.end());
+  entries.clear ();
 
-  map<String, Section*>::iterator p;
+  map<string, Section*>::iterator p;
 
   for (p=subsections.begin(); p!=subsections.end(); ++p)
     delete p->second;
 
 
-  subsections.erase (subsections.begin(), subsections.end());
+  subsections.clear ();
 };
 
 
@@ -627,14 +698,14 @@ bool MultipleParameterLoop::read_input (istream &input) {
 };
 
 
-bool MultipleParameterLoop::read_input (const String &filename) {
+bool MultipleParameterLoop::read_input (const string &filename) {
                                   // I don't know why it is necessary to
                                   // declare this function: simply not
                                   // overloading it in MultipleParameterLoop
                                   // should suffice, but then the compiler can't
                                   // find the inherited version and complains that
                                   // it can't find a function MultipleParameterLoop::
-                                  // read_input (String, ostream) instead of trying the
+                                  // read_input (string, ostream) instead of trying the
                                   // base class (maybe wait for gcc2.8)
   return ParameterHandler::read_input (filename);
                                   // don't call init_branches, since this read_input
@@ -666,8 +737,7 @@ void MultipleParameterLoop::loop (MultipleParameterLoop::UserClass &uc) {
 
 
 void MultipleParameterLoop::init_branches () {
-  if (multiple_choices.size() != 0)
-    multiple_choices.erase (multiple_choices.begin(), multiple_choices.end());
+  multiple_choices.clear ();
   
   ParameterHandler::Section *sec;
                                   // first check the defaults entries whether it
@@ -726,16 +796,16 @@ void MultipleParameterLoop::init_branches () {
 void MultipleParameterLoop::init_branches_section (const ParameterHandler::Section &sec) {
                                   // check all entries in the present subsection
                                   // whether it is a multiple entry
-  map<String, pair<String,String> >::const_iterator e;
+  Section::EntryType::const_iterator e;
   for (e = sec.entries.begin(); e != sec.entries.end(); ++e) 
-    if (e->second.first.contains('{')
+    if (e->second.first.find('{') != string::npos
       multiple_choices.push_back (Entry(subsection_path,
                                        e->first,
                                        e->second.first));
                
 
                                   // transverse subsections
-  map<String, Section*>::const_iterator s;
+  map<string, Section*>::const_iterator s;
   for (s = sec.subsections.begin(); s != sec.subsections.end(); ++s) 
     {
       enter_subsection (s->first);
@@ -760,7 +830,7 @@ void MultipleParameterLoop::fill_entry_values (const unsigned int run_no) {
                                       // set entry
       Section* pd = get_present_defaults_subsection ();
       int selection = (run_no/possibilities) % choice->different_values.size();
-      String entry_value;
+      string entry_value;
       if (choice->type == variant)
        entry_value = choice->different_values[selection];
       else 
@@ -777,15 +847,15 @@ void MultipleParameterLoop::fill_entry_values (const unsigned int run_no) {
        };
       
                                       // check conformance with regex
-      if (!entry_value.matches (Regex(pd->entries[choice->entry_name].second)))
+      if (!pd->entries[choice->entry_name].second->match(entry_value))
        {
          cerr << "In run no.  " << run_no+1 << ":" << endl
               << "    The entry value" << endl
               << "        " << entry_value << endl
               << "    for the entry named" << endl
               << "        " << choice->entry_name << endl
-              << "    does not match the given regular expression" << endl
-              << "        " << pd->entries[choice->entry_name].second << endl
+              << "    does not match the given pattern" << endl
+              << "        " << pd->entries[choice->entry_name].second->description() << endl
               << "    Taking default value" << endl
               << "        " << pd->entries[choice->entry_name].first << endl;
          
@@ -794,7 +864,14 @@ void MultipleParameterLoop::fill_entry_values (const unsigned int run_no) {
        };
 
       Section* pc = get_present_changed_subsection ();
-      pc->entries[choice->entry_name] = make_pair(entry_value, String(""));
+                                      // the following line declares this entry
+                                      // if not yet existent and overwrites it
+                                      // otherwise (the pattern is set to a null
+                                      // pointer, since we don't need the
+                                      // pattern in the entries section -- only
+                                      // in the defaults section)
+      pc->entries[choice->entry_name] = make_pair(entry_value,
+                                                 static_cast<Patterns::PatternBase*>(0));
             
                                       // get out of subsection again
       subsection_path.swap (choice->subsection_path);
@@ -808,50 +885,53 @@ void MultipleParameterLoop::fill_entry_values (const unsigned int run_no) {
 
   
 
-MultipleParameterLoop::Entry::Entry (const vector<String> &ssp,
-                                    const String& Name,
-                                    const String& Value) :
+MultipleParameterLoop::Entry::Entry (const vector<string> &ssp,
+                                    const string& Name,
+                                    const string& Value) :
     subsection_path (ssp), entry_name(Name), entry_value(Value) {};
 
 
 
 void MultipleParameterLoop::Entry::split_different_values () {
-  Regex re_entry ("\\([^{]*\\){{? *\\([^}]*[^ }]\\) *}}?\\(.*\\)");
-  int start, len;
-
                                   // split string into three parts:
                                   // part before the opening "{",
                                   // the selection itself, final
                                   // part after "}"
-  String prefix, multiple, postfix;
-  re_entry.match (entry_value, entry_value.length());
-
-  re_entry.match_info (start, len, 1);
-  prefix   = entry_value.at (start, len);
-
-  re_entry.match_info (start, len, 2);
-  multiple = entry_value.at (start, len);
-
-  re_entry.match_info (start, len, 3);
-  postfix  = entry_value.at (start, len);
-
-
-                                  // delete spaces around '|'
-  multiple.gsub (" |", '|');
-  multiple.gsub ("| ", '|');
+  string prefix  (entry_value, 0, entry_value.find('{'));
+  string multiple(entry_value, entry_value.find('{')+1,
+                 entry_value.rfind('}')-entry_value.find('{')-1);
+  string postfix (entry_value, entry_value.rfind('}')+1, string::npos);
+                                  // if array entry {{..}}: delete inner
+                                  // pair of braces
+  if (multiple[0]=='{')
+    multiple.erase (0,1);
+  if (multiple[multiple.size()-1] == '}')
+    multiple.erase (multiple.size()-1, 1);
+                                  // erase leading and trailing spaces
+                                  // in multiple
+  while (multiple[0] == ' ') multiple.erase (0,1);
+  while (multiple[multiple.size()-1] == ' ') multiple.erase (multiple.size()-1,1);
   
-  while (multiple.contains ('|')) 
+                                  // delete spaces around '|'
+  while (multiple.find(" |") != string::npos)
+    multiple.replace (multiple.find(" |"), 2, '|');
+  while (multiple.find("| ") != string::npos)
+    multiple.replace (multiple.find("| "), 2, '|');
+
+  while (multiple.find('|') != string::npos) 
     {
-      different_values.push_back (prefix+multiple.before('|')+postfix);
-      multiple.through ('|') = "";
+      different_values.push_back (prefix +
+                                 string(multiple, 0, multiple.find('|'))+
+                                 postfix);
+      multiple.erase (0, multiple.find('|')+1);
     };
                                   // make up the last selection ("while" broke
                                   // because there was no '|' any more
   different_values.push_back (prefix+multiple+postfix);
-
                                 // finally check whether this was a variant
                                 // entry ({...}) or an array ({{...}})
-  if (entry_value.contains(Regex(".*{{.*}}.*")))
+  if ((entry_value.find("{{") != string::npos) &&
+      (entry_value.find("}}") != string::npos))
     type = array;
   else
     type = variant;

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.