utilities.h
Go to the documentation of this file.
00001 /** 00002 * @file utilities.h 00003 * @brief Main module of project-independent BASIS utilities. 00004 * 00005 * This module defines project-independent implementations of the BASIS utility 00006 * functions. They are intended for use outside a BASIS-based project only. 00007 * Within source code of a BASIS-based project, the overloads declared by 00008 * the basis.h module should be used instead as these are specifically configured 00009 * by BASIS for this project during the build of the software. 00010 * 00011 * Note that this module includes all other BASIS utility header files. 00012 * Hence, it is sufficient to include this file only. 00013 * 00014 * Copyright (c) 2011, 2012 University of Pennsylvania. All rights reserved.<br /> 00015 * See https://www.cbica.upenn.edu/sbia/software/license.html or COPYING file. 00016 * 00017 * Contact: SBIA Group <sbia-software at uphs.upenn.edu> 00018 * 00019 * @ingroup BasisCxxUtilities 00020 */ 00021 00022 #ifndef _BASIS_UTILITIES_H 00023 #define _BASIS_UTILITIES_H 00024 00025 // standard library 00026 #include <string> 00027 #include <iostream> 00028 #include <vector> 00029 00030 // build configuration - has to be included using full path in case the build 00031 // tree of BASIS is used instead of an installation 00032 #include <basis/config.h> 00033 00034 // basic utilities 00035 #include "assert.h" 00036 #include "except.h" 00037 #include "os.h" 00038 00039 // command-line parsing 00040 #include "CmdLine.h" 00041 00042 00043 /// @addtogroup BasisCxxUtilities 00044 /// @{ 00045 00046 00047 // the subnamespace is required to avoid conflict with configured 00048 // project-specific utilities of BASIS itself 00049 namespace basis { namespace util { 00050 00051 00052 // =========================================================================== 00053 // executable information 00054 // =========================================================================== 00055 00056 /** 00057 * @brief Provides information about executable build targets. 00058 * 00059 * Within source code of a BASIS project, other SBIA executables are called 00060 * only indirectly using the build target name which must be fixed and unique 00061 * within the lab. The name of the output executable file of these targets may 00062 * however vary and be finally set by BASIS, for example, depending on 00063 * whether the project is build as part of a superproject or not. Therefore, 00064 * each BASIS CMake function may adjust the output name in order to resolve 00065 * name conflicts with other targets or SBIA executables. 00066 * 00067 * The idea is that a target name is supposed to be stable and known to the 00068 * developer as soon as the target is added to a CMakeLists.txt file, while 00069 * the name of the actual executable file is not known a priori as it is set 00070 * by the BASIS CMake functions during the configure step. Thus, the developer 00071 * should not rely on a particular name of the executable file. Instead, they 00072 * can rely on the name of the corresponding build target which was chosen by 00073 * themselves when adding the target to the build configuration. 00074 * 00075 * In order to get the actual file path of the built executable file, the 00076 * function get_executable_path() is provided by the stdaux.h module. 00077 * This function uses the static singleton instance of this class in order to 00078 * map the given build target name to the name of the built and optionally 00079 * installed executable. The code which initializes the required maps is 00080 * generated automatically during the configuration of the build system. 00081 * 00082 * @sa exepath() 00083 */ 00084 class IExecutableTargetInfo 00085 { 00086 // ----------------------------------------------------------------------- 00087 // construction / destruction 00088 protected: 00089 00090 /// @brief Constructor 00091 IExecutableTargetInfo() {} 00092 00093 /// @brief Destructor. 00094 virtual ~IExecutableTargetInfo() {}; 00095 00096 // ----------------------------------------------------------------------- 00097 // public interface 00098 public: 00099 00100 /** 00101 * @brief Get UID of build target. 00102 * 00103 * In order to be able to distinguish build targets with identical name 00104 * but which are built as part of different BASIS projects, the UID of 00105 * a build target is composed of the build target name as given as 00106 * argument to the basis_add_* CMake functions and a namespace identifier 00107 * (i.e., the project name in lowercase letters). If the specified build 00108 * target name is neither known by this module nor a build target UID yet, 00109 * this method prepends the namespace identifier corresponding to the 00110 * project this module was built from, assuming that the caller refers 00111 * to another target within the same project. 00112 * 00113 * @param [in] target Name/UID of build target. 00114 * 00115 * @returns UID of build target. 00116 */ 00117 virtual std::string targetuid(const std::string& target) const = 0; 00118 00119 /** 00120 * @brief Determine whether a given build target is known. 00121 * 00122 * @param [in] target Name/UID of build target. 00123 * 00124 * @returns Whether the given build target is known by this module. 00125 */ 00126 virtual bool istarget(const std::string& target) const = 0; 00127 00128 /** 00129 * @brief Get name of executable file without directory path. 00130 * 00131 * @param [in] target Name/UID of build target. 00132 * 00133 * @returns Name of built executable file without path. 00134 */ 00135 virtual std::string basename(const std::string& target) const = 0; 00136 00137 /** 00138 * @brief Get absolute path of directory containing executable. 00139 * 00140 * @param [in] target Name/UID of build target. 00141 * 00142 * @returns Absolute path of directory containing executable file. 00143 */ 00144 virtual std::string dirname(const std::string& target) const = 0; 00145 00146 }; // class IExecutableTargetInfo 00147 00148 00149 /** 00150 * @brief Print contact information. 00151 * 00152 * @param [in] contact Name of contact. 00153 */ 00154 void print_contact(const char* contact); 00155 00156 /** 00157 * @brief Print version information including copyright and license notices. 00158 * 00159 * @param [in] name Name of executable. Should not be set programmatically 00160 * to the first argument of the @c main() function, but 00161 * a string literal instead. 00162 * @param [in] version Version of executable, e.g., release of project 00163 * this executable belongs to. 00164 * @param [in] project Name of project this executable belongs to. 00165 * If @c NULL or an empty string, no project information 00166 * is printed. 00167 * @param [in] copyright The copyright notice, excluding the common prefix 00168 * "Copyright (c) " and suffix ". All rights reserved.". 00169 * If @c NULL or an empty string, no copyright notice 00170 * is printed. 00171 * @param [in] license Information regarding licensing. If @c NULL or an empty 00172 * string, no license information is printed. 00173 */ 00174 void print_version(const char* name, 00175 const char* version, 00176 const char* project = NULL, 00177 const char* copyright = NULL, 00178 const char* license = NULL); 00179 00180 /** 00181 * @brief Get UID of build target. 00182 * 00183 * The UID of a build target is its name prepended by a namespace identifier 00184 * which should be unique for each project. 00185 * 00186 * @param [in] name Name of build target. 00187 * @param [in] targets Structure providing information about executable targets. 00188 * 00189 * @returns UID of named build target. 00190 */ 00191 std::string targetuid(const std::string& name, const IExecutableTargetInfo* targets = NULL); 00192 00193 /** 00194 * @brief Determine whether a given build target is known. 00195 * 00196 * @param [in] name Name of build target. 00197 * @param [in] targets Structure providing information about executable targets. 00198 * 00199 * @returns Whether the named target is a known executable target. 00200 */ 00201 bool istarget(const std::string& name, const IExecutableTargetInfo* targets = NULL); 00202 00203 /** 00204 * @brief Get absolute path of executable file. 00205 * 00206 * This function determines the absolute file path of an executable. If no 00207 * arguments are given, the absolute path of this executable is returned. 00208 * If the command names a known executable build target, the absolute path to 00209 * the corresonding built (and installed) executable file is returned. 00210 * Otherwise, the named command is searched in the system @c PATH and its 00211 * absolute path returned if found. If the executable is not found, an 00212 * empty string is returned. 00213 * 00214 * @todo This function currently makes use of the which command implemented 00215 * in Python and called as subprocess in order to search a command 00216 * in the system @c PATH. This which command is part of BASIS and 00217 * can also be used on Windows. However, a native C++ implementation 00218 * would be desireable. 00219 * 00220 * @param [in] name Name of command or @c NULL. 00221 * @param [in] targets Structure providing information about executable targets. 00222 * 00223 * @returns Absolute path of executable or an empty string if not found. 00224 * If @p name is @c NULL, the path of this executable is returned. 00225 * 00226 * @sa exename() 00227 * @sa exedir() 00228 */ 00229 std::string exepath(const std::string& name = std::string(), 00230 const IExecutableTargetInfo* targets = NULL); 00231 00232 /** 00233 * @brief Get name of executable file. 00234 * 00235 * The name of the executable may or may not include the file name extension 00236 * depending on the executable type and operating system. Hence, this function 00237 * is neither an equivalent to os::path::basename(exepath()) nor 00238 * os::path::filename(exepath()). In particular, on Windows, the .exe and .com 00239 * extension is not included in the returned executable name. 00240 * 00241 * @param [in] name Name of command or @c NULL. 00242 * @param [in] targets Structure providing information about executable targets. 00243 * 00244 * @returns Name of executable file or an empty string if not found. 00245 * If @p name is @c NULL, the name of this executable is returned. 00246 * 00247 * @sa exepath() 00248 */ 00249 std::string exename(const std::string& name = std::string(), 00250 const IExecutableTargetInfo* targets = NULL); 00251 00252 /** 00253 * @brief Get directory of executable file. 00254 * 00255 * @param [in] name Name of command or @c NULL. 00256 * @param [in] targets Structure providing information about executable targets. 00257 * 00258 * @returns Absolute path of directory containing executable or an empty string if not found. 00259 * If @p name is @c NULL, the directory of this executable is returned. 00260 * 00261 * @sa exepath() 00262 */ 00263 std::string exedir(const std::string& name = std::string(), 00264 const IExecutableTargetInfo* targets = NULL); 00265 00266 // =========================================================================== 00267 // command execution 00268 // =========================================================================== 00269 00270 /** 00271 * @class SubprocessError 00272 * @brief Exception type thrown by execute(). 00273 */ 00274 class SubprocessError : public std::exception 00275 { 00276 public: 00277 SubprocessError(const std::string& msg) : msg_(msg) {} 00278 ~SubprocessError() throw () {} 00279 00280 private: 00281 std::string msg_; ///< Error message. 00282 }; // class SubprocessError 00283 00284 /** 00285 * @brief Convert array of arguments to quoted string. 00286 * 00287 * @param [in] args Array of arguments. 00288 * 00289 * @returns Double quoted string, i.e., string where arguments are separated 00290 * by a space character and surrounded by double quotes if necessary. 00291 * Double quotes within an argument are escaped with a backslash. 00292 * 00293 * @sa split() 00294 */ 00295 std::string tostring(const std::vector<std::string>& args); 00296 00297 /** 00298 * @brief Split quoted string. 00299 * 00300 * @param [in] args Quoted string of arguments. 00301 * 00302 * @returns Array of arguments. 00303 * 00304 * @sa tostring() 00305 */ 00306 std::vector<std::string> qsplit(const std::string& args); 00307 00308 /** 00309 * @brief Execute command as subprocess. 00310 * 00311 * This function is a replacement for system() on Unix and is furthermore 00312 * less platform dependent. The first argument of the given command-line string 00313 * is mapped to an absolute executable file using exepath() if the given first 00314 * argument is a know build target name. Otherwise, the command-line is used 00315 * unmodified. 00316 * 00317 * @param [in] cmd Command-line given as double quoted string. Arguments 00318 * containing whitespaces have to be quoted using double 00319 * quotes. Use a backslash (\\) to escape double quotes 00320 * inside an argument as well as to escape a backslash 00321 * itself (required if backslash at end of double quoted 00322 * argument, e.g., "this argument \\"). 00323 * @param [in] quiet Turns off output of stdout of child process to stdout 00324 * of parent process. 00325 * @param [out] out Output stream where command output is written to. 00326 * @param [in] allow_fail If true, no exception is thrown if the exit code 00327 * of the child process is non-zero. Otherwise, 00328 * a SubprocessException object is thrown in that case. 00329 * @param [in] verbose Verbosity of output messages. Does not affect 00330 * verbosity of executed command. 00331 * @param [in] simulate Whether to simulate command execution only. 00332 * @param [in] targets Structure providing information about executable targets. 00333 * 00334 * @returns Exit code of command or -1 if subprocess creation failed. 00335 * 00336 * @throws SubprocessError If subprocess creation failed or command returned 00337 * a non-zero exit code while @p allow_fail is false. 00338 */ 00339 int execute(const std::string& cmd, 00340 bool quiet = false, 00341 // attention: stdout is a macro defined by windows.h 00342 std::ostream* out = NULL, 00343 bool allow_fail = false, 00344 int verbose = 0, 00345 bool simulate = false, 00346 const IExecutableTargetInfo* targets = NULL); 00347 00348 /** 00349 * @brief Execute command as subprocess. 00350 * 00351 * This function is a replacement for system() on Unix and is furthermore 00352 * less platform dependent. The first argument of the given command-line string 00353 * is mapped to an absolute executable file using exepath() if the given first 00354 * argument is a know build target name. Otherwise, the command-line is used 00355 * unmodified. 00356 * 00357 * @param [in] args Command-line given as argument vector. The first 00358 * argument has to be either a build target name or the 00359 * name/path of the command to execute. Note that as a 00360 * side effect, the first argument of the input vector 00361 * is replaced by the absolute path of the actual 00362 * executable file if applicable. 00363 * @param [in] quiet Turns off output of stdout of child process to 00364 * stdout of parent process. 00365 * @param [out] out Output stream where command output is written to. 00366 * @param [in] allow_fail If true, no exception is thrown if the exit code 00367 * of the child process is non-zero. Otherwise, 00368 * a SubprocessException object is thrown in that case. 00369 * @param [in] verbose Verbosity of output messages. Does not affect 00370 * verbosity of executed command. 00371 * @param [in] simulate Whether to simulate command execution only. 00372 * @param [in] targets Structure providing information about executable targets. 00373 * 00374 * @returns Exit code of command or -1 if subprocess creation failed. 00375 * 00376 * @throws SubprocessError If subprocess creation failed or command returned 00377 * a non-zero exit code while @p allow_fail is false. 00378 */ 00379 int execute(std::vector<std::string> args, 00380 bool quiet = false, 00381 // attention: stdout is a macro defined by windows.h 00382 std::ostream* out = NULL, 00383 bool allow_fail = false, 00384 int verbose = 0, 00385 bool simulate = false, 00386 const IExecutableTargetInfo* targets = NULL); 00387 00388 00389 } } // end of namespaces 00390 00391 00392 /// @} 00393 // end of Doxygen group 00394 00395 #endif // _BASIS_UTILITIES_H