00001 ############################################################################## 00002 # @file StdAux.pm 00003 # @brief Standard auxiliary functions. 00004 # 00005 # @note The StdAux.pm module is automatically created by BASIS from the 00006 # template file StdAux.pm.in which is part of the BASIS installation. 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 # @ingroup BasisPerlUtilities 00014 ############################################################################## 00015 00016 package SBIA::BASIS::StdAux; 00017 00018 # ============================================================================ 00019 # modules 00020 # ============================================================================ 00021 00022 use strict; 00023 use warnings; 00024 00025 use SBIA::BASIS::ExecutableTargetInfo qw(get_executable_path get_executable_name); 00026 00027 # ============================================================================ 00028 # exports 00029 # ============================================================================ 00030 00031 our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); 00032 00033 BEGIN { 00034 use Exporter (); 00035 00036 $VERSION = 1.02_03; 00037 @ISA = qw (Exporter); 00038 00039 %EXPORT_TAGS = ( 00040 default => [qw ( 00041 print_version 00042 print_contact 00043 execute_process 00044 )], 00045 00046 everything => [qw ( 00047 print_version 00048 print_contact 00049 execute_process 00050 )] 00051 ); 00052 00053 Exporter::export_ok_tags ('everything'); 00054 } 00055 00056 00057 ## @addtogroup BasisPerlUtilities 00058 # @{ 00059 00060 00061 # ============================================================================ 00062 # version / contact 00063 # ============================================================================ 00064 00065 # ---------------------------------------------------------------------------- 00066 ## @brief Print version information including copyright and license notices. 00067 # 00068 # @param [in] name Name of executable. Should not be set programmatically 00069 # to the first argument of the main script. 00070 # @param [in] copyright The copyright notice. If undef, the official default 00071 # copyright is used without year, which is not desired. 00072 # If an empty string is given, no copyright notice is 00073 # printed. 00074 # @param [in] license Information regarding licensing. If undef, the official 00075 # software license of SBIA is used. If an empty string 00076 # is given, no license information is printed. 00077 sub print_version 00078 { 00079 my ($name, $copyright, $license) = @_; 00080 # version 00081 die "print_version(): Executable name not specified!\n" unless defined($name); 00082 print $name, " (BASIS) version 1.2.3 (revision 2104)\n"; 00083 # copyright notice 00084 if (defined $copyright) { 00085 print $copyright, "\n" unless $copyright == ''; 00086 } else { 00087 print "Copyright (c) University of Pennsylvania. All rights reserved.\n"; 00088 } 00089 # license information 00090 if (defined $license) { 00091 print $license, "\n" unless $license == ''; 00092 } else { 00093 print "See https://www.cbica.upenn.edu/sbia/software/license.html or COPYING file.\n"; 00094 } 00095 } 00096 00097 # ---------------------------------------------------------------------------- 00098 ## @brief Print contact information. 00099 # 00100 # @param [in] contact Name of contact. If undef, the default contact of SBIA 00101 # is used, which is recommended. 00102 sub print_contact 00103 { 00104 my $contact = $_[0]; 00105 print "Contact:\n "; 00106 if (defined $contact) { 00107 print $contact 00108 } else { 00109 print "SBIA Group <sbia-software at uphs.upenn.edu>" 00110 } 00111 print "\n"; 00112 } 00113 00114 # ============================================================================ 00115 # command execution 00116 # ============================================================================ 00117 00118 # ---------------------------------------------------------------------------- 00119 ## @brief Execute command as subprocess. 00120 # 00121 # This command takes either an array reference reference or a string as first 00122 # argument. All other arguments are keyword arguments using hash notation. 00123 # 00124 # Example: 00125 # @code 00126 # # only returns exit code of command but does not output anything 00127 # my $status = execute_process(['ls', '/'], quiet => 1); 00128 # # returns exit code of command and returns command output without 00129 # # printing it to stdout. 00130 # my ($status, $stdout) = execute_process('ls /', quiet => 1, stdout => 1); 00131 # @endcode 00132 # 00133 # @param [in] args Command with arguments given either as single quoted 00134 # string or array of command name and arguments. 00135 # In the latter case, the array elements are converted 00136 # to strings using the built-in str() function. 00137 # Hence, any type which can be converted to a string 00138 # can be used. 00139 # @param [in] quiet Turns off output of stdout of child process to 00140 # stdout of parent process. 00141 # @param [in] stdout Whether to return the command output. 00142 # @param [in] allow_fail If true, does not raise an exception if return 00143 # value is non-zero. Otherwise, an exception is 00144 # raised by this function using die. 00145 # @param [in] verbose Verbosity of output messages. 00146 # Does not affect verbosity of executed command. 00147 # @param [in] simulate Whether to simulate command execution only. 00148 # 00149 # @return Exit code of executed command. If @p stdout is true, a tuple 00150 # consisting of the exit code and command output is returned. 00151 # 00152 # @throws die If command execution failed. This exception is not raised 00153 # if the command executed with non-zero exit code but 00154 # @p allow_fail is set to a non-false value. 00155 sub execute_process 00156 { 00157 # arguments 00158 my $args = shift or die "execute_process(): Too few arguments given"; 00159 if ($args =~ m/^(quiet|stdout|allow_fail|verbose|simulate)$/) { 00160 warn "execute_process(): First argument matches option name. Missing args argument?"; 00161 } 00162 my %defaults = (quiet => 0, stdout => 0, allow_fail => 0, 00163 verbose => 0, simulate => 0); 00164 my %options = (%defaults, @_); 00165 # get command name and arguments 00166 my $command = ''; 00167 my $arguments = ''; 00168 # if input is an array 00169 if (ref($args) eq 'ARRAY') { 00170 @$args > 0 or die "execute_process(): No command specified"; 00171 $command = shift @$args; 00172 $arguments = ''; 00173 for my $arg (@$args) { 00174 if ($arg =~ m/\s/) { 00175 # escape double quotes 00176 $arg =~ s/"/\\"/g; 00177 # quote argument 00178 $arg = '"' . $arg . '"'; 00179 } 00180 $arguments .= ' '; 00181 $arguments .= $arg; 00182 } 00183 # if input is a string 00184 } elsif (ref($args) eq '') { 00185 # extract command from string 00186 $args =~ m/^\s*('([^']|\\')*[^\\]'|"([^"]|\\")*[^\\]"|\S+)(.*)$/; 00187 $command = $1; 00188 $arguments = $4; 00189 # otherwise, wrong input type 00190 } else { 00191 die "execute_process(): Argument args must be either array reference or string"; 00192 } 00193 # map build target name to executable file 00194 my $exec_path = get_executable_path($command); 00195 defined $exec_path or die "$command: Either unknown build target or command not found"; 00196 # quote executable path if necessary 00197 not $exec_path =~ m/\s/ or $exec_path = '"' . $exec_path . '"'; 00198 # prepend absolute path of found executable 00199 $args = $exec_path . $arguments; 00200 # some verbose output 00201 if ($options{'verbose'} gt 0) { 00202 print "\$ ", $args; 00203 $options{'simulate'} and print " (simulated)"; 00204 print "\n"; 00205 } 00206 # execute command 00207 my $status = 0; 00208 my $output = ''; 00209 if (not $options{'simulate'}) { 00210 open CMD, "$args |" or die "$command: Failed to open subprocess"; 00211 my $ofh = select STDOUT; 00212 $|++; 00213 while (<CMD>) { 00214 print $_ unless $options{'quiet'}; 00215 $output .= $_ if $options{'stdout'}; 00216 } 00217 $|--; 00218 select $ofh; 00219 close CMD; 00220 $status = $?; 00221 } 00222 # if command failed, throw an exception 00223 if ($status != 0 and not $options{'allow_fail'}) { 00224 die "Command $args failed"; 00225 } 00226 # return 00227 if ($options{'stdout'}) { 00228 return ($status, $output); 00229 } else { 00230 return $status; 00231 } 00232 } 00233 00234 00235 ## @} 00236 # end of Doxygen group 00237 00238 00239 1; # indicate success of module loading