00001 /*!@file Util/version.C strings giving version info about the package */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00005 // by the University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Rob Peters <rjpeters at usc dot edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Util/version.C $ 00035 // $Id: version.C 6357 2006-03-10 00:07:35Z rjpeters $ 00036 // 00037 00038 #ifndef UTIL_VERSION_C_DEFINED 00039 #define UTIL_VERSION_C_DEFINED 00040 00041 #include "Util/version.H" 00042 00043 #include "Util/log.H" 00044 #include "Util/sformat.H" 00045 00046 #include <cctype> 00047 #include <fstream> 00048 #include <sys/types.h> 00049 #include <sys/stat.h> 00050 #include <unistd.h> 00051 00052 #ifndef PACKAGE_NAME 00053 #define PACKAGE_NAME "packagename-unknown" 00054 #endif 00055 00056 #ifndef PACKAGE_VERSION 00057 #define PACKAGE_VERSION "packageversion-unknown" 00058 #endif 00059 00060 #ifndef PACKAGE_TARNAME 00061 #define PACKAGE_TARNAME "packagetarname-unknown" 00062 #endif 00063 00064 namespace 00065 { 00066 // don't access these variables directly; instead always go through 00067 // svnversion() since that will ensure that it is properly 00068 // initialized via a pthread_once() call 00069 std::string g_fullversion; 00070 std::string g_svnversion; 00071 std::string g_date; 00072 00073 pthread_once_t version_init_once = PTHREAD_ONCE_INIT; 00074 00075 void version_init() 00076 { 00077 g_svnversion = "svnversion-unknown"; 00078 g_date = __DATE__; 00079 00080 #ifdef INVT_LIB_DIR 00081 LDEBUG("looking for svnversion in %s", INVT_LIB_DIR "/buildversion"); 00082 00083 // we flush stderr so that the previous LDEBUG() message is sure 00084 // to reach the terminal before we try to open the file in the 00085 // next line; that way, in case the filesystem hangs for some 00086 // reason, the user will have an idea where to start looking for 00087 // the problem 00088 fflush(stderr); 00089 00090 std::ifstream f(INVT_LIB_DIR "/buildversion"); 00091 00092 if (f.is_open()) 00093 { 00094 std::string s; 00095 00096 f >> s; 00097 00098 if (s.length() != 0) 00099 g_svnversion = s; 00100 00101 LDEBUG("got svnversion=%s", g_svnversion.c_str()); 00102 00103 struct stat statbuf; 00104 const int code = stat(INVT_LIB_DIR "/buildversion", &statbuf); 00105 00106 if (code == 0) 00107 { 00108 // use the last-modification time of the buildversion time 00109 // to determine the date in the fullversion string; this 00110 // is more accurate than the value of __DATE__ in this 00111 // source file (version.C), since __DATE__ changes only 00112 // when version.C is recompiled, while the timestamp on 00113 // buildversion changes each time 'make' is called 00114 const time_t t = statbuf.st_mtime; 00115 struct tm tt; 00116 00117 if (localtime_r(&t, &tt) != 0) 00118 { 00119 const char* format = "%a %b %d %H:%M:%S %Z %Y"; 00120 char buf[512]; 00121 const size_t count = 00122 strftime(buf, sizeof(buf), format, &tt); 00123 00124 buf[sizeof(buf)-1] = '\0'; 00125 00126 if (count > 0) 00127 g_date = &buf[0]; 00128 } 00129 } 00130 } 00131 else 00132 { 00133 LDEBUG("couldn't open %s for reading", INVT_LIB_DIR "/buildversion"); 00134 } 00135 #endif 00136 00137 g_fullversion = sformat("%s (%s) %s [%s] (%s)", 00138 PACKAGE_NAME, 00139 PACKAGE_TARNAME, 00140 PACKAGE_VERSION, 00141 g_date.c_str(), 00142 g_svnversion.c_str()); 00143 } 00144 } 00145 00146 const char* fullversion() 00147 { 00148 pthread_once(&version_init_once, &version_init); 00149 return g_fullversion.c_str(); 00150 } 00151 00152 const char* svnversion() 00153 { 00154 pthread_once(&version_init_once, &version_init); 00155 return g_svnversion.c_str(); 00156 } 00157 00158 bool isSourcePristine() 00159 { 00160 bool gotdigits = false; 00161 bool gotnondigits = false; 00162 00163 for (const char* p = svnversion(); *p != '\0'; ++p) 00164 { 00165 if (isdigit(*p)) gotdigits = true; 00166 else gotnondigits = true; 00167 } 00168 00169 // to be pristine we need to have a non-empty string with digits and 00170 // only digits (i.e. 5864 is OK, but 5864M, 5864:5865, and 00171 // 5864:5865M are not OK): 00172 return gotdigits && !gotnondigits; 00173 } 00174 00175 // ###################################################################### 00176 /* So things look consistent in everyone's emacs... */ 00177 /* Local Variables: */ 00178 /* indent-tabs-mode: nil */ 00179 /* End: */ 00180 00181 #endif // UTIL_VERSION_C_DEFINED