about summary refs log tree commit diff
path: root/src/libutil
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/compression.cc1
-rw-r--r--src/libutil/hash.cc12
-rw-r--r--src/libutil/hash.hh17
-rw-r--r--src/libutil/types.hh60
-rw-r--r--src/libutil/util.cc11
-rw-r--r--src/libutil/util.hh20
6 files changed, 105 insertions, 16 deletions
diff --git a/src/libutil/compression.cc b/src/libutil/compression.cc
index 446fcb781564..fb4160669a29 100644
--- a/src/libutil/compression.cc
+++ b/src/libutil/compression.cc
@@ -2,6 +2,7 @@
 #include "types.hh"
 
 #include <lzma.h>
+#include <cstdio>
 
 namespace nix {
 
diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc
index 2d97c5e6b6a7..64739300302b 100644
--- a/src/libutil/hash.cc
+++ b/src/libutil/hash.cc
@@ -96,19 +96,13 @@ Hash parseHash(HashType ht, const string & s)
 }
 
 
-unsigned int hashLength32(const Hash & hash)
-{
-    return (hash.hashSize * 8 - 1) / 5 + 1;
-}
-
-
 // omitted: E O U T
 const string base32Chars = "0123456789abcdfghijklmnpqrsvwxyz";
 
 
 string printHash32(const Hash & hash)
 {
-    unsigned int len = hashLength32(hash);
+    size_t len = hash.base32Len();
 
     string s;
     s.reserve(len);
@@ -136,7 +130,7 @@ string printHash16or32(const Hash & hash)
 Hash parseHash32(HashType ht, const string & s)
 {
     Hash hash(ht);
-    unsigned int len = hashLength32(ht);
+    size_t len = hash.base32Len();
     assert(s.size() == len);
 
     for (unsigned int n = 0; n < len; ++n) {
@@ -163,7 +157,7 @@ Hash parseHash16or32(HashType ht, const string & s)
     if (s.size() == hash.hashSize * 2)
         /* hexadecimal representation */
         hash = parseHash(ht, s);
-    else if (s.size() == hashLength32(hash))
+    else if (s.size() == hash.base32Len())
         /* base-32 representation */
         hash = parseHash32(ht, s);
     else
diff --git a/src/libutil/hash.hh b/src/libutil/hash.hh
index 841b4cb2936c..bac2ebf2dcfa 100644
--- a/src/libutil/hash.hh
+++ b/src/libutil/hash.hh
@@ -7,7 +7,7 @@
 namespace nix {
 
 
-typedef enum { htUnknown, htMD5, htSHA1, htSHA256, htSHA512 } HashType;
+enum HashType : char { htUnknown, htMD5, htSHA1, htSHA256, htSHA512 };
 
 
 const int md5HashSize = 16;
@@ -40,6 +40,18 @@ struct Hash
 
     /* For sorting. */
     bool operator < (const Hash & h) const;
+
+    /* Returns the length of a base-16 representation of this hash. */
+    size_t base16Len() const
+    {
+        return hashSize * 2;
+    }
+
+    /* Returns the length of a base-32 representation of this hash. */
+    size_t base32Len() const
+    {
+        return (hashSize * 8 - 1) / 5 + 1;
+    }
 };
 
 
@@ -49,9 +61,6 @@ string printHash(const Hash & hash);
 /* Parse a hexadecimal representation of a hash code. */
 Hash parseHash(HashType ht, const string & s);
 
-/* Returns the length of a base-32 hash representation. */
-unsigned int hashLength32(const Hash & hash);
-
 /* Convert a hash to a base-32 representation. */
 string printHash32(const Hash & hash);
 
diff --git a/src/libutil/types.hh b/src/libutil/types.hh
index 160884ee1ad7..0eae46c5fe93 100644
--- a/src/libutil/types.hh
+++ b/src/libutil/types.hh
@@ -5,6 +5,7 @@
 #include <string>
 #include <list>
 #include <set>
+#include <memory>
 
 #include <boost/format.hpp>
 
@@ -96,4 +97,63 @@ typedef enum {
 } Verbosity;
 
 
+/* A simple non-nullable reference-counted pointer. Actually a wrapper
+   around std::shared_ptr that prevents non-null constructions. */
+template<typename T>
+class ref
+{
+private:
+
+    std::shared_ptr<T> p;
+
+public:
+
+    ref<T>(const ref<T> & r)
+        : p(r.p)
+    { }
+
+    explicit ref<T>(const std::shared_ptr<T> & p)
+        : p(p)
+    {
+        if (!p)
+            throw std::invalid_argument("null pointer cast to ref");
+    }
+
+    T* operator ->() const
+    {
+        return &*p;
+    }
+
+    T& operator *() const
+    {
+        return *p;
+    }
+
+    operator std::shared_ptr<T> ()
+    {
+        return p;
+    }
+
+    template<typename T2>
+    operator ref<T2> ()
+    {
+        return ref<T2>((std::shared_ptr<T2>) p);
+    }
+
+private:
+
+    template<typename T2, typename... Args>
+    friend ref<T2>
+    make_ref(Args&&... args);
+
+};
+
+template<typename T, typename... Args>
+inline ref<T>
+make_ref(Args&&... args)
+{
+    auto p = std::make_shared<T>(std::forward<Args>(args)...);
+    return ref<T>(p);
+}
+
 }
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 75032bf90d0b..def0525abc18 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -150,7 +150,7 @@ Path dirOf(const Path & path)
 string baseNameOf(const Path & path)
 {
     if (path.empty())
-        return string("");
+        return "";
 
     Path::size_type last = path.length() - 1;
     if (path[last] == '/' && last > 0)
@@ -161,6 +161,7 @@ string baseNameOf(const Path & path)
         pos = 0;
     else
         pos += 1;
+
     return string(path, pos, last - pos + 1);
 }
 
@@ -232,7 +233,13 @@ DirEntries readDirectory(const Path & path)
         checkInterrupt();
         string name = dirent->d_name;
         if (name == "." || name == "..") continue;
-        entries.emplace_back(name, dirent->d_ino, dirent->d_type);
+        entries.emplace_back(name, dirent->d_ino,
+#ifdef HAVE_STRUCT_DIRENT_D_TYPE
+            dirent->d_type
+#else
+            DT_UNKNOWN
+#endif
+        );
     }
     if (errno) throw SysError(format("reading directory ‘%1%’") % path);
 
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index 7ebfd7cee0e9..9eebb67fdf3a 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -8,9 +8,15 @@
 #include <unistd.h>
 #include <signal.h>
 #include <functional>
-
+#include <limits>
 #include <cstdio>
 
+#ifndef HAVE_STRUCT_DIRENT_D_TYPE
+#define DT_UNKNOWN 0
+#define DT_REG 1
+#define DT_LNK 2
+#define DT_DIR 3
+#endif
 
 namespace nix {
 
@@ -353,6 +359,8 @@ bool statusOk(int status);
 /* Parse a string into an integer. */
 template<class N> bool string2Int(const string & s, N & n)
 {
+    if (string(s, 0, 1) == "-" && !std::numeric_limits<N>::is_signed)
+        return false;
     std::istringstream str(s);
     str >> n;
     return str && str.get() == EOF;
@@ -413,4 +421,14 @@ string base64Encode(const string & s);
 string base64Decode(const string & s);
 
 
+/* Get a value for the specified key from an associate container, or a
+   default value if the key doesn't exist. */
+template <class T>
+string get(const T & map, const string & key, const string & def = "")
+{
+    auto i = map.find(key);
+    return i == map.end() ? def : i->second;
+}
+
+
 }