Open Source Tomb Raider Engine
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

strings.cpp 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*!
  2. * \file src/utils/strings.cpp
  3. * \brief String handling utilities
  4. *
  5. * \author xythobuz
  6. * \author Mongoose
  7. */
  8. #include <cstdlib>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #if defined(unix) || defined(__APPLE__) || defined(__linux__)
  12. #include <wordexp.h>
  13. #elif defined(WIN32)
  14. #include <Windows.h>
  15. #include <shlobj.h>
  16. #ifndef va_copy
  17. #define va_copy(d,s) ((d) = (s))
  18. #endif
  19. #endif
  20. #include "global.h"
  21. #include "utils/strings.h"
  22. char *stringRemoveQuotes(const char *s) {
  23. size_t length = strlen(s);
  24. if ((s[0] == '"') && (s[length - 1] == '"')) {
  25. char *buf = new char[length - 1];
  26. for (size_t i = 1; i < (length - 1); i++)
  27. buf[i - 1] = s[i];
  28. buf[length - 2] = '\0';
  29. return buf;
  30. } else {
  31. return bufferString("%s", s);
  32. }
  33. }
  34. char *stringReplace(const char *s, const char *search, const char *replace) {
  35. const char *tmp = strstr(s, search);
  36. if (tmp == NULL)
  37. return bufferString("%s", s);
  38. size_t offset = tmp - s;
  39. size_t length = strlen(s) - strlen(search) + strlen(replace);
  40. char *buf = new char[length + 1];
  41. buf[length] = '\0';
  42. for (size_t i = 0; i < offset; i++)
  43. buf[i] = s[i];
  44. for (size_t i = 0; i < strlen(replace); i++)
  45. buf[offset + i] = replace[i];
  46. for (size_t i = (offset + strlen(search)); i < strlen(s); i++)
  47. buf[i + strlen(replace) - strlen(search)] = s[i];
  48. char *ret = stringReplace(buf, search, replace);
  49. delete [] buf;
  50. return ret;
  51. }
  52. int readBool(const char *value, bool *var) {
  53. if ((strcmp(value, "1") == 0) || (strcmp(value, "true") == 0) || (strcmp(value, "on") == 0)) {
  54. *var = true;
  55. } else if ((strcmp(value, "0") == 0) || (strcmp(value, "false") == 0) || (strcmp(value, "off") == 0)) {
  56. *var = false;
  57. } else {
  58. return -1;
  59. }
  60. return 0;
  61. }
  62. bool stringEndsWith(const char *str, const char *suffix) {
  63. assert(str != NULL);
  64. assert(suffix != NULL);
  65. size_t lenstr = strlen(str);
  66. size_t lensuffix = strlen(suffix);
  67. if (lensuffix > lenstr)
  68. return false;
  69. return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0;
  70. }
  71. char *bufferString(const char *string, va_list args) {
  72. int sz = 60;
  73. int n;
  74. char *text;
  75. va_list tmp;
  76. assert(string != NULL);
  77. assert(string[0] != '\0');
  78. text = new char[sz];
  79. va_copy(tmp, args);
  80. n = vsnprintf(text, sz, string, tmp);
  81. va_end(tmp);
  82. if (n < 0) {
  83. delete [] text;
  84. return NULL; // encoding error
  85. } else if (n >= sz) {
  86. sz = n + 1; // buffer too small
  87. delete [] text;
  88. text = new char[sz + 1];
  89. va_copy(tmp, args);
  90. vsnprintf(text, sz, string, tmp);
  91. va_end(tmp);
  92. }
  93. return text;
  94. }
  95. char *bufferString(const char *string, ...) {
  96. va_list args;
  97. va_start(args, string);
  98. char *text = bufferString(string, args);
  99. va_end(args);
  100. return text;
  101. }
  102. char *fullPath(const char *path, char end) {
  103. unsigned int lenPath;
  104. char *dir;
  105. assert(path != NULL);
  106. assert(path[0] != '\0');
  107. if (path[0] == '~') {
  108. #if defined(unix) || defined(__APPLE__) || defined(__linux__)
  109. wordexp_t word;
  110. #ifdef __APPLE__
  111. // Workaround for Mac OS X. See:
  112. // http://stackoverflow.com/questions/20534788/why-does-wordexp-fail-with-wrde-syntax-on-os-x
  113. signal(SIGCHLD, SIG_DFL);
  114. #endif
  115. // Expand string into segments
  116. int res = wordexp(path, &word, 0);
  117. #ifdef __APPLE__
  118. signal(SIGCHLD, SIG_IGN);
  119. #endif
  120. if (res != 0) {
  121. printf("fullPath> wordexp() failed: %d\n", res);
  122. return NULL;
  123. }
  124. // Get length of complete string
  125. lenPath = 0;
  126. for (unsigned int i = 0; i < word.we_wordc; i++) {
  127. lenPath += strlen(word.we_wordv[i]);
  128. }
  129. // Allocate new string
  130. dir = new char[lenPath + 2]; // space for end char
  131. // Copy segments into new string
  132. unsigned int offset = 0;
  133. for (unsigned int i = 0; i < word.we_wordc; i++) {
  134. unsigned int len = strlen(word.we_wordv[i]);
  135. strncpy(dir + offset, word.we_wordv[i], len);
  136. offset += len;
  137. }
  138. wordfree(&word);
  139. #elif defined(WIN32)
  140. WCHAR newPath[MAX_PATH];
  141. if (SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, newPath) == S_OK) {
  142. lenPath = strlen((const char *)newPath);
  143. unsigned int lenPath2 = strlen(path);
  144. dir = new char[lenPath + lenPath2 + 2]; // space for end char
  145. strncpy(dir, (const char *)newPath, lenPath);
  146. dir[lenPath] = '\\';
  147. strncpy((dir + lenPath + 1), (path + 1), lenPath2 - 1);
  148. lenPath += lenPath2;
  149. } else {
  150. printf("WARNING: Could not get home folder location for tilde expansion!\n");
  151. lenPath = strlen(path);
  152. dir = new char[lenPath + 2]; // space for end char
  153. strncpy(dir, path, lenPath);
  154. }
  155. #else
  156. printf("WARNING: Tilde expansion not supported on this platform:\n\t%s\n", path);
  157. lenPath = strlen(path);
  158. dir = new char[lenPath + 2]; // space for end char
  159. strncpy(dir, path, lenPath);
  160. #endif
  161. } else {
  162. lenPath = strlen(path);
  163. dir = new char[lenPath + 2]; // space for end char
  164. strncpy(dir, path, lenPath);
  165. }
  166. // Make sure ends in "end" char
  167. if ((lenPath > 0) && (end != 0) && (dir[lenPath - 1] != end)) {
  168. dir[lenPath] = end;
  169. dir[lenPath + 1] = '\0';
  170. } else {
  171. dir[lenPath] = '\0';
  172. }
  173. return dir;
  174. }