some finishing touches to printf

This commit is contained in:
2025-05-30 15:20:02 -04:00
parent 47056f7d9a
commit f8c38d22b0
4 changed files with 316 additions and 110 deletions

View File

@ -22,4 +22,12 @@ void kmain(void)
terminal_initialize();
serial_initialize();
#endif
uint8_t a = 2;
uint16_t b = 3;
int c = 4;
uint64_t d = 10;
printf("%d, %d, %d, %3", a, b, c, d);
}

View File

@ -1,17 +1,24 @@
#include <stdint.h>
#ifndef _STDLIB_H
#define _STDLIB_H 1
#include <sys/cdefs.h>
#ifdef __cplusplus
extern "C" {
#endif
__attribute__((__noreturn__))
void abort(void);
#ifdef __cplusplus
}
#endif
char* s64toa(int64_t num, char* buf, int base);
char* u64toa(uint64_t num, char* buf, int base);
char* s32toa(int32_t num, char* buf, int base);
char* u32toa(uint32_t num, char* buf, int base);
char* s16toa(int16_t num, char* buf, int base);
char* u16toa(uint16_t num, char* buf, int base);
char* s8toa(int8_t num, char* buf, int base);
char* u8toa(uint8_t num, char* buf, int base);
char* itoa(int num, char* buf, int base);
char* utoa(unsigned int num, char* buf, int base);
#endif

View File

