From d64c6034a2ebfe2c3f6e4a152f09da9f0b3e381b Mon Sep 17 00:00:00 2001 From: zetaPRIME Date: Sat, 21 Jan 2017 18:52:17 -0500 Subject: [PATCH] some path stuffs --- libstarlight/Makefile | 3 +- .../source/starlight/ConfigManager.cpp | 9 +-- .../source/starlight/util/FSHelper.cpp | 31 ++++++++++ libstarlight/source/starlight/util/FSHelper.h | 19 ++++++ libstarlight/source/starlight/util/Path.cpp | 60 +++++++++++++++++++ libstarlight/source/starlight/util/Path.h | 30 ++++++++++ libstarlight/todo.txt | 3 +- maketest.sh | 6 +- testbed/source/Core.cpp | 7 ++- 9 files changed, 159 insertions(+), 9 deletions(-) create mode 100644 libstarlight/source/starlight/util/FSHelper.cpp create mode 100644 libstarlight/source/starlight/util/FSHelper.h create mode 100644 libstarlight/source/starlight/util/Path.cpp create mode 100644 libstarlight/source/starlight/util/Path.h diff --git a/libstarlight/Makefile b/libstarlight/Makefile index d0df14a..fc1f204 100644 --- a/libstarlight/Makefile +++ b/libstarlight/Makefile @@ -29,7 +29,8 @@ INCLUDES := include #--------------------------------------------------------------------------------- ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft -CFLAGS := -g -Wall -Werror -O2 -mword-relocations \ +# why was -Werror here? +CFLAGS := -g -Wall -O2 -mword-relocations \ -ffunction-sections \ -fomit-frame-pointer \ $(ARCH) diff --git a/libstarlight/source/starlight/ConfigManager.cpp b/libstarlight/source/starlight/ConfigManager.cpp index 8e59dc3..5988740 100644 --- a/libstarlight/source/starlight/ConfigManager.cpp +++ b/libstarlight/source/starlight/ConfigManager.cpp @@ -10,12 +10,16 @@ #include "starlight/Application.h" +#include "starlight/util/FSHelper.h" + using std::string; using std::ifstream; using std::ofstream; using starlight::Application; +using starlight::util::FSHelper; + using starlight::Config; using starlight::ConfigManager; @@ -70,10 +74,7 @@ void Config::Save() { std::unordered_map> ConfigManager::cfg; void ConfigManager::Init() { - ensureDirectory("sdmc:/.starlight/"); - ensureDirectory("sdmc:/.starlight/config/"); - ensureDirectory("sdmc:/.starlight/config/app/"); - ensureDirectory("sdmc:/.starlight/config/app/" + Application::AppName()); + FSHelper::AssertDirPath("sdmc:/.starlight/config/app/" + Application::AppName()); } void ConfigManager::End() { diff --git a/libstarlight/source/starlight/util/FSHelper.cpp b/libstarlight/source/starlight/util/FSHelper.cpp new file mode 100644 index 0000000..27fe9d5 --- /dev/null +++ b/libstarlight/source/starlight/util/FSHelper.cpp @@ -0,0 +1,31 @@ +#include "FSHelper.h" + +#include + +#include +#include + +using std::string; +using std::stringstream; +using std::getline; + +using starlight::util::FSHelper; + +void FSHelper::AssertDirectory(const string& path) { + struct stat st; + if (stat(path.c_str(), &st) != 0) mkdir(path.c_str(), 0); +} + +void FSHelper::AssertDirPath(const string& path) { + struct stat st; + stringstream stm(path); + string ac(path.length() + 16, ' '); + string tk = ""; + ac.clear(); + + while (getline(stm, tk, '/')) { + ac.append(tk); ac.append("/"); + if (tk.back() == ':') continue; // no further processing on "sdmc:/" etc. + if (stat(ac.c_str(), &st) != 0) mkdir(ac.c_str(), 0); + } +} diff --git a/libstarlight/source/starlight/util/FSHelper.h b/libstarlight/source/starlight/util/FSHelper.h new file mode 100644 index 0000000..0e656c2 --- /dev/null +++ b/libstarlight/source/starlight/util/FSHelper.h @@ -0,0 +1,19 @@ +#pragma once +#include "starlight/_global.h" + +#include + +namespace starlight { + namespace util { + class FSHelper { + private: + // + + public: + FSHelper() = delete; + + static void AssertDirectory(const std::string& path); + static void AssertDirPath(const std::string& path); + }; + } +} diff --git a/libstarlight/source/starlight/util/Path.cpp b/libstarlight/source/starlight/util/Path.cpp new file mode 100644 index 0000000..a154dcb --- /dev/null +++ b/libstarlight/source/starlight/util/Path.cpp @@ -0,0 +1,60 @@ +#include "Path.h" + +#include + +#include +#include + +using std::string; +using std::stringstream; +using std::getline; + +using starlight::util::Path; + +Path::Path(const string& path, bool noverify) { + if (noverify) { strpath = path; return; } + size_t sls = path.find('/'); + if (sls == string::npos) strpath = "sdmc:/" + path; + else if (path.rfind(':', sls) != sls-1) strpath = "sdmc:/" + path; + else strpath = path; + if (strpath.back() == '/') strpath.pop_back(); // clip trailing slash +} + +Path::Path(const Path& path) { + strpath = path.strpath; // no need to check here! +} + +Path Path::Up(int levels) { + if (levels < 1) return *this; + size_t spos = IsDirPath() ? strpath.length() - 1 : string::npos; + for (int i = 0; i < levels; i++) { + size_t pos = strpath.rfind('/', spos-1); + if (pos == string::npos) break; + if (strpath[pos] == ':') break; // don't move past root + spos = pos; + } + return Path(strpath.substr(0, spos), true); +} + +Path Path::Combine(const string& token) { + string path(strpath); + stringstream st(token); + string tk; + while (getline(st, tk, '/')) { + if (tk == "") { } // ... + else if (tk == ".") { } // ignore + else if (tk == "..") { + size_t pos = path.rfind('/'); + if (pos != string::npos && path[pos-1] != ':') path.erase(pos); + } + else if (tk.back() == ':') { // root switch... + path.clear(); + path.append(tk); + } + else { + if (path.back() != '/') path.append("/"); + path.append(tk); + } + } + return Path(path, true); +} diff --git a/libstarlight/source/starlight/util/Path.h b/libstarlight/source/starlight/util/Path.h new file mode 100644 index 0000000..097f5f1 --- /dev/null +++ b/libstarlight/source/starlight/util/Path.h @@ -0,0 +1,30 @@ +#pragma once +#include "starlight/_global.h" + +#include +#include +#include + +namespace starlight { + namespace util { + class Path { + private: + std::string strpath; + + public: + // vars... + + Path(const std::string& path, bool noverify = false); + Path(const Path& path); + ~Path() = default; + + Path Up(int levels = 1); + Path Combine(const std::string& token); + + // semi-obsolete but whatever, it can stay for now + inline bool IsDirPath() const { return strpath.back() == '/'; } + + inline operator std::string () const { return strpath; } + }; + } +} diff --git a/libstarlight/todo.txt b/libstarlight/todo.txt index b3eb838..b11c13b 100644 --- a/libstarlight/todo.txt +++ b/libstarlight/todo.txt @@ -2,8 +2,7 @@ today's agenda { - app:/ prefix for local ("local") assets - cfg? + FSHelper, recursive directory assertion etc. } then { change Label to move the rect instead of resizing to accomodate drops (add an offset thing to Font) figure out how I want to do separate forms??? diff --git a/maketest.sh b/maketest.sh index aa826a8..ed1f89b 100644 --- a/maketest.sh +++ b/maketest.sh @@ -3,9 +3,13 @@ function abort { echo Make or send failed exit } +mode=send +if [ "$1" = "c" ]; then + mode=run +fi cd libstarlight make install || abort cd ../testbed make clean -make send || abort +make $mode || abort cd .. diff --git a/testbed/source/Core.cpp b/testbed/source/Core.cpp index bd57645..58a0f36 100644 --- a/testbed/source/Core.cpp +++ b/testbed/source/Core.cpp @@ -10,6 +10,8 @@ #include "starlight/GFXManager.h" #include "starlight/gfx/RenderCore.h" +#include "starlight/util/Path.h" + #include "starlight/ui/ParallaxLayer.h" #include "starlight/ui/ScrollField.h" #include "starlight/ui/Button.h" @@ -24,6 +26,8 @@ using starlight::ThemeManager; using starlight::GFXManager; using starlight::gfx::RenderCore; +using starlight::util::Path; + using starlight::Application; void Core::Init() { @@ -66,7 +70,8 @@ void Core::Init() { auto pipf = std::make_shared(VRect(0,0,400,240)); pipf->SetFont("default.16"); pipf->borderColor = Color::black; - pipf->SetText("I am the very model of something on the top screen. :D\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."); + //pipf->SetText("I am the very model of something on the top screen. :D\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."); + pipf->SetText(Path("sdmc:/banana/algorithm/").Combine("porcupine/kumquat/romfs:/annual/sdmc:/puffin/pie")); parallax->Add(pipf); clearColor = Color(0.0f, 0.5f, 0.5f);