dbg.cpp 2.5 KB

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