@ -4,104 +4,8 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <kernel/_kernel.h>
static void reverse(char* buf, int len)
{
int start = 0;
int end = len - 1;
while (start < end) {
char tmp = buf[start];
buf[start] = buf[end];
buf[end] = tmp;
end--;
start++;
}
}
static char* s64toa(int64_t num, char* buf, int base)
{
int i = 0;
bool neg = false;
if (num == 0) { // Handle zero explicitly
buf[i++] = '0';
buf[i] = '\0';
return buf;
}
if (num < 0 && base == 10) { // only handle negative on base10
neg = true;
num = -num;
}
while (num != 0) {
int rem = num % base;
buf[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
num = num / base;
}
if (neg) // lets reapply the negative sign
buf[i++] = '-';
buf[i] = '\0';
reverse(buf, i); // reverse, since we did it backwards!
return buf;
}
static char* u64toa(uint64_t num, char* buf, int base)
{
int i = 0;
if (num == 0) { // Handle zero explicitly
buf[i++] = '0';
buf[i] = '\0';
return buf;
}
while (num != 0) {
int rem = num % base;
buf[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
num = num / base;
}
buf[i] = '\0';
reverse(buf, i); // reverse, since we did it backwards!
return buf;
}
static char* itoa(int num, char* buf, int base)
{
int i = 0;
bool neg = false;
if (num == 0) { // Handle zero explicitly
buf[i++] = '0';
buf[i] = '\0';
return buf;
}
if (num < 0 && base == 10) { // only handle negative on base10
neg = true;
num = -num;
}
while (num != 0) {
int rem = num % base;
buf[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
num = num / base;
}
if (neg) // lets reapply the negative sign
buf[i++] = '-';
buf[i] = '\0';
reverse(buf, i); // reverse, since we did it backwards!
return buf;
}
static bool print(const char* data, size_t length) {
const unsigned char* bytes = (const unsigned char*) data;
@ -173,6 +77,18 @@ int printf(const char* restrict format, ...) {
if (!print(buffer, len))
return -1;
written += len;
} else if (*format == 'u') {
format++;
unsigned int i = (unsigned int) va_arg(parameters, unsigned int);
utoa(i, buffer, 10);
size_t len = strlen(buffer);
if (maxrem < len) {
// TODO: Set errno to EOVERFLOW.
return -1;
}
if (!print(buffer, len))
return -1;
written += len;
} else if (*format == 'x') {
format++;
int i = (int) va_arg(parameters, int);
@ -187,8 +103,8 @@ int printf(const char* restrict format, ...) {
written += len;
} else if (*format == '1') {
format++;
uint64_t i = (uint64_t) va_arg(parameters, uint64_t);
u64toa(i, buffer, 10);
int32_t i = (int32_t) va_arg(parameters, int32_t);
s32toa(i, buffer, 10);
size_t len = strlen(buffer);
if (maxrem < len) {
// TODO: Set errno to EOVERFLOW.
@ -199,8 +115,8 @@ int printf(const char* restrict format, ...) {
written += len;
} else if (*format == '2') {
format++;
uint64_t i = (uint64_t) va_arg(parameters, uint64_t);
u64toa(i, buffer, 16);
uint32_t i = (uint32_t) va_arg(parameters, uint32_t);
u32toa(i, buffer, 16);
size_t len = strlen(buffer);
if (maxrem < len) {
// TODO: Set errno to EOVERFLOW.
@ -223,8 +139,8 @@ int printf(const char* restrict format, ...) {
written += len;
} else if (*format == '4') {
format++;
int64_t i = (int64_t) va_arg(parameters, int64_t);
s64toa(i, buffer, 16);
uint64_t i = (uint64_t) va_arg(parameters, uint64_t);
u64toa(i, buffer, 16);
size_t len = strlen(buffer);
if (maxrem < len) {
// TODO: Set errno to EOVERFLOW.

275
libc/stdlib/itoa.c Normal file
View File

@ -0,0 +1,275 @@
#include <stdbool.h>
#include <stdint.h>
static void reverse(char* buf, int len)
{
int start = 0;
int end = len - 1;
while (start < end) {
char tmp = buf[start];
buf[start] = buf[end];
buf[end] = tmp;
end--;
start++;
}
}
char* s64toa(int64_t num, char* buf, int base)
{
int i = 0;
bool neg = false;
if (num == 0) { // Handle zero explicitly
buf[i++] = '0';
buf[i] = '\0';
return buf;
}
if (num < 0 && base == 10) { // only handle negative on base10
neg = true;
num = -num;
}
while (num != 0) {
int rem = num % base;
buf[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
num = num / base;
}
if (neg) // lets reapply the negative sign
buf[i++] = '-';
buf[i] = '\0';
reverse(buf, i); // reverse, since we did it backwards!
return buf;
}
char* u64toa(uint64_t num, char* buf, int base)
{
int i = 0;
if (num == 0) { // Handle zero explicitly
buf[i++] = '0';
buf[i] = '\0';
return buf;
}
while (num != 0) {
int rem = num % base;
buf[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
num = num / base;
}
buf[i] = '\0';
reverse(buf, i); // reverse, since we did it backwards!
return buf;
}
char* s32toa(int32_t num, char* buf, int base)
{
int i = 0;
bool neg = false;
if (num == 0) { // Handle zero explicitly
buf[i++] = '0';
buf[i] = '\0';
return buf;
}
if (num < 0 && base == 10) { // only handle negative on base10
neg = true;
num = -num;
}
while (num != 0) {
int rem = num % base;
buf[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
num = num / base;
}
if (neg) // lets reapply the negative sign
buf[i++] = '-';
buf[i] = '\0';
reverse(buf, i); // reverse, since we did it backwards!
return buf;
}
char* u32toa(uint32_t num, char* buf, int base)
{
int i = 0;
if (num == 0) { // Handle zero explicitly
buf[i++] = '0';
buf[i] = '\0';
return buf;
}
while (num != 0) {
int rem = num % base;
buf[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
num = num / base;
}
buf[i] = '\0';
reverse(buf, i); // reverse, since we did it backwards!
return buf;
}
char* s16toa(int16_t num, char* buf, int base)
{
int i = 0;
bool neg = false;
if (num == 0) { // Handle zero explicitly
buf[i++] = '0';
buf[i] = '\0';
return buf;
}
if (num < 0 && base == 10) { // only handle negative on base10
neg = true;
num = -num;
}
while (num != 0) {
int rem = num % base;
buf[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
num = num / base;
}
if (neg) // lets reapply the negative sign
buf[i++] = '-';
buf[i] = '\0';
reverse(buf, i); // reverse, since we did it backwards!
return buf;
}
char* u16toa(uint16_t num, char* buf, int base)
{
int i = 0;
if (num == 0) { // Handle zero explicitly
buf[i++] = '0';
buf[i] = '\0';
return buf;
}
while (num != 0) {
int rem = num % base;
buf[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
num = num / base;
}
buf[i] = '\0';
reverse(buf, i); // reverse, since we did it backwards!
return buf;
}
char* s8toa(int8_t num, char* buf, int base)
{
int i = 0;
bool neg = false;
if (num == 0) { // Handle zero explicitly
buf[i++] = '0';
buf[i] = '\0';
return buf;
}
if (num < 0 && base == 10) { // only handle negative on base10
neg = true;
num = -num;
}
while (num != 0) {
int rem = num % base;
buf[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
num = num / base;
}
if (neg) // lets reapply the negative sign
buf[i++] = '-';
buf[i] = '\0';
reverse(buf, i); // reverse, since we did it backwards!
return buf;
}
char* u8toa(uint8_t num, char* buf, int base)
{
int i = 0;
if (num == 0) { // Handle zero explicitly
buf[i++] = '0';
buf[i] = '\0';
return buf;
}
while (num != 0) {
int rem = num % base;
buf[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
num = num / base;
}
buf[i] = '\0';
reverse(buf, i); // reverse, since we did it backwards!
return buf;
}
char* itoa(int num, char* buf, int base)
{
int i = 0;
bool neg = false;
if (num == 0) { // Handle zero explicitly
buf[i++] = '0';
buf[i] = '\0';
return buf;
}
if (num < 0 && base == 10) { // only handle negative on base10
neg = true;
num = -num;
}
while (num != 0) {
int rem = num % base;
buf[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
num = num / base;
}
if (neg) // lets reapply the negative sign
buf[i++] = '-';
buf[i] = '\0';
reverse(buf, i); // reverse, since we did it backwards!
return buf;
}
char* utoa(unsigned int num, char* buf, int base)
{
int i = 0;
if (num == 0) { // Handle zero explicitly
buf[i++] = '0';
buf[i] = '\0';
return buf;
}
while (num != 0) {
int rem = num % base;
buf[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
num = num / base;
}
buf[i] = '\0';
reverse(buf, i); // reverse, since we did it backwards!
return buf;
}