diff options
Diffstat (limited to 'src/user/lib/libc')
-rw-r--r-- | src/user/lib/libc/include/stdio.h | 13 | ||||
-rw-r--r-- | src/user/lib/libc/include/string.h | 4 | ||||
-rw-r--r-- | src/user/lib/libc/include/tce/syscall.h | 16 | ||||
-rw-r--r-- | src/user/lib/libc/start.c | 13 | ||||
-rw-r--r-- | src/user/lib/libc/std/stdio.c | 75 | ||||
-rw-r--r-- | src/user/lib/libc/std/string.c | 54 | ||||
-rw-r--r-- | src/user/lib/libc/tce/syscall.c | 16 |
7 files changed, 108 insertions, 83 deletions
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); } |