utils.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. #include "utils.h"
  2. #include <regex>
  3. #include <string>
  4. #include <vector>
  5. /**
  6. * Clean up the trailing ../ in __FILE__
  7. *
  8. * This is used by the logging macro.
  9. *
  10. * @param filepath
  11. * @return const char*
  12. */
  13. const char *trim_path(const char *filepath) {
  14. if (strncmp(filepath, "../", 3) == 0) {
  15. filepath += 3;
  16. }
  17. return filepath;
  18. }
  19. #include <fstream>
  20. bool file_exists(const std::string &name) {
  21. std::ifstream f(name.c_str());
  22. return f.good();
  23. }
  24. bool replace(std::string &str, const std::string &from, const std::string &to) {
  25. size_t start_pos = str.find(from);
  26. if (start_pos == std::string::npos) return false;
  27. do {
  28. str.replace(start_pos, from.length(), to);
  29. } while ((start_pos = str.find(from)) != std::string::npos);
  30. return true;
  31. }
  32. bool replace(std::string &str, const char *from, const char *to) {
  33. size_t start_pos = str.find(from);
  34. if (start_pos == std::string::npos) return false;
  35. do {
  36. str.replace(start_pos, strlen(from), to);
  37. } while ((start_pos = str.find(from)) != std::string::npos);
  38. return true;
  39. }
  40. void ansi_clean(std::string &str) {
  41. static std::regex ansi_cleaner("\x1b\[[0-9;]*[A-Zmh]",
  42. std::regex_constants::ECMAScript);
  43. str = std::regex_replace(str, ansi_cleaner, "");
  44. }
  45. void high_ascii(std::string &str) {
  46. // the + replaces all of them into one. I want each high ascii replaced with
  47. // #.
  48. static std::regex high_cleaner("[\x80-\xff]",
  49. std::regex_constants::ECMAScript);
  50. str = std::regex_replace(str, high_cleaner, "#");
  51. }
  52. std::smatch ansi_newline(const std::string &str) {
  53. static std::regex ansi_nl("\x1b\[[0-9;]*[JK]",
  54. std::regex_constants::ECMAScript);
  55. std::smatch m;
  56. std::regex_search(str, m, ansi_nl);
  57. return m;
  58. }
  59. std::string repr(const std::string &source) {
  60. std::string output = source;
  61. replace(output, "\n", "\\n");
  62. replace(output, "\r", "\\r");
  63. replace(output, "\b", "\\b");
  64. replace(output, "\x1b", "\\[");
  65. high_ascii(output);
  66. return output;
  67. }
  68. std::string clean_string(const std::string &source) {
  69. std::string clean = source;
  70. /*
  71. replace(clean, "\n", "\\n");
  72. replace(clean, "\r", "\\r");
  73. replace(clean, "\b", "\\b");
  74. replace(clean, "\x1b", "\\[");
  75. */
  76. replace(clean, "\n", "");
  77. replace(clean, "\r", "");
  78. // ANSI too
  79. ansi_clean(clean);
  80. // BUGZ_LOG(error) << "cleaned: " << clean;
  81. high_ascii(clean);
  82. // replace(clean, "\x1b", "^");
  83. return clean;
  84. }
  85. std::vector<std::string> split(const std::string &line) {
  86. static std::regex rx_split("[^\\s]+");
  87. std::vector<std::string> results;
  88. for (auto it = std::sregex_iterator(line.begin(), line.end(), rx_split);
  89. it != std::sregex_iterator(); ++it) {
  90. results.push_back(it->str());
  91. }
  92. return results;
  93. }
  94. std::vector<std::string> split(const std::string &line, const std::string &by) {
  95. std::string work = line;
  96. std::vector<std::string> results;
  97. size_t pos;
  98. while ((pos = work.find(by)) != std::string::npos) {
  99. results.push_back(work.substr(0, pos));
  100. work.erase(0, pos + by.length());
  101. }
  102. if (!work.empty()) results.push_back(work);
  103. return results;
  104. }
  105. bool in(const std::string &line, const std::string &has) {
  106. return (line.find(has) != std::string::npos);
  107. }
  108. bool startswith(const std::string &line, const std::string &has) {
  109. return (line.substr(0, has.length()) == has);
  110. }
  111. bool endswith(const std::string &line, const std::string &has) {
  112. if (line.length() < has.length()) return false;
  113. return (line.substr(line.length() - has.length()) == has);
  114. }
  115. void trim(std::string &str) {
  116. while (str.substr(0, 1) == " ") str.erase(0, 1);
  117. while (str.substr(str.length() - 1) == " ") str.erase(str.length() - 1);
  118. }
  119. bool at_command_prompt(const std::string &prompt) {
  120. if (startswith(prompt, "Command ["))
  121. if (endswith(prompt, "] (?=Help)? : ")) return true;
  122. return false;
  123. }
  124. bool at_computer_prompt(const std::string &prompt) {
  125. if (startswith(prompt, "Computer command ["))
  126. if (endswith(prompt, "] (?=Help)? ")) return true;
  127. return false;
  128. }
  129. bool at_planet_prompt(const std::string &prompt) {
  130. if (startswith(prompt, "Planet command (?=Help)"))
  131. if (endswith(prompt, " [D] ")) return true;
  132. return false;
  133. }
  134. bool density_clear(int sector, int density, int navhaz) {
  135. if(sector == 0) return false;
  136. //if(anomoly) return false;
  137. /*
  138. http://wiki.classictw.com/index.php?title=Gypsy%27s_Big_Dummy%27s_Guide_to_TradeWars_Text#Trader_Information
  139. Density Readings:
  140. 0 = Empty Sector or Ferrengi Dreadanought
  141. 1 = Marker Beacon
  142. 2 = Limpet Type 2 Tracking Mine
  143. 5 = Fighter (per Fighter)
  144. 10 = Armid Type 1 Mine
  145. 21 = Navigation Hazard (Per 1 Percent)
  146. 21 = Destroyed Ship (Due to 1 Percent Nav-Haz)
  147. 38 = Unmanned Ship
  148. 40 = Manned Ship, Alien or Ferrengi Assault Trader
  149. 50 = Destroyed Starport (After 25 Percent Nav-Haz Clears)
  150. 100 = Starport or Ferrengi Battle Cruiser
  151. 210 = Destroyed Planet (Due to 10 Percent Nav-Haz)
  152. 462 = Federation Starship under Admiral Nelson
  153. 489 = Federation Starship under Captain Zyrain
  154. 500 = Planet
  155. 512 = Federation Starship under Admiral Clausewitz
  156. 575 = Destroyed Port (Before 25% Nav-Haz Clears)
  157. */
  158. int dense = density;
  159. if((navhaz != 0) && (navhaz <= 5)) {
  160. // Adjust density by upto 5% navhaz, exlude greather than 5%
  161. dense -= navhaz * 21;
  162. }
  163. if(navhaz > 5) return false;
  164. switch (dense) {
  165. case 0:
  166. case 1:
  167. case 100:
  168. case 101:
  169. return true;
  170. }
  171. // Special case for Sector 001.
  172. if((sector == 1) && (dense == 601)) return true;
  173. return false;
  174. }
  175. #include <algorithm>
  176. #include <cctype>
  177. void str_toupper(std::string &str) {
  178. std::transform(str.begin(), str.end(), str.begin(), ::toupper);
  179. }
  180. void str_tolower(std::string &str) {
  181. std::transform(str.begin(), str.end(), str.begin(), ::tolower);
  182. }
  183. void remove_telnet_commands(std::string &text) {
  184. size_t pos;
  185. while ((pos = text.find('\xff')) != std::string::npos) {
  186. text.erase(pos, pos + 3);
  187. }
  188. }
  189. int sstoi(const std::string &text, int failure) {
  190. int result;
  191. try {
  192. result = stoi(text);
  193. } catch (const std::invalid_argument &e) {
  194. // BUGZ_LOG(fatal) << e.what();
  195. return failure;
  196. } catch (const std::out_of_range &e) {
  197. // BUGZ_LOG(fatal) << e.what();
  198. return failure;
  199. }
  200. return result;
  201. }