KString.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #include "KString.h"
  2. #include <stdarg.h>
  3. #include "MiniCppUnit.hxx"
  4. ///////////////////////////////////////////////////////////////////////////////
  5. ///////////////////////////////////////////////////////////////////////////////
  6. // String Helper
  7. static std::string vasprintf(const char *fmt, va_list argv) {
  8. std::string result;
  9. va_list argv_copy; // vsnprintf modifies argv, need copy
  10. #ifndef va_copy
  11. argv_copy = argv;
  12. #else
  13. va_copy(argv_copy, argv);
  14. #endif
  15. int len = vsnprintf(NULL, 0, fmt, argv_copy);
  16. if (len > 0 && len < 255) {
  17. // cover 90% of all calls
  18. char str[256] = {0};
  19. int len2 = vsnprintf(str, 255, fmt, argv);
  20. result = str;
  21. } else if (len > 0) {
  22. char *str = static_cast<char *>(alloca(len + 1)); // alloca on stack, space for null-termination
  23. int len2 = vsnprintf(str, len + 1, fmt, argv);
  24. result = str;
  25. }
  26. return result;
  27. }
  28. static void reportWarning(const std::string &warnStr) {
  29. if (JetBrains::underTeamcity())
  30. gTeamCityListener.messages.messageWarning(warnStr);
  31. else
  32. fprintf(stderr, "%s", warnStr.c_str());
  33. }
  34. static void reportError(const std::string &errorStr) {
  35. if (JetBrains::underTeamcity())
  36. gTeamCityListener.messages.messageError(errorStr);
  37. else
  38. fprintf(stderr, "%s", errorStr.c_str());
  39. }
  40. static void reportInfo(const std::string &infoStr) {
  41. if (JetBrains::underTeamcity())
  42. gTeamCityListener.messages.messageNormal(infoStr);
  43. else
  44. fprintf(stderr, "%s", infoStr.c_str());
  45. }
  46. static void reportDebug(const std::string &debugStr) {
  47. fprintf(stderr, "%s", debugStr.c_str());
  48. }
  49. static void report(ErrorLevel level, const std::string &Str) {
  50. switch (level) {
  51. case WARNLVL:
  52. reportWarning(Str);
  53. break;
  54. case ERRORLVL:
  55. reportError(Str);
  56. break;
  57. case INFOLVL:
  58. reportInfo(Str);
  59. break;
  60. case DEBUGLVL:
  61. reportDebug(Str);
  62. break;
  63. }
  64. }
  65. void KOutputDebug(ErrorLevel lvl, const char *fmt ...) {
  66. va_list argList;
  67. va_start(argList, fmt);
  68. std::string str = vasprintf(fmt, argList);
  69. va_end(argList);
  70. report(lvl, str);
  71. }
  72. #define K_MAX(a, b) ((a>b) ? a : b)
  73. std::string GetFileName(const std::string &thePath, bool noExtension) {
  74. int aLastSlash = K_MAX((int) thePath.rfind('\\'), (int) thePath.rfind('/'));
  75. if (noExtension) {
  76. int aLastDot = (int) thePath.rfind('.');
  77. if (aLastDot > aLastSlash)
  78. return thePath.substr(aLastSlash + 1, aLastDot - aLastSlash - 1);
  79. }
  80. if (aLastSlash == -1)
  81. return thePath;
  82. else
  83. return thePath.substr(aLastSlash + 1);
  84. }
  85. std::string GetFileDir(const std::string &thePath, bool withSlash) {
  86. int aLastSlash = K_MAX((int) thePath.rfind(('\\')), (int) thePath.rfind(('/')));
  87. if (aLastSlash == -1)
  88. return ("");
  89. else {
  90. if (withSlash)
  91. return thePath.substr(0, aLastSlash + 1);
  92. else
  93. return thePath.substr(0, aLastSlash);
  94. }
  95. }
  96. std::string GetFileExt(const std::string &thePath) {
  97. std::string::size_type idx = thePath.find_last_of('.');
  98. if (idx != std::string::npos)
  99. return thePath.substr(idx + 1);
  100. return ("");
  101. }
  102. /**
  103. * g_ascii_strcasecmp:
  104. * @s1: string to compare with @s2.
  105. * @s2: string to compare with @s1.
  106. *
  107. * Compare two strings, ignoring the case of ASCII characters.
  108. *
  109. * Unlike the BSD strcasecmp() function, this only recognizes standard
  110. * ASCII letters and ignores the locale, treating all non-ASCII
  111. * bytes as if they are not letters.
  112. *
  113. * This function should be used only on strings that are known to be
  114. * in encodings where the bytes corresponding to ASCII letters always
  115. * represent themselves. This includes UTF-8 and the ISO-8859-*
  116. * charsets, but not for instance double-byte encodings like the
  117. * Windows Codepage 932, where the trailing bytes of double-byte
  118. * characters include all ASCII letters. If you compare two CP932
  119. * strings using this function, you will get false matches.
  120. *
  121. * Return value: an integer less than, equal to, or greater than
  122. * zero if @s1 is found, respectively, to be less than,
  123. * to match, or to be greater than @s2.
  124. **/
  125. static int g_ascii_compare_caseless(const char *s1, const char *s2) {
  126. #define TOUPPER(c) (((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 'A' : (c))
  127. #define TOLOWER(c) (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' + 'a' : (c))
  128. #define g_return_val_if_fail(expr, val) { if (!(expr)) return (val); }
  129. int c1, c2;
  130. g_return_val_if_fail(s1 != NULL, 0);
  131. g_return_val_if_fail(s2 != NULL, 0);
  132. while (*s1 && *s2) {
  133. c1 = (int) (unsigned char) TOLOWER(*s1);
  134. c2 = (int) (unsigned char) TOLOWER(*s2);
  135. if (c1 != c2)
  136. return (c1 - c2);
  137. s1++;
  138. s2++;
  139. }
  140. return (((int) (unsigned char) *s1) - ((int) (unsigned char) *s2));
  141. #undef g_return_val_if_fail
  142. #undef TOUPPER
  143. #undef TOLOWER
  144. }
  145. int CompareNoCase(const std::string &str1, const std::string &str2) {
  146. return g_ascii_compare_caseless(str1.c_str(), str2.c_str());
  147. }