Commits

Anonymous committed 06b82e5

Added basic filesystem support.

Comments (0)

Files changed (17)

neglect/clib/src/platform.cpp

 
     extern const char *neglect_platform_get_home_folder()
     {
-        try {
-            return platform::get_home_folder().c_str();
-        }
-        catch (platform_exception &) {
-            return 0;
-        }
+        return platform::get_home_folder().c_str();
     }
 
     extern char *neglect_platform_get_settings_folder(const char *appname)
     {
-        try {
-            std::string rv = platform::get_settings_folder(std::string(appname));
-            char *buf = (char *)malloc(rv.size());
-            if (!buf)
-                return 0;
-            memcpy(buf, rv.c_str(), rv.size() + 1);
-            return buf;
-        }
-        catch (neglect::platform_exception &) {
+        string rv = platform::get_settings_folder(string(appname));
+        char *buf = (char *)malloc(rv.size());
+        if (!buf)
             return 0;
-        }
+        memcpy(buf, rv.c_str(), rv.size() + 1);
+        return buf;
     }
 }

neglect/cpplib/CMakeLists.txt

 	src/exception.cpp
     src/format.cpp
     src/platform.cpp
+    src/ntpath.cpp
 )
 set(HEADERS
 	include/neglect/boot.hpp
 	include/neglect/_vector3.hpp
 	include/neglect/_vector4.hpp
 	include/neglect/unittest.hpp
+	include/neglect/path.hpp
+	include/neglect/ntpath.hpp
 	
 	include/neglect/boot.h
 )

neglect/cpplib/include/neglect/boot.hpp

 
 // core includes
 #include <string>
+#include <sstream>
 #include <vector>
 #include <map>
 #include <iostream>
 namespace neglect {
     // the types we use.  This is typedefed in case anyone wants to
     // later add support for alternative string types etc.
-    using std::string;
-    using std::map;
+    typedef std::string string;
+    typedef std::stringstream stringstream;
 
     // if tr1 is unavailable, boost will add that for us.
     using std::tr1::shared_ptr;

neglect/cpplib/include/neglect/exception.hpp

         }
 
     private:
-        shared_array<char> m_message;
+        neglect::shared_array<char> m_message;
     };
 }
 

neglect/cpplib/include/neglect/format.hpp

        formatter does reset the flags so it can be used on other streams
        than the one used by format() internally as well. */
     void set_standard_formatting(std::ostream &stream,
-                                 const std::string &fmt);
+                                 const neglect::string &fmt);
 
     /* formats an object v with the flags fmt and writes it to the given
        stream.  This is used for format() internally */
     template <class T>
-    void format_object(const T &v, const std::string &fmt,
+    void format_object(const T &v, const neglect::string &fmt,
                        std::ostream &stream)
     {
         std::ios_base::fmtflags old_flags = stream.flags();
 
     /* formats an object v with the flags and returns it a string */
     template <class T>
-    std::string format_object(const T &v, const std::string &fmt)
+    neglect::string format_object(const T &v, const neglect::string &fmt)
     {
-        std::stringstream stream;
+        neglect::stringstream stream;
         format_object(v, fmt, stream);
         return stream.str();
     }
     /* raised for malformed format strings */
     class string_format_exception : public exception {
     public:
-        string_format_exception(const std::string &str) {}
+        string_format_exception(const neglect::string &str) {}
     };
 
     // the string formatting implementation
            the value and the corresponding index.  If it's below zero,
            it means that node holds static text. */
         struct node {
-            std::string value;
-            std::string fmtinfo;
+            neglect::string value;
+            neglect::string fmtinfo;
             int index;
 
             /* static string value */
-            node(const std::string value);
+            node(const neglect::string value);
 
             /* variable value. does parsing as well */
-            node(const std::string &fmt, size_t &idx, int &last_index);
+            node(const neglect::string &fmt, size_t &idx, int &last_index);
         };
 
         /* internal helper used to hold the format string and attached
             int curval;
 
             /* creates the tokenize_format from a format string */
-            tokenize_format(const std::string &fmt);
+            tokenize_format(const neglect::string &fmt);
 
             /* fills the next value in.  check the format() template
                functions below */
                 for (std::vector<node>::iterator iter = nodes.begin();
                      iter != nodes.end(); ++iter)
                     if (iter->index == curval) {
-                        std::stringstream ss;
+                        neglect::stringstream ss;
                         neglect::format_object(value, iter->fmtinfo, ss);
                         iter->value = ss.str();
                     }
             }
 
             /* return the value from str() */
-            std::string str() const;
+            neglect::string str() const;
         };
     }
 
     // the string formatting function.
 
     template <class T1>
