macros.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. This software is subject to the license described in the License.txt file
  3. included with this software distribution. You may not use this file except
  4. in compliance with this license.
  5. Copyright (c) Dynastream Innovations Inc. 2016
  6. All rights reserved.
  7. */
  8. #include "types.h"
  9. #include "macros.h"
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <stdarg.h>
  13. #if defined(_MSC_VER)
  14. //////////////////////////////////////////////////////////////////////////////////
  15. // Public Functions
  16. //////////////////////////////////////////////////////////////////////////////////
  17. int SNPRINTF(char* pcDst_, size_t uNum_, const char* pcFormat_, ...)
  18. {
  19. va_list hList;
  20. int iWritten;
  21. if(uNum_ == 0)
  22. return -1;
  23. va_start(hList, pcFormat_);
  24. iWritten = vsnprintf_s(pcDst_, uNum_, _TRUNCATE, pcFormat_, hList);
  25. va_end(hList);
  26. if(iWritten == -1) //check for truncation
  27. return ((int)(uNum_-1));
  28. return iWritten;
  29. }
  30. size_t VSNPRINTF(char* pcDst_, size_t uNum_, const char* pcFormat_, va_list args)
  31. {
  32. int iWritten;
  33. if(uNum_ == 0)
  34. return -1;
  35. iWritten = vsnprintf_s(pcDst_, uNum_, _TRUNCATE, pcFormat_, args);
  36. if(iWritten == -1) //check for truncation
  37. return uNum_-1; //uNum-1 to match SNPRINTF return, don't know why it treats truncation that way
  38. return iWritten;
  39. }
  40. BOOL STRNCPY(char* pcDst_, const char* pcSrc_, size_t uNum_)
  41. {
  42. if(strlen(pcSrc_) + 1 > uNum_)
  43. return FALSE;
  44. return (strcpy_s(pcDst_, uNum_, pcSrc_) == 0);
  45. }
  46. BOOL STRNCAT(char* pcDst_, const char* pcSrc_, size_t uNum_)
  47. {
  48. if(strlen(pcDst_) + strlen(pcSrc_) + 1 > uNum_)
  49. return FALSE;
  50. return (strcat_s(pcDst_, uNum_, pcSrc_) == 0);
  51. }
  52. FILE* FOPEN(const char* pcFilename_, const char* pcMode_)
  53. {
  54. FILE* pfFile;
  55. return (fopen_s(&pfFile, pcFilename_, pcMode_) == 0) ? pfFile : NULL;
  56. }
  57. #else
  58. // NOTE: Alternative macro --> #define SNPRINTF(dst, num, fmt, ...) (snprintf(dst, num, fmt, __VA_ARGS__) != -1 ? strlen(dst) : -1)
  59. // C99 standard states that it will return the number of bytes that should have been written. This is not necessarily the case with older libraries.
  60. int SNPRINTF(char* pcDst_, size_t uNum_, const char* pcFormat_, ...)
  61. {
  62. int iReturn;
  63. va_list hList;
  64. if(uNum_ == 0)
  65. return -1;
  66. if(uNum_ == 1)
  67. {
  68. pcDst_[0] = '\0';
  69. return 0;
  70. }
  71. va_start(hList, pcFormat_);
  72. iReturn = vsnprintf(pcDst_, uNum_, pcFormat_, hList);
  73. pcDst_[uNum_-1] = '\0';
  74. va_end(hList);
  75. if(iReturn < 0) //check if an error occured
  76. return iReturn;
  77. if(iReturn >= (int)( uNum_-1) ) //check if output is truncated
  78. return uNum_-1;
  79. return iReturn;
  80. }
  81. size_t VSNPRINTF(char* pcDst_, size_t uNum_, const char* pcFormat_, va_list args)
  82. {
  83. int iWritten;
  84. if(uNum_ == 0)
  85. return -1;
  86. iWritten = vsnprintf(pcDst_, uNum_, pcFormat_, args);
  87. if(iWritten >= uNum_) //check if output is truncated
  88. return uNum_-1; //uNum-1 to match SNPRINTF return, don't know why it treats truncation that way
  89. return iWritten;
  90. }
  91. BOOL STRNCPY(char* pcDst_, const char* pcSrc_, size_t uNum_)
  92. {
  93. if(uNum_ == 0) //cannot copy a negative amount
  94. return FALSE;
  95. if(strlen(pcSrc_) + 1 > uNum_) //make sure it won't get truncated
  96. return FALSE;
  97. strncpy(pcDst_, pcSrc_, uNum_-1);
  98. pcDst_[uNum_-1] = '\0';
  99. return TRUE;
  100. }
  101. BOOL STRNCAT(char* pcDst_, const char* pcSrc_, size_t uNum_)
  102. {
  103. size_t uDstLen = strlen(pcDst_);
  104. if(uNum_ == 0 || uNum_-1 < uDstLen) //cannot concatenate a negative amount
  105. return FALSE;
  106. if(uDstLen + strlen(pcSrc_) + 1 > uNum_)
  107. return FALSE;
  108. strncat(pcDst_, pcSrc_, (uNum_-1)-uDstLen);
  109. return TRUE;
  110. }
  111. FILE* FOPEN(const char* pcFilename_, const char* pcMode_)
  112. {
  113. return fopen(pcFilename_, pcMode_);
  114. }
  115. #endif