Advertisement
Guest User

Untitled

a guest
Feb 25th, 2020
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.04 KB | None | 0 0
  1. #include <libc/stdio.h>
  2. #include <libc/string.h>
  3.  
  4. #include <kernel/vga.h>
  5.  
  6. #include <limits.h>
  7. #include <stdbool.h>
  8. #include <stdarg.h>
  9.  
  10. int putchar(int ic) {
  11.     char c = (char) ic;
  12.     term_write(&c, sizeof(c));
  13.    
  14.     return ic;
  15. }
  16.  
  17. char* str_reverse(char* str, int length) {
  18.     char temp;
  19.     int i=0, j;
  20.     j=length;
  21.     while(i<j)
  22.     {
  23.         temp=str[i];
  24.         str[i]=str[j];
  25.         str[j]=temp;
  26.         i++;
  27.         j--;
  28.     }
  29.  
  30.     return str;
  31. }
  32.  
  33. char* itoa(int num, char* str, int base)
  34. {
  35.     int i = 0;
  36.     bool isNegative = false;
  37.  
  38.     /* Handle 0 explicitely, otherwise empty string is printed for 0 */
  39.     if (num == 0)
  40.     {
  41.         str[i++] = '0';
  42.         str[i] = '\0';
  43.         return str;
  44.     }
  45.  
  46.     // In standard itoa(), negative numbers are handled only with  
  47.     // base 10. Otherwise numbers are considered unsigned.
  48.     if (num < 0 && base == 10)
  49.     {
  50.         isNegative = true;
  51.         num = -num;
  52.     }
  53.  
  54.     // Process individual digits
  55.     while (num != 0)
  56.     {
  57.         int rem = num % base;
  58.         str[i++] = (rem > 9)? (rem-10) + 'a' : rem + '0';
  59.         num = num/base;
  60.     }
  61.  
  62.     // If number is negative, append '-'
  63.     if (isNegative)
  64.         str[i++] = '-';
  65.  
  66.     str[i] = '\0'; // Append string terminator
  67.  
  68.     // Reverse the string
  69.     str_reverse(str, i);
  70.  
  71.     return str;
  72. }
  73.  
  74. static bool print(const char* data, size_t length) {
  75.     const unsigned char* bytes = (const unsigned char*) data;
  76.     for (size_t i = 0; i < length; i++)
  77.         if (putchar(bytes[i]) == 0)
  78.             return false;
  79.     return true;
  80. }
  81.  
  82. int printf(const char* format, ...) {
  83.     va_list parameters;
  84.     va_start(parameters, format);
  85.  
  86.     int written = 0;
  87.  
  88.     while (*format != '\0') {
  89.         size_t maxrem = INT_MAX - written;
  90.  
  91.         if (format[0] != '%' || format[1] == '%') {
  92.             if (format[0] == '%')
  93.                 format++;
  94.             size_t amount = 1;
  95.             while (format[amount] && format[amount] != '%')
  96.                 amount++;
  97.             if (maxrem < amount) {
  98.                 // TODO: Set errno to EOVERFLOW.
  99.                 return -1;
  100.             }
  101.             if (!print(format, amount))
  102.                 return -1;
  103.             format += amount;
  104.             written += amount;
  105.             continue;
  106.         }
  107.  
  108.         const char* format_begun_at = format++;
  109.  
  110.         if (*format == 'c') {
  111.             format++;
  112.             char c = (char) va_arg(parameters, int /* char promotes to int */);
  113.             if (!maxrem) {
  114.                 // TODO: Set errno to EOVERFLOW.
  115.                 return -1;
  116.             }
  117.             if (!print(&c, sizeof(c)))
  118.                 return -1;
  119.             written++;
  120.         } else if (*format == 's') {
  121.             format++;
  122.             const char* str = va_arg(parameters, const char*);
  123.             size_t len = strlen(str);
  124.             if (maxrem < len) {
  125.                 // TODO: Set errno to EOVERFLOW.
  126.                 return -1;
  127.             }
  128.             if (!print(str, len))
  129.                 return -1;
  130.             written += len;
  131.         } else if(*format == 'i' || *format == 'd') {
  132.             format++;
  133.             if (!maxrem) {
  134.                 // TODO: Set errno to EOVERFLOW
  135.                 return 1;
  136.             }
  137.         } else {
  138.             format = format_begun_at;
  139.             size_t len = strlen(format);
  140.             if (maxrem < len) {
  141.                 // TODO: Set errno to EOVERFLOW.
  142.                 return -1;
  143.             }
  144.             if (!print(format, len))
  145.                 return -1;
  146.             written += len;
  147.             format += len;
  148.         }
  149.     }
  150.  
  151.     va_end(parameters);
  152.     return written;
  153. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement