BASIS  version 1.2.3 (revision 2104)
stdaux.cxx
Go to the documentation of this file.
00001 /**
00002  * @file  stdaux.cxx
00003  * @brief Implementation of standard auxiliary functions.
00004  *
00005  * @note The file stdaux.cxx is automatically generated by BASIS from the
00006  *       template file stdaux.cxx.in which is part of BASIS.
00007  *
00008  * Copyright (c) 2011 University of Pennsylvania. All rights reserved.<br />
00009  * See https://www.cbica.upenn.edu/sbia/software/license.html or COPYING file.
00010  *
00011  * Contact: SBIA Group <sbia-software at uphs.upenn.edu>
00012  */
00013 
00014 #include <iostream>
00015 
00016 #include <sbia/basis/config.h>      // cProjectName, cVersionAndRevision
00017 #include <sbia/basis/path.h>
00018 #include <sbia/basis/except.h>
00019 #include <sbia/basis/assert.h>
00020 #include <sbia/basis/subprocess.h>
00021 #include "ExecutableTargetInfo.h"
00022 
00023 #include "stdaux.h"
00024 
00025 
00026 using namespace std;
00027 
00028 
00029 namespace sbia
00030 {
00031 
00032 namespace basis
00033 {
00034 
00035 
00036 // ===========================================================================
00037 // version / contact
00038 // ===========================================================================
00039 
00040 // ---------------------------------------------------------------------------
00041 void print_version(const char* name, const char* copyright, const char* license)
00042 {
00043     assert(name != NULL);
00044     cout << name << " (" << cProjectName << ") " << cVersionAndRevision << endl;
00045     if (copyright == NULL) {
00046         cout << "Copyright (c) University of Pennsylvania. All rights reserved." << endl;
00047     } else if (*copyright != '\0') {
00048         cout << copyright << endl;
00049     }
00050     if (license == NULL) {
00051         cout << "See https://www.cbica.upenn.edu/sbia/software/license.html or COPYING file." << endl;
00052     } else if (*license != '\0') {
00053         cout << license << endl;
00054     }
00055 }
00056 
00057 // ---------------------------------------------------------------------------
00058 void print_contact(const char* contact)
00059 {
00060     cout << "Contact:" << endl;
00061     if (contact) cout << "  " << contact << endl;
00062     else         cout << "  SBIA Group <sbia-software at uphs.upenn.edu>" << endl;
00063 }
00064 
00065 // ===========================================================================
00066 // installation directories
00067 // ===========================================================================
00068 
00069 // ---------------------------------------------------------------------------
00070 bool executing_in_build_tree()
00071 {
00072     // get executable path relative to top directory of build tree
00073     string rel_path = to_relative_path(get_real_path(cBuildRoot), get_executable_directory());
00074     // return whether executable directory is inside the build tree or not
00075     return !(rel_path == "" || rel_path == "." ||
00076             (rel_path.substr(0, 2) == ".." && (rel_path.size() == 2 || rel_path[2] == '/')));
00077 }
00078 
00079 // ---------------------------------------------------------------------------
00080 string get_installation_prefix()
00081 {
00082 #ifdef LIBEXEC
00083     return join_paths(get_executable_directory(), cLibexecPathPrefix);
00084 #else
00085     return join_paths(get_executable_directory(), cRuntimePathPrefix);
00086 #endif
00087 }
00088 
00089 // ---------------------------------------------------------------------------
00090 string get_runtime_directory()
00091 {
00092     if (executing_in_build_tree()) {
00093         return cRuntimeBuildPath;
00094     } else {
00095         return join_paths(get_installation_prefix(), cRuntimePath);
00096     }
00097 }
00098 
00099 // ---------------------------------------------------------------------------
00100 string get_libexec_directory()
00101 {
00102     if (executing_in_build_tree()) {
00103         return cLibexecBuildPath;
00104     } else {
00105         return join_paths(get_installation_prefix(), cLibexecPath);
00106     }
00107 }
00108 
00109 // ---------------------------------------------------------------------------
00110 string get_library_directory()
00111 {
00112     if (executing_in_build_tree()) {
00113         return cLibraryBuildPath;
00114     } else {
00115         return join_paths(get_installation_prefix(), cLibraryPath);
00116     }
00117 }
00118 
00119 // ---------------------------------------------------------------------------
00120 string get_data_directory()
00121 {
00122     if (executing_in_build_tree()) {
00123         return cDataBuildPath;
00124     } else {
00125         return join_paths(get_installation_prefix(), cDataPath);
00126     }
00127 }
00128 
00129 // ===========================================================================
00130 // executable file path of other build targets
00131 // ===========================================================================
00132 
00133 // ---------------------------------------------------------------------------
00134 string get_executable_path(const string& target)
00135 {
00136     // get executable target information instance
00137     const ExecutableTargetInfo& info = ExecutableTargetInfo::instance();
00138     // get name of executable and check if target name is known
00139     string exec_name = info.get_executable_name(target);
00140     // is this target known?
00141     if (exec_name.empty()) return "";
00142     // prepend either build tree directory or installation directory
00143     if (executing_in_build_tree()) {
00144         return join_paths(info.get_build_directory(target), exec_name);
00145     } else {
00146         return join_paths(info.get_installation_directory(target), exec_name);
00147     }
00148 }
00149 
00150 // ===========================================================================
00151 // command execution
00152 // ===========================================================================
00153 
00154 // ---------------------------------------------------------------------------
00155 int execute_process(const string& cmd, bool quiet, ostream* out,
00156                     bool allow_fail, int verbose, bool simulate)
00157 {
00158     vector<string> args = Subprocess::split(cmd);
00159     return execute_process(args, quiet, out, allow_fail, verbose, simulate);
00160 }
00161 
00162 // ---------------------------------------------------------------------------
00163 int execute_process(vector<string>& args, bool quiet, ostream* out,
00164                     bool allow_fail, int verbose, bool simulate)
00165 {
00166     if (args.empty() || args[0].empty()) {
00167         BASIS_THROW(SubprocessException, "execute_process(): No command specified");
00168     }
00169     // map build target name to executable file path
00170     string exec_path = get_executable_path(args[0]);
00171     // prepend absolute path of found executable
00172     if (!exec_path.empty()) args[0] = exec_path;
00173     // some verbose output
00174     if (verbose > 0) {
00175         cout << "$ " << Subprocess::tostring(args);
00176         if (simulate) cout << " (simulated)";
00177         cout << endl;
00178     }
00179     // execute command
00180     char buf[1024];
00181     int  n;
00182     int status = 0;
00183     Subprocess p;
00184     if (!p.popen(args, Subprocess::RM_NONE, Subprocess::RM_PIPE, Subprocess::RM_PIPE)) {
00185         BASIS_THROW(SubprocessException, "execute_process(): Failed to create subprocess");
00186     }
00187     // read child's stdout (blocking)
00188     if (!quiet || out != NULL) {
00189         while ((n = p.read(buf, 1023)) > 0) {
00190             buf[n] = '\0';
00191             if (!quiet) {
00192                 cout << buf;
00193                 cout.flush();
00194             }
00195             if (out) *out << buf;
00196         }
00197     }
00198     // wait for child process
00199     if (!p.wait()) {
00200         BASIS_THROW(SubprocessException, "execute_process(): Failed to wait for subprocess");
00201     }
00202     // write error messages to stderr of parent process
00203     while ((n = p.read(buf, 1023, true)) > 0) {
00204         buf[n] = '\0';
00205         cerr << buf;
00206     }
00207     // get exit code
00208     status = p.returncode();
00209     // if command failed, throw an exception
00210     if (status != 0 && !allow_fail) {
00211         BASIS_THROW(SubprocessException, "Command " << Subprocess::tostring(args) << " failed");
00212     }
00213     return status;
00214 }
00215 
00216 
00217 } // namespace basis
00218 
00219 } // namespace sbia