00001 /* 00002 * Copyright (C) 2003-2009 Olivier Boudeville 00003 * 00004 * This file is part of the Ceylan library. 00005 * 00006 * The Ceylan library is free software: you can redistribute it and/or modify 00007 * it under the terms of either the GNU Lesser General Public License or 00008 * the GNU General Public License, as they are published by the Free Software 00009 * Foundation, either version 3 of these Licenses, or (at your option) 00010 * any later version. 00011 * 00012 * The Ceylan library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License and the GNU General Public License 00016 * for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License and the GNU General Public License along with the Ceylan library. 00020 * If not, see <http://www.gnu.org/licenses/>. 00021 * 00022 * Author: Olivier Boudeville (olivier.boudeville@esperide.com) 00023 * 00024 */ 00025 00026 00027 #include "CeylanLibtoolVersion.h" 00028 00029 #include "CeylanOperators.h" // for toNumericalString 00030 00031 #include <list> 00032 00033 00034 using std::string ; 00035 00036 using namespace Ceylan ; 00037 00038 00039 00040 LibtoolVersion::LibtoolVersion( VersionNumber current, 00041 VersionNumber revision, VersionNumber age ) : 00042 Version( current, revision, age ) 00043 { 00044 00045 checkConsistency() ; 00046 00047 } 00048 00049 00050 00051 LibtoolVersion::LibtoolVersion( const std::string & versionText ) : 00052 Version( versionText ) 00053 { 00054 00055 checkConsistency() ; 00056 00057 } 00058 00059 00060 00061 LibtoolVersion::~LibtoolVersion() throw() 00062 { 00063 00064 } 00065 00066 00067 00068 Version::VersionNumber LibtoolVersion::getCurrentInterfaceNumber() const 00069 { 00070 00071 return _major ; 00072 00073 } 00074 00075 00076 00077 void LibtoolVersion::setCurrentInterfaceNumber( VersionNumber newCurrent ) 00078 { 00079 00080 _major = newCurrent ; 00081 00082 } 00083 00084 00085 00086 Version::VersionNumber LibtoolVersion::getRevisionInterfaceNumber() const 00087 { 00088 00089 return _minor ; 00090 00091 } 00092 00093 00094 00095 void LibtoolVersion::setRevisionInterfaceNumber( VersionNumber newRevision ) 00096 { 00097 00098 _minor = newRevision ; 00099 00100 } 00101 00102 00103 00104 Version::VersionNumber LibtoolVersion::getInterfaceAge() const 00105 { 00106 00107 return _release ; 00108 00109 } 00110 00111 00112 00113 void LibtoolVersion::setInterfaceAge( VersionNumber newAge ) 00114 { 00115 00116 _release = newAge ; 00117 00118 } 00119 00120 00121 00122 bool LibtoolVersion::isCompatibleWith( const Version & expectedVersion ) const 00123 { 00124 00125 if ( ! canBeComparedWith( expectedVersion ) ) 00126 throw VersionException( "LibtoolVersion::isCompatibleWith: " 00127 + toString( Ceylan::high ) + " and " 00128 + expectedVersion.toString( Ceylan::high ) 00129 + " cannot be compared." ) ; 00130 00131 // The cast has been checked by previous call: 00132 const LibtoolVersion * originalVersion = 00133 dynamic_cast<const LibtoolVersion *>( & expectedVersion ) ; 00134 00135 VersionNumber originalInterfaceNumber 00136 = originalVersion->getCurrentInterfaceNumber() ; 00137 00138 00139 /* 00140 * The user program is expecting to link with original version, let's 00141 * check whether this version is the same, or if it is more recent yet 00142 * still compatible. 00143 * If older, no hope of compatibility. 00144 * 00145 */ 00146 00147 // Same is ok. 00148 if ( getCurrentInterfaceNumber() == originalInterfaceNumber ) 00149 return true ; 00150 00151 // Older is ko. 00152 if ( getCurrentInterfaceNumber() < originalInterfaceNumber ) 00153 return false ; 00154 00155 /* 00156 * Here this library version is more recent than the user-expected one, 00157 * age will tell if compatibility is ensured: 00158 * 00159 */ 00160 return ( originalInterfaceNumber >= 00161 ( getCurrentInterfaceNumber() - getInterfaceAge() ) ) ; 00162 00163 } 00164 00165 00166 00167 const string LibtoolVersion::toString( VerbosityLevels level ) const 00168 { 00169 00170 string rawVersion = Version::toString( low ) ; 00171 00172 if ( level == Ceylan::low ) 00173 return rawVersion ; 00174 00175 if ( level == Ceylan::medium ) 00176 return "Libtool version " + rawVersion ; 00177 00178 return "Libtool version: current interface number = " 00179 + Ceylan::toNumericalString( _major ) 00180 + ", current revision number = " 00181 + Ceylan::toNumericalString( _minor ) + ", interface age = " 00182 + Ceylan::toNumericalString( _release ) ; 00183 00184 } 00185 00186 00187 00188 bool LibtoolVersion::isUsualVersionSchemeCompliant() const 00189 { 00190 00191 return false ; 00192 00193 } 00194 00195 00196 00197 bool LibtoolVersion::canBeComparedWith( const Version & version ) const 00198 { 00199 00200 // Only Libtool versions can be compared with Libtool versions: 00201 00202 return ( dynamic_cast<const LibtoolVersion *>( & version ) != 0 ) ; 00203 00204 } 00205 00206 00207 00208 void LibtoolVersion::checkConsistency() const 00209 { 00210 00211 /* 00212 * More restrictions apply to Libtool versions, age must be less than or 00213 * equal to current: 00214 * 00215 */ 00216 00217 if ( _release > _major ) 00218 throw VersionException( "Incorrect Libtool version: interface age (" 00219 + Ceylan::toString( _release ) 00220 + ") must be less than or equal to current (" 00221 + Ceylan::toString( _major ) + ")." ) ; 00222 00223 } 00224