2011-06-21 20:26:32 +10:00
|
|
|
/*
|
|
|
|
* This file is part of libgim.
|
|
|
|
*
|
|
|
|
* libgim is free software: you can redistribute it and/or modify it under the
|
|
|
|
* terms of the GNU General Public License as published by the Free Software
|
|
|
|
* Foundation, either version 3 of the License, or (at your option) any later
|
|
|
|
* version.
|
|
|
|
*
|
|
|
|
* libgim is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
|
|
* details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with libgim. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* Copyright 2010 Danny Robson <danny@blubinc.net>
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2011-05-23 17:18:52 +10:00
|
|
|
#include "version.hpp"
|
|
|
|
|
2011-10-07 21:58:16 +11:00
|
|
|
#include <cstring>
|
2011-05-23 17:18:52 +10:00
|
|
|
#include <stdexcept>
|
|
|
|
|
|
|
|
#include "debug.hpp"
|
|
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
2011-10-07 21:58:16 +11:00
|
|
|
using namespace util;
|
2011-05-23 17:18:52 +10:00
|
|
|
|
|
|
|
|
|
|
|
version::version (unsigned int _major,
|
|
|
|
unsigned int _minor):
|
|
|
|
m_values (2),
|
|
|
|
m_release (RELEASE_PRODUCTION) {
|
|
|
|
m_values[OFFSET_MAJOR] = _major;
|
|
|
|
m_values[OFFSET_MINOR] = _minor;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
version::version (const string& str):
|
|
|
|
m_values (NUM_OFFSETS, 0),
|
|
|
|
m_release (RELEASE_PRODUCTION) {
|
|
|
|
m_values.clear ();
|
|
|
|
parse (str);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-10-07 21:58:16 +11:00
|
|
|
version::version (const char *str):
|
|
|
|
m_values (NUM_OFFSETS, 0),
|
|
|
|
m_release (RELEASE_PRODUCTION) {
|
|
|
|
m_values.clear ();
|
|
|
|
parse (str);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-05-23 17:18:52 +10:00
|
|
|
static void
|
|
|
|
check_release (version::release_t r) {
|
|
|
|
switch (r) {
|
|
|
|
case version::RELEASE_ALPHA:
|
|
|
|
case version::RELEASE_BETA:
|
|
|
|
case version::RELEASE_GAMMA:
|
|
|
|
case version::RELEASE_PRODUCTION:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
panic ("invalid release_t value");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
version::sanity (void) const {
|
|
|
|
check_release (m_release);
|
|
|
|
check (!m_values.empty ());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
%%{
|
|
|
|
machine version;
|
|
|
|
|
|
|
|
action clear
|
|
|
|
{ current = 0; }
|
|
|
|
action increment
|
|
|
|
{ current *= 10;
|
|
|
|
current += (uintptr_t)(fc - (unsigned char)'0'); }
|
|
|
|
action finish
|
|
|
|
{ m_values.push_back (current); }
|
|
|
|
|
|
|
|
number = (digit+)
|
|
|
|
>clear
|
|
|
|
$increment
|
|
|
|
%finish;
|
|
|
|
|
|
|
|
dots = (number '.')* number;
|
|
|
|
|
|
|
|
type = ('beta'i | 'b'i) %{ m_release = RELEASE_BETA; }
|
|
|
|
| ('alpha'i | 'a'i) %{ m_release = RELEASE_ALPHA; }
|
|
|
|
| ('gamma'i | 'g'i) %{ m_release = RELEASE_GAMMA; };
|
|
|
|
|
|
|
|
version := (dots type?)
|
|
|
|
$!{ throw invalid_argument (str); };
|
|
|
|
|
|
|
|
write data;
|
|
|
|
}%%
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
version::parse (const string& str) {
|
|
|
|
unsigned int current;
|
|
|
|
|
2012-04-11 15:49:11 +10:00
|
|
|
int cs;
|
2011-05-23 17:18:52 +10:00
|
|
|
const char *p = str.data (),
|
|
|
|
*pe = str.data () + str.size (),
|
|
|
|
*eof = pe;
|
|
|
|
|
|
|
|
%%write init;
|
|
|
|
%%write exec;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-10-07 21:58:16 +11:00
|
|
|
void
|
|
|
|
version::parse (const char *str) {
|
|
|
|
unsigned int current;
|
|
|
|
|
2012-04-11 15:49:11 +10:00
|
|
|
int cs;
|
2011-10-07 21:58:16 +11:00
|
|
|
const char *p = str,
|
|
|
|
*pe = str + strlen (str),
|
|
|
|
*eof = pe;
|
|
|
|
|
|
|
|
%%write init;
|
|
|
|
%%write exec;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-05-23 17:18:52 +10:00
|
|
|
static string
|
|
|
|
release_string (const version::release_t r) {
|
|
|
|
switch (r) {
|
|
|
|
case (version::RELEASE_ALPHA): return "a";
|
|
|
|
case (version::RELEASE_BETA): return "b";
|
|
|
|
case (version::RELEASE_GAMMA): return "g";
|
|
|
|
case (version::RELEASE_PRODUCTION): return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
panic ("invalid release_t");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
version::operator > (const version &rhs) const {
|
|
|
|
unsigned int count = min (m_values.size (), rhs.m_values.size ());
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < count; ++i)
|
|
|
|
if (m_values[i] < rhs.m_values[i])
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (m_values.size () < rhs.m_values.size())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (m_release <= rhs.m_release)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-10-07 21:58:16 +11:00
|
|
|
namespace util {
|
|
|
|
ostream&
|
|
|
|
operator <<(ostream& os, const util::version& rhs) {
|
|
|
|
auto i = rhs.m_values.begin();
|
|
|
|
os << *i; ++i;
|
2011-05-23 17:18:52 +10:00
|
|
|
|
2011-10-07 21:58:16 +11:00
|
|
|
for (; i != rhs.m_values.end(); ++i)
|
|
|
|
os << '.' << *i;
|
2011-05-23 17:18:52 +10:00
|
|
|
|
2011-10-07 21:58:16 +11:00
|
|
|
os << release_string (rhs.m_release);
|
|
|
|
return os;
|
|
|
|
}
|
2011-05-23 17:18:52 +10:00
|
|
|
}
|
|
|
|
|