From b88f84b4cd470c38bfabe459aa04024c5b7ed9c3 Mon Sep 17 00:00:00 2001 From: Tom-on64 Date: Tue, 27 Aug 2024 15:17:42 +0200 Subject: [PATCH] Improved printf() --- include/c/_printf.h | 152 ++++++++++++++++++++++++++++++-------------- kern.iso | Bin 1470464 -> 1470464 bytes src/kernel.c | 38 +++++------ 3 files changed, 120 insertions(+), 70 deletions(-) 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 7245df411f2226b9b5bde18a780e0df2a505c6cf..47e0c8705daac4c2e60799b0b749318133a7aef3 100644 GIT binary patch delta 7259 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 delta 5939 zcmcIndsq`!7QY!12nZyK;0q-v2#9t;@r7uk7$1FYAPPc@Rz;nnttdpI{n|t^njxU* zZSAhDpCW2sx^*{QrE9g}LkzxJ+xoRCw2dvR6JwROwopZ9&zS*?uDk6YHs5#Vp5J-R zx%ZxX=fvX9vAA>g*J~MPDs^e^C|*<&qM#=xj#GT(Pl((RG%4&6^QlzgbSY+}6DJ{l zq)OSFkZL`ks$k@v0FM78kP!a5nve|k8X<(O3M5X}0vx{zHJ5t9BMq!w@)!oC{=nbj zi(-L2oB$8Aq=Nv2AK#Y{u5R`mmXIW(=l|m0kC3WUsdQ)Ikk|%D1;sAKG%=kd!u6jF zoJ*mFrwrW_hSMJk!*Y*;Wo{1JoW{E(E zA&Wm7M>j4{Vcdzdet8rF=n@Q$I2uqC#cYnF@h~ilqtju~$I${9{uD>;MUhPRIQn)` z0&_c#o`oSYkqR)p8Apc{N1FS_;S@BiAP9sV3M-?LXz){DwpuzH<=8!_+(Nqa)nekEzSV^*h;))~W@K?-`oIM{qf)NbhXRavie ztltGt@XrRoa$kePQn776)FOmGVj4@FA3%MPio+=SX}5iZUSD9!;=cs5S-Hra1}RT5lq8tLk#|Y^@wolf9gvUl zlVgfsClO~*4IBk>2;!0t5OWt!TUNsnBBbPQ+HD%?r%jI!@FkVub?th zbU-v(eJ!U6rhfg!nSBVQlMWu^X3Lj1qIE1Lj> z#elN%ZqBjvJyT9NuDHE-4U{BFKF*yuZ4pA?3(|jOG~*sYwJVb*x4`we&?T?`5k@6B zCa=E%46y~*{|sa874<@{XZs{wSjR+*G51dp)TJpWa8f zbIG5z{=l`CZPq|uwk;^7&t8mRH0ciWs?CgfXbtQoIYeMvq_j9)b2R}gKq2k0P02!X zBbRrE%X7PQO=wnO47Tge`013K?yO}DQLRk@;n8Ji6Vpt_=PRbjIh`BMx!N1l#Rmza z_#W+MLCDR~Lw>vyZe;vgErc{7ADK&fqc>6Vut#uh$;T6JmPIma8;iTyjm@@5f9>C8 z-fL@*7Y9^ha-7R$d+;8D1*7$dD+%arV-6D|)9NQMpM-&s5sv!~Z+5WWwF? z?t9QRK!>auIcK37zb&>lLBO+BdP`%xq-Qt6Ia0-2G?G$EN8~tW&J|dlU7!JkO1&pzkHd><* z-LXzd#O6mRR0@T`LZMtpD$wv6SVgfX60~yI8l`u7n$q|rNa)ga5$Lvl-8?4oXX;&- zYSzNVAllkzHYDifo@h8Eomd9AyAMuKdl(-mQ+s}b$#+_FYEQEd^hTAw)F3HUuW0*t z8hmt|+CK9X2hkmYAcgx0bKAE*p*zln(+7KBENxR7SD^Ir`hjC5snRH8{#rI51bgOM zUcu?ER)OSb*_wgq&ehg>f;myigTD3=Xp^hA`giw5(zcv*I$vgT+hf;Xf}-vbHc@5kuIyoadBOw zpTar9v5}Vg1s?7N3#;MJen=lwEo^IB(d zfOI2j;KNs@m4hJkPJ=ND+lpS`?G4fEK_e6@*d7?HdlR+oj4}^E-rER)&%u|A9g46C zVFSWcgr^anK{yTJ5ri!Wvk<%N8>;{BIjl%$o zq2EB9kFngSeh1-9ggn9;gi{)+p?XxnG2{aqX=Qbv*c-rmBXNo{_=n>a8@~|blql;D z9Dnix{kVESS_1NWF2F~!KOW!Q90NNUMHEFN@zl?mmBr?w$O58Sxd}fR*b;=xF3|X0 zgUr})K_e`7kQ~a#ff;;X^el0vIExf><*M7W?&=b4V^y03l=%3-+lnYnj z;O@kk1t&IPAaRxehUVItpdrp}j_BR-GP5a&ESP7~;4jG(i)j8mDE}T*^qj9{zAu_z zB&s^1DLMm0mCW^9C5P#o*+%qPs~+Uw7{wumc21HTd*xn3Dn9w(L;S*%y1u zQR!H{s`7s{%&&kNI)ac&9RJ{k8Q%p{`t61plliTN8Eqb3!;H~>XTyx9_czQadx#D5 zBnT%p%)`RUf%mz!5z+~(e9zw-jKbqE3 zHNXvgQVl+Ri<1JjZE^dH#fi%QQ=Df(jm3Ee$3M6@@m;^GI5C;uDo(U{c*Tj)erIu_ z>HWotvWHllyC7U=ah?L+r#KP%6sP}gG(AE0ukJ}h_%H*ieXA7l{Z;yahZSZQ(5? HVyXWJNV`g3 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;