Brought in my temporary printf to cleanup the shell

This commit is contained in:
Ali Mashtizadeh 2014-12-05 18:33:29 -08:00
parent 6d9ca7f578
commit 4dde777570
5 changed files with 250 additions and 12 deletions

View File

@ -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'])

View File

@ -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);
}
}

View File

@ -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__ */

View File

@ -12,6 +12,7 @@ src_common = [
"file.c",
"string.c",
"syscall.c",
"printf.c",
"posix/mman.c",
]

236
lib/libc/printf.c Normal file
View File

@ -0,0 +1,236 @@
/*
* Copyright (c) 2013-2014 Stanford University
* Copyright (c) 2006-2008 Ali Mashtizadeh
* All rights reserved.
*/
#include <stdbool.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
// 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;
}