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"
47 static set<string> supportedCmds({"RM", "SH", "CP", "MKDIR", "RSH", "RCP", "SSH", "SCP", "RSYNC"});
52 CommandsOverloader::CommandsOverloader()
54 if (!isCmdFileDefined() && 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 ()
74 static CommandsOverloader instance;
79 * Return an overridden definition of RM command.
81 string CommandsOverloader::RM_Command()
83 string cmd = CMD_Command("RM");
92 throw RunTimeException("Can't use SH protocol (RM command was "
93 "not found neither in the file pointed by "
94 "LIBBATCH_OVERRIDE_CMDS environment variable "
95 "nor on the system at compile time).");
100 * Return an overridden definition of SH command.
102 string CommandsOverloader::SH_Command()
104 string cmd = CMD_Command("SH");
113 throw RunTimeException("Can't use SH protocol (SH command was "
114 "not found neither in the file pointed by "
115 "LIBBATCH_OVERRIDE_CMDS environment variable "
116 "nor on the system at compile time).");
121 * Return an overridden definition of CP command.
123 string CommandsOverloader::CP_Command()
125 string cmd = CMD_Command("CP");
134 throw RunTimeException("Can't use SH protocol (CP command was "
135 "not found neither in the file pointed by "
136 "LIBBATCH_OVERRIDE_CMDS environment variable "
137 "nor on the system at compile time).");
142 * Return an overridden definition of MKDIR command.
144 string CommandsOverloader::MKDIR_Command()
146 string cmd = CMD_Command("MKDIR");
153 return MKDIR_COMMAND;
155 throw RunTimeException("Can't use SH protocol (MKDIR command was "
156 "not found neither in the file pointed by "
157 "LIBBATCH_OVERRIDE_CMDS environment variable "
158 "nor on the system at compile time).");
163 * Return an overridden definition of RSH command.
165 string CommandsOverloader::RSH_Command()
167 string cmd = CMD_Command("RSH");
176 throw RunTimeException("Can't use RSH protocol (RSH command was "
177 "not found neither in the file pointed by "
178 "LIBBATCH_OVERRIDE_CMDS environment variable "
179 "nor on the system at compile time).");
184 * Return an overridden definition of RCP command.
186 string CommandsOverloader::RCP_Command()
188 string cmd = CMD_Command("RCP");
197 throw RunTimeException("Can't use RSH protocol (RCP command was "
198 "not found neither in the file pointed by "
199 "LIBBATCH_OVERRIDE_CMDS environment variable "
200 "nor on the system at compile time).");
205 * Return an overridden definition of SSH command.
207 string CommandsOverloader::SSH_Command()
209 string cmd = CMD_Command("SSH");
218 throw RunTimeException("Can't use SSH protocol (SSH command was "
219 "not found neither in the file pointed by "
220 "LIBBATCH_OVERRIDE_CMDS environment variable "
221 "nor on the system at compile time).");
226 * Return an overridden definition of SCP command.
228 string CommandsOverloader::SCP_Command()
230 string cmd = CMD_Command("SCP");
239 throw RunTimeException("Can't use SSH protocol (SCP command was "
240 "not found neither in the file pointed by "
241 "LIBBATCH_OVERRIDE_CMDS environment variable "
242 "nor on the system at compile time).");
247 * Return an overridden definition of RSYNC command.
249 string CommandsOverloader::RSYNC_Command()
251 string cmd = CMD_Command("RSYNC");
258 return RSYNC_COMMAND;
260 throw RunTimeException("Can't use RSYNC protocol (RSYNC command was "
261 "not found neither in the file pointed by "
262 "LIBBATCH_OVERRIDE_CMDS environment variable "
263 "nor on the system at compile time).");
268 * Parse text file with the given file name and fill in the map of
269 * <CMD> - <associated command desired by the user at runtime>.
270 * \param theFilename the name of text file to be parsed
272 void CommandsOverloader::parse(const std::string & theFilename)
274 ifstream fileStream(theFilename.c_str());
278 errMsg << "Can't open file with overridden commands definitions " << theFilename;
279 throw RunTimeException(errMsg.str());
284 while (getline(fileStream, line))
290 // Find ' ' symbol and split the line
291 size_t pos = str.find_first_of(' ');
292 if (pos == string::npos)
295 errMsg << "Wrong format of " << theFilename << " file on line " << lineNumber
296 << ": Syntax error (missing ' ' character between key and value): " << line;
297 throw RunTimeException(errMsg.str());
300 string key = str.substr(0, pos);
301 string value = str.substr(pos+1);
303 // Check non-completeness of the file.
304 string trimmedKey = trim(key);
305 string trimmedValue = trim(value);
306 if (trimmedKey.empty() || trimmedValue.empty())
309 errMsg << "Wrong format of " << theFilename << " file on line " << lineNumber
310 << ": The non-completeness of the file: " << line;
311 throw RunTimeException(errMsg.str());
314 // Check the presence of an unsupported command.
315 if (supportedCmds.find(trimmedKey) == supportedCmds.end())
318 errMsg << "Wrong format of " << theFilename << " file on line " << lineNumber
319 << ": The presence of an unsupported command: " << trimmedKey;
320 throw RunTimeException(errMsg.str());
323 if (!hasKey(trimmedKey))
325 _cmdmap[trimmedKey] = trimmedValue;
329 // Redifinition of already overloaded command is found.
331 errMsg << "Wrong format of " << theFilename << " file on line " << lineNumber
332 <<": A repetition of the " << trimmedKey << " key in several lines.";
333 throw RunTimeException(errMsg.str());
342 errMsg << "Wrong format of " << theFilename << " file: Empty file.";
343 throw RunTimeException(errMsg.str());
349 * Strip leading and trailing spaces in the given string.
350 * \param theStr string to be stripped
351 * \return stripped string
353 string CommandsOverloader::trim(const std::string & theStr) const noexcept
355 size_t beg = theStr.find_first_not_of(" \t");
356 if (beg == string::npos) beg = 0;
357 size_t end = theStr.find_last_not_of(" \t");
358 return theStr.substr(beg, end-beg+1);
362 * Return name of file with overloaded commands defined by
363 * LIBBATCH_OVERRIDE_CMDS environment variable.
364 * \return the name of file with overloaded commands
366 string CommandsOverloader::getCmdFileName() const
368 auto parseCmdFileName = []() -> std::string
370 const char* cmdFileName = getenv("LIBBATCH_OVERRIDE_CMDS");
371 if (cmdFileName != NULL && !string(cmdFileName).empty())
378 static const string cmdFileName = parseCmdFileName();
383 * Check, if file with overloaded commands is defined by
384 * LIBBATCH_OVERRIDE_CMDS environment variable.
385 * \return true, if file is defined; false - otherwise
387 bool CommandsOverloader::isCmdFileDefined() const
389 static const bool isFileDefined = !getCmdFileName().empty();
390 return isFileDefined;
394 * Check, if it is needed to show information about overloaded or not
395 * commands are used. It can be switched ON via the environment
396 * variable LIBBATCH_CHECK_CMDS=1.
397 * \return true, if it is needed to show information; false - otherwise
399 bool CommandsOverloader::isCheckCmdsDefined() const
401 char * check_cmds_env = getenv("LIBBATCH_CHECK_CMDS");
402 if (check_cmds_env && atoi(check_cmds_env) == 1)
408 * Return an overridden definition of the given command.
409 * \param theKey command name
410 * \return overridden definition of the given command
412 string CommandsOverloader::CMD_Command(const std::string & theKey)
416 if (isCmdFileDefined())
418 // Environment variable LIBBATCH_OVERRIDE_CMDS is defined.
419 // Parse text file pointed by LIBBATCH_OVERRIDE_CMDS environment variable.
420 parse(getCmdFileName());
421 // Note: If environment variable LIBBATCH_OVERRIDE_CMDS is not defined,
422 // use command configuration established at compile time.
424 // Showing information about overloaded or not commands are used is disabled by default.
425 // It can be switched ON via the environment variable: LIBBATCH_CHECK_CMDS=1
426 if (isCheckCmdsDefined())
428 cout << "================================================================" << endl;
431 cout << "Commands found on the system at compile time are used." << endl;
432 } else if (_cmdmap.size() == supportedCmds.size())
434 cout << "Overloaded commands are used." << endl;
437 cout << "Command(s)" << endl;
438 map<string,string>::const_iterator iter;
439 for (iter = _cmdmap.begin() ; iter != _cmdmap.end() ; ++iter)
441 cout << "\t" << iter->first << endl;
443 cout << "is(are) overloaded." << endl;
444 cout << "The rest command(s) is(are) found on the system at compile time." << endl;
446 cout << "================================================================" << endl;
451 return hasKey(theKey) ? _cmdmap[theKey] : string();
455 * Check, if commands map contains the given command key.
456 * \param theKey command name
457 * \return true, if command key exists in the map
459 bool CommandsOverloader::hasKey(const string & theKey) const
461 return (_cmdmap.find(theKey) != _cmdmap.end());