dbg.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * Copyright 2011-2012 Branimir Karadzic. All rights reserved.
  3. * License: http://www.opensource.org/licenses/BSD-2-Clause
  4. */
  5. #include <bx/bx.h>
  6. #include <stdio.h>
  7. #include <stdint.h>
  8. #include <inttypes.h>
  9. #include <ctype.h> // isprint
  10. #include "dbg.h"
  11. #if BX_COMPILER_MSVC
  12. # define snprintf _snprintf
  13. #endif // BX_COMPILER_MSVC
  14. #if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360
  15. extern "C"
  16. {
  17. __declspec(dllimport) void __stdcall OutputDebugStringA(const char* _str);
  18. }
  19. #endif // BX_PLATFORM_WINDOWS
  20. void dbgOutput(const char* _out)
  21. {
  22. #if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360
  23. OutputDebugStringA(_out);
  24. #elif BX_PLATFORM_NACL || BX_PLATFORM_LINUX
  25. fputs(_out, stderr);
  26. fflush(stderr);
  27. #endif // BX_PLATFORM_
  28. }
  29. void dbgPrintfVargs(const char* _format, va_list _argList)
  30. {
  31. char temp[8192];
  32. vsnprintf(temp, sizeof(temp), _format, _argList);
  33. temp[sizeof(temp)-1] = '\0';
  34. dbgOutput(temp);
  35. }
  36. void dbgPrintf(const char* _format, ...)
  37. {
  38. va_list argList;
  39. va_start(argList, _format);
  40. dbgPrintfVargs(_format, argList);
  41. va_end(argList);
  42. }
  43. #define DBG_ADDRESS "%" PRIxPTR
  44. void dbgPrintfData(const void* _data, uint32_t _size, const char* _format, ...)
  45. {
  46. #define HEX_DUMP_WIDTH 16
  47. #define HEX_DUMP_SPACE_WIDTH 48
  48. #define HEX_DUMP_FORMAT "%-" DBG_STRINGIZE(HEX_DUMP_SPACE_WIDTH) "." DBG_STRINGIZE(HEX_DUMP_SPACE_WIDTH) "s"
  49. va_list argList;
  50. va_start(argList, _format);
  51. dbgPrintfVargs(_format, argList);
  52. va_end(argList);
  53. dbgPrintf("\ndata: " DBG_ADDRESS ", size: %d\n", _data, _size);
  54. if (NULL != _data)
  55. {
  56. const uint8_t* data = reinterpret_cast<const uint8_t*>(_data);
  57. char hex[HEX_DUMP_WIDTH*3+1];
  58. char ascii[HEX_DUMP_WIDTH+1];
  59. uint32_t hexPos = 0;
  60. uint32_t asciiPos = 0;
  61. for (uint32_t ii = 0; ii < _size; ++ii)
  62. {
  63. snprintf(&hex[hexPos], sizeof(hex)-hexPos, "%02x ", data[asciiPos]);
  64. hexPos += 3;
  65. ascii[asciiPos] = isprint(data[asciiPos]) ? data[asciiPos] : '.';
  66. asciiPos++;
  67. if (HEX_DUMP_WIDTH == asciiPos)
  68. {
  69. ascii[asciiPos] = '\0';
  70. dbgPrintf("\t" DBG_ADDRESS "\t" HEX_DUMP_FORMAT "\t%s\n", data, hex, ascii);
  71. data += asciiPos;
  72. hexPos = 0;
  73. asciiPos = 0;
  74. }
  75. }
  76. if (0 != asciiPos)
  77. {
  78. ascii[asciiPos] = '\0';
  79. dbgPrintf("\t" DBG_ADDRESS "\t" HEX_DUMP_FORMAT "\t%s\n", data, hex, ascii);
  80. }
  81. }
  82. #undef HEX_DUMP_WIDTH
  83. #undef HEX_DUMP_SPACE_WIDTH
  84. #undef HEX_DUMP_FORMAT
  85. }