summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex AUVOLAT <alexis211@gmail.com>2012-05-19 15:56:25 +0200
committerAlex AUVOLAT <alexis211@gmail.com>2012-05-19 15:56:25 +0200
commit8e07c1db6ba4bedd0f8fe537a6fb0ca80e5d25f4 (patch)
tree08df626a28c290f5cde43424dd62dd43fc441a35 /src
parent0d2f7645c3fb45d83497faf2a4b6fff8c3f175d1 (diff)
downloadTCE-8e07c1db6ba4bedd0f8fe537a6fb0ca80e5d25f4.tar.gz
TCE-8e07c1db6ba4bedd0f8fe537a6fb0ca80e5d25f4.zip
Better sprintf, vsprintf, String::sprintf, etc.
Diffstat (limited to 'src')
-rw-r--r--src/user/app/yosh/main.cpp156
-rw-r--r--src/user/lib/fwik/String.cpp36
-rw-r--r--src/user/lib/fwik/include/IO/IOStream.h10
-rw-r--r--src/user/lib/fwik/include/IO/Node.h6
-rw-r--r--src/user/lib/fwik/include/IO/Term.h8
-rw-r--r--src/user/lib/fwik/include/String.h24
-rw-r--r--src/user/lib/fwik/io/IOStream.cpp4
-rw-r--r--src/user/lib/fwik/io/Node.cpp87
-rw-r--r--src/user/lib/fwik/io/Term.cpp8
-rw-r--r--src/user/lib/libc/include/stdio.h13
-rw-r--r--src/user/lib/libc/include/string.h4
-rw-r--r--src/user/lib/libc/include/tce/syscall.h16
-rw-r--r--src/user/lib/libc/start.c13
-rw-r--r--src/user/lib/libc/std/stdio.c75
-rw-r--r--src/user/lib/libc/std/string.c54
-rw-r--r--src/user/lib/libc/tce/syscall.c16
-rw-r--r--src/user/link.ld6
17 files changed, 293 insertions, 243 deletions
diff --git a/src/user/app/yosh/main.cpp b/src/user/app/yosh/main.cpp
index 6277701..37b557d 100644
--- a/src/user/app/yosh/main.cpp
+++ b/src/user/app/yosh/main.cpp
@@ -6,7 +6,7 @@
#include <IO/IOStream.h>
FILE cwd_f;
-char *cwd;
+String cwd;
void about() {
stdio << "Trivial/Computing Environment v0.1.0 - yosh 3.\n";
@@ -35,117 +35,27 @@ void help(String *args) {
}
}
-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++;
- }
- }
-}
-
-char* path_cat (char* a, char* b, bool trailing_slash = true) {
- char* ret;
- if (b[0] == '/') {
- int lb = libc::strlen(b);
- ret = (char*)malloc(lb + 2);
- libc::memcpy(ret, b, lb);
- if (ret[lb - 1] != '/') {
- ret[lb] = '/';
- lb++;
- }
- ret[lb] = 0;
- } else {
- int la = libc::strlen(a);
- int lb = libc::strlen(b);
-
- ret = (char*)malloc(la + lb + 3);
- libc::memcpy(ret, a, la);
- if (ret[la-1] != '/') {
- ret[la] = '/';
- la++;
- }
- libc::memcpy(ret + la, b, lb);
- if (ret[la + lb - 1] != '/') {
- ret[la + lb] = '/';
- lb++;
- }
- ret[la + lb] = 0;
- }
- simplify_path(ret);
- if (!trailing_slash) {
- int l = libc::strlen(ret);
- if (ret[l-1] == '/') ret[l-1] = 0;
- }
- return ret;
-}
-
void cd(String *args) {
if (!args[1]) {
stdio << "Usage: cd <directory>\n";
}
if (args[1] == ".") return;
- char* newcwd = path_cat(cwd, args[1].c_str());
+ String newcwd = path_cat(cwd, args[1]);
file_info info;
- int i = libc::stat(newcwd, &info);
+ int i = libc::stat(newcwd.c_str(), &info);
if (i == E_NOT_FOUND) {
stdio << "No such file or directory.\n";
- free(newcwd);
} else if (i < 0) {
stdio.printf("Error stating: %i\n", i);
- free(newcwd);
} else if ((info.type & FT_DIR) == 0) {
stdio << "Not a directory.\n";
- free(newcwd);
} else {
- FILE nf = libc::open(newcwd, 0);
+ FILE nf = libc::open(newcwd.c_str(), 0);
if (nf < 0) {
stdio.printf("Error opening: %i\n", nf);
- free(newcwd);
} else {
- free(cwd);
cwd = newcwd;
libc::close(cwd_f);
cwd_f = nf;
@@ -192,9 +102,9 @@ void ls(String *args) {
int i;
for (i = 1; args[i]; i++) {
stdio.printf("Contents of %s :\n", args[i].c_str());
- char* d = path_cat(cwd, args[i].c_str());
+ String d = path_cat(cwd, args[i].c_str());
file_info info;
- int e = libc::stat(d, &info);
+ int e = libc::stat(d.c_str(), &info);
if (e == E_NOT_FOUND) {
stdio << " No such file or directory\n";
} else if (e < 0) {
@@ -202,7 +112,7 @@ void ls(String *args) {
} else if ((info.type & FT_DIR) == 0) {
stdio.printf(" Not a directory.\n");
} else {
- FILE ff = libc::open(d, 0);
+ FILE ff = libc::open(d.c_str(), 0);
if (ff < 0) {
stdio.printf(" Error opening: %i\n", ff);
} else {
@@ -210,7 +120,6 @@ void ls(String *args) {
libc::close(ff);
}
}
- free(d);
}
}
}
@@ -218,17 +127,17 @@ void ls(String *args) {
void cat(String *args) {
int i;
for (i = 1; args[i]; i++) {
- char *d = path_cat(cwd, args[i].c_str(), false);
+ String d = path_cat(cwd, args[i], false);
file_info info;
- int e = libc::stat(d, &info);
+ int e = libc::stat(d.c_str(), &info);
if (e == E_NOT_FOUND) {
- stdio.printf("No such file: %s\n", d);
+ stdio.printf("No such file: %s\n", d.c_str());
} else if (e < 0) {
- stdio.printf("Error stating %s : %i\n", d, e);
+ stdio.printf("Error stating %s : %i\n", d.c_str(), e);
} else if ((info.type & FT_FILE) == 0) {
- stdio.printf("Not a file: %s\n", d);
+ stdio.printf("Not a file: %s\n", d.c_str());
} else {
- FILE ff = libc::open(d, 0);
+ FILE ff = libc::open(d.c_str(), 0);
char* buff = (char*)malloc(info.size);
libc::read(ff, 0, info.size, buff);
libc::close(ff);
@@ -243,10 +152,10 @@ void t_goto(String *args) {
stdio << "Usage: goto <vt_name>\n";
return;
}
- char* p = path_cat("/.ui/", args[1].c_str(), false);
+ String p = path_cat("/.ui/", args[1], false);
int i;
- if ((i = libc::link(p, "/.dev/vgatxt", LM_OUTPUT_TO)) == 0) {
- libc::link("/.dev/ps2kbd", p, LM_OUTPUT_TO);
+ if ((i = libc::link(p.c_str(), "/.dev/vgatxt", LM_OUTPUT_TO)) == 0) {
+ libc::link("/.dev/ps2kbd", p.c_str(), LM_OUTPUT_TO);
} else {
stdio.printf("Error %i\n", i);
}
@@ -255,10 +164,10 @@ void t_goto(String *args) {
int Main(String *sh_args) {
about();
- cwd = libc::strdup("/");
- cwd_f = libc::open(cwd, 0);
+ cwd = "/";
+ cwd_f = libc::open(cwd.c_str(), 0);
- char *path = path_cat(sh_args[0].c_str(), "..");
+ String path = path_cat(sh_args[0], "..");
int bg_pr[128], bg_pr_c = 0;
@@ -269,7 +178,7 @@ int Main(String *sh_args) {
}
while (1) {
- stdio.printf("\x1b[33m %s \x1b[1m", cwd);
+ stdio.printf("\x1b[33m %s \x1b[1m", cwd.c_str());
String s = term->readline();
stdio.printf("\x1b[0m");
@@ -310,37 +219,36 @@ int Main(String *sh_args) {
cat(c_args);
} else {
FILE vt = term->fd;
- char *t = 0;
String *first_arg = c_args + 1;
+ String t;
if (c_args[0] == "on") {
if (!c_args[1] || !c_args[2]) {
stdio.printf("Usage:\ton <vt> <command>\n");
continue;
}
- t = path_cat("/.ui/", c_args[1].c_str(), false);
- vt = libc::open(t, 0);
+ t = path_cat("/.ui/", c_args[1], false);
+ vt = libc::open(t.c_str(), 0);
if (vt < 0 || vt == term->fd) {
- stdio.printf("Error: cannot open terminal %s (%i)\n", t, vt);
- free(t);
+ stdio.printf("Error: cannot open terminal %s (%i)\n", t.c_str(), vt);
continue;
}
first_arg += 2;
}
- char *c;
+ String c;
if (libc::strchr(c_args[0].c_str(), '/')) {
- c = path_cat(cwd, c_args[0].c_str(), false);
+ c = path_cat(cwd, c_args[0], false);
} else {
- c = path_cat(path, c_args[0].c_str(), false);
+ c = path_cat(path, c_args[0], false);
}
- char *run_args[15] = {0};
+ const char *run_args[15] = {0};
for (int i = 0; first_arg[i]; i++) run_args[i] = first_arg[i].c_str();
- int pid = libc::run(c, run_args, vt);
+ int pid = libc::run(c.c_str(), run_args, vt);
if (pid <= 0) {
if (pid == E_NOT_FOUND) {
- stdio.printf("Error: no such file %s\n", c);
+ stdio.printf("Error: no such file %s\n", c.c_str());
} else {
stdio.printf("Error %i\n", pid);
}
@@ -349,12 +257,10 @@ int Main(String *sh_args) {
int ret = libc::waitpid(pid, 1);
stdio.printf("(yosh) child (pid %i) exited with status %i\n", pid, ret);
} else {
- stdio.printf("(yosh) running on terminal %s, pid:%i\n", t, pid);
+ stdio.printf("(yosh) running on terminal %s, pid:%i\n", t.c_str(), pid);
bg_pr[bg_pr_c++] = pid;
- free(t);
}
}
- free(c);
}
int i = 0;
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 <stdio.h>
#include <cpp.h>
+#include <String.h>
+
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 <IO/IOStream.h>
-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);
}
diff --git a/src/user/lib/libc/include/stdio.h b/src/user/lib/libc/include/stdio.h
index d93ebf0..f19ce60 100644
--- a/src/user/lib/libc/include/stdio.h
+++ b/src/user/lib/libc/include/stdio.h
@@ -10,16 +10,13 @@ extern "C" { namespace libc {
extern FILE term;
-void print(char *s);
-void printf(char *s, ...);
+void print(const char *s);
+void printf(const char *s, ...);
char *readln();
-void fprint(FILE f, char *s);
-void fprint_int(FILE f, int number);
-void fprint_hex(FILE f, unsigned number);
-void fprintf(FILE f, char *s, ...);
-
-void vfprintf(FILE f, char *s, va_list arg);
+void fprint(FILE f, const char *s);
+void fprintf(FILE f, const char *s, ...);
+void vfprintf(FILE f, const char *s, va_list arg);
#ifdef __cplusplus
} }
diff --git a/src/user/lib/libc/include/string.h b/src/user/lib/libc/include/string.h
index 54fdf7a..5b86868 100644
--- a/src/user/lib/libc/include/string.h
+++ b/src/user/lib/libc/include/string.h
@@ -2,6 +2,7 @@
#define DEF_LIB_STRING_H
#include <types.h>
+#include <stdarg.h>
#ifdef __cplusplus
extern "C" { namespace libc {
@@ -20,6 +21,9 @@ int strcmp(const char *s1, const char *s2);
char* format_int(char* buf, int number);
char* format_hex(char *buf, unsigned v);
+int printf_str_len(const char *fmt, va_list arg);
+int vsprintf(char *buf, const char *fmt, va_list arg);
+int sprintf(char *buf, const char *fmt, ...);
#ifdef __cplusplus
} }
diff --git a/src/user/lib/libc/include/tce/syscall.h b/src/user/lib/libc/include/tce/syscall.h
index 6ad37f1..6679f1a 100644
--- a/src/user/lib/libc/include/tce/syscall.h
+++ b/src/user/lib/libc/include/tce/syscall.h
@@ -15,7 +15,7 @@ void thread_exit();
void schedule();
void thread_sleep(int time);
void process_exit(int retval);
-void printk(char* str);
+void printk(const char* str);
void thread_new(void (*entry)(void*), void *data);
void irq_wait(int number);
int proc_priv();
@@ -23,18 +23,18 @@ int proc_priv();
void* sbrk(ptrdiff_t size);
void brk(void* ptr);
-int run(char* file, char** args, FILE zero_fd);
+int run(const char* file, const char** args, FILE zero_fd);
int waitpid(int pid, int block);
-FILE open(char* filename, int mode);
-FILE open_relative(FILE root, char* filename, int mode);
-int stat(char* filename, file_info *info);
-int stat_relative(FILE root, char* filename, file_info *info);
+FILE open(const char* filename, int mode);
+FILE open_relative(FILE root, const char* filename, int mode);
+int stat(const char* filename, file_info *info);
+int stat_relative(FILE root, const char* filename, file_info *info);
int statf(FILE file, file_info *info);
void close(FILE file);
int read(FILE file, size_t offset, size_t len, char *buffer);
-int write(FILE file, size_t offset, size_t len, char *buffer);
-int link(char* from, char* to, int mode);
+int write(FILE file, size_t offset, size_t len, const char *buffer);
+int link(const char* from, const char* to, int mode);
#ifdef __cplusplus
} }
diff --git a/src/user/lib/libc/start.c b/src/user/lib/libc/start.c
index 2521f97..f15f90d 100644
--- a/src/user/lib/libc/start.c
+++ b/src/user/lib/libc/start.c
@@ -2,7 +2,20 @@
extern int main(char **args);
+extern size_t start_ctors, end_ctors, start_dtors, end_dtors;
+
void start(char **args) {
+ size_t *call;
+
+ for (call = &start_ctors; call < &end_ctors; call++) {
+ ((void(*)(void))*call)();
+ }
+
int ret = main(args);
+
+ for (call = &start_dtors; call < &end_dtors; call++) {
+ ((void(*)(void))*call)();
+ }
+
process_exit(ret);
}
diff --git a/src/user/lib/libc/std/stdio.c b/src/user/lib/libc/std/stdio.c
index da2f094..23ec989 100644
--- a/src/user/lib/libc/std/stdio.c
+++ b/src/user/lib/libc/std/stdio.c
@@ -4,8 +4,8 @@
#include <readline.h>
FILE term = 0;
-void print(char *s) { fprint(term, s); }
-void printf(char *format, ...) {
+void print(const char *s) { fprint(term, s); }
+void printf(const char *format, ...) {
va_list ap;
va_start(ap, format);
vfprintf(term, format, ap);
@@ -13,67 +13,24 @@ void printf(char *format, ...) {
}
char* readln() { return freadln(term); }
-void fprintf(FILE f, char* format, ...) {
+void fprint(FILE f, const char *s) {
+ write(f, 0, strlen(s), s);
+}
+
+void fprintf(FILE f, const char* format, ...) {
va_list ap;
va_start(ap, format);
vfprintf(f, format, ap);
va_end(ap);
}
-// FUNCTIONS
-
-void fprint(FILE f, char *s) {
- write(f, 0, strlen(s), s);
-}
-
-void fprint_int(FILE f, int number) {
- char s[32];
- char *v = format_int(s, number);
- *v = 0;
- fprint(f, s);
-}
-
-void fprint_hex(FILE f, unsigned v) {
- char s[11];
- char *e = format_hex(s, v);
- *e = 0;
- fprint(f, s);
-}
-
-void vfprintf(FILE f, char *format, va_list ap) {
- char bb[256];
- int bufl = 256;
-
- char *buf = bb;
- char *end = buf;
-
- while (*format) {
- if (*format == '%') {
- // ASSUMPTION : (TODO) WE HAVE ENOUGH SPACE - NOT THE CASE!!!
- format++;
- if (*format == 'd' || *format == 'i') {
- end = format_int(end, va_arg(ap, int));
- } else if (*format == 'p') {
- end = format_hex(end, va_arg(ap, uint32_t));
- } else if (*format == 's') {
- char *s = va_arg(ap, char*);
- strcpy(end, s);
- end += strlen(s);
- }
- format++;
- } else {
- *(end++) = *(format++);
- }
- if (end - buf > bufl - 2) {
- bufl *= 2;
- char *nbuf = (char*)malloc(bufl);
- memcpy(nbuf, buf, end - buf);
- end = nbuf + (end - buf);
- if (buf != bb) free(buf);
- buf = nbuf;
- }
- }
- *end = 0;
- fprint(f, buf);
- if (buf != bb) free(buf);
+void vfprintf(FILE f, const char *fmt, va_list ap) {
+ va_list ap2;
+ va_copy(ap2, ap);
+ int l = printf_str_len(fmt, ap2);
+ va_end(ap2);
+ char* buf = (char*) malloc(l+1);
+ l = vsprintf(buf, fmt, ap);
+ if (l > 0) write(f, 0, l, buf);
+ free(buf);
}
diff --git a/src/user/lib/libc/std/string.c b/src/user/lib/libc/std/string.c
index d8e4a48..619b8c6 100644
--- a/src/user/lib/libc/std/string.c
+++ b/src/user/lib/libc/std/string.c
@@ -119,3 +119,57 @@ char* format_hex(char *buf, unsigned v) {
}
return buf;
}
+
+int printf_str_len(const char *format, va_list ap) {
+ int l = 0;
+ while (*format) {
+ if (*format == '%') {
+ format++;
+ if (*format == 'd' || *format == 'i') {
+ l += 15;
+ va_arg(ap, int);
+ } else if (*format == 'p') {
+ l += 11;
+ va_arg(ap, void*);
+ } else if (*format == 's') {
+ l += strlen(va_arg(ap, const char*));
+ }
+ } else {
+ l++;
+ }
+ format++;
+ }
+ return l;
+}
+
+int sprintf(char *buf, const char *fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ int ret = vsprintf(buf, fmt, ap);
+ va_end(ap);
+ return ret;
+}
+
+int vsprintf(char *buf, const char *format, va_list ap) {
+ char *end = buf;
+
+ while (*format) {
+ if (*format == '%') {
+ format++;
+ if (*format == 'd' || *format == 'i') {
+ end = format_int(end, va_arg(ap, int));
+ } else if (*format == 'p') {
+ end = format_hex(end, va_arg(ap, uint32_t));
+ } else if (*format == 's') {
+ const char *s = va_arg(ap, const char*);
+ strcpy(end, s);
+ end += strlen(s);
+ }
+ format++;
+ } else {
+ *(end++) = *(format++);
+ }
+ }
+ *end = 0;
+ return end - buf;
+}
diff --git a/src/user/lib/libc/tce/syscall.c b/src/user/lib/libc/tce/syscall.c
index 80e0e0e..acdcc51 100644
--- a/src/user/lib/libc/tce/syscall.c
+++ b/src/user/lib/libc/tce/syscall.c
@@ -25,7 +25,7 @@ void process_exit(int retval) {
call(SC_PROCESS_EXIT, retval, 0, 0, 0, 0);
}
-void printk(char* str) {
+void printk(const char* str) {
call(SC_PRINTK, (unsigned)str, 0, 0, 0, 0);
}
@@ -75,7 +75,7 @@ void brk(void* ptr) {
// ********** proc
-int run(char* filename, char** args, FILE zero_fd) {
+int run(const char* filename, const char** args, FILE zero_fd) {
return call(SC_RUN, (unsigned)filename, (unsigned)args, (unsigned)zero_fd, 0, 0);
}
@@ -85,19 +85,19 @@ int waitpid(int p, int block) {
// ********** file
-FILE open(char* filename, int mode) {
+FILE open(const char* filename, int mode) {
return call(SC_OPEN, (unsigned)filename, mode, 0, 0, 0);
}
-FILE open_relative(FILE root, char* filename, int mode) {
+FILE open_relative(FILE root, const char* filename, int mode) {
return call(SC_OPEN_RELATIVE, root, (unsigned) filename, mode, 0, 0);
}
-int stat(char* filename, file_info *info) {
+int stat(const char* filename, file_info *info) {
return call(SC_STAT, (unsigned) filename, (unsigned) info, 0, 0, 0);
}
-int stat_relative(FILE root, char* filename, file_info *info) {
+int stat_relative(FILE root, const char* filename, file_info *info) {
return call(SC_STAT_RELATIVE, root, (unsigned) filename, (unsigned) info, 0, 0);
}
@@ -113,10 +113,10 @@ int read(FILE file, size_t offset, size_t len, char *buffer) {
return call(SC_READ, file, offset, len, (unsigned) buffer, 0);
}
-int write(FILE file, size_t offset, size_t len, char* buffer) {
+int write(FILE file, size_t offset, size_t len, const char* buffer) {
return call(SC_WRITE, file, offset, len, (unsigned) buffer, 0);
}
-int link(char* from, char* to, int mode) {
+int link(const char* from, const char* to, int mode) {
return call(SC_LINK, (unsigned) from, (unsigned)to, mode, 0, 0);
}
diff --git a/src/user/link.ld b/src/user/link.ld
index 95c2fc1..aa3759c 100644
--- a/src/user/link.ld
+++ b/src/user/link.ld
@@ -12,6 +12,12 @@ SECTIONS{
}
.data ALIGN (0x1000) : {
+ start_ctors = .;
+ *(.ctor*)
+ end_ctors = .;
+ start_dtors = .;
+ *(.dtor*)
+ end_dtors = .;
*(.data)
}