diff --git a/bin/shell/SConscript b/bin/shell/SConscript index 212ebf0..2c6d898 100644 --- a/bin/shell/SConscript +++ b/bin/shell/SConscript @@ -13,7 +13,7 @@ src_common = [ src.append(src_common) init_env.Append(LINKFLAGS = ['-nostdlib']) -init_env.Append(CPPFLAGS = ['-nostdinc']) +init_env.Append(CPPFLAGS = ['-fno-builtin', '-nostdinc']) init_env.Append(CPPPATH = ['#build/include']) init_env.Append(LIBPATH = ['#build/lib/libc'], LIBS = ['c']) diff --git a/bin/shell/shell.c b/bin/shell/shell.c index 4c4d9bc..90c1378 100644 --- a/bin/shell/shell.c +++ b/bin/shell/shell.c @@ -17,7 +17,7 @@ main(int argc, const char *argv[]) { char buf[256]; - fputs("System Shell\n", stdout); + printf("System Shell\n"); while (1) { fputs("Shell> ", stdout); fgets(buf, sizeof(buf), stdin); @@ -29,10 +29,10 @@ main(int argc, const char *argv[]) void Cmd_Help(int argc, const char *argv[]) { - fputs("cat Print file\n", stdout); - fputs("echo Echo arguments\n", stdout); - fputs("exit Exit shell\n", stdout); - fputs("help Display the list of commands\n", stdout); + printf("cat Print file\n"); + printf("echo Echo arguments\n"); + printf("exit Exit shell\n"); + printf("help Display the list of commands\n"); } void @@ -42,10 +42,9 @@ Cmd_Echo(int argc, const char *argv[]) for (i = 1; i < argc; i++) { - fputs(argv[i], stdout); - fputs(" ", stdout); + printf("%s ", argv[i]); } - fputs("\n", stdout); + printf("\n"); } void @@ -78,8 +77,7 @@ Cmd_List(int argc, const char *argv[]) break; } - fputs(de.d_name, stdout); - fputs("\n", stdout); + printf("%s\n", de.d_name); } } @@ -158,7 +156,7 @@ DispatchCommand(char *buf) } else if (strcmp(argv[0], "#") == 0) { // Ignore comments } else if (buf[0] != '\0') { - fputs("Unknown command\n", stdout); + printf("Unknown command '%s'\n", buf); } } diff --git a/include/stdio.h b/include/stdio.h index 00621ea..e4cdbaf 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -34,5 +34,8 @@ int fputs(const char *str, FILE *fh); int fgetc(FILE *fh); char *fgets(char *str, int size, FILE *fh); +int printf(const char *fmt, ...); +int fprintf(FILE *stream, const char *fmt, ...); + #endif /* __STDIO_H__ */ diff --git a/lib/libc/SConscript b/lib/libc/SConscript index ea982f8..88d42a0 100644 --- a/lib/libc/SConscript +++ b/lib/libc/SConscript @@ -12,6 +12,7 @@ src_common = [ "file.c", "string.c", "syscall.c", + "printf.c", "posix/mman.c", ] diff --git a/lib/libc/printf.c b/lib/libc/printf.c new file mode 100644 index 0000000..851e39d --- /dev/null +++ b/lib/libc/printf.c @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2013-2014 Stanford University + * Copyright (c) 2006-2008 Ali Mashtizadeh + * All rights reserved. + */ + +#include +#include +#include +#include +#include + +// static unsigned long getuint(va_list *ap, int lflag) +#define getuint(ap, lflag) \ + (lflag == 8) ? va_arg(ap, uint64_t) : \ + (lflag == 4) ? va_arg(ap, uint32_t) : \ + (lflag == 2) ? va_arg(ap, uint32_t) : \ + (lflag == 1) ? va_arg(ap, uint32_t) : 0 + +// static long getint(va_list *ap, int lflag) +#define getint(ap, lflag) \ + (lflag == 8) ? va_arg(ap, int64_t) : \ + (lflag == 4) ? va_arg(ap, int32_t) : \ + (lflag == 2) ? va_arg(ap, int32_t) : \ + (lflag == 1) ? va_arg(ap, int32_t) : 0 + +static const char *numberstring_lower = "0123456789abcdef"; +static const char *numberstring_upper = "0123456789ABCDEF"; + +static void printnum(void (*func)(int, void*),void *handle, + uint64_t num,int base,int width,int padc) +{ + char buf[64]; + char *p = buf; + int spaces; + if (base < 0) + { + base = -base; + do { + *p = numberstring_upper[num % base]; + p++; + } while (num /= base); + } else { + do { + *p = numberstring_lower[num % base]; + p++; + } while (num /= base); + } + + // Print spacers (pre-number) + spaces = width - (p - buf); + if (padc == ' ' || padc == '0') { + while (spaces > 0) + { + func(padc, handle); + spaces--; + } + } + + // Print Number + while (p != buf) { + p--; + func((int)*p, handle); + } + + // Print spacers (post-number) + if (padc == '-') { + while (spaces > 0) + { + func(' ', handle); + spaces--; + } + } +} + +static int kvprintf(char const *fmt, void (*func)(int,void *), void *handle, va_list ap) +{ + const char *p; + int ch; + uint64_t unum; + int64_t num; + int lflag, width, padc; + + while (1) { + while ((ch = *(unsigned char *)fmt++) != '%') { + if (ch == '\0') return -1; + func(ch, handle); + } + + width = -1; + lflag = 4; + padc = ' '; +again: + switch (ch = *(unsigned char *)fmt++) { + case '-': + padc = '-'; + goto again; + case '0': + padc = '0'; + goto again; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + width = 0; + while (1) { + width = 10 * width + ch - '0'; + ch = *fmt; + if (ch < '0' || ch > '9') + { + break; + } + fmt++; + if (ch == '\0') + { + fmt--; + goto again; + } + } + goto again; + case 'c': + func(va_arg(ap, int) & 0xff, handle); + break; + case 's': { + int spaces; + + p = va_arg(ap, char *); + if (p == NULL) { + func('*', handle); + func('N', handle); + func('U', handle); + func('L', handle); + func('L', handle); + func('*', handle); + break; + } + spaces = width - strlen(p); + + if (padc == ' ') { + while (spaces > 0) + { + func(' ', handle); + spaces--; + } + } + + while (*p != '\0') + { + func(*p++, handle); + } + + if (padc == '-') { + while (spaces > 0) + { + func(' ', handle); + spaces--; + } + } + break; + } + case 'd': + num = getint(ap, lflag); + if (num < 0) { + func('-', handle); + unum = -num; + } else { + unum = num; + } + printnum(func, handle, unum, 10, width, padc); + break; + case 'u': + unum = getuint(ap, lflag); + printnum(func, handle, unum, 10, width, padc); + break; + case 'o': + unum = getuint(ap, lflag); + printnum(func, handle, unum, 8, width, padc); + break; + case 'p': + unum = (unsigned long)va_arg(ap, void *); + printnum(func, handle, unum, 8, width, padc); + break; + case 'x': + unum = getuint(ap, lflag); + printnum(func, handle, unum, 16, width, padc); + break; + case 'X': + unum = getuint(ap, lflag); + printnum(func, handle, unum, -16, width, padc); + break; + case 'l': + lflag = 8; + goto again; + case '%': + default: // Print Literally + func(ch, handle); + break; + } + } + return 0; +} + +static void fileputc(int c, void* handle) +{ + fputc(c, (FILE *)handle); +} + +int printf(const char *fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = kvprintf(fmt, fileputc, (void *)stdout, ap); + va_end(ap); + + return ret; +} + +int fprintf(FILE *stream, const char *fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = kvprintf(fmt, fileputc, stream, ap); + va_end(ap); + + return ret; +} +