Salome HOME
Copyright update 2021
[tools/libbatch.git] / src / Core / Test / SimpleParser.cxx
1 // Copyright (C) 2007-2021  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 /*
23  *  SimpleParser.cpp
24  *
25  *  Created on: 23 juil. 2009
26  *  Author: Renaud BARATE - EDF R&D
27  */
28
29 #include <iostream>
30 #include <fstream>
31 #include <sstream>
32 #include <cstdlib>
33
34 #include <Test_config.h>
35
36 #include "SimpleParser.hxx"
37
38 using namespace std;
39
40
41 ParserException::ParserException(string msg) noexcept
42   : exception(),
43     _msg(msg)
44 {
45 }
46
47 ParserException::~ParserException() noexcept
48 {
49 }
50
51 const char * ParserException::what() const noexcept
52 {
53   return _msg.c_str();
54 }
55
56
57 SimpleParser::SimpleParser() noexcept
58 {
59 }
60
61 SimpleParser::~SimpleParser() noexcept
62 {
63 }
64
65 std::string SimpleParser::trim(const std::string & str) const noexcept
66 {
67   size_t beg = str.find_first_not_of(" \t");
68   if (beg == string::npos) beg = 0;
69   size_t end = str.find_last_not_of(" \t");
70   return str.substr(beg, end-beg+1);
71 }
72
73 void SimpleParser::parse(const string & filename)
74 {
75   ifstream fileStream(filename.c_str());
76   if (!fileStream) {
77     throw ParserException(string("Can't open file ") + filename);
78   }
79   string line;
80   int lineNumber = 1;
81   while (getline(fileStream, line)) {
82     string str = line;
83     // Strip comments
84     size_t pos = str.find_first_of('#');
85     if (pos != string::npos) {
86       str = str.substr(0, pos);
87     }
88     // Strip leading and trailing spaces
89     str = trim(str);
90     if (!str.empty()) {
91       // Find '=' symbol and split the line
92       pos = str.find_first_of('=');
93       if (pos == string::npos) {
94         stringstream msg;
95         msg << "Syntax error (missing =) on line " << lineNumber << ": " << line;
96         throw ParserException(msg.str());
97       } else {
98         string key = trim(str.substr(0, pos));
99         string value = trim(str.substr(pos+1));
100         // Eventually remove '"' symbols at the beginning and at the end of the string
101         if (value.size()>1 && value[0] == '"' && value[value.size()-1] == '"') {
102           value = value.substr(1, value.size()-2);
103         }
104         _configmap[key] = value;
105       }
106     }
107     ++lineNumber;
108   }
109   fileStream.close();
110 }
111
112 void SimpleParser::parseTestConfigFile()
113 {
114   char * filename = getenv(TEST_CONFIG_FILE_ENV_VAR);
115   if (filename == NULL) {
116     throw ParserException(string("Environment variable ") + TEST_CONFIG_FILE_ENV_VAR + " is not declared.");
117   } else {
118     parse(filename);
119   }
120 }
121
122 const string & SimpleParser::getValue(const string & key) const
123 {
124   map<string,string>::const_iterator iter = _configmap.find(key);
125   if (iter == _configmap.end()) {
126     throw ParserException(string("No value found for key ") + key + ".");
127   }
128   return iter->second;
129 }
130
131 const string & SimpleParser::getTestValue(const string & bmType, const string & protocolStr,
132                                           const string & key) const
133 {
134   string fullkey = string("TEST_") + bmType + "_" + protocolStr + "_" + key;
135   try {
136     return getValue(fullkey);
137   } catch (const ParserException &) {}
138   fullkey = string("TEST_") + bmType + "_" + key;
139   try {
140     return getValue(fullkey);
141   } catch (const ParserException &) {}
142   fullkey = string("TEST_") + key;
143   return getValue(fullkey);
144 }
145
146 int SimpleParser::getValueAsInt(const string & key) const
147 {
148   const string & valueStr = getValue(key);
149   const char * valueCStr = valueStr.c_str();
150   char * end = NULL;
151   int res = strtol(valueCStr, &end, 0);
152   if (*valueCStr == '\0' || *end != '\0') {
153     throw ParserException(string("Invalid value (not integer) for key ") + key + ".");
154   }
155   return res;
156 }
157
158 int SimpleParser::getTestValueAsInt(const string & bmType, const string & protocolStr,
159                                     const string & key) const
160 {
161   string fullkey = string("TEST_") + bmType + "_" + protocolStr + "_" + key;
162   try {
163     return getValueAsInt(fullkey);
164   } catch (const ParserException &) {}
165   fullkey = string("TEST_") + bmType + "_" + key;
166   try {
167     return getValueAsInt(fullkey);
168   } catch (const ParserException &) {}
169   fullkey = string("TEST_") + key;
170   return getValueAsInt(fullkey);
171 }
172
173 ostream & operator <<(ostream & os, const SimpleParser & parser) noexcept
174 {
175   if (parser._configmap.empty()) {
176     os << "Empty map" << endl;
177   } else {
178     map<string,string>::const_iterator iter;
179     for (iter = parser._configmap.begin() ; iter != parser._configmap.end() ; ++iter) {
180       os << iter->first << " = " << iter->second << endl;
181     }
182   }
183   return os;
184 }