/* * version.cpp * ----------- * Purpose: OpenMPT version handling. * Notes : (currently none) * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #include "stdafx.h" #include "version.h" #include "mptString.h" #include "mptStringFormat.h" #include "mptStringParse.h" #include "versionNumber.h" #include "svn_version.h" OPENMPT_NAMESPACE_BEGIN static_assert((MPT_VERSION_CURRENT.GetRawVersion() & 0xffffu) != 0x0000u, "Version numbers ending in .00.00 shall never exist again, as they make interpreting the version number ambiguous for file formats which can only store the two major parts of the version number (e.g. IT and S3M)."); Version Version::Current() noexcept { return MPT_VERSION_CURRENT; } mpt::ustring Version::GetOpenMPTVersionString() const { return U_("OpenMPT ") + ToUString(); } Version Version::Parse(const mpt::ustring &s) { uint32 result = 0; std::vector numbers = mpt::String::Split(s, U_(".")); for (std::size_t i = 0; i < numbers.size() && i < 4; ++i) { result |= (mpt::String::Parse::Hex(numbers[i]) & 0xff) << ((3 - i) * 8); } return Version(result); } mpt::ustring Version::ToUString() const { uint32 v = m_Version; if(v == 0) { // Unknown version return U_("Unknown"); } else if((v & 0xFFFF) == 0) { // Only parts of the version number are known (e.g. when reading the version from the IT or S3M file header) return mpt::format(U_("%1.%2"))(mpt::ufmt::HEX((v >> 24) & 0xFF), mpt::ufmt::HEX0<2>((v >> 16) & 0xFF)); } else { // Full version info available return mpt::format(U_("%1.%2.%3.%4"))(mpt::ufmt::HEX((v >> 24) & 0xFF), mpt::ufmt::HEX0<2>((v >> 16) & 0xFF), mpt::ufmt::HEX0<2>((v >> 8) & 0xFF), mpt::ufmt::HEX0<2>((v) & 0xFF)); } } Version Version::WithoutTestNumber() const noexcept { return Version(m_Version & 0xFFFFFF00u); } Version Version::WithoutPatchOrTestNumbers() const noexcept { return Version(m_Version & 0xFFFF0000u); } bool Version::IsTestVersion() const noexcept { return ( // Legacy (*this > MAKE_VERSION_NUMERIC(1,17,02,54) && *this < MAKE_VERSION_NUMERIC(1,18,02,00) && *this != MAKE_VERSION_NUMERIC(1,18,00,00)) || // Test builds have non-zero VER_MINORMINOR (*this > MAKE_VERSION_NUMERIC(1,18,02,00) && ((m_Version & 0xFFFFFF00u) != m_Version)) ); } namespace Source { static mpt::ustring GetUrl() { #ifdef OPENMPT_VERSION_URL return mpt::ToUnicode(mpt::CharsetASCII, OPENMPT_VERSION_URL); #else return mpt::ustring(); #endif } static int GetRevision() { #if defined(OPENMPT_VERSION_REVISION) return OPENMPT_VERSION_REVISION; #elif defined(OPENMPT_VERSION_SVNVERSION) std::string svnversion = OPENMPT_VERSION_SVNVERSION; if(svnversion.length() == 0) { return 0; } if(svnversion.find(":") != std::string::npos) { svnversion = svnversion.substr(svnversion.find(":") + 1); } if(svnversion.find("-") != std::string::npos) { svnversion = svnversion.substr(svnversion.find("-") + 1); } if(svnversion.find("M") != std::string::npos) { svnversion = svnversion.substr(0, svnversion.find("M")); } if(svnversion.find("S") != std::string::npos) { svnversion = svnversion.substr(0, svnversion.find("S")); } if(svnversion.find("P") != std::string::npos) { svnversion = svnversion.substr(0, svnversion.find("P")); } return ConvertStrTo(svnversion); #else #if MPT_COMPILER_MSVC #pragma message("SVN revision unknown. Please check your build system.") #elif MPT_COMPILER_GCC || MPT_COMPILER_CLANG #warning "SVN revision unknown. Please check your build system." #else // There is no portable way to display a warning. // Try to provoke a warning with an unused variable. int SVN_revision_unknown__Please_check_your_build_system; #endif return 0; #endif } static bool IsDirty() { #if defined(OPENMPT_VERSION_DIRTY) return OPENMPT_VERSION_DIRTY != 0; #elif defined(OPENMPT_VERSION_SVNVERSION) std::string svnversion = OPENMPT_VERSION_SVNVERSION; if(svnversion.length() == 0) { return false; } if(svnversion.find("M") != std::string::npos) { return true; } return false; #else return false; #endif } static bool HasMixedRevisions() { #if defined(OPENMPT_VERSION_MIXEDREVISIONS) return OPENMPT_VERSION_MIXEDREVISIONS != 0; #elif defined(OPENMPT_VERSION_SVNVERSION) std::string svnversion = OPENMPT_VERSION_SVNVERSION; if(svnversion.length() == 0) { return false; } if(svnversion.find(":") != std::string::npos) { return true; } if(svnversion.find("-") != std::string::npos) { return true; } if(svnversion.find("S") != std::string::npos) { return true; } if(svnversion.find("P") != std::string::npos) { return true; } return false; #else return false; #endif } static bool IsPackage() { #if defined(OPENMPT_VERSION_IS_PACKAGE) return OPENMPT_VERSION_IS_PACKAGE != 0; #else return false; #endif } static mpt::ustring GetSourceDate() { #if defined(OPENMPT_VERSION_DATE) return mpt::ToUnicode(mpt::CharsetASCII, OPENMPT_VERSION_DATE); #else return mpt::ustring(); #endif } } // namespace Source SourceInfo::SourceInfo() : m_Url(Source::GetUrl()) , m_Revision(Source::GetRevision()) , m_IsDirty(Source::IsDirty()) , m_HasMixedRevisions(Source::HasMixedRevisions()) , m_IsPackage(Source::IsPackage()) , m_Date(Source::GetSourceDate()) { } mpt::ustring SourceInfo::GetUrlWithRevision() const { if(m_Url.empty() || (m_Revision == 0)) { return mpt::ustring(); } return m_Url + UL_("@") + mpt::ufmt::val(m_Revision); } mpt::ustring SourceInfo::GetStateString() const { mpt::ustring retval; if(m_IsDirty) { retval += UL_("+dirty"); } if(m_HasMixedRevisions) { retval += UL_("+mixed"); } if(retval.empty()) { retval += UL_("clean"); } if(m_IsPackage) { retval += UL_("-pkg"); } return retval; } SourceInfo SourceInfo::Current() { return SourceInfo(); } namespace Build { bool IsReleasedBuild() { return !(Version::Current().IsTestVersion() || IsDebugBuild() || Source::IsDirty() || Source::HasMixedRevisions()); } bool IsDebugBuild() { #if defined(MPT_BUILD_DEBUG) || defined(DEBUG) || defined(_DEBUG) return true; #else return false; #endif } mpt::ustring GetBuildDateString() { mpt::ustring result; #ifdef MODPLUG_TRACKER #if defined(OPENMPT_BUILD_DATE) result = mpt::ToUnicode(mpt::CharsetASCII, OPENMPT_BUILD_DATE ); #else result = mpt::ToUnicode(mpt::CharsetASCII, __DATE__ " " __TIME__ ); #endif #else // !MODPLUG_TRACKER result = SourceInfo::Current().Date(); #endif // MODPLUG_TRACKER return result; } static mpt::ustring GetBuildFlagsString() { mpt::ustring retval; #ifdef MODPLUG_TRACKER if(Version::Current().IsTestVersion()) { retval += UL_(" TEST"); } #endif // MODPLUG_TRACKER if(IsDebugBuild()) { retval += UL_(" DEBUG"); } return retval; } mpt::ustring GetBuildFeaturesString() { mpt::ustring retval; #ifdef LIBOPENMPT_BUILD retval = UL_("") #if defined(MPT_CHARSET_WIN32) UL_(" +WINAPI") #endif #if defined(MPT_CHARSET_ICONV) UL_(" +ICONV") #endif #if defined(MPT_CHARSET_CODECVTUTF8) UL_(" +CODECVTUTF8") #endif #if defined(MPT_CHARSET_INTERNAL) UL_(" +INTERNALCHARSETS") #endif #if defined(MPT_WITH_ZLIB) UL_(" +ZLIB") #endif #if defined(MPT_WITH_MINIZ) UL_(" +MINIZ") #endif #if !defined(MPT_WITH_ZLIB) && !defined(MPT_WITH_MINIZ) UL_(" -INFLATE") #endif #if defined(MPT_WITH_MPG123) UL_(" +MPG123") #endif #if defined(MPT_WITH_MINIMP3) UL_(" +MINIMP3") #endif #if defined(MPT_WITH_MEDIAFOUNDATION) UL_(" +MF") #endif #if !defined(MPT_WITH_MPG123) && !defined(MPT_WITH_MINIMP3) && !defined(MPT_WITH_MEDIAFOUNDATION) UL_(" -MP3") #endif #if defined(MPT_WITH_OGG) && defined(MPT_WITH_VORBIS) && defined(MPT_WITH_VORBISFILE) UL_(" +VORBIS") #endif #if defined(MPT_WITH_STBVORBIS) UL_(" +STBVORBIS") #endif #if !(defined(MPT_WITH_OGG) && defined(MPT_WITH_VORBIS) && defined(MPT_WITH_VORBISFILE)) && !defined(MPT_WITH_STBVORBIS) UL_(" -VORBIS") #endif #if !defined(NO_PLUGINS) UL_(" +PLUGINS") #else UL_(" -PLUGINS") #endif #if !defined(NO_DMO) UL_(" +DMO") #endif ; #endif #ifdef MODPLUG_TRACKER MPT_CONSTANT_IF(mpt::arch_bits == 64) { if (true && (mpt::Windows::Version::GetMinimumKernelLevel() <= mpt::Windows::Version::WinXP64) && (mpt::Windows::Version::GetMinimumAPILevel() <= mpt::Windows::Version::WinXP64) ) { retval += UL_(" WIN64OLD"); } } else MPT_CONSTANT_IF(mpt::arch_bits == 32) { if (true && (mpt::Windows::Version::GetMinimumKernelLevel() <= mpt::Windows::Version::WinXP) && (mpt::Windows::Version::GetMinimumAPILevel() <= mpt::Windows::Version::WinXP) ) { retval += UL_(" WIN32OLD"); } } retval += UL_("") #if defined(UNICODE) UL_(" UNICODE") #else UL_(" ANSI") #endif #ifdef NO_VST UL_(" NO_VST") #endif #ifdef NO_DMO UL_(" NO_DMO") #endif #ifdef NO_PLUGINS UL_(" NO_PLUGINS") #endif #ifndef MPT_WITH_ASIO UL_(" NO_ASIO") #endif ; #endif return retval; } mpt::ustring GetBuildCompilerString() { mpt::ustring retval; #if MPT_COMPILER_GENERIC retval += U_("Generic C++11 Compiler"); #elif MPT_COMPILER_MSVC #if defined(_MSC_FULL_VER) && defined(_MSC_BUILD) && (_MSC_BUILD > 0) retval += mpt::format(U_("Microsoft Compiler %1.%2.%3.%4")) ( _MSC_FULL_VER / 10000000 , mpt::ufmt::dec0<2>((_MSC_FULL_VER / 100000) % 100) , mpt::ufmt::dec0<5>(_MSC_FULL_VER % 100000) , mpt::ufmt::dec0<2>(_MSC_BUILD) ); #elif defined(_MSC_FULL_VER) retval += mpt::format(U_("Microsoft Compiler %1.%2.%3")) ( _MSC_FULL_VER / 10000000 , mpt::ufmt::dec0<2>((_MSC_FULL_VER / 100000) % 100) , mpt::ufmt::dec0<5>(_MSC_FULL_VER % 100000) ); #else retval += mpt::format(U_("Microsoft Compiler %1.%2"))(MPT_COMPILER_MSVC_VERSION / 100, MPT_COMPILER_MSVC_VERSION % 100); #endif #elif MPT_COMPILER_GCC retval += mpt::format(U_("GNU Compiler Collection %1.%2.%3"))(MPT_COMPILER_GCC_VERSION / 10000, (MPT_COMPILER_GCC_VERSION / 100) % 100, MPT_COMPILER_GCC_VERSION % 100); #elif MPT_COMPILER_CLANG retval += mpt::format(U_("Clang %1.%2.%3"))(MPT_COMPILER_CLANG_VERSION / 10000, (MPT_COMPILER_CLANG_VERSION / 100) % 100, MPT_COMPILER_CLANG_VERSION % 100); #else retval += U_("unknown"); #endif return retval; } static mpt::ustring GetRevisionString() { mpt::ustring result; if(Source::GetRevision() == 0) { return result; } result = U_("-r") + mpt::ufmt::val(Source::GetRevision()); if(Source::HasMixedRevisions()) { result += UL_("!"); } if(Source::IsDirty()) { result += UL_("+"); } if(Source::IsPackage()) { result += UL_("p"); } return result; } mpt::ustring GetVersionString(FlagSet strings) { std::vector result; if(strings[StringVersion]) { result.push_back(mpt::ufmt::val(Version::Current())); } if(strings[StringRevision]) { if(!IsReleasedBuild()) { result.push_back(GetRevisionString()); } } if(strings[StringBitness]) { result.push_back(mpt::format(U_(" %1 bit"))(mpt::arch_bits)); } if(strings[StringSourceInfo]) { const SourceInfo sourceInfo = SourceInfo::Current(); if(!sourceInfo.GetUrlWithRevision().empty()) { result.push_back(mpt::format(U_(" %1"))(sourceInfo.GetUrlWithRevision())); } if(!sourceInfo.Date().empty()) { result.push_back(mpt::format(U_(" (%1)"))(sourceInfo.Date())); } if(!sourceInfo.GetStateString().empty()) { result.push_back(mpt::format(U_(" %1"))(sourceInfo.GetStateString())); } } if(strings[StringBuildFlags]) { if(!IsReleasedBuild()) { result.push_back(GetBuildFlagsString()); } } if(strings[StringBuildFeatures]) { result.push_back(GetBuildFeaturesString()); } return mpt::String::Trim(mpt::String::Combine(result, U_(""))); } mpt::ustring GetVersionStringPure() { FlagSet strings; strings |= Build::StringVersion; strings |= Build::StringRevision; #ifdef MODPLUG_TRACKER strings |= Build::StringBitness; #endif return GetVersionString(strings); } mpt::ustring GetVersionStringSimple() { FlagSet strings; strings |= Build::StringVersion; strings |= Build::StringRevision; strings |= Build::StringBuildFlags; return GetVersionString(strings); } mpt::ustring GetVersionStringExtended() { FlagSet strings; strings |= Build::StringVersion; strings |= Build::StringRevision; #ifdef MODPLUG_TRACKER strings |= Build::StringBitness; #endif #ifndef MODPLUG_TRACKER strings |= Build::StringSourceInfo; #endif strings |= Build::StringBuildFlags; #ifdef MODPLUG_TRACKER strings |= Build::StringBuildFeatures; #endif return GetVersionString(strings); } mpt::ustring GetURL(Build::Url key) { mpt::ustring result; switch(key) { case Url::Website: #ifdef LIBOPENMPT_BUILD result = U_("https://lib.openmpt.org/"); #else result = U_("https://openmpt.org/"); #endif break; case Url::Download: #ifdef MODPLUG_TRACKER result = IsReleasedBuild() ? U_("https://openmpt.org/download") : U_("https://builds.openmpt.org/builds/"); #else result = U_("https://lib.openmpt.org/libopenmpt/download/"); #endif break; case Url::Forum: result = U_("https://forum.openmpt.org/"); break; case Url::Bugtracker: result = U_("https://bugs.openmpt.org/"); break; case Url::Updates: result = U_("https://openmpt.org/download"); break; case Url::TopPicks: result = U_("https://openmpt.org/top_picks"); break; } return result; } mpt::ustring GetFullCreditsString() { return mpt::ToUnicode(mpt::CharsetUTF8, #ifdef MODPLUG_TRACKER "OpenMPT / ModPlug Tracker\n" #else "libopenmpt (based on OpenMPT / ModPlug Tracker)\n" #endif "\n" "Copyright \xC2\xA9 2004-2019 Contributors\n" "Copyright \xC2\xA9 1997-2003 Olivier Lapicque\n" "\n" "Contributors:\n" "Johannes Schultz (2008-2019)\n" "J\xC3\xB6rn Heusipp (2012-2019)\n" "Ahti Lepp\xC3\xA4nen (2005-2011)\n" "Robin Fernandes (2004-2007)\n" "Sergiy Pylypenko (2007)\n" "Eric Chavanon (2004-2005)\n" "Trevor Nunes (2004)\n" "Olivier Lapicque (1997-2003)\n" "\n" "Additional patch submitters:\n" "coda (https://coda.s3m.us/)\n" "kode54 (https://kode54.net/)\n" "Revenant (https://revenant1.net/)\n" "xaimus (http://xaimus.com/)\n" "\n" "Thanks to:\n" "\n" "Konstanty for the XMMS-ModPlug resampling implementation\n" "http://modplug-xmms.sourceforge.net/\n" "\n" #ifdef MODPLUG_TRACKER "Stephan M. Bernsee for pitch shifting source code\n" "http://www.dspdimension.com/\n" "\n" "Aleksey Vaneev of Voxengo for r8brain sample rate converter\n" "https://github.com/avaneev/r8brain-free-src\n" "\n" "Olli Parviainen for SoundTouch Library (time stretching)\n" "https://www.surina.net/soundtouch/\n" "\n" #endif #ifndef NO_VST "Hermann Seib for his example VST Host implementation\n" "http://www.hermannseib.com/english/vsthost.htm\n" "\n" "Benjamin \"BeRo\" Rosseaux for his independent VST header\n" "https://blog.rosseaux.net/\n" "\n" #endif "Storlek for all the IT compatibility hints and testcases\n" "as well as the IMF, MDL, OKT and ULT loaders\n" "http://schismtracker.org/\n" "\n" "Sergei \"x0r\" Kolzun for various hints on Scream Tracker 2 compatibility\n" "https://github.com/viiri/st2play\n" "\n" "Laurent Cl\xc3\xA9vy for unofficial MO3 documentation and decompression code\n" "https://github.com/lclevy/unmo3\n" "\n" "Ben \"GreaseMonkey\" Russell for IT sample compression code\n" "https://github.com/iamgreaser/it2everything/\n" "\n" "Antti S. Lankila for Amiga resampler implementation\n" "https://bel.fi/alankila/modguide/interpolate.txt\n" "\n" "Shayde / Reality Productions for Opal OPL3 emulator\n" "https://www.3eality.com/\n" "\n" #ifdef MPT_WITH_ZLIB "Jean-loup Gailly and Mark Adler for zlib\n" "https://zlib.net/\n" "\n" #endif #ifdef MPT_WITH_MINIZ "Rich Geldreich et al. for miniz\n" "https://github.com/richgel999/miniz\n" "\n" #endif #ifdef MPT_WITH_LHASA "Simon Howard for lhasa\n" "https://fragglet.github.io/lhasa/\n" "\n" #endif #ifdef MPT_WITH_UNRAR "Alexander L. Roshal for UnRAR\n" "https://rarlab.com/\n" "\n" #endif #ifdef MPT_WITH_PORTAUDIO "PortAudio contributors\n" "http://www.portaudio.com/\n" "\n" #endif #ifdef MPT_WITH_RTAUDIO "Gary P. Scavone, McGill University\n" "https://www.music.mcgill.ca/~gary/rtaudio/\n" "\n" #endif #ifdef MPT_WITH_FLAC "Josh Coalson / Xiph.Org Foundation for libFLAC\n" "https://xiph.org/flac/\n" "\n" #endif #if defined(MPT_WITH_MPG123) "The mpg123 project for libmpg123\n" "https://mpg123.de/\n" "\n" #endif #ifdef MPT_WITH_MINIMP3 "Lion (github.com/lieff) for minimp3\n" "https://github.com/lieff/minimp3/\n" "\n" #endif #ifdef MPT_WITH_STBVORBIS "Sean Barrett for stb_vorbis\n" "https://github.com/nothings/stb/\n" "\n" #endif #ifdef MPT_WITH_OGG "Xiph.Org Foundation for libogg\n" "https://xiph.org/ogg/\n" "\n" #endif #if defined(MPT_WITH_VORBIS) || defined(MPT_WITH_LIBVORBISFILE) "Xiph.Org Foundation for libvorbis\n" "https://xiph.org/vorbis/\n" "\n" #endif #if defined(MPT_WITH_OPUS) "Xiph.Org, Skype Limited, Octasic, Jean-Marc Valin, Timothy B. Terriberry,\n" "CSIRO, Gregory Maxwell, Mark Borgerding, Erik de Castro Lopo,\n" "Xiph.Org Foundation, Microsoft Corporation, Broadcom Corporation for libopus\n" "https://opus-codec.org/\n" "\n" #endif #if defined(MPT_WITH_OPUSFILE) "Xiph.Org Foundation and contributors for libopusfile\n" "https://opus-codec.org/\n" "\n" #endif #if defined(MPT_WITH_OPUSENC) "Xiph.Org Foundation, Jean-Marc Valin and contributors for libopusenc\n" "https://git.xiph.org/?p=libopusenc.git;a=summary\n" "\n" #endif #if defined(MPT_WITH_LAME) "The LAME project for LAME\n" "http://lame.sourceforge.net/\n" #endif #if defined(MPT_WITH_NLOHMANNJSON) "Niels Lohmann et al. for nlohmann-json\n" "https://github.com/nlohmann/json\n" "\n" #endif #ifdef MODPLUG_TRACKER "Lennart Poettering and David Henningsson for RealtimeKit\n" "http://git.0pointer.net/rtkit.git/\n" "\n" "Gary P. Scavone for RtMidi\n" "https://www.music.mcgill.ca/~gary/rtmidi/\n" "\n" "Alexander Uckun for decimal input field\n" "https://www.codeproject.com/Articles/21257/_\n" "\n" "\xc3\x9alfur Kolka for application icon, splash and about screen\n" "https://www.behance.net/ulfurkolka\n" "\n" "Nobuyuki for file icon\n" "https://twitter.com/nobuyukinyuu\n" "\n" #endif "Daniel Collin (emoon/TBL) for providing test infrastructure\n" "https://twitter.com/daniel_collin\n" "\n" "The people at ModPlug forums for crucial contribution\n" "in the form of ideas, testing and support;\n" "thanks particularly to:\n" "33, 8bitbubsy, Anboi, BooT-SectoR-ViruZ, Bvanoudtshoorn\n" "christofori, cubaxd, Diamond, Ganja, Georg, Goor00,\n" "Harbinger, jmkz, KrazyKatz, LPChip, Nofold, Rakib, Sam Zen\n" "Skaven, Skilletaudio, Snu, Squirrel Havoc, Teimoso, Waxhead\n" "\n" #ifndef NO_VST "VST PlugIn Technology by Steinberg Media Technologies GmbH\n" "\n" #endif #ifdef MPT_WITH_ASIO "ASIO Technology by Steinberg Media Technologies GmbH\n" "\n" #endif ); } mpt::ustring GetLicenseString() { return MPT_UTF8( "Copyright (c) 2004-2019, OpenMPT contributors" "\n" "Copyright (c) 1997-2003, Olivier Lapicque" "\n" "All rights reserved." "\n" "" "\n" "Redistribution and use in source and binary forms, with or without" "\n" "modification, are permitted provided that the following conditions are met:" "\n" " * Redistributions of source code must retain the above copyright" "\n" " notice, this list of conditions and the following disclaimer." "\n" " * Redistributions in binary form must reproduce the above copyright" "\n" " notice, this list of conditions and the following disclaimer in the" "\n" " documentation and/or other materials provided with the distribution." "\n" " * Neither the name of the OpenMPT project nor the" "\n" " names of its contributors may be used to endorse or promote products" "\n" " derived from this software without specific prior written permission." "\n" "" "\n" "THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY" "\n" "EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED" "\n" "WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE" "\n" "DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY" "\n" "DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES" "\n" "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;" "\n" "LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND" "\n" "ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT" "\n" "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS" "\n" "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." "\n" ); } } // namespace Build OPENMPT_NAMESPACE_END