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. --- Makefile | 15 +-- src/user/app/yosh/main.cpp | 156 +++++++------------------------- 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 +- src/user/lib/libc/include/stdio.h | 13 +-- src/user/lib/libc/include/string.h | 4 + src/user/lib/libc/include/tce/syscall.h | 16 ++-- src/user/lib/libc/start.c | 13 +++ src/user/lib/libc/std/stdio.c | 75 ++++----------- src/user/lib/libc/std/string.c | 54 +++++++++++ src/user/lib/libc/tce/syscall.c | 16 ++-- src/user/link.ld | 6 ++ 18 files changed, 302 insertions(+), 249 deletions(-) diff --git a/Makefile b/Makefile index 01b6062..1e64bbe 100644 --- a/Makefile +++ b/Makefile @@ -42,14 +42,17 @@ $(Cdrom): menu_cdrom.lst src/kernel/kernel.elf src/user/app/test/test.elf src/us echo "Please copy grub's stage2_eltorito to cdrom/boot/grub."; \ exit -1; \ fi + cp menu_cdrom.lst cdrom/boot/grub/menu.lst + cp src/kernel/kernel.elf cdrom; strip cdrom/kernel.elf + cp src/user/app/init/init.elf cdrom; strip cdrom/init.elf + cp src/user/app/test/test.elf cdrom; strip cdrom/test.elf + cp src/user/app/yosh/yosh.elf cdrom; strip cdrom/yosh.elf + cp src/user/app/prime/prime.elf cdrom; strip cdrom/prime.elf src/tools/makeinitrd/makeinitrd cdrom/initrd \ - src/user/app/test/test.elf:/bin/test \ - src/user/app/yosh/yosh.elf:/bin/yosh \ - src/user/app/prime/prime.elf:/bin/prime \ + cdrom/test.elf:/bin/test \ + cdrom/yosh.elf:/bin/yosh \ + cdrom/prime.elf:/bin/prime \ README:/readme - cp menu_cdrom.lst cdrom/boot/grub/menu.lst - cp src/kernel/kernel.elf cdrom - cp src/user/app/init/init.elf cdrom genisoimage -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 \ -boot-info-table -input-charset ascii -A TCE -o $(Cdrom) cdrom 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 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 \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 \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 \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 #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); } 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 +#include #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 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) } -- cgit v1.2.3