Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

strings.cpp 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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. size_t 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. // Workunsigned long systemTimerStart = 0;around 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. size_t offset = 0;
  133. for (unsigned int i = 0; i < word.we_wordc; i++) {
  134. size_t 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. char newPath[MAX_PATH];
  141. if (SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, 0, newPath) == S_OK) {
  142. lenPath = strlen(newPath);
  143. size_t lenPath2 = strlen(path);
  144. dir = new char[lenPath + lenPath2 + 2]; // space for end char
  145. strncpy(dir, newPath, lenPath);
  146. strncpy((dir + lenPath), (path + 1), lenPath2 - 1);
  147. lenPath += lenPath2 - 1;
  148. for (unsigned int i = 0; i < lenPath; i++)
  149. if(dir[i] == '\\')
  150. dir[i] = '/';
  151. } else {
  152. printf("WARNING: Could not get home folder location for tilde expansion!\n");
  153. lenPath = strlen(path);
  154. dir = new char[lenPath + 2]; // space for end char
  155. strncpy(dir, path, lenPath);
  156. }
  157. #else
  158. printf("WARNING: Tilde expansion not supported on this platform:\n\t%s\n", path);
  159. lenPath = strlen(path);
  160. dir = new char[lenPath + 2]; // space for end char
  161. strncpy(dir, path, lenPath);
  162. #endif
  163. } else {
  164. lenPath = strlen(path);
  165. dir = new char[lenPath + 2]; // space for end char
  166. strncpy(dir, path, lenPath);
  167. }
  168. // Make sure ends in "end" char
  169. if ((lenPath > 0) && (end != 0) && (dir[lenPath - 1] != end)) {
  170. dir[lenPath] = end;
  171. dir[lenPath + 1] = '\0';
  172. } else {
  173. dir[lenPath] = '\0';
  174. }
  175. return dir;
  176. }