-    std::string format(const std::string &str, const T1 &v1)
+    neglect::string format(const neglect::string &str, const T1 &v1)
     {
         return (_string_format_impl::tokenize_format(str)
                 % v1).str();
     }
 
     template <class T1, class T2>
-    std::string format(const std::string &str, const T1 &v1,
-                       const T2 &v2)
+    neglect::string format(const neglect::string &str, const T1 &v1, const T2 &v2)
     {
         return (_string_format_impl::tokenize_format(str)
                 % v1 % v2).str();
     }
 
     template <class T1, class T2, class T3>
-    std::string format(const std::string &str, const T1 &v1,
-                       const T2 &v2, const T3 &v3)
+    neglect::string format(const neglect::string &str, const T1 &v1,
+                           const T2 &v2, const T3 &v3)
     {
         return (_string_format_impl::tokenize_format(str)
                 % v1 % v2 % v3).str();
     }
 
     template <class T1, class T2, class T3, class T4>
-    std::string format(const std::string &str, const T1 &v1,
-                       const T2 &v2, const T3 &v3, const T4 &v4)
+    neglect::string format(const neglect::string &str, const T1 &v1,
+                           const T2 &v2, const T3 &v3, const T4 &v4)
     {
         return (_string_format_impl::tokenize_format(str)
                 % v1 % v2 % v3 % v4).str();
     }
 
     template <class T1, class T2, class T3, class T4, class T5>
-    std::string format(const std::string &str, const T1 &v1, const T2 &v2,
-                       const T3 &v3, const T4 &v4, const T5 &v5)
+    neglect::string format(const neglect::string &str, const T1 &v1, const T2 &v2,
+                           const T3 &v3, const T4 &v4, const T5 &v5)
     {
         return (_string_format_impl::tokenize_format(str)
                 % v1 % v2 % v3 % v4 % v5).str();
     }
 
     template <class T1, class T2, class T3, class T4, class T5, class T6>
