dbg.cpp 2.6 KB

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