porting.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /*
  2. Minetest
  3. Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. /*
  17. Random portability stuff
  18. */
  19. #pragma once
  20. #if (defined(__linux__) || defined(__GNU__)) && !defined(_GNU_SOURCE)
  21. #define _GNU_SOURCE
  22. #endif
  23. // Be mindful of what you include here!
  24. #include <string>
  25. #include "config.h"
  26. #include "irrlichttypes.h" // u64
  27. #include "debug.h"
  28. #include "constants.h"
  29. #include "util/timetaker.h" // TimePrecision
  30. #ifdef _MSC_VER
  31. #define SWPRINTF_CHARSTRING L"%S"
  32. #else
  33. #define SWPRINTF_CHARSTRING L"%s"
  34. #endif
  35. #ifdef _WIN32
  36. #include <windows.h>
  37. #define sleep_ms(x) Sleep(x)
  38. #define sleep_us(x) Sleep((x)/1000)
  39. #define setenv(n,v,o) _putenv_s(n,v)
  40. #define unsetenv(n) _putenv_s(n,"")
  41. #else
  42. #include <unistd.h>
  43. #include <cstdlib> // setenv
  44. #define sleep_ms(x) usleep((x)*1000)
  45. #define sleep_us(x) usleep(x)
  46. #endif
  47. #ifdef _MSC_VER
  48. #define strtok_r(x, y, z) strtok_s(x, y, z)
  49. #define strtof(x, y) (float)strtod(x, y)
  50. #define strtoll(x, y, z) _strtoi64(x, y, z)
  51. #define strtoull(x, y, z) _strtoui64(x, y, z)
  52. #define strcasecmp(x, y) stricmp(x, y)
  53. #define strncasecmp(x, y, n) strnicmp(x, y, n)
  54. #endif
  55. #ifdef __MINGW32__
  56. // was broken in 2013, unclear if still needed
  57. #define strtok_r(x, y, z) mystrtok_r(x, y, z)
  58. #endif
  59. #if !HAVE_STRLCPY
  60. #define strlcpy(d, s, n) mystrlcpy(d, s, n)
  61. #endif
  62. #ifndef _WIN32 // POSIX
  63. #include <sys/time.h>
  64. #include <ctime>
  65. #if defined(__MACH__) && defined(__APPLE__)
  66. #include <TargetConditionals.h>
  67. #endif
  68. #endif
  69. namespace porting
  70. {
  71. /*
  72. Signal handler (grabs Ctrl-C on POSIX systems)
  73. */
  74. void signal_handler_init();
  75. // Returns a pointer to a bool.
  76. // When the bool is true, program should quit.
  77. bool * signal_handler_killstatus();
  78. /*
  79. Path of static data directory.
  80. */
  81. extern std::string path_share;
  82. /*
  83. Directory for storing user data. Examples:
  84. Windows: "C:\Documents and Settings\user\Application Data\<PROJECT_NAME>"
  85. Linux: "~/.<PROJECT_NAME>"
  86. Mac: "~/Library/Application Support/<PROJECT_NAME>"
  87. */
  88. extern std::string path_user;
  89. /*
  90. Path to gettext locale files
  91. */
  92. extern std::string path_locale;
  93. /*
  94. Path to directory for storing caches.
  95. */
  96. extern std::string path_cache;
  97. /*
  98. Gets the path of our executable.
  99. */
  100. bool getCurrentExecPath(char *buf, size_t len);
  101. /*
  102. Get full path of stuff in data directory.
  103. Example: "stone.png" -> "../data/stone.png"
  104. */
  105. std::string getDataPath(const char *subpath);
  106. /*
  107. Initialize path_*.
  108. */
  109. void initializePaths();
  110. /*
  111. Return system information
  112. e.g. "Linux/3.12.7 x86_64"
  113. */
  114. std::string get_sysinfo();
  115. // Monotonic timer
  116. #ifdef _WIN32 // Windows
  117. extern double perf_freq;
  118. inline u64 os_get_time(double mult)
  119. {
  120. LARGE_INTEGER t;
  121. QueryPerformanceCounter(&t);
  122. return static_cast<double>(t.QuadPart) / (perf_freq / mult);
  123. }
  124. // Resolution is <1us.
  125. inline u64 getTimeS() { return os_get_time(1); }
  126. inline u64 getTimeMs() { return os_get_time(1000); }
  127. inline u64 getTimeUs() { return os_get_time(1000*1000); }
  128. inline u64 getTimeNs() { return os_get_time(1000*1000*1000); }
  129. #else // POSIX
  130. inline void os_get_clock(struct timespec *ts)
  131. {
  132. #if defined(CLOCK_MONOTONIC_RAW)
  133. clock_gettime(CLOCK_MONOTONIC_RAW, ts);
  134. #elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK > 0
  135. clock_gettime(CLOCK_MONOTONIC, ts);
  136. #else
  137. # if defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK == 0
  138. // zero means it might be supported at runtime
  139. if (clock_gettime(CLOCK_MONOTONIC, ts) == 0)
  140. return;
  141. # endif
  142. struct timeval tv;
  143. gettimeofday(&tv, NULL);
  144. TIMEVAL_TO_TIMESPEC(&tv, ts);
  145. #endif
  146. }
  147. inline u64 getTimeS()
  148. {
  149. struct timespec ts;
  150. os_get_clock(&ts);
  151. return ts.tv_sec;
  152. }
  153. inline u64 getTimeMs()
  154. {
  155. struct timespec ts;
  156. os_get_clock(&ts);
  157. return ((u64) ts.tv_sec) * 1000LL + ((u64) ts.tv_nsec) / 1000000LL;
  158. }
  159. inline u64 getTimeUs()
  160. {
  161. struct timespec ts;
  162. os_get_clock(&ts);
  163. return ((u64) ts.tv_sec) * 1000000LL + ((u64) ts.tv_nsec) / 1000LL;
  164. }
  165. inline u64 getTimeNs()
  166. {
  167. struct timespec ts;
  168. os_get_clock(&ts);
  169. return ((u64) ts.tv_sec) * 1000000000LL + ((u64) ts.tv_nsec);
  170. }
  171. #endif
  172. inline u64 getTime(TimePrecision prec)
  173. {
  174. switch (prec) {
  175. case PRECISION_SECONDS: return getTimeS();
  176. case PRECISION_MILLI: return getTimeMs();
  177. case PRECISION_MICRO: return getTimeUs();
  178. case PRECISION_NANO: return getTimeNs();
  179. }
  180. FATAL_ERROR("Called getTime with invalid time precision");
  181. }
  182. /**
  183. * Delta calculation function arguments.
  184. * @param old_time_ms old time for delta calculation
  185. * @param new_time_ms new time for delta calculation
  186. * @return positive delta value
  187. */
  188. inline u64 getDeltaMs(u64 old_time_ms, u64 new_time_ms)
  189. {
  190. if (new_time_ms >= old_time_ms) {
  191. return (new_time_ms - old_time_ms);
  192. }
  193. return (old_time_ms - new_time_ms);
  194. }
  195. inline const char *getPlatformName()
  196. {
  197. return
  198. #if defined(ANDROID)
  199. "Android"
  200. #elif defined(__linux__)
  201. "Linux"
  202. #elif defined(_WIN32) || defined(_WIN64)
  203. "Windows"
  204. #elif defined(__DragonFly__) || defined(__FreeBSD__) || \
  205. defined(__NetBSD__) || defined(__OpenBSD__)
  206. "BSD"
  207. #elif defined(__APPLE__) && defined(__MACH__)
  208. #if TARGET_OS_MAC
  209. "OSX"
  210. #elif TARGET_OS_IPHONE
  211. "iOS"
  212. #else
  213. "Apple"
  214. #endif
  215. #elif defined(_AIX)
  216. "AIX"
  217. #elif defined(__hpux)
  218. "HP-UX"
  219. #elif defined(__sun) || defined(sun)
  220. #if defined(__SVR4)
  221. "Solaris"
  222. #else
  223. "SunOS"
  224. #endif
  225. #elif defined(__HAIKU__)
  226. "Haiku"
  227. #elif defined(__CYGWIN__)
  228. "Cygwin"
  229. #elif defined(__unix__) || defined(__unix)
  230. #if defined(_POSIX_VERSION)
  231. "POSIX"
  232. #else
  233. "Unix"
  234. #endif
  235. #else
  236. "?"
  237. #endif
  238. ;
  239. }
  240. bool secure_rand_fill_buf(void *buf, size_t len);
  241. // Call once near beginning of main function.
  242. void osSpecificInit();
  243. // This attaches to the parents process console, or creates a new one if it doesnt exist.
  244. void attachOrCreateConsole();
  245. #ifdef _WIN32
  246. // Quotes an argument for use in a CreateProcess() commandline (not cmd.exe!!)
  247. std::string QuoteArgv(const std::string &arg);
  248. #endif
  249. int mt_snprintf(char *buf, const size_t buf_size, const char *fmt, ...);
  250. /**
  251. * Opens URL in default web browser
  252. *
  253. * Must begin with http:// or https://, and not contain any new lines
  254. *
  255. * @param url The URL
  256. * @return true on success, false on failure
  257. */
  258. bool open_url(const std::string &url);
  259. /**
  260. * Opens a directory in the default file manager
  261. *
  262. * The directory must exist.
  263. *
  264. * @param path Path to directory
  265. * @return true on success, false on failure
  266. */
  267. bool open_directory(const std::string &path);
  268. } // namespace porting
  269. #ifdef __ANDROID__
  270. #include "porting_android.h"
  271. #endif