Open Source Tomb Raider Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

strings.cpp 4.8KB

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