-    std::string format(const std::string &str, const T1 &v1, const T2 &v2,
-                       const T3 &v3, const T4 &v4, const T5 &v5,
-                       const T6 &v6)
+    neglect::string format(const neglect::string &str, const T1 &v1,
+                           const T2 &v2, const T3 &v3, const T4 &v4,
+                           const T5 &v5, const T6 &v6)
     {
         return (_string_format_impl::tokenize_format(str)
                 % v1 % v2 % v3 % v4 % v5 % v6).str();
 
     template <class T1, class T2, class T3, class T4, class T5, class T6,
               class T7>
-    std::string format(const std::string &str, const T1 &v1, const T2 &v2,
-                       const T3 &v3, const T4 &v4, const T5 &v5,
-                       const T6 &v6, const T7 &v7)
+    neglect::string format(const neglect::string &str, const T1 &v1,
+                           const T2 &v2, const T3 &v3, const T4 &v4,
+                           const T5 &v5, const T6 &v6, const T7 &v7)
     {
         return (_string_format_impl::tokenize_format(str)
                 % v1 % v2 % v3 % v4 % v5 % v6 % v7).str();
 
     template <class T1, class T2, class T3, class T4, class T5, class T6,
               class T7, class T8>
-    std::string format(const std::string &str, const T1 &v1, const T2 &v2,
-                       const T3 &v3, const T4 &v4, const T5 &v5,
-                       const T6 &v6, const T7 &v7, const T8 &v8)
+    neglect::string format(const neglect::string &str, const T1 &v1,
+                           const T2 &v2, const T3 &v3, const T4 &v4,
+                           const T5 &v5, const T6 &v6, const T7 &v7,
+                           const T8 &v8)
     {
         return (_string_format_impl::tokenize_format(str)
                 % v1 % v2 % v3 % v4 % v5 % v6 % v7 % v8).str();
 
     template <class T1, class T2, class T3, class T4, class T5, class T6,
               class T7, class T8, class T9>
-    std::string format(const std::string &str, const T1 &v1, const T2 &v2,
-                       const T3 &v3, const T4 &v4, const T5 &v5,
-                       const T6 &v6, const T7 &v7, const T8 &v8,
-                       const T9 &v9)
+    neglect::string format(const neglect::string &str, const T1 &v1,
+                           const T2 &v2, const T3 &v3, const T4 &v4,
+                           const T5 &v5, const T6 &v6, const T7 &v7,
+                           const T8 &v8, const T9 &v9)
     {
         return (_string_format_impl::tokenize_format(str)
                 % v1 % v2 % v3 % v4 % v5 % v6 % v7 % v8 % v9).str();
 
     template <class T1, class T2, class T3, class T4, class T5, class T6,
               class T7, class T8, class T9, class T10>
-    std::string format(const std::string &str, const T1 &v1, const T2 &v2,
-                       const T3 &v3, const T4 &v4, const T5 &v5,
-                       const T6 &v6, const T7 &v7, const T8 &v8,
-                       const T9 &v9, const T10 &v10)
+    neglect::string format(const neglect::string &str, const T1 &v1,
+                           const T2 &v2, const T3 &v3, const T4 &v4,
+                           const T5 &v5, const T6 &v6, const T7 &v7,
+                           const T8 &v8, const T9 &v9, const T10 &v10)
     {
         return (_string_format_impl::tokenize_format(str)
                 % v1 % v2 % v3 % v4 % v5 % v6 % v7 % v8 % v9 % v10).str();
 
     template <class T1, class T2, class T3, class T4, class T5, class T6,
               class T7, class T8, class T9, class T10, class T11>
-    std::string format(const std::string &str, const T1 &v1, const T2 &v2,
-                       const T3 &v3, const T4 &v4, const T5 &v5,
-                       const T6 &v6, const T7 &v7, const T8 &v8,
-                       const T9 &v9, const T10 &v10, const T11 &v11)
+    neglect::string format(const neglect::string &str, const T1 &v1,
+                           const T2 &v2, const T3 &v3, const T4 &v4,
+                           const T5 &v5, const T6 &v6, const T7 &v7,
+                           const T8 &v8, const T9 &v9, const T10 &v10,
+                           const T11 &v11)
     {
         return (_string_format_impl::tokenize_format(str)
                 % v1 % v2 % v3 % v4 % v5 % v6 % v7 % v8 % v9 % v10
 
     template <class T1, class T2, class T3, class T4, class T5, class T6,
               class T7, class T8, class T9, class T10, class T11, class T12>
-    std::string format(const std::string &str, const T1 &v1, const T2 &v2,
-                       const T3 &v3, const T4 &v4, const T5 &v5,
-                       const T6 &v6, const T7 &v7, const T8 &v8,
-                       const T9 &v9, const T10 &v10, const T11 &v11,
-                       const T12 &v12)
+    neglect::string format(const neglect::string &str, const T1 &v1,
+                           const T2 &v2, const T3 &v3, const T4 &v4,
+                           const T5 &v5, const T6 &v6, const T7 &v7,
+                           const T8 &v8, const T9 &v9, const T10 &v10,
+                           const T11 &v11, const T12 &v12)
     {
         return (_string_format_impl::tokenize_format(str)
                 % v1 % v2 % v3 % v4 % v5 % v6 % v7 % v8 % v9 % v10

neglect/cpplib/include/neglect/ntpath.hpp

+#ifndef _INC_NEGLECT_NTPATH_HPP_
+#define _INC_NEGLECT_NTPATH_HPP_
+
+#include <neglect/boot.hpp>
+
+namespace neglect { namespace ntpath {
+
+    bool is_abs(const neglect::string &filename);
+    neglect::string join(const neglect::string &a, const neglect::string &b);
+    neglect::string dirname(const neglect::string &filename);
+    neglect::string basename(const neglect::string &filename);
+
+    // the following functions will only work if compiled for
+    // windows (obviously)
+#if NEGLECT_PLATFORM == NEGLECT_PLATFORM_WINDOWS
+    neglect::string abspath(const neglect::string &filename);
+    neglect::string getcwd();
+    bool exists(const neglect::string &filename);
+    bool is_file(const neglect::string &filename);
+    bool is_dir(const neglect::string &filename);
+    bool mkdir(const neglect::string &filename);
+    bool remove(const neglect::string &filename);
+    bool rename(const neglect::string &filename,
+                const neglect::string &new_name);
+#endif
+}}
+
+#endif

neglect/cpplib/include/neglect/path.hpp

+#ifndef _INC_NEGLECT_PATH_HPP_
+#define _INC_NEGLECT_PATH_HPP_
+
+#include <neglect/boot.hpp>
+
+#if NEGLECT_PLATFORM == NEGLECT_PLATFORM_WINDOWS
+#   include <neglect/ntpath.hpp>
+namespace neglect {
+    namespace path = neglect::ntpath;
+}
+#elif NEGLECT_PLATFORM == NEGLECT_PLATFORM_OSX
+#   include <neglect/posixpath.hpp>
+namespace neglect {
+    namespace path = neglect::posixpath;
+}
+#else
+#   error "unsupported platform in path.hpp"
+#endif
+
+#endif

neglect/cpplib/include/neglect/platform.hpp

 
 namespace neglect {
 
-    class platform_exception : public exception {
-    public:
-        platform_exception(const std::string &msg);
-    };
-
     namespace platform {
 
         /* name of the platform */
-        extern const std::string name;
+        extern const string name;
 
         /* returns the path to the users's home directory */
-        const std::string &get_home_folder();
+        const string &get_home_folder();
 
         /* returns the path to the users's settings directory */
-        std::string get_settings_folder(const std::string &appname);
+        string get_settings_folder(const string &appname);
     }
 }
 

neglect/cpplib/include/neglect/unittest.hpp

 #include <neglect/math.hpp>
 
 #include <fstream>
-#include <sstream>
 #include <stack>
 
 #include <boost/noncopyable.hpp>
 
     /* stores the location of an assertion/check */
     struct location {
-        std::string filename;
+        neglect::string filename;
         int lineno;
         const test_case *test;
 
         location() : filename(""), lineno(0), test(0) {}
-        location(const std::string &filename, int lineno, const test_case *test)
+        location(const neglect::string &filename, int lineno, const test_case *test)
             : filename(filename), lineno(lineno), test(test) {}
     };
 
     /* holds test error details */
     struct test_error {
         location loc;
-        std::string type;
-        std::string message;
-        std::string details;
+        neglect::string type;
+        neglect::string message;
+        neglect::string details;
     };
 
 
     class test_node : public boost::noncopyable {
     public:
-        test_node(const std::string &name, test_node *parent,
-                  const std::string &filename)
+        test_node(const neglect::string &name, test_node *parent,
+                  const neglect::string &filename)
             : m_name(name), m_parent(parent), m_filename(filename)
         {
             if (parent)
 
         virtual ~test_node() {};
 
-        const std::string &name() const
+        const neglect::string &name() const
         {
             return m_name;
         }
 
-        virtual std::string header() const
+        virtual neglect::string header() const
         {
             return name();
         }
 
-        const std::string full_name() const
+        const neglect::string full_name() const
         {
-            std::string out = name();
+            neglect::string out = name();
             test_node *node = m_parent;
             while (node) {
-                std::string name = node->name();
+                neglect::string name = node->name();
                 if (!name.empty())
                     out = name + "." + out;
                 node = node->parent();
             return out;
         }
 
-        const std::string &filename() const
+        const neglect::string &filename() const
         {
             return m_filename;
         }
         }
 
     private:
-        std::string m_name;
-        std::string m_filename;
+        neglect::string m_name;
+        neglect::string m_filename;
         test_node *m_parent;
     };
 
     class test_group : public test_node {
     public:
 
-        test_group(const std::string &name, test_node *parent,
-                   const std::string &filename)
+        test_group(const neglect::string &name, test_node *parent,
+                   const neglect::string &filename)
             : test_node(name, parent, filename)
         {
         }
 
-        std::string header() const
+        neglect::string header() const
         {
             if (this == &get_root_test_group())
                 return "Test Suite";
 
     class test_file : public test_group {
     public:
-        test_file(test_group *parent, const std::string &filename)
+        test_file(test_group *parent, const neglect::string &filename)
             : test_group("", parent, filename)
         {
         }
 
-        std::string header() const
+        neglect::string header() const
         {
             return "File [" + filename() + "]";
         }
 
     class test_case : public test_node {
     public:
-        test_case(const std::string &name, test_node *parent,
-                  const std::string &filename, int lineno)
+        test_case(const neglect::string &name, test_node *parent,
+                  const neglect::string &filename, int lineno)
             : test_node(name, parent, filename)
         {
             m_lineno = lineno;
                 m_stream << "  ";
         }
 
-        void write_line(const std::string &msg)
+        void write_line(const neglect::string &msg)
         {
             write_indentation();
             m_stream << msg << std::endl;
         }
 
         /* check and requirement functions */
-        bool check(bool expr, const std::string &expr_repr, const location &loc)
+        bool check(bool expr, const neglect::string &expr_repr, const location &loc)
         {
             if (expr)
                 return true;
 
-            std::stringstream details;
+            neglect::stringstream details;
             details << "expression: " << expr_repr;
 
             test_error err;
             if (a == b)
                 return true;
 
-            std::stringstream details;
+            neglect::stringstream details;
             details << "expression: " << a << " == " << b;
 
             test_error err;
             if (a != b)
                 return true;
 
-            std::stringstream details;
+            neglect::stringstream details;
             details << "expression: " << a << " != " << b;
 
             test_error err;
             if (almost_equal(a, b))
                 return true;
 
-            std::stringstream details;
+            neglect::stringstream details;
             details << "expression: " << a << " almost equal to " << b;
 
             test_error err;

neglect/cpplib/src/exception.cpp

     m_message.get()[0] = 0;
 }
 
-exception::exception(const string &msg)
+exception::exception(const neglect::string &msg)
 {
     size_t len = msg.size();
     m_message.reset(new char[len]);

neglect/cpplib/src/format.cpp

 #include <neglect/format.hpp>
 
-#include <sstream>
-
 namespace {
     bool read_int(const char *&ptr, int &out)
     {
     }
 }
 
-void neglect::set_standard_formatting(std::ostream &stream, const std::string &fmt)
+void neglect::set_standard_formatting(std::ostream &stream, const neglect::string &fmt)
 {
     const char *ptr = fmt.c_str();
     if (*ptr == '<') {
     stream << std::boolalpha;
 }
 
-neglect::_string_format_impl::node::node(const std::string value)
+neglect::_string_format_impl::node::node(const string value)
 : value(value), index(-1)
 {
 }
 
 neglect::_string_format_impl::node::node(
-    const std::string &fmt, size_t &idx, int &last_index)
+    const string &fmt, size_t &idx, int &last_index)
 : value("")
 {
     int c;
         c = fmt[idx++];
         if (!idx_set && (c == ':' || c == '}')) {
             if (idx != start + 1) {
-                std::stringstream ss(fmt.substr(start,
-                                                idx - start - 1));
+                stringstream ss(fmt.substr(start,
+                                           idx - start - 1));
                 ss >> index;
                 if (ss.fail() || index < 0 ||
                     (ss >> std::ws, !ss.eof()))
 }
 
 neglect::_string_format_impl::tokenize_format::tokenize_format(
-    const std::string &fmt)
+    const string &fmt)
 {
     curval = 0;
     int c;
     int last_index = -1;
-    std::stringstream ss;
+    stringstream ss;
 
     for (size_t i = 0; i < fmt.size(); )
         switch (c = fmt[i++]) {
     nodes.push_back(node(ss.str()));
 }
 
-std::string neglect::_string_format_impl::tokenize_format::str() const
+neglect::string neglect::_string_format_impl::tokenize_format::str() const
 {
-    std::stringstream out;
+    neglect::stringstream out;
     for (std::vector<node>::const_iterator iter = nodes.begin();
          iter != nodes.end(); ++iter)
         out << iter->value;

neglect/cpplib/src/ntpath.cpp

+#include <neglect/ntpath.hpp>
+
+#if NEGLECT_PLATFORM == NEGLECT_PLATFORM_WINDOWS
+#   include <direct.h>
+#   include <sys/types.h>
+#   include <sys/stat.h>
+#   include <stdio.h>
+#   include <errno.h>
+#endif
+
+using namespace neglect;
+
+namespace {
+    inline bool is_slash(char c)
+    {
+        return c == '/' || c == '\\';
+    }
+}
+
+bool ntpath::is_abs(const neglect::string &filename)
+{
+    if (filename.empty())
+        return false;
+    return (is_slash(filename[0]) ||
+            (filename.size() > 2 && filename[1] == ':' &&
+             is_slash(filename[2])));
+}
+
+neglect::string ntpath::join(const neglect::string &a, const neglect::string &b)
+{
+    if (a.empty())
+        return b;
+
+    if (is_abs(b)) {
+        if ((a.size() < 2 && a[1] != ':') ||
+            (b.size() >= 2 && b[1] == ':'))
+            return b;
+        if (a.size() > 3 || (a.size() == 3 && !is_slash(a[a.size() - 1])))
+            return b;
+    }
+
+    char a_last = a[a.size() - 1];
+    char b_first = b.empty() ? 0 : b[0];
+
+    if (is_slash(a_last))
+        return a + (is_slash(b_first) ? b.substr(1) : b);
+    else if (a_last == ':')
+        return a + b;
+    else if (!b.empty())
+        return a + (is_slash(b_first) ? b : "\\" + b);
+    return a;
+}
+
+neglect::string ntpath::dirname(const neglect::string &filename)
+{
+    size_t idx = filename.find_last_of("/\\");
+    if (idx == neglect::string::npos)
+        return filename;
+    neglect::string rv = filename.substr(0, idx);
+    while (!rv.empty() && is_slash(rv[rv.size() - 1]))
+        rv.resize(rv.size() - 1);
+    if (rv.size() == 2 && rv[1] == ':')
+        rv += "\\";
+    return rv;
+}
+
+neglect::string ntpath::basename(const neglect::string &filename)
+{
+    size_t idx = filename.find_last_of("/\\");
+    if (idx != neglect::string::npos)
+        return filename.substr(idx + 1);
+    if (filename.size() >= 2 && filename[1] == ':')
+        return filename.substr(2);
+    return filename;
+}
+
+
+#if NEGLECT_PLATFORM == NEGLECT_PLATFORM_WINDOWS
+
+neglect::string ntpath::getcwd()
+{
+    char *buffer = _getcwd(0, 0);
+    if (!buffer)
+        return "";
+    neglect::string rv(buffer);
+    free(buffer);
+    return rv;
+}
+
+neglect::string ntpath::abspath(const neglect::string &filename)
+{
+    if (!ntpath::is_abs(filename))
+        return ntpath::join(ntpath::getcwd(), filename);
+    return filename;
+}
+
+bool ntpath::exists(const neglect::string &filename)
+{
+    struct _stat buf;
+    neglect::string path = ntpath::abspath(filename);
+    if (_stat(path.c_str(), &buf) != 0)
+        if (errno == ENOENT)
+            return false;
+    return true;
+}
+
+bool ntpath::is_file(const neglect::string &filename)
+{
+    struct _stat buf;
+    neglect::string path = ntpath::abspath(filename);
+    int rv = _stat(path.c_str(), &buf);
+    if (rv != 0)
+        return false;
+    return !!(buf.st_mode & _S_IFREG);
+}
+
+bool ntpath::is_dir(const neglect::string &filename)
+{
+    struct _stat buf;
+    neglect::string path = ntpath::abspath(filename);
+    int rv = _stat(path.c_str(), &buf);
+    if (rv != 0)
+        return false;
+    return !!(buf.st_mode & _S_IFDIR);
+}
+
+bool ntpath::mkdir(const neglect::string &filename)
+{
+    neglect::string path = ntpath::abspath(filename);
+    if (CreateDirectoryA(path.c_str(), 0))
+        return true;
+    return GetLastError() == ERROR_ALREADY_EXISTS;
+}
+
+bool ntpath::remove(const neglect::string &filename)
+{
+    neglect::string path = ntpath::abspath(filename);
+    if (!ntpath::exists(path))
+        return true;
+    if (ntpath::is_dir(path))
+        return !!RemoveDirectoryA(path.c_str());
+    return !!DeleteFileA(path.c_str());
+}
+
+bool ntpath::rename(const neglect::string &filename,
+                    const neglect::string &new_name)
+{
+    neglect::string a = ntpath::abspath(filename);
+    neglect::string b = ntpath::abspath(new_name);
+    return !!MoveFileExA(a.c_str(), b.c_str(),
+                         MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING);
+}
+
+#endif

neglect/cpplib/src/platform.cpp

 
 using namespace neglect;
 
-const std::string platform::name =
+const neglect::string platform::name =
 #if NEGLECT_PLATFORM == NEGLECT_PLATFORM_WINDOWS
     "Windows"
 #elif NEGLECT_PLATFORM == NEGLECT_PLATFORM_OSX
 
 namespace {
     bool _home_folder_cached = false;
-    std::string _home_folder;
+    neglect::string _home_folder;
 }
 
-
-platform_exception::platform_exception(const std::string &msg)
-: exception(msg)
-{
-}
-
-const std::string &platform::get_home_folder()
+const neglect::string &platform::get_home_folder()
 {
     if (_home_folder_cached)
         return _home_folder;
     SHGetFolderLocation(0, CSIDL_PROFILE, 0, 0, &pidl);
     SHGetPathFromIDList(pidl, path);
     CoTaskMemFree(pidl);
-    _home_folder = std::string(path);
+    _home_folder = neglect::string(path);
 #elif NEGLECT_PLATFORM == NEGLECT_PLATFORM_OSX
     const char *env_home = getenv("HOME");
     if (env_home)
-        _home_folder = std::string(env_home);
+        _home_folder = neglect::string(env_home);
     else {
         struct passwd *pw = getpwuid(getuid());
         endpwent();
         if (!pw)
             throw platform_exception("Unable to locate home folder");
-        _home_folder = std::string(pw->pw_dir);
+        _home_folder = neglect::string(pw->pw_dir);
         if (!_home_folder.empty() and dir[dir.size() - 1] == '/')
             _home_folder.resize(_home_folder.size() - 1);
     }
     return _home_folder;
 }
 
-std::string platform::get_settings_folder(const std::string &appname)
+neglect::string platform::get_settings_folder(const neglect::string &appname)
 {
 #if NEGLECT_PLATFORM == NEGLECT_PLATFORM_WINDOWS
     char path[MAX_PATH], *pathptr;
     SHGetFolderLocation(0, CSIDL_APPDATA, 0, 0, &pidl);
     SHGetPathFromIDList(pidl, path);
     CoTaskMemFree(pidl);
-    return std::string(path) + "\\" + appname;
+    return neglect::string(path) + "\\" + appname;
 #elif NEGLECT_PLATFORM == NEGLECT_PLATFORM_OSX
     return platform::get_home_folder() + "/Library/Application Support/" + appname
 #else

neglect/tests/CMakeLists.txt

     src/main.cpp
     src/test_vectors.cpp
     src/test_format.cpp
+    src/test_path.cpp
 )
 set(HEADERS
 )

neglect/tests/src/test_format.cpp

 
     NUT_TESTCASE(multiple_arguments)
     {
-        NUT_CHECK_EQUAL(format("Hello {}! The weather is {}.", "World", "good"),
-                        "Hello World! The weather is good.");
+        NUT_CHECK_EQUAL(format("Hello {}! The weather is {}.", "World", "good"),
+                        "Hello World! The weather is good.");
         NUT_CHECK_EQUAL(format("Hello {0}! The weather is {1}.", "World", "good"),
                         "Hello World! The weather is good.");
         NUT_CHECK_EQUAL(format("Hello {1}! The weather is {0}.", "good", "World"),
 
     NUT_TESTCASE(escaping)
     {
-        NUT_CHECK_EQUAL(format("\\begin\\{verbatim}{}", 0), "\\begin{verbatim}0");
+        NUT_CHECK_EQUAL(format("\\begin\\{verbatim\\}{}", 0), "\\begin{verbatim}0");
     }
 
     NUT_TESTCASE(number_formatting)
     {
         NUT_CHECK_EQUAL(format("Value: {:05}", 23), "Value: 00023");
-        NUT_CHECK_EQUAL(format("{: 5}", 42), "   42");
+        NUT_CHECK_EQUAL(format("{: 5}", 42), "   42");
         NUT_CHECK_EQUAL(format("{:.2}", 42.1337), "42.13");
     }
 }

neglect/tests/src/test_path.cpp

+#include <neglect/unittest.hpp>
+#include <neglect/path.hpp>
+#include <neglect/ntpath.hpp>
+
+#include <fstream>
+
+
+using namespace neglect;
+
+NUT_TESTGROUP(ntpath) {
+
+    NUT_TESTCASE(join)
+    {
+        NUT_CHECK_EQUAL(ntpath::join("a", "b"), "a\\b");
+        NUT_CHECK_EQUAL(ntpath::join("a", "\\b"), "\\b");
+        NUT_CHECK_EQUAL(ntpath::join("a", "/b"), "/b");
+        NUT_CHECK_EQUAL(ntpath::join("c:", "a"), "c:a");
+        NUT_CHECK_EQUAL(ntpath::join("c:\\", "a"), "c:\\a");
+        NUT_CHECK_EQUAL(ntpath::join("c:\\", "\\a"), "c:\\a");
+        NUT_CHECK_EQUAL(ntpath::join("c:\\", "d:\\a"), "d:\\a");
+        NUT_CHECK_EQUAL(ntpath::join("foo/bar", "baz"), "foo/bar\\baz");
+    }
+
+    NUT_TESTCASE(is_abs)
+    {
+        NUT_CHECK(ntpath::is_abs("\\test"));
+        NUT_CHECK(ntpath::is_abs("/test"));
+        NUT_CHECK(ntpath::is_abs("c:\\test"));
+        NUT_CHECK(ntpath::is_abs("c:/test"));
+        NUT_CHECK(!ntpath::is_abs("test"));
+        NUT_CHECK(!ntpath::is_abs("./test"));
+        NUT_CHECK(!ntpath::is_abs("../test"));
+        NUT_CHECK(!ntpath::is_abs("c:test"));
+    }
+
+    NUT_TESTCASE(dirname)
+    {
+        NUT_CHECK_EQUAL(ntpath::dirname("C:\\testing\\bar.txt"), "C:\\testing");
+        NUT_CHECK_EQUAL(ntpath::dirname("C:\\\\broken.txt"), "C:\\");
+        NUT_CHECK_EQUAL(ntpath::dirname("C:\\more\\\\/broken.txt"), "C:\\more");
+        NUT_CHECK_EQUAL(ntpath::dirname("C:/more/broken.txt"), "C:/more");
+    }
+
+    NUT_TESTCASE(basename)
+    {
+        NUT_CHECK_EQUAL(ntpath::basename("C:\\testing\\bar.txt"), "bar.txt");
+        NUT_CHECK_EQUAL(ntpath::basename("C:\\\\broken.txt"), "broken.txt");
+        NUT_CHECK_EQUAL(ntpath::basename("C:\\more\\\\broken.txt"), "broken.txt");
+        NUT_CHECK_EQUAL(ntpath::basename("C:/more/broken.txt"), "broken.txt");
+    }
+}
+
+
+NUT_TESTGROUP(native_path) {
+
+    NUT_TESTCASE(select_correct)
+    {
+#if NEGLECT_PLATFORM == NEGLECT_PLATFORM_WINDOWS
+        NUT_CHECK_EQUAL(&neglect::path::mkdir, &neglect::ntpath::mkdir);
+#elif NEGLECT_PLATFORM == NEGLECT_PLATFORM_OSX
+        NUT_CHECK_EQUAL(&neglect::path::mkdir, &neglect::posixpath::mkdir);
+#else
+#error  "unsupported platform in test_path.cpp for native_path tests"
+#endif
+    }
+
+    NUT_TESTCASE(directory)
+    {
+        neglect::string folder = "mkdir_test_folder";
+        neglect::string folder2 = folder + "2";
+        NUT_CHECK(!path::exists(folder));
+        NUT_CHECK(path::mkdir(folder));
+        NUT_CHECK(path::is_dir(folder));
+        NUT_CHECK(path::rename(folder, folder2));
+        NUT_CHECK(!path::is_dir(folder));
+        NUT_CHECK(path::is_dir(folder2));
+        NUT_CHECK(path::remove(folder2));
+        NUT_CHECK(!path::is_dir(folder2));
+    }
+
+    NUT_TESTCASE(abspath)
+    {
+        neglect::string path = "test.txt";
+        NUT_CHECK_EQUAL(path::abspath(path), path::join(path::getcwd(), path));
+    }
+
+    NUT_TESTCASE(file)
+    {
+        neglect::string filename = "filetest_test_file.txt";
+        neglect::string filename2 = filename + "2";
+        NUT_CHECK(!path::is_file(filename));
+        NUT_CHECK(!path::is_file(filename));
+        {
+            std::fstream test(filename.c_str(), std::fstream::out);
+            test << "Hello World" << std::endl;
+        }
+        NUT_CHECK(path::exists(filename));
+        NUT_CHECK(path::is_file(filename));
+        NUT_CHECK(path::rename(filename, filename2));
+        NUT_CHECK(!path::is_file(filename));
+        NUT_CHECK(path::is_file(filename2));
+        NUT_CHECK(path::remove(filename2));
+        NUT_CHECK(!path::is_file(filename2));
+        NUT_CHECK(!path::is_file(filename2));
+    }
+}

neglect/tests/src/test_vectors.cpp

 
 #include <boost/type_traits.hpp>
 
-#include <sstream>
-
 
 #define HAS_EXPECTED_TYPE(the_type, expected) \
     boost::is_same<the_type::value_type, expected>::value
 
     NUT_TESTCASE(stream_support)
     {
-        std::stringstream ss;
+        stringstream ss;
         vector<float, 2> v1;
         vector<float, 2> v2(1.0f, 2.5f);
 
 
         NUT_CHECK_EQUAL(ss.str(), "(0, 0) (1, 2.5)");
 
-        std::stringstream in("(1, 2)  3 , 4 2 5");
+        stringstream in("(1, 2)  3 , 4 2 5");
         NUT_CHECK_EQUAL((in >> v1, v1), vec2(1.0f, 2.0f));
         NUT_CHECK_EQUAL((in >> v1, v1), vec2(3.0f, 4.0f));
         NUT_CHECK_EQUAL((in >> v1, v1), vec2(2.0f, 5.0f));
 
     NUT_TESTCASE(stream_support)
     {
-        std::stringstream ss;
+        stringstream ss;
         vector<float, 3> v1;
         vector<float, 3> v2(1.0f, 2.5f, 1.5f);
 
 
         NUT_CHECK_EQUAL(ss.str(), "(0, 0, 0) (1, 2.5, 1.5)");
 
-        std::stringstream in("(1, 2, 3)  3 , 4, 5   2 5 1.5");
+        stringstream in("(1, 2, 3)  3 , 4, 5   2 5 1.5");
         NUT_CHECK_EQUAL((in >> v1, v1), vec3(1.0f, 2.0f, 3.0f));
         NUT_CHECK_EQUAL((in >> v1, v1), vec3(3.0f, 4.0f, 5.0f));
         NUT_CHECK_EQUAL((in >> v1, v1), vec3(2.0f, 5.0f, 1.5f));