kprintf.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #include "kprintf.h"
  2. #include "Console.h"
  3. #include <stdarg.h>
  4. #include <AK/Types.h>
  5. template<typename PutChFunc> static int printNumber(PutChFunc, char*&, dword);
  6. template<typename PutChFunc> static int printHex(PutChFunc, char*&, dword, byte fields);
  7. template<typename PutChFunc> static int printSignedNumber(PutChFunc, char*&, int);
  8. static void console_putch(char*, char ch)
  9. {
  10. Console::the().write((byte*)&ch, 1);
  11. }
  12. template<typename PutChFunc>
  13. int kprintfInternal(PutChFunc putch, char* buffer, const char*& fmt, char*& ap)
  14. {
  15. const char *p;
  16. int ret = 0;
  17. char* bufptr = buffer;
  18. for (p = fmt; *p; ++p) {
  19. if (*p == '%' && *(p + 1)) {
  20. ++p;
  21. switch( *p )
  22. {
  23. case 's':
  24. {
  25. const char* sp = va_arg(ap, const char*);
  26. //ASSERT(sp != nullptr);
  27. if (!sp) {
  28. putch(bufptr, '<');
  29. putch(bufptr, 'N');
  30. putch(bufptr, 'u');
  31. putch(bufptr, 'L');
  32. putch(bufptr, '>');
  33. ret += 5;
  34. } else {
  35. for (; *sp; ++sp) {
  36. putch(bufptr, *sp);
  37. ++ret;
  38. }
  39. }
  40. }
  41. break;
  42. case 'd':
  43. ret += printSignedNumber(putch, bufptr, va_arg(ap, int));
  44. break;
  45. case 'u':
  46. ret += printNumber(putch, bufptr, va_arg(ap, dword));
  47. break;
  48. case 'x':
  49. ret += printHex(putch, bufptr, va_arg(ap, dword), 8);
  50. break;
  51. case 'w':
  52. ret += printHex(putch, bufptr, va_arg(ap, int), 4);
  53. break;
  54. case 'b':
  55. ret += printHex(putch, bufptr, va_arg(ap, int), 2);
  56. break;
  57. case 'c':
  58. putch(bufptr, (char)va_arg(ap, int));
  59. ++ret;
  60. break;
  61. case 'p':
  62. putch(bufptr, '0');
  63. putch(bufptr, 'x');
  64. ret += 2;
  65. ret += printHex(putch, bufptr, va_arg(ap, dword), 8);
  66. break;
  67. }
  68. }
  69. else {
  70. putch(bufptr, *p);
  71. ++ret;
  72. }
  73. }
  74. return ret;
  75. }
  76. int kprintf(const char* fmt, ...)
  77. {
  78. va_list ap;
  79. va_start(ap, fmt);
  80. int ret = kprintfInternal(console_putch, nullptr, fmt, ap);
  81. va_end(ap);
  82. return ret;
  83. }
  84. static void buffer_putch(char*& bufptr, char ch)
  85. {
  86. *bufptr++ = ch;
  87. }
  88. int ksprintf(char* buffer, const char* fmt, ...)
  89. {
  90. va_list ap;
  91. va_start(ap, fmt);
  92. int ret = kprintfInternal(buffer_putch, buffer, fmt, ap);
  93. buffer[ret] = '\0';
  94. va_end(ap);
  95. return ret;
  96. }
  97. template<typename PutChFunc>
  98. int printHex(PutChFunc putch, char*& bufptr, dword number, byte fields)
  99. {
  100. static const char h[] = {
  101. '0','1','2','3','4','5','6','7',
  102. '8','9','a','b','c','d','e','f'
  103. };
  104. int ret = 0;
  105. byte shr_count = fields * 4;
  106. while (shr_count) {
  107. shr_count -= 4;
  108. putch(bufptr, h[(number >> shr_count) & 0x0F]);
  109. ++ret;
  110. }
  111. return ret;
  112. }
  113. template<typename PutChFunc>
  114. int printNumber(PutChFunc putch, char*& bufptr, dword number)
  115. {
  116. dword divisor = 1000000000;
  117. char ch;
  118. char padding = 1;
  119. int ret = 0;
  120. for (;;) {
  121. ch = '0' + (number / divisor);
  122. number %= divisor;
  123. if (ch != '0')
  124. padding = 0;
  125. if (!padding || divisor == 1) {
  126. putch(bufptr, ch);
  127. ++ret;
  128. }
  129. if (divisor == 1)
  130. break;
  131. divisor /= 10;
  132. }
  133. return ret;
  134. }
  135. template<typename PutChFunc>
  136. static int printSignedNumber(PutChFunc putch, char*& bufptr, int number)
  137. {
  138. if (number < 0) {
  139. putch(bufptr, '-');
  140. return printNumber(putch, bufptr, 0 - number) + 1;
  141. }
  142. return printNumber(putch, bufptr, number);
  143. }