forked from lix-project/lix
* Refactoring.
This commit is contained in:
parent
49bafe1faf
commit
7abf9911d9
|
@ -1,6 +1,6 @@
|
||||||
bin_PROGRAMS = nix-env
|
bin_PROGRAMS = nix-env
|
||||||
|
|
||||||
nix_env_SOURCES = main.cc help.txt
|
nix_env_SOURCES = main.cc names.cc names.hh help.txt
|
||||||
nix_env_LDADD = ../libmain/libmain.a ../libexpr/libexpr.a \
|
nix_env_LDADD = ../libmain/libmain.a ../libexpr/libexpr.a \
|
||||||
../libstore/libstore.a ../libutil/libutil.a \
|
../libstore/libstore.a ../libutil/libutil.a \
|
||||||
../boost/format/libformat.a -L../../externals/inst/lib -ldb_cxx \
|
../boost/format/libformat.a -L../../externals/inst/lib -ldb_cxx \
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
|
|
||||||
|
#include "names.hh"
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
#include "normalise.hh"
|
#include "normalise.hh"
|
||||||
#include "shared.hh"
|
#include "shared.hh"
|
||||||
|
@ -253,136 +254,6 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct DrvName
|
|
||||||
{
|
|
||||||
string fullName;
|
|
||||||
string name;
|
|
||||||
string version;
|
|
||||||
unsigned int hits;
|
|
||||||
|
|
||||||
/* Parse a derivation name. The `name' part of a derivation name
|
|
||||||
is everything up to but not including the first dash *not*
|
|
||||||
followed by a letter. The `version' part is the rest
|
|
||||||
(excluding the separating dash). E.g., `apache-httpd-2.0.48'
|
|
||||||
is parsed to (`apache-httpd', '2.0.48'). */
|
|
||||||
DrvName(const string & s) : hits(0)
|
|
||||||
{
|
|
||||||
name = fullName = s;
|
|
||||||
for (unsigned int i = 0; i < s.size(); ++i) {
|
|
||||||
/* !!! isalpha/isdigit are affected by the locale. */
|
|
||||||
if (s[i] == '-' && i + 1 < s.size() && !isalpha(s[i + 1])) {
|
|
||||||
name = string(s, 0, i);
|
|
||||||
version = string(s, i + 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool matches(DrvName & n)
|
|
||||||
{
|
|
||||||
if (name != "*" && name != n.name) return false;
|
|
||||||
if (version != "" && version != n.version) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
string nextComponent(string::const_iterator & p,
|
|
||||||
const string::const_iterator end)
|
|
||||||
{
|
|
||||||
/* Skip any dots and dashes (component separators). */
|
|
||||||
while (p != end && (*p == '.' || *p == '-')) ++p;
|
|
||||||
|
|
||||||
if (p == end) return "";
|
|
||||||
|
|
||||||
/* If the first character is a digit, consume the longest sequence
|
|
||||||
of digits. Otherwise, consume the longest sequence of
|
|
||||||
non-digit, non-separator characters. */
|
|
||||||
string s;
|
|
||||||
if (isdigit(*p))
|
|
||||||
while (p != end && isdigit(*p)) s += *p++;
|
|
||||||
else
|
|
||||||
while (p != end && (!isdigit(*p) && *p != '.' && *p != '-'))
|
|
||||||
s += *p++;
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
bool parseInt(const string & s, int & n)
|
|
||||||
{
|
|
||||||
istringstream st(s);
|
|
||||||
st >> n;
|
|
||||||
return !st.fail();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static bool componentsLT(const string & c1, const string & c2)
|
|
||||||
{
|
|
||||||
int n1, n2;
|
|
||||||
bool c1Num = parseInt(c1, n1), c2Num = parseInt(c2, n2);
|
|
||||||
|
|
||||||
if (c1Num && c2Num) return n1 < n2;
|
|
||||||
else if (c1 == "" && c2Num) return true;
|
|
||||||
else if (c1 == "pre" && c2 != "pre") return true;
|
|
||||||
else if (c2 == "pre") return false;
|
|
||||||
/* Assume that `2.3a' < `2.3.1'. */
|
|
||||||
else if (c2Num) return true;
|
|
||||||
else if (c1Num) return false;
|
|
||||||
else return c1 < c2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int compareVersions(const string & v1, const string & v2)
|
|
||||||
{
|
|
||||||
string::const_iterator p1 = v1.begin();
|
|
||||||
string::const_iterator p2 = v2.begin();
|
|
||||||
|
|
||||||
while (p1 != v1.end() || p2 != v2.end()) {
|
|
||||||
string c1 = nextComponent(p1, v1.end());
|
|
||||||
string c2 = nextComponent(p2, v2.end());
|
|
||||||
if (componentsLT(c1, c2)) return -1;
|
|
||||||
else if (componentsLT(c2, c1)) return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void testCompareVersions()
|
|
||||||
{
|
|
||||||
#define TEST(v1, v2, n) assert( \
|
|
||||||
compareVersions(v1, v2) == n && compareVersions(v2, v1) == -n)
|
|
||||||
TEST("1.0", "2.3", -1);
|
|
||||||
TEST("2.1", "2.3", -1);
|
|
||||||
TEST("2.3", "2.3", 0);
|
|
||||||
TEST("2.5", "2.3", 1);
|
|
||||||
TEST("3.1", "2.3", 1);
|
|
||||||
TEST("2.3.1", "2.3", 1);
|
|
||||||
TEST("2.3.1", "2.3a", 1);
|
|
||||||
TEST("2.3pre1", "2.3", -1);
|
|
||||||
TEST("2.3pre3", "2.3pre12", -1);
|
|
||||||
TEST("2.3a", "2.3c", -1);
|
|
||||||
TEST("2.3pre1", "2.3c", -1);
|
|
||||||
TEST("2.3pre1", "2.3q", -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
typedef list<DrvName> DrvNames;
|
|
||||||
|
|
||||||
|
|
||||||
static DrvNames drvNamesFromArgs(const Strings & opArgs)
|
|
||||||
{
|
|
||||||
DrvNames result;
|
|
||||||
for (Strings::const_iterator i = opArgs.begin();
|
|
||||||
i != opArgs.end(); ++i)
|
|
||||||
result.push_back(DrvName(*i));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void installDerivations(EvalState & state,
|
static void installDerivations(EvalState & state,
|
||||||
Path nePath, DrvNames & selectors, const Path & profile)
|
Path nePath, DrvNames & selectors, const Path & profile)
|
||||||
{
|
{
|
||||||
|
|
121
src/nix-env/names.cc
Normal file
121
src/nix-env/names.cc
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
#include "names.hh"
|
||||||
|
|
||||||
|
|
||||||
|
/* Parse a derivation name. The `name' part of a derivation name is
|
||||||
|
everything up to but not including the first dash *not* followed by
|
||||||
|
a letter. The `version' part is the rest (excluding the separating
|
||||||
|
dash). E.g., `apache-httpd-2.0.48' is parsed to (`apache-httpd',
|
||||||
|
'2.0.48'). */
|
||||||
|
DrvName::DrvName(const string & s) : hits(0)
|
||||||
|
{
|
||||||
|
name = fullName = s;
|
||||||
|
for (unsigned int i = 0; i < s.size(); ++i) {
|
||||||
|
/* !!! isalpha/isdigit are affected by the locale. */
|
||||||
|
if (s[i] == '-' && i + 1 < s.size() && !isalpha(s[i + 1])) {
|
||||||
|
name = string(s, 0, i);
|
||||||
|
version = string(s, i + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DrvName::matches(DrvName & n)
|
||||||
|
{
|
||||||
|
if (name != "*" && name != n.name) return false;
|
||||||
|
if (version != "" && version != n.version) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static string nextComponent(string::const_iterator & p,
|
||||||
|
const string::const_iterator end)
|
||||||
|
{
|
||||||
|
/* Skip any dots and dashes (component separators). */
|
||||||
|
while (p != end && (*p == '.' || *p == '-')) ++p;
|
||||||
|
|
||||||
|
if (p == end) return "";
|
||||||
|
|
||||||
|
/* If the first character is a digit, consume the longest sequence
|
||||||
|
of digits. Otherwise, consume the longest sequence of
|
||||||
|
non-digit, non-separator characters. */
|
||||||
|
string s;
|
||||||
|
if (isdigit(*p))
|
||||||
|
while (p != end && isdigit(*p)) s += *p++;
|
||||||
|
else
|
||||||
|
while (p != end && (!isdigit(*p) && *p != '.' && *p != '-'))
|
||||||
|
s += *p++;
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
static bool parseInt(const string & s, int & n)
|
||||||
|
{
|
||||||
|
istringstream st(s);
|
||||||
|
st >> n;
|
||||||
|
return !st.fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool componentsLT(const string & c1, const string & c2)
|
||||||
|
{
|
||||||
|
int n1, n2;
|
||||||
|
bool c1Num = parseInt(c1, n1), c2Num = parseInt(c2, n2);
|
||||||
|
|
||||||
|
if (c1Num && c2Num) return n1 < n2;
|
||||||
|
else if (c1 == "" && c2Num) return true;
|
||||||
|
else if (c1 == "pre" && c2 != "pre") return true;
|
||||||
|
else if (c2 == "pre") return false;
|
||||||
|
/* Assume that `2.3a' < `2.3.1'. */
|
||||||
|
else if (c2Num) return true;
|
||||||
|
else if (c1Num) return false;
|
||||||
|
else return c1 < c2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int compareVersions(const string & v1, const string & v2)
|
||||||
|
{
|
||||||
|
string::const_iterator p1 = v1.begin();
|
||||||
|
string::const_iterator p2 = v2.begin();
|
||||||
|
|
||||||
|
while (p1 != v1.end() || p2 != v2.end()) {
|
||||||
|
string c1 = nextComponent(p1, v1.end());
|
||||||
|
string c2 = nextComponent(p2, v2.end());
|
||||||
|
if (componentsLT(c1, c2)) return -1;
|
||||||
|
else if (componentsLT(c2, c1)) return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void testCompareVersions()
|
||||||
|
{
|
||||||
|
#define TEST(v1, v2, n) assert( \
|
||||||
|
compareVersions(v1, v2) == n && compareVersions(v2, v1) == -n)
|
||||||
|
TEST("1.0", "2.3", -1);
|
||||||
|
TEST("2.1", "2.3", -1);
|
||||||
|
TEST("2.3", "2.3", 0);
|
||||||
|
TEST("2.5", "2.3", 1);
|
||||||
|
TEST("3.1", "2.3", 1);
|
||||||
|
TEST("2.3.1", "2.3", 1);
|
||||||
|
TEST("2.3.1", "2.3a", 1);
|
||||||
|
TEST("2.3pre1", "2.3", -1);
|
||||||
|
TEST("2.3pre3", "2.3pre12", -1);
|
||||||
|
TEST("2.3a", "2.3c", -1);
|
||||||
|
TEST("2.3pre1", "2.3c", -1);
|
||||||
|
TEST("2.3pre1", "2.3q", -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DrvNames drvNamesFromArgs(const Strings & opArgs)
|
||||||
|
{
|
||||||
|
DrvNames result;
|
||||||
|
for (Strings::const_iterator i = opArgs.begin();
|
||||||
|
i != opArgs.end(); ++i)
|
||||||
|
result.push_back(DrvName(*i));
|
||||||
|
return result;
|
||||||
|
}
|
29
src/nix-env/names.hh
Normal file
29
src/nix-env/names.hh
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef __NAMES_H
|
||||||
|
#define __NAMES_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
#include "util.hh"
|
||||||
|
|
||||||
|
|
||||||
|
struct DrvName
|
||||||
|
{
|
||||||
|
string fullName;
|
||||||
|
string name;
|
||||||
|
string version;
|
||||||
|
unsigned int hits;
|
||||||
|
|
||||||
|
DrvName(const string & s);
|
||||||
|
bool matches(DrvName & n);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef list<DrvName> DrvNames;
|
||||||
|
|
||||||
|
|
||||||
|
int compareVersions(const string & v1, const string & v2);
|
||||||
|
DrvNames drvNamesFromArgs(const Strings & opArgs);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* !__NAMES_H */
|
Loading…
Reference in a new issue