bpp-core  2.2.0
KeyvalTools.cpp
Go to the documentation of this file.
1 //
2 // File: KeyvalTools.cpp
3 // Created by: Julien Dutheil
4 // Created on: Mon May 13:16 CET 2009
5 //
6 
7 /*
8 Copyright or © or Copr. Bio++ Development Team, (2009)
9 
10 This software is a computer program whose purpose is to provide classes
11 for numerical calculus.
12 
13 This software is governed by the CeCILL license under French law and
14 abiding by the rules of distribution of free software. You can use,
15 modify and/ or redistribute the software under the terms of the CeCILL
16 license as circulated by CEA, CNRS and INRIA at the following URL
17 "http://www.cecill.info".
18 
19 As a counterpart to the access to the source code and rights to copy,
20 modify and redistribute granted by the license, users are provided only
21 with a limited warranty and the software's author, the holder of the
22 economic rights, and the successive licensors have only limited
23 liability.
24 
25 In this respect, the user's attention is drawn to the risks associated
26 with loading, using, modifying and/or developing or reproducing the
27 software by the user in light of its specific status of free software,
28 that may mean that it is complicated to manipulate, and that also
29 therefore means that it is reserved for developers and experienced
30 professionals having in-depth computer knowledge. Users are therefore
31 encouraged to load and test the software's suitability as regards their
32 requirements in conditions enabling the security of their systems and/or
33 data to be ensured and, more generally, to use and operate it in the
34 same conditions as regards security.
35 
36 The fact that you are presently reading this means that you have had
37 knowledge of the CeCILL license and that you accept its terms.
38 */
39 
40 #include "KeyvalTools.h"
41 #include "NestedStringTokenizer.h"
42 
43 //From the STL:
44 #include <memory>
45 
46 using namespace bpp;
47 using namespace std;
48 
49 void KeyvalTools::singleKeyval(const std::string& desc, std::string& key, std::string& val, const std::string& split) throw (KeyvalException)
50 {
51  string::size_type i = desc.find(split);
52  if (i == string::npos)
53  throw KeyvalException("Bad syntax! keyval should be of the form 'key" + split + "=value', found '" + desc + "'.");
54  key = desc.substr(0, i);
55  val = desc.substr(i+1);
56 }
57 
58 void KeyvalTools::multipleKeyvals(const std::string& desc, std::map<std::string,std::string>& keyvals, const std::string& split, bool nested) throw (KeyvalException)
59 {
60  auto_ptr<StringTokenizer> st;
61  if (nested)
62  st.reset(new NestedStringTokenizer(desc, "(", ")", split));
63  else
64  st.reset(new StringTokenizer(desc, split));
65  string key, val;
66  vector<string> tokens;
67  //Check tokens:
68  string token;
69  while (st->hasMoreToken())
70  {
71  token = st->nextToken();
72  if (token == "=")
73  {
74  //We need to merge the next token with the last one:
75  if (tokens.size() == 0)
76  throw KeyvalException("Invalid syntax, found '=' without argument name.");
77  if (!st->hasMoreToken())
78  throw KeyvalException("Invalid syntax, found '=' without argument value.");
79  string nextToken = st->nextToken();
80  if (nextToken == "=")
81  throw KeyvalException("Invalid syntax, found a double '='.");
82  tokens[tokens.size() - 1] += "=" + nextToken;
83  }
84  else
85  {
86  tokens.push_back(token);
87  }
88  }
89  for (vector<string>::iterator it = tokens.begin(); it != tokens.end(); it++)
90  {
91  singleKeyval(*it, key, val);
94  keyvals[key] = val;
95  }
96 }
97 
98 void KeyvalTools::parseProcedure(const std::string& desc, std::string& name, std::map<std::string, std::string>& args) throw (KeyvalException)
99 {
100  string::size_type begin = desc.find_first_of("(");
101  string::size_type end = desc.find_last_of(")");
102 
103  if (begin == string::npos && end == string::npos)
104  {
105  //Empty procedure:
106  name = desc;
107  return;
108  }
109  if (begin == string::npos && end != string::npos)
110  throw KeyvalException("Bad keyval procedure, missing opening parenthesis.");
111  if (begin == string::npos && end != string::npos)
112  throw KeyvalException("Bad keyval procedure, missing closing parenthesis.");
113 
114  if (!TextTools::isEmpty(desc.substr(end + 1)))
115  throw KeyvalException("Bad keyval procedure, extra characters after closing parenthesis: " + desc.substr(end + 1));
116  //Get the procedure name (without leading spaces):
117  name = TextTools::removeFirstWhiteSpaces(desc.substr(0, begin));
118  multipleKeyvals(desc.substr(begin + 1, end - begin - 1), args);
119 }
120 
A tokenizer for strings.
This class allows to perform a correspondence analysis.
bool hasMoreToken() const
Tell if some tokens are still available.
STL namespace.
const std::string & nextToken()
Get the next available token. If no token is availbale, throw an Exception.
static void singleKeyval(const std::string &desc, std::string &key, std::string &val, const std::string &split="=")
Split a string into a key and a value (General purpose function).
Definition: KeyvalTools.cpp:49
static bool isEmpty(const std::string &s)
Tell if a string is empty.
Definition: TextTools.cpp:52
static std::string removeSurroundingWhiteSpaces(const std::string &s)
Remove all white spaces characters at the beginning and the end of a string.
Definition: TextTools.cpp:153
static std::string removeFirstWhiteSpaces(const std::string &s)
Remove all white spaces characters at the beginning of a string.
Definition: TextTools.cpp:121
Exception thrown by the Keyval parser.
Definition: KeyvalTools.h:56
static void parseProcedure(const std::string &desc, std::string &name, std::map< std::string, std::string > &args)
Parse (not recursively) a procedure string.
Definition: KeyvalTools.cpp:98
An improved tokenizer for strings.
static void multipleKeyvals(const std::string &desc, std::map< std::string, std::string > &keyvals, const std::string &split=",", bool nested=true)
Split a string into several keys and corresponding values (General purpose function).
Definition: KeyvalTools.cpp:58