X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/9440be3a5115a91dcdf8dff05a361cac4b6cea29..0e1309c02f0703c050df09b71346dab60fc6df87:/lunaix-os/libs/klibc/stdio/sprintf.c diff --git a/lunaix-os/libs/klibc/stdio/sprintf.c b/lunaix-os/libs/klibc/stdio/sprintf.c index 460b206..d357068 100644 --- a/lunaix-os/libs/klibc/stdio/sprintf.c +++ b/lunaix-os/libs/klibc/stdio/sprintf.c @@ -8,20 +8,20 @@ static const char flag_chars[] = "#0- +"; -#define FLAG_ALT (1<<0) -#define FLAG_ZERO (1<<1) -#define FLAG_LEFTJUSTIFY (1<<2) -#define FLAG_SPACEPOSITIVE (1<<3) -#define FLAG_PLUSPOSITIVE (1<<4) -#define FLAG_NUMERIC (1<<5) -#define FLAG_SIGNED (1<<6) -#define FLAG_NEGATIVE (1<<7) -#define FLAG_ALT2 (1<<8) -#define FLAG_CAPS (1<<9) - - -// FIXME: use something like IO_FILE to abstract this into a more flexible, stream based, vprintf -void +#define FLAG_ALT (1 << 0) +#define FLAG_ZERO (1 << 1) +#define FLAG_LEFTJUSTIFY (1 << 2) +#define FLAG_SPACEPOSITIVE (1 << 3) +#define FLAG_PLUSPOSITIVE (1 << 4) +#define FLAG_NUMERIC (1 << 5) +#define FLAG_SIGNED (1 << 6) +#define FLAG_NEGATIVE (1 << 7) +#define FLAG_ALT2 (1 << 8) +#define FLAG_CAPS (1 << 9) + +// FIXME: use something like IO_FILE to abstract this into a more flexible, +// stream based, vprintf +size_t __sprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs) { // This sprintf just a random implementation I found it on Internet . lol. @@ -33,7 +33,7 @@ __sprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs) if (max_len && ptr >= max_len - 1) { break; } - + if (*fmt != '%') { buffer[ptr++] = *fmt; continue; @@ -53,7 +53,7 @@ __sprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs) // process width int width = -1; if (*fmt >= '1' && *fmt <= '9') { - for (width = 0; *fmt >= '0' && *fmt <= '9'; ) { + for (width = 0; *fmt >= '0' && *fmt <= '9';) { width = 10 * width + *fmt++ - '0'; } } else if (*fmt == '*') { @@ -66,7 +66,7 @@ __sprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs) if (*fmt == '.') { ++fmt; if (*fmt >= '0' && *fmt <= '9') { - for (precision = 0; *fmt >= '0' && *fmt <= '9'; ) { + for (precision = 0; *fmt >= '0' && *fmt <= '9';) { precision = 10 * precision + *fmt++ - '0'; } } else if (*fmt == '*') { @@ -85,60 +85,60 @@ __sprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs) char* data = ""; again: switch (*fmt) { - case 'l': - case 'z': - length = 1; - ++fmt; - goto again; - case 'd': - case 'i': { - long x = length ? va_arg(vargs, long) : va_arg(vargs, int); - int negative = x < 0 ? FLAG_NEGATIVE : 0; - num = negative ? -x : x; - flags |= FLAG_NUMERIC | FLAG_SIGNED | negative; - break; - } - case 'u': - format_unsigned: - num = length ? va_arg(vargs, unsigned long) : va_arg(vargs, unsigned); - flags |= FLAG_NUMERIC; - break; - case 'x': - base = 16; - goto format_unsigned; - case 'X': - flags = flags | FLAG_CAPS; - base = 16; - goto format_unsigned; - case 'p': - num = (uintptr_t) va_arg(vargs, void*); - base = 16; - flags |= FLAG_ALT | FLAG_ALT2 | FLAG_NUMERIC; - break; - case 's': - data = va_arg(vargs, char*); - break; - case 'c': - data = numbuf; - numbuf[0] = va_arg(vargs, int); - numbuf[1] = '\0'; - break; - default: - data = numbuf; - numbuf[0] = (*fmt ? *fmt : '%'); - numbuf[1] = '\0'; - if (!*fmt) { - fmt--; + case 'l': + case 'z': + length = 1; + ++fmt; + goto again; + case 'd': + case 'i': { + long x = length ? va_arg(vargs, long) : va_arg(vargs, int); + int negative = x < 0 ? FLAG_NEGATIVE : 0; + num = negative ? -x : x; + flags |= FLAG_NUMERIC | FLAG_SIGNED | negative; + break; } - break; + case 'u': + format_unsigned: + num = length ? va_arg(vargs, unsigned long) + : va_arg(vargs, unsigned); + flags |= FLAG_NUMERIC; + break; + case 'x': + base = 16; + goto format_unsigned; + case 'X': + flags = flags | FLAG_CAPS; + base = 16; + goto format_unsigned; + case 'p': + num = (uintptr_t)va_arg(vargs, void*); + base = 16; + flags |= FLAG_ALT | FLAG_ALT2 | FLAG_NUMERIC; + break; + case 's': + data = va_arg(vargs, char*); + break; + case 'c': + data = numbuf; + numbuf[0] = va_arg(vargs, int); + numbuf[1] = '\0'; + break; + default: + data = numbuf; + numbuf[0] = (*fmt ? *fmt : '%'); + numbuf[1] = '\0'; + if (!*fmt) { + fmt--; + } + break; } if (flags & FLAG_NUMERIC) { data = itoa(num, numbuf, base); int i = 0; char c; - while ((flags & FLAG_CAPS) && (c = data[i])) - { + while ((flags & FLAG_CAPS) && (c = data[i])) { data[i] = c & ~((c & 0x40) >> 1); i++; } @@ -153,9 +153,9 @@ __sprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs) } else if (flags & FLAG_SPACEPOSITIVE) { prefix = " "; } - } else if ((flags & FLAG_NUMERIC) && (flags & FLAG_ALT) - && (base == 16 || base == -16) - && (num || (flags & FLAG_ALT2))) { + } else if ((flags & FLAG_NUMERIC) && (flags & FLAG_ALT) && + (base == 16 || base == -16) && + (num || (flags & FLAG_ALT2))) { prefix = "0x"; } @@ -168,9 +168,9 @@ __sprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs) int zeros; if ((flags & FLAG_NUMERIC) && precision >= 0) { zeros = precision > len ? precision - len : 0; - } else if ((flags & FLAG_NUMERIC) && (flags & FLAG_ZERO) - && !(flags & FLAG_LEFTJUSTIFY) - && len + (int) strlen(prefix) < width) { + } else if ((flags & FLAG_NUMERIC) && (flags & FLAG_ZERO) && + !(flags & FLAG_LEFTJUSTIFY) && + len + (int)strlen(prefix) < width) { zeros = width - len - strlen(prefix); } else { zeros = 0; @@ -193,22 +193,26 @@ __sprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs) } } buffer[ptr++] = '\0'; + + return ptr; } -void +size_t sprintf(char* buffer, char* fmt, ...) { va_list args; va_start(args, fmt); - __sprintf_internal(buffer, fmt, 0, args); + size_t len = __sprintf_internal(buffer, fmt, 0, args); va_end(args); + return len; } -void +size_t snprintf(char* buffer, size_t n, char* fmt, ...) { va_list args; va_start(args, fmt); - __sprintf_internal(buffer, fmt, n, args); + size_t len = __sprintf_internal(buffer, fmt, n, args); va_end(args); + return len; } \ No newline at end of file