1 // Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 * CommandsOverloader.cxx :
25 * Author : Margarita KARPUNINA - OCC
35 #include <libbatch_config.h>
37 #include "CommandsOverloader.hxx"
39 #include "RunTimeException.hxx"
46 static set<string> supportedCmds({"RM", "SH", "CP", "MKDIR", "RSH", "RCP", "SSH", "SCP", "RSYNC"});
51 CommandsOverloader::CommandsOverloader()
54 isCmdFileDefined(isFileDefined);
55 if (!isFileDefined && isCheckCmdsDefined()) {
56 cout << "================================================================" << endl;
57 cout << "Commands found on the system at compile time are used." << endl;
58 cout << "================================================================" << endl;
65 CommandsOverloader::~CommandsOverloader()
70 * Return the CommandsOverloader singleton.
72 CommandsOverloader& CommandsOverloader::getInstance () {
73 static CommandsOverloader instance;
78 * Return an overridden definition of RM command.
80 string CommandsOverloader::RM_Command() {
81 string cmd = CMD_Command("RM");
86 throw RunTimeException("Can't use SH protocol (RM command was "
87 "not found neither in the file pointed by "
88 "LIBBATCH_OVERRIDE_CMDS environment variable "
89 "nor on the system at compile time).");
97 * Return an overridden definition of SH command.
99 string CommandsOverloader::SH_Command() {
100 string cmd = CMD_Command("SH");
105 throw RunTimeException("Can't use SH protocol (SH command was "
106 "not found neither in the file pointed by "
107 "LIBBATCH_OVERRIDE_CMDS environment variable "
108 "nor on the system at compile time).");
116 * Return an overridden definition of CP command.
118 string CommandsOverloader::CP_Command() {
119 string cmd = CMD_Command("CP");
124 throw RunTimeException("Can't use SH protocol (CP command was "
125 "not found neither in the file pointed by "
126 "LIBBATCH_OVERRIDE_CMDS environment variable "
127 "nor on the system at compile time).");
135 * Return an overridden definition of MKDIR command.
137 string CommandsOverloader::MKDIR_Command() {
138 string cmd = CMD_Command("MKDIR");
141 return MKDIR_COMMAND;
143 throw RunTimeException("Can't use SH protocol (MKDIR command was "
144 "not found neither in the file pointed by "
145 "LIBBATCH_OVERRIDE_CMDS environment variable "
146 "nor on the system at compile time).");
154 * Return an overridden definition of RSH command.
156 string CommandsOverloader::RSH_Command() {
157 string cmd = CMD_Command("RSH");
162 throw RunTimeException("Can't use RSH protocol (RSH command was "
163 "not found neither in the file pointed by "
164 "LIBBATCH_OVERRIDE_CMDS environment variable "
165 "nor on the system at compile time).");
173 * Return an overridden definition of RCP command.
175 string CommandsOverloader::RCP_Command() {
176 string cmd = CMD_Command("RCP");
181 throw RunTimeException("Can't use RSH protocol (RCP command was "
182 "not found neither in the file pointed by "
183 "LIBBATCH_OVERRIDE_CMDS environment variable "
184 "nor on the system at compile time).");
192 * Return an overridden definition of SSH command.
194 string CommandsOverloader::SSH_Command() {
195 string cmd = CMD_Command("SSH");
200 throw RunTimeException("Can't use SSH protocol (SSH command was "
201 "not found neither in the file pointed by "
202 "LIBBATCH_OVERRIDE_CMDS environment variable "
203 "nor on the system at compile time).");
211 * Return an overridden definition of SCP command.
213 string CommandsOverloader::SCP_Command() {
214 string cmd = CMD_Command("SCP");
219 throw RunTimeException("Can't use SSH protocol (SCP command was "
220 "not found neither in the file pointed by "
221 "LIBBATCH_OVERRIDE_CMDS environment variable "
222 "nor on the system at compile time).");
230 * Return an overridden definition of RSYNC command.
232 string CommandsOverloader::RSYNC_Command() {
233 string cmd = CMD_Command("RSYNC");
236 return RSYNC_COMMAND;
238 throw RunTimeException("Can't use RSYNC protocol (RSYNC command was "
239 "not found neither in the file pointed by "
240 "LIBBATCH_OVERRIDE_CMDS environment variable "
241 "nor on the system at compile time).");
249 * Parse text file with the given file name and fill in the map of
250 * <CMD> - <associated command desired by the user at runtime>.
251 * \param theFilename the name of text file to be parsed
253 void CommandsOverloader::parse(const std::string & theFilename) {
254 ifstream fileStream(theFilename.c_str());
257 errMsg << "Can't open file with overridden commands definitions " << theFilename;
258 throw RunTimeException(errMsg.str());
263 while (getline(fileStream, line)) {
267 // Find ' ' symbol and split the line
268 size_t pos = str.find_first_of(' ');
269 if (pos == string::npos) {
271 errMsg << "Wrong format of " << theFilename << " file on line " << lineNumber
272 << ": Syntax error (missing ' ' character between key and value): " << line;
273 throw RunTimeException(errMsg.str());
275 string key = str.substr(0, pos);
276 string value = str.substr(pos+1);
278 // Check non-completeness of the file.
279 string trimmedKey = trim(key);
280 string trimmedValue = trim(value);
281 if (trimmedKey.empty() || trimmedValue.empty()) {
283 errMsg << "Wrong format of " << theFilename << " file on line " << lineNumber
284 << ": The non-completeness of the file: " << line;
285 throw RunTimeException(errMsg.str());
288 // Check the presence of an unsupported command.
289 if (supportedCmds.find(trimmedKey) == supportedCmds.end()) {
291 errMsg << "Wrong format of " << theFilename << " file on line " << lineNumber
292 << ": The presence of an unsupported command: " << trimmedKey;
293 throw RunTimeException(errMsg.str());
296 if (!hasKey(trimmedKey)) {
297 _cmdmap[trimmedKey] = trimmedValue;
300 // Redifinition of already overloaded command is found.
302 errMsg << "Wrong format of " << theFilename << " file on line " << lineNumber
303 <<": A repetition of the " << trimmedKey << " key in several lines.";
304 throw RunTimeException(errMsg.str());
312 errMsg << "Wrong format of " << theFilename << " file: Empty file.";
313 throw RunTimeException(errMsg.str());
319 * Strip leading and trailing spaces in the given string.
320 * \param theStr string to be stripped
321 * \return stripped string
323 std::string CommandsOverloader::trim(const std::string & theStr) const noexcept
325 size_t beg = theStr.find_first_not_of(" \t");
326 if (beg == string::npos) beg = 0;
327 size_t end = theStr.find_last_not_of(" \t");
328 return theStr.substr(beg, end-beg+1);
332 * Check, if file with overloaded commands is defined by
333 * LIBBATCH_OVERRIDE_CMDS environment variable.
334 * \param theIsDefined in/out parameter; true, if file is defined; false - otherwise
335 * \return the name of file with overloaded commands
337 const char * CommandsOverloader::isCmdFileDefined(bool & theIsDefined) const
339 const char * filename = getenv("LIBBATCH_OVERRIDE_CMDS");
340 theIsDefined = (filename != NULL && !string(filename).empty());
345 * Check, if it is needed to show information about overloaded or not
346 * commands are used. It can be switched ON via the environment
347 * variable LIBBATCH_CHECK_CMDS=1.
348 * \return true, if it is needed to show information; false - otherwise
350 bool CommandsOverloader::isCheckCmdsDefined() const
352 char * check_cmds_env = getenv("LIBBATCH_CHECK_CMDS");
353 if (check_cmds_env && atoi(check_cmds_env) == 1)
359 * Return an overridden definition of the given command.
360 * \param theKey command name
361 * \return overridden definition of the given command
363 string CommandsOverloader::CMD_Command(const std::string & theKey) {
364 if (_cmdmap.empty()) {
366 const char * filename = isCmdFileDefined(isFileDefined);
368 // Environment variable LIBBATCH_OVERRIDE_CMDS is defined.
369 // Parse text file pointed by LIBBATCH_OVERRIDE_CMDS environment variable.
371 // Note: If environment variable LIBBATCH_OVERRIDE_CMDS is not defined,
372 // use command configuration established at compile time.
374 // Showing information about overloaded or not commands are used is disabled by default.
375 // It can be switched ON via the environment variable: LIBBATCH_CHECK_CMDS=1
376 if (isCheckCmdsDefined()) {
377 cout << "================================================================" << endl;
378 if (_cmdmap.empty()) {
379 cout << "Commands found on the system at compile time are used." << endl;
380 } else if (_cmdmap.size() == supportedCmds.size()) {
381 cout << "Overloaded commands are used." << endl;
383 cout << "Command(s)" << endl;
384 map<string,string>::const_iterator iter;
385 for (iter = _cmdmap.begin() ; iter != _cmdmap.end() ; ++iter) {
386 cout << "\t" << iter->first << endl;
388 cout << "is(are) overloaded." << endl;
389 cout << "The rest command(s) is(are) found on the system at compile time." << endl;
391 cout << "================================================================" << endl;
396 return (hasKey(theKey) ? _cmdmap[theKey] : string());
400 * Check, if commands map contains the given command key.
401 * \param theKey command name
402 * \return true, if command key exists in the map
404 bool CommandsOverloader::hasKey(const string & theKey) const
406 return (_cmdmap.find(theKey) != _cmdmap.end());