summaryrefslogtreecommitdiff
path: root/src/user/lib/fwik/io/Node.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/user/lib/fwik/io/Node.cpp')
-rw-r--r--src/user/lib/fwik/io/Node.cpp87
1 files changed, 86 insertions, 1 deletions
diff --git a/src/user/lib/fwik/io/Node.cpp b/src/user/lib/fwik/io/Node.cpp
index 1d8b7f5..daccc18 100644
--- a/src/user/lib/fwik/io/Node.cpp
+++ b/src/user/lib/fwik/io/Node.cpp
@@ -6,7 +6,7 @@ Node::Node(FILE f) {
valid = (i == 0);
}
-Node::Node(char* filename, int mode) {
+Node::Node(const char* filename, int mode) {
fd = libc::open(filename, mode);
if (fd < 0) {
valid = false;
@@ -21,3 +21,88 @@ void Node::close() {
if (valid) libc::close(fd);
valid = false;
}
+
+////////
+
+static void simplify_path(char* p) {
+ char *it = p;
+ char *member = it;
+ while (*it != 0) {
+ if (*it == '/') {
+ if (it == member && it != p) {
+ // two consecutive slashes
+ char *i = member;
+ while (1) {
+ i[0] = i[1];
+ if (i[0] == 0) break;
+ i++;
+ }
+ } else {
+ *it = 0;
+ if (libc::strcmp(member, ".") == 0) {
+ char *i = member;
+ while (1) {
+ i[0] = i[2];
+ if (i[0] == 0) break;
+ i++;
+ }
+ } else if (libc::strcmp(member, "..") == 0) {
+ *it = '/';
+ char* start = member - 2;
+ char* next = member + 3;
+ while (start > p && *start != '/') {
+ start--;
+ }
+ start++;
+ it = member = start;
+ while (1) {
+ *start = *next;
+ if (*start == 0) break;
+ start++;
+ next++;
+ }
+ } else {
+ *it = '/';
+ it++;
+ member = it;
+ }
+ }
+ } else {
+ it++;
+ }
+ }
+}
+
+String path_cat(const String &a, const String &b, bool trailing_slash) {
+ int len, la = a.size(), lb = b.size();
+ if (b[0] == '/') {
+ len = lb + 2;
+ } else {
+ len = la + lb + 3;
+ }
+ char buf[len];
+ if (b[0] == '/') {
+ libc::memcpy(buf, b.c_str(), lb);
+ if (buf[lb-1] != '/') {
+ buf[lb++] = '/';
+ }
+ buf[lb] = 0;
+ } else {
+ libc::memcpy(buf, a.c_str(), la);
+ if (buf[la-1] != '/') {
+ buf[la++] = '/';
+ }
+ libc::memcpy(buf + la, b.c_str(), lb);
+ if (buf[la + lb - 1] != '/') {
+ buf[la + lb] = '/';
+ lb++;
+ }
+ buf[la + lb] = 0;
+ }
+ simplify_path(buf);
+ if (!trailing_slash) {
+ int l = libc::strlen(buf);
+ if (buf[l-1] == '/') buf[l-1] = 0;
+ }
+ return String(buf);
+}