From 8e07c1db6ba4bedd0f8fe537a6fb0ca80e5d25f4 Mon Sep 17 00:00:00 2001 From: Alex AUVOLAT Date: Sat, 19 May 2012 15:56:25 +0200 Subject: Better sprintf, vsprintf, String::sprintf, etc. --- src/user/lib/fwik/String.cpp | 36 ++++++++++---- src/user/lib/fwik/include/IO/IOStream.h | 10 ++-- src/user/lib/fwik/include/IO/Node.h | 6 ++- src/user/lib/fwik/include/IO/Term.h | 8 +-- src/user/lib/fwik/include/String.h | 24 ++++----- src/user/lib/fwik/io/IOStream.cpp | 4 +- src/user/lib/fwik/io/Node.cpp | 87 ++++++++++++++++++++++++++++++++- src/user/lib/fwik/io/Term.cpp | 8 +-- 8 files changed, 148 insertions(+), 35 deletions(-) (limited to 'src/user/lib/fwik') diff --git a/src/user/lib/fwik/String.cpp b/src/user/lib/fwik/String.cpp index 982ce4e..e3455e3 100644 --- a/src/user/lib/fwik/String.cpp +++ b/src/user/lib/fwik/String.cpp @@ -16,7 +16,7 @@ String::String(const String &other) { } } -String::String(char* from) { +String::String(const char* from) { len = (from == 0 ? 0 : libc::strlen(from)); if (len == 0) { ptr = 0; @@ -26,7 +26,7 @@ String::String(char* from) { } } -String::String(char* from, int l) { +String::String(const char* from, int l) { len = l; if (len < 0) len = 0; if (len == 0) { @@ -64,7 +64,7 @@ void String::operator=(const String &other) { } } -void String::operator=(char* from) { +void String::operator=(const char* from) { if (ptr != 0) free(ptr); len = (from == 0 ? 0 : libc::strlen(from)); if (len == 0) { @@ -75,25 +75,25 @@ void String::operator=(char* from) { } } -char* String::c_str() { +const char* String::c_str() const { if (ptr == 0) return ""; return ptr; } -bool String::operator==(const String& other) { +bool String::operator==(const String& other) const { if (len != other.len) return false; for (int i = 0; i < len; i++) if (ptr[i] != other.ptr[i]) return false; return true; } -bool String::operator==(char* other) { +bool String::operator==(const char* other) const { if (other == 0) return (len == 0); if (len != libc::strlen(other)) return false; for (int i = 0; i < len; i++) if (ptr[i] != other[i]) return false; return true; } -bool String::operator<(const String& other) { +bool String::operator<(const String& other) const { for (int i = 0; i < len && i < other.len; i++) { if (ptr[i] > other.ptr[i]) return false; if (ptr[i] < other.ptr[i]) return true; @@ -109,12 +109,17 @@ char &String::operator[](int pos) { return crap; } -String String::substr(int start, int count) { +char String::operator[](int pos) const { + if (pos >= 0 && pos < len) return ptr[pos]; + return 0; +} + +String String::substr(int start, int count) const { if (start + count > len) count = len - start; return String(ptr + start, count); } -String String::operator+(const String& other) { +String String::operator+(const String& other) const { String ret(' ', len + other.len); libc::memcpy(ret.ptr, ptr, len); libc::memcpy(ret.ptr + len, other.ptr, other.len); @@ -155,4 +160,17 @@ String String::hex(uint32_t v) { return String(b, e - b); } +String String::sprintf(const char* format, ...) { + va_list ap; + va_start(ap, format); + va_list ap2; + va_copy(ap2, ap); + String ret; + ret.len = libc::printf_str_len(format, ap2); + va_end(ap2); + ret.ptr = (char*)malloc(ret.len + 1); + ret.len = libc::vsprintf(ret.ptr, format, ap); + va_end(ap); + return ret; +} diff --git a/src/user/lib/fwik/include/IO/IOStream.h b/src/user/lib/fwik/include/IO/IOStream.h index e381cf5..2e33268 100644 --- a/src/user/lib/fwik/include/IO/IOStream.h +++ b/src/user/lib/fwik/include/IO/IOStream.h @@ -12,14 +12,18 @@ class IOStream { IOStream() : term(0) {} IOStream(Term *t) : term(t) {} - void print(char* str); - void printf(char* fmt, ...); + void print(const char* str); + void printf(const char* fmt, ...); String readln(); - IOStream &operator<<(char* s) { + IOStream &operator<<(const char* s) { print(s); return *this; } + IOStream &operator<<(const String& s) { + print(s.c_str()); + return *this; + } IOStream &operator<<(int i) { printf("%d", i); return *this; diff --git a/src/user/lib/fwik/include/IO/Node.h b/src/user/lib/fwik/include/IO/Node.h index 6100fc9..ed8290f 100644 --- a/src/user/lib/fwik/include/IO/Node.h +++ b/src/user/lib/fwik/include/IO/Node.h @@ -6,6 +6,8 @@ #include #include +#include + class Term; class Node { public: @@ -14,7 +16,7 @@ class Node { bool valid; Node(FILE f); - Node(char* filename, int mode); + Node(const char* filename, int mode); virtual ~Node() {} void close(); @@ -22,4 +24,6 @@ class Node { virtual Term* as_term() { return 0; } }; +String path_cat(const String &a, const String &b, bool trailing_slash = true); + #endif diff --git a/src/user/lib/fwik/include/IO/Term.h b/src/user/lib/fwik/include/IO/Term.h index 4fd9306..5b8aba3 100644 --- a/src/user/lib/fwik/include/IO/Term.h +++ b/src/user/lib/fwik/include/IO/Term.h @@ -16,13 +16,13 @@ class Term : public Node { public: Term(FILE f); - Term(char* filename, int mode); + Term(const char* filename, int mode); Term(const Node &n); virtual ~Term(); - virtual void print(char *s); - virtual void printf(char* fmt, ...); - virtual void vprintf(char* fmt, va_list ap); + virtual void print(const char *s); + virtual void printf(const char* fmt, ...); + virtual void vprintf(const char* fmt, va_list ap); virtual String readln(); String readline(); diff --git a/src/user/lib/fwik/include/String.h b/src/user/lib/fwik/include/String.h index 672220d..59fa0b6 100644 --- a/src/user/lib/fwik/include/String.h +++ b/src/user/lib/fwik/include/String.h @@ -11,30 +11,32 @@ class String { public: String(); String(const String& other); - String(char* ptr); - String(char* ptr, int len); + String(const char* ptr); + String(const char* ptr, int len); String(char c, int count); ~String(); void operator=(const String &string); - void operator=(char* ptr); + void operator=(const char* ptr); - char* c_str(); + const char* c_str() const; - bool operator==(const String& other); - bool operator==(char* other); - bool operator<(const String& other); + bool operator==(const String& other) const; + bool operator==(const char* other) const; + bool operator<(const String& other) const; char &operator[](int pos); + char operator[](int pos) const; - int size() { return len; } - operator bool() { return len != 0; } - String substr(int start, int count); + int size() const { return len; } + operator bool() const { return len != 0; } + String substr(int start, int count) const; - String operator+(const String& other); + String operator+(const String& other) const; void operator+=(const String& other); void operator+=(char c); static String dec(int i); static String hex(uint32_t v); + static String sprintf(const char* format, ...); }; #endif diff --git a/src/user/lib/fwik/io/IOStream.cpp b/src/user/lib/fwik/io/IOStream.cpp index ae495c0..9d13251 100644 --- a/src/user/lib/fwik/io/IOStream.cpp +++ b/src/user/lib/fwik/io/IOStream.cpp @@ -1,11 +1,11 @@ #include -void IOStream::print(char* str) { +void IOStream::print(const char* str) { if (term == 0) return; term->print(str); } -void IOStream::printf(char* fmt, ...) { +void IOStream::printf(const char* fmt, ...) { if (term == 0) return; va_list ap; va_start(ap, fmt); 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); +} diff --git a/src/user/lib/fwik/io/Term.cpp b/src/user/lib/fwik/io/Term.cpp index f7f28ec..1540b9a 100644 --- a/src/user/lib/fwik/io/Term.cpp +++ b/src/user/lib/fwik/io/Term.cpp @@ -8,7 +8,7 @@ Term::Term(FILE f) : Node(f) { _init(); } -Term::Term(char* filename, int mode) : Node(filename, mode) { +Term::Term(const char* filename, int mode) : Node(filename, mode) { _init(); } @@ -27,18 +27,18 @@ Term::~Term() { //TODO : free readline history } -void Term::print(char *s) { +void Term::print(const char *s) { libc::fprint(fd, s); } -void Term::printf(char* fmt, ...) { +void Term::printf(const char* fmt, ...) { va_list ap; va_start(ap, fmt); libc::vfprintf(fd, fmt, ap); va_end(ap); } -void Term::vprintf(char* fmt, va_list ap) { +void Term::vprintf(const char* fmt, va_list ap) { libc::vfprintf(fd, fmt, ap); } -- cgit v1.2.3