Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <libc/stdio.h>
- #include <libc/string.h>
- #include <kernel/vga.h>
- #include <limits.h>
- #include <stdbool.h>
- #include <stdarg.h>
- int putchar(int ic) {
- char c = (char) ic;
- term_write(&c, sizeof(c));
- return ic;
- }
- char* str_reverse(char* str, int length) {
- char temp;
- int i=0, j;
- j=length;
- while(i<j)
- {
- temp=str[i];
- str[i]=str[j];
- str[j]=temp;
- i++;
- j--;
- }
- return str;
- }
- char* itoa(int num, char* str, int base)
- {
- int i = 0;
- bool isNegative = false;
- /* Handle 0 explicitely, otherwise empty string is printed for 0 */
- if (num == 0)
- {
- str[i++] = '0';
- str[i] = '\0';
- return str;
- }
- // In standard itoa(), negative numbers are handled only with
- // base 10. Otherwise numbers are considered unsigned.
- if (num < 0 && base == 10)
- {
- isNegative = true;
- num = -num;
- }
- // Process individual digits
- while (num != 0)
- {
- int rem = num % base;
- str[i++] = (rem > 9)? (rem-10) + 'a' : rem + '0';
- num = num/base;
- }
- // If number is negative, append '-'
- if (isNegative)
- str[i++] = '-';
- str[i] = '\0'; // Append string terminator
- // Reverse the string
- str_reverse(str, i);
- return str;
- }
- static bool print(const char* data, size_t length) {
- const unsigned char* bytes = (const unsigned char*) data;
- for (size_t i = 0; i < length; i++)
- if (putchar(bytes[i]) == 0)
- return false;
- return true;
- }
- int printf(const char* format, ...) {
- va_list parameters;
- va_start(parameters, format);
- int written = 0;
- while (*format != '\0') {
- size_t maxrem = INT_MAX - written;
- if (format[0] != '%' || format[1] == '%') {
- if (format[0] == '%')
- format++;
- size_t amount = 1;
- while (format[amount] && format[amount] != '%')
- amount++;
- if (maxrem < amount) {
- // TODO: Set errno to EOVERFLOW.
- return -1;
- }
- if (!print(format, amount))
- return -1;
- format += amount;
- written += amount;
- continue;
- }
- const char* format_begun_at = format++;
- if (*format == 'c') {
- format++;
- char c = (char) va_arg(parameters, int /* char promotes to int */);
- if (!maxrem) {
- // TODO: Set errno to EOVERFLOW.
- return -1;
- }
- if (!print(&c, sizeof(c)))
- return -1;
- written++;
- } else if (*format == 's') {
- format++;
- const char* str = va_arg(parameters, const char*);
- size_t len = strlen(str);
- if (maxrem < len) {
- // TODO: Set errno to EOVERFLOW.
- return -1;
- }
- if (!print(str, len))
- return -1;
- written += len;
- } else if(*format == 'i' || *format == 'd') {
- format++;
- if (!maxrem) {
- // TODO: Set errno to EOVERFLOW
- return 1;
- }
- } else {
- format = format_begun_at;
- size_t len = strlen(format);
- if (maxrem < len) {
- // TODO: Set errno to EOVERFLOW.
- return -1;
- }
- if (!print(format, len))
- return -1;
- written += len;
- format += len;
- }
- }
- va_end(parameters);
- return written;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement