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.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*!
  2. * \file include/utils/strings.h
  3. * \brief String handling utilities
  4. *
  5. * \author xythobuz
  6. * \author Mongoose
  7. */
  8. #include <cstdarg>
  9. #include <cstdlib>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <assert.h>
  13. #if defined(unix) || defined(__APPLE__)
  14. #include <wordexp.h>
  15. #endif
  16. #include "utils/strings.h"
  17. bool stringEndsWith(const char *str, const char *suffix) {
  18. assert(str != NULL);
  19. assert(suffix != NULL);
  20. size_t lenstr = strlen(str);
  21. size_t lensuffix = strlen(suffix);
  22. if (lensuffix > lenstr)
  23. return false;
  24. return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0;
  25. }
  26. char *bufferString(const char *string, va_list args) {
  27. int sz = 60;
  28. int n;
  29. char *text;
  30. assert(string != NULL);
  31. assert(string[0] != '\0');
  32. text = new char[sz];
  33. va_list copy;
  34. va_copy(copy, args);
  35. n = vsnprintf(text, sz, string, args);
  36. if (n < 0) {
  37. delete [] text;
  38. return NULL; // encoding error
  39. } else if (n >= sz) {
  40. sz = n + 1; // buffer too small
  41. delete [] text;
  42. text = new char[sz];
  43. n = vsnprintf(text, sz, string, copy);
  44. }
  45. va_end(copy);
  46. return text;
  47. }
  48. char *bufferString(const char *string, ...) {
  49. va_list args;
  50. va_start(args, string);
  51. char *text = bufferString(string, args);
  52. va_end(args);
  53. return text;
  54. }
  55. char *fullPath(const char *path, char end) {
  56. unsigned int lenPath, offset;
  57. wordexp_t word;
  58. char *dir;
  59. assert(path != NULL);
  60. assert(path[0] != '\0');
  61. if (path[0] == '~') {
  62. #if defined(unix) || defined(__APPLE__)
  63. #ifdef __APPLE__
  64. // Workaround for Mac OS X. See:
  65. // http://stackoverflow.com/questions/20534788/why-does-wordexp-fail-with-wrde-syntax-on-os-x
  66. signal(SIGCHLD, SIG_DFL);
  67. #endif
  68. // Expand string into segments
  69. int res = wordexp(path, &word, 0);
  70. #ifdef __APPLE__
  71. signal(SIGCHLD, SIG_IGN);
  72. #endif
  73. if (res != 0) {
  74. printf("fullPath> wordexp() failed: %d\n", res);
  75. return NULL;
  76. }
  77. // Get length of complete string
  78. lenPath = 0;
  79. for (unsigned int i = 0; i < word.we_wordc; i++) {
  80. lenPath += strlen(word.we_wordv[i]);
  81. }
  82. // Allocate new string
  83. dir = new char[lenPath + 2]; // space for end char
  84. // Copy segments into new string
  85. offset = 0;
  86. for (unsigned int i = 0; i < word.we_wordc; i++) {
  87. unsigned int len = strlen(word.we_wordv[i]);
  88. strncpy(dir + offset, word.we_wordv[i], len);
  89. offset += len;
  90. }
  91. wordfree(&word);
  92. #else
  93. printf("WARNING: Tilde expansion not supported on this platform!\n");
  94. lenPath = strlen(path);
  95. dir = new char[lenPath + 2]; // space for end char
  96. strncpy(dir, path, lenPath);
  97. #endif
  98. } else {
  99. lenPath = strlen(path);
  100. dir = new char[lenPath + 2]; // space for end char
  101. strncpy(dir, path, lenPath);
  102. }
  103. // Make sure ends in "end" char
  104. if ((lenPath > 0) && (end != 0) && (dir[lenPath - 1] != end)) {
  105. dir[lenPath] = end;
  106. dir[lenPath + 1] = 0;
  107. } else {
  108. dir[lenPath] = 0;
  109. }
  110. return dir;
  111. }
  112. bool rc_command(const char *symbol, char *command) {
  113. assert(symbol != NULL);
  114. assert(symbol[0] != '\0');
  115. assert(command != NULL);
  116. assert(command[0] != '\0');
  117. int lens = strlen(symbol);
  118. if (strncmp(command, symbol, lens) == 0) {
  119. int lenc = strlen(command);
  120. //! \fixme Should ignore whitespace, but only if it is really there...?
  121. // lens+1 skips '=' or ' '
  122. for (int i = 0, j = lens+1; j < lenc; ++i, ++j) {
  123. command[i] = command[j];
  124. command[i+1] = 0;
  125. }
  126. return true;
  127. }
  128. return false;
  129. }
  130. int rc_get_bool(const char *buffer, bool *val) {
  131. assert(buffer != NULL);
  132. assert(buffer[0] != '\0');
  133. assert(val != NULL);
  134. if ((buffer[0] == '1') || (strncmp(buffer, "true", 4) == 0))
  135. *val = true;
  136. else if ((buffer[0] == '0') || (strncmp(buffer, "false", 5) == 0))
  137. *val = false;
  138. else
  139. return -2;
  140. return 0;
  141. }