diff --git a/include/c/_printf.h b/include/c/_printf.h index 0c0a85c..cd3457f 100644 --- a/include/c/_printf.h +++ b/include/c/_printf.h @@ -1,75 +1,129 @@ #ifndef _PRINTF_H #define _PRINTF_H +#include #include #include +#include #include +#include <_fileio.h> -// TODO: Support negative numbers -int printf(const char* fmt, ...) { - va_list args; - va_start(args, fmt); - - // Printing buffer +// Warning: returns a allocated buffer, must be freed! +char* _format(const char* fmt, va_list args) { static char* buffer; - static unsigned int len; - int max = 256; + size_t len = 0; + size_t max = 256; buffer = malloc(max); - len = 0; - - int state = 0; - for (int i = 0; fmt[i] != '\0'; i++) { + + size_t i = 0; + while (fmt[i] != '\0') { if (len > max) { max *= 2; - // Reallocate larger buffer TODO: Use realloc(); + // Reallocate a larger buffer char* temp = malloc(max); strcpy(temp, buffer); free(buffer); buffer = temp; } - buffer[len] = '\0'; - char c = fmt[i]; - if (state == 0) { - if (c == '%') state = '%'; - else buffer[len++] = c; - } else if (state == '%') { - switch (c) { - case 'd': // Decimal number - strcat(buffer, itoa(va_arg(args, int), 10)); - len += strlen(&buffer[len]); // Add the remaining length - break; - case 'x': // Hex number - strcat(buffer, itoa(va_arg(args, int), 16)); - len += strlen(&buffer[len]); - break; - case 's': // String - char* s = va_arg(args, char*); - - while (*s != '\0') { - buffer[len++] = *s++; - } - break; - case 'c': // Char - buffer[len++] = va_arg(args, char); - break; - default: // This looks insane - buffer[len++] = '%'; - case '%': // Just print '%' - buffer[len++] = c; - break; - } - state = 0; - } + // Formatting magic... + if (fmt[i] == '%') { i++; + /* TODO: + %p - pointer (0x########) + %n - "" + */ + int pad = -1; + char padc = ' '; + + if (fmt[i] == '0') { i++; padc = '0'; } + if (fmt[i] >= '0' && fmt[i] <= '9') { + pad = atoi(fmt + i); + while (fmt[i] >= '0' && fmt[i] <= '9') { i++; } + } + while (pad > 0) { buffer[len++] = padc; pad--; } + + char c = fmt[i++]; + if (c == 'd' || c == 'x' || c == 'o') { + int base = 10; + if (c == 'x') base = 16; + else if (c == 'o') base = 8; + + char* s = itoa(va_arg(args, int), base); + if (pad == 0) len -= strlen(s); + while ((buffer[len++] = *s++) != '\0'); + len--; + } else if (c == 'c') { + if (pad == 0) len--; + buffer[len++] = va_arg(args, char); + } else if (c == 's') { + char* s = va_arg(args, char*); + if (pad == 0) len -= strlen(s); + while ((buffer[len++] = *s++) != '\0'); + len--; + } else if (c == '%') { + buffer[len++] = '%'; + } else { + buffer[len++] = '%'; + if (padc == '0') { buffer[len++] = '0'; } + if (pad > 0) { buffer[len++] = '#'; } // TODO + buffer[len++] = c; + } + } else { buffer[len++] = fmt[i++]; } } - + buffer[len] = '\0'; - write(1, buffer, len); + return buffer; +} + +int sprintf(char* str, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + + char* buffer = _format(fmt, args); + strcpy(str, buffer); free(buffer); va_end(args); - return 0; + return strlen(str); +} + +int snprintf(char* str, size_t n, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + + char* buffer = _format(fmt, args); + strncpy(str, buffer, n); + free(buffer); + va_end(args); + + return strlen(str); +} + +int fprintf(FILE* stream, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + + char* buffer = _format(fmt, args); + size_t len = strlen(buffer); + write(stream->_file, buffer, len); // TODO: use fwrite() + + free(buffer); + va_end(args); + return len; +} + +int printf(const char* fmt, ...) { + va_list args; + va_start(args, fmt); + + char* buffer = _format(fmt, args); + size_t len = strlen(buffer); + write(stdout->_file, buffer, len); // TODO: use fwrite() + + free(buffer); + va_end(args); + return len; } #endif diff --git a/kern.iso b/kern.iso index 7245df4..47e0c87 100644 Binary files a/kern.iso and b/kern.iso differ diff --git a/src/kernel.c b/src/kernel.c index a766153..daa0d5c 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -88,7 +88,7 @@ void main() { terminal->fg = FG_COLOR; terminal->bg = BG_COLOR; clear(); - print("kern.\n\n"); + printf("kern.\n\n"); // Run Interactive Shell Program // TODO: Make it in another file @@ -254,17 +254,13 @@ void main() { } putc('\n'); } - if (i < 0x10) printf("0"); - if (i < 0x100) printf("0"); - if (i < 0x1000) printf("0"); - printf("%x: ", i); + printf("%04x: ", i); } - if (fp->_ptr[i] < 0x10) putc('0'); - printf("%x ", fp->_ptr[i]); + printf("%02x ", fp->_ptr[i]); } if (fp->_size % 32 != 0) { for (size_t i = 0; i < 32-(fp->_size % 32); i++) { - printf("00 "); + printf(" "); } } printf(" "); @@ -314,35 +310,35 @@ void printRegs() { // a, b, c, d __asm__ volatile ("movl %%eax, %0" : "=r"(val)); - printf("eax 0x%x\n", val); + printf("eax 0x%08x\n", val); __asm__ volatile ("movl %%ebx, %0" : "=r"(val)); - printf("ebx 0x%x\n", val); + printf("ebx 0x%08x\n", val); __asm__ volatile ("movl %%ecx, %0" : "=r"(val)); - printf("ecx 0x%x\n", val); + printf("ecx 0x%08x\n", val); __asm__ volatile ("movl %%edx, %0" : "=r"(val)); - printf("edx 0x%x\n", val); + printf("edx 0x%08x\n", val); // si, di __asm__ volatile ("movl %%esi, %0" : "=r"(val)); - printf("esi 0x%x\n", val); + printf("esi 0x%08x\n", val); __asm__ volatile ("movl %%edi, %0" : "=r"(val)); - printf("edi 0x%x\n", val); + printf("edi 0x%08x\n", val); // cs, ds, es, ss __asm__ volatile ("movl %%cs, %0" : "=r"(val)); - printf("cs 0x%x\n", val); + printf("cs 0x%08x\n", val); __asm__ volatile ("movl %%ds, %0" : "=r"(val)); - printf("ds 0x%x\n", val); + printf("ds 0x%08x\n", val); __asm__ volatile ("movl %%es, %0" : "=r"(val)); - printf("es 0x%x\n", val); + printf("es 0x%08x\n", val); __asm__ volatile ("movl %%ss, %0" : "=r"(val)); - printf("ss 0x%x\n", val); + printf("ss 0x%08x\n", val); // stack __asm__ volatile ("movl %%esp, %0" : "=r"(val)); - printf("esp 0x%x\n", val); + printf("esp 0x%08x\n", val); __asm__ volatile ("movl %%ebp, %0" : "=r"(val)); - printf("ebp 0x%x\n", val); + printf("ebp 0x%08x\n", val); } void printPhysicalMemmap() { @@ -350,7 +346,7 @@ void printPhysicalMemmap() { smapEntry_t* smapEntry = (smapEntry_t*)SMAP_ENTRIES; for (uint32_t i = 0; i < entryCount; i++) { - printf("Region %d - base: 0x%x length: 0x%x type: %d ", i, (uint32_t)smapEntry->baseAddress, (uint32_t)smapEntry->length, smapEntry->type); + printf("Region %02d - base: 0x%08x length: 0x%08x type: %2d ", i, (uint32_t)smapEntry->baseAddress, (uint32_t)smapEntry->length, smapEntry->type); switch (smapEntry->type) { case 1: printf("(Available)\n"); break;