about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/nix-env/Makefile.am2
-rw-r--r--src/nix-env/main.cc131
-rw-r--r--src/nix-env/names.cc121
-rw-r--r--src/nix-env/names.hh29
4 files changed, 152 insertions, 131 deletions
diff --git a/src/nix-env/Makefile.am b/src/nix-env/Makefile.am
index 5353a7a6b8..bb418ae06c 100644
--- a/src/nix-env/Makefile.am
+++ b/src/nix-env/Makefile.am
@@ -1,6 +1,6 @@
 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 \
  ../libstore/libstore.a ../libutil/libutil.a \
  ../boost/format/libformat.a -L../../externals/inst/lib -ldb_cxx \
diff --git a/src/nix-env/main.cc b/src/nix-env/main.cc
index 00b6c7f8d3..0512366818 100644
--- a/src/nix-env/main.cc
+++ b/src/nix-env/main.cc
@@ -1,5 +1,6 @@
 #include <cerrno>
 
+#include "names.hh"
 #include "globals.hh"
 #include "normalise.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,
     Path nePath, DrvNames & selectors, const Path & profile)
 {
diff --git a/src/nix-env/names.cc b/src/nix-env/names.cc
new file mode 100644
index 0000000000..252b07b91c
--- /dev/null
+++ b/src/nix-env/names.cc
@@ -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;
+}
diff --git a/src/nix-env/names.hh b/src/nix-env/names.hh
new file mode 100644
index 0000000000..0fc9b57d07
--- /dev/null
+++ b/src/nix-env/names.hh
@@ -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 */