Audio plugin host https://kx.studio/carla
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.

533 lines
13KB

  1. /*
  2. * Carla common utils
  3. * Copyright (C) 2011-2015 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #ifndef CARLA_UTILS_HPP_INCLUDED
  18. #define CARLA_UTILS_HPP_INCLUDED
  19. #include "CarlaDefines.h"
  20. #include <cassert>
  21. #include <cstdarg>
  22. #include <cstdio>
  23. #include <cstdlib>
  24. #include <cstring>
  25. #ifdef CARLA_PROPER_CPP11_SUPPORT
  26. # include <cstdint>
  27. #else
  28. # include <stdint.h>
  29. #endif
  30. #ifdef CARLA_OS_WIN
  31. # include <winsock2.h>
  32. # include <windows.h>
  33. #else
  34. # include <unistd.h>
  35. #endif
  36. // --------------------------------------------------------------------------------------------------------------------
  37. // misc functions
  38. /*
  39. * Return "true" or "false" according to yesNo.
  40. */
  41. static inline
  42. const char* bool2str(const bool yesNo) noexcept
  43. {
  44. return yesNo ? "true" : "false";
  45. }
  46. /*
  47. * Set a string as empty/null.
  48. */
  49. static inline
  50. void nullStrBuf(char* const strBuf) noexcept
  51. {
  52. strBuf[0] = '\0';
  53. }
  54. /*
  55. * Dummy function.
  56. */
  57. static inline
  58. void pass() noexcept {}
  59. // --------------------------------------------------------------------------------------------------------------------
  60. // string print functions
  61. /*
  62. * Internal noexcept-safe fopen function.
  63. */
  64. static inline
  65. FILE* __carla_fopen(const char* const filename, FILE* const fallback) noexcept
  66. {
  67. #ifdef CARLA_OS_LINUX
  68. if (std::getenv("CARLA_CAPTURE_CONSOLE_OUTPUT") == nullptr)
  69. return fallback;
  70. FILE* ret = nullptr;
  71. try {
  72. ret = std::fopen(filename, "a+");
  73. } catch (...) {}
  74. if (ret == nullptr)
  75. ret = fallback;
  76. return ret;
  77. #else
  78. return fallback;
  79. // unused
  80. (void)filename;
  81. #endif
  82. }
  83. /*
  84. * Print a string to stdout with newline (gray color).
  85. * Does nothing if DEBUG is not defined.
  86. */
  87. #ifndef DEBUG
  88. # define carla_debug(...)
  89. #else
  90. static inline
  91. void carla_debug(const char* const fmt, ...) noexcept
  92. {
  93. static FILE* const output = __carla_fopen("/tmp/carla.debug.log", stdout);
  94. try {
  95. ::va_list args;
  96. ::va_start(args, fmt);
  97. if (output == stdout)
  98. {
  99. std::fprintf(output, "\x1b[30;1m");
  100. std::vfprintf(output, fmt, args);
  101. std::fprintf(output, "\x1b[0m\n");
  102. }
  103. else
  104. {
  105. std::vfprintf(output, fmt, args);
  106. std::fprintf(output, "\n");
  107. std::fflush(output);
  108. }
  109. ::va_end(args);
  110. } catch (...) {}
  111. }
  112. #endif
  113. /*
  114. * Print a string to stdout with newline.
  115. */
  116. static inline
  117. void carla_stdout(const char* const fmt, ...) noexcept
  118. {
  119. static FILE* const output = __carla_fopen("/tmp/carla.stdout.log", stdout);
  120. try {
  121. ::va_list args;
  122. ::va_start(args, fmt);
  123. std::vfprintf(output, fmt, args);
  124. std::fprintf(output, "\n");
  125. if (output != stdout)
  126. std::fflush(output);
  127. ::va_end(args);
  128. } catch (...) {}
  129. }
  130. /*
  131. * Print a string to stderr with newline.
  132. */
  133. static inline
  134. void carla_stderr(const char* const fmt, ...) noexcept
  135. {
  136. static FILE* const output = __carla_fopen("/tmp/carla.stderr.log", stderr);
  137. try {
  138. ::va_list args;
  139. ::va_start(args, fmt);
  140. std::vfprintf(output, fmt, args);
  141. std::fprintf(output, "\n");
  142. if (output != stderr)
  143. std::fflush(output);
  144. ::va_end(args);
  145. } catch (...) {}
  146. }
  147. /*
  148. * Print a string to stderr with newline (red color).
  149. */
  150. static inline
  151. void carla_stderr2(const char* const fmt, ...) noexcept
  152. {
  153. static FILE* const output = __carla_fopen("/tmp/carla.stderr2.log", stderr);
  154. try {
  155. ::va_list args;
  156. ::va_start(args, fmt);
  157. if (output == stderr)
  158. {
  159. std::fprintf(output, "\x1b[31m");
  160. std::vfprintf(output, fmt, args);
  161. std::fprintf(output, "\x1b[0m\n");
  162. }
  163. else
  164. {
  165. std::vfprintf(output, fmt, args);
  166. std::fprintf(output, "\n");
  167. std::fflush(output);
  168. }
  169. ::va_end(args);
  170. } catch (...) {}
  171. }
  172. // --------------------------------------------------------------------------------------------------------------------
  173. // carla_safe_assert*
  174. /*
  175. * Print a safe assertion error message.
  176. */
  177. static inline
  178. void carla_safe_assert(const char* const assertion, const char* const file, const int line) noexcept
  179. {
  180. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i", assertion, file, line);
  181. }
  182. /*
  183. * Print a safe assertion error message, with 1 extra integer value.
  184. */
  185. static inline
  186. void carla_safe_assert_int(const char* const assertion, const char* const file, const int line,
  187. const int value) noexcept
  188. {
  189. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, value %i", assertion, file, line, value);
  190. }
  191. static inline
  192. void carla_safe_assert_uint(const char* const assertion, const char* const file, const int line,
  193. const uint value) noexcept
  194. {
  195. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, value %u", assertion, file, line, value);
  196. }
  197. /*
  198. * Print a safe assertion error message, with 2 extra integer values.
  199. */
  200. static inline
  201. void carla_safe_assert_int2(const char* const assertion, const char* const file, const int line,
  202. const int v1, const int v2) noexcept
  203. {
  204. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, v1 %i, v2 %i", assertion, file, line, v1, v2);
  205. }
  206. static inline
  207. void carla_safe_assert_uint2(const char* const assertion, const char* const file, const int line,
  208. const uint v1, const uint v2) noexcept
  209. {
  210. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, v1 %u, v2 %u", assertion, file, line, v1, v2);
  211. }
  212. // --------------------------------------------------------------------------------------------------------------------
  213. // carla_safe_exception*
  214. /*
  215. * Print a safe exception error message.
  216. */
  217. static inline
  218. void carla_safe_exception(const char* const exception, const char* const file, const int line) noexcept
  219. {
  220. carla_stderr2("Carla exception caught: \"%s\" in file %s, line %i", exception, file, line);
  221. }
  222. // --------------------------------------------------------------------------------------------------------------------
  223. // carla_*sleep
  224. /*
  225. * Sleep for 'secs' seconds.
  226. */
  227. static inline
  228. void carla_sleep(const uint secs) noexcept
  229. {
  230. CARLA_SAFE_ASSERT_RETURN(secs > 0,);
  231. try {
  232. #ifdef CARLA_OS_WIN
  233. ::Sleep(secs * 1000);
  234. #else
  235. ::sleep(secs);
  236. #endif
  237. } CARLA_SAFE_EXCEPTION("carla_sleep");
  238. }
  239. /*
  240. * Sleep for 'msecs' milliseconds.
  241. */
  242. static inline
  243. void carla_msleep(const uint msecs) noexcept
  244. {
  245. CARLA_SAFE_ASSERT_RETURN(msecs > 0,);
  246. try {
  247. #ifdef CARLA_OS_WIN
  248. ::Sleep(msecs);
  249. #else
  250. ::usleep(msecs * 1000);
  251. #endif
  252. } CARLA_SAFE_EXCEPTION("carla_msleep");
  253. }
  254. // --------------------------------------------------------------------------------------------------------------------
  255. // carla_setenv
  256. /*
  257. * Set environment variable 'key' to 'value'.
  258. */
  259. static inline
  260. void carla_setenv(const char* const key, const char* const value) noexcept
  261. {
  262. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  263. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  264. #ifdef CARLA_OS_WIN
  265. try {
  266. ::SetEnvironmentVariableA(key, value);
  267. } CARLA_SAFE_EXCEPTION("carla_setenv");
  268. #else
  269. ::setenv(key, value, 1);
  270. #endif
  271. }
  272. /*
  273. * Unset environment variable 'key'.
  274. */
  275. static inline
  276. void carla_unsetenv(const char* const key) noexcept
  277. {
  278. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  279. #ifdef CARLA_OS_WIN
  280. try {
  281. ::SetEnvironmentVariableA(key, nullptr);
  282. } CARLA_SAFE_EXCEPTION("carla_unsetenv");
  283. #else
  284. ::unsetenv(key);
  285. #endif
  286. }
  287. // --------------------------------------------------------------------------------------------------------------------
  288. // carla_strdup
  289. /*
  290. * Custom 'strdup' function.
  291. * Returned value is always valid, and must be freed with "delete[] var".
  292. * May throw.
  293. */
  294. static inline
  295. const char* carla_strdup(const char* const strBuf)
  296. {
  297. CARLA_SAFE_ASSERT(strBuf != nullptr);
  298. const std::size_t bufferLen = (strBuf != nullptr) ? std::strlen(strBuf) : 0;
  299. char* const buffer = new char[bufferLen+1];
  300. if (strBuf != nullptr && bufferLen > 0)
  301. std::memcpy(buffer, strBuf, bufferLen);
  302. buffer[bufferLen] = '\0';
  303. return buffer;
  304. }
  305. /*
  306. * Custom 'strdup' function.
  307. * Calls "std::free(strBuf)".
  308. * Returned value is always valid, and must be freed with "delete[] var".
  309. * May throw.
  310. */
  311. static inline
  312. const char* carla_strdup_free(char* const strBuf)
  313. {
  314. const char* const buffer(carla_strdup(strBuf));
  315. std::free(strBuf);
  316. return buffer;
  317. }
  318. /*
  319. * Custom 'strdup' function, safe version.
  320. * Returned value may be null.
  321. */
  322. static inline
  323. const char* carla_strdup_safe(const char* const strBuf) noexcept
  324. {
  325. CARLA_SAFE_ASSERT(strBuf != nullptr);
  326. const std::size_t bufferLen = (strBuf != nullptr) ? std::strlen(strBuf) : 0;
  327. char* buffer;
  328. try {
  329. buffer = new char[bufferLen+1];
  330. } CARLA_SAFE_EXCEPTION_RETURN("carla_strdup_safe", nullptr);
  331. if (strBuf != nullptr && bufferLen > 0)
  332. std::memcpy(buffer, strBuf, bufferLen);
  333. buffer[bufferLen] = '\0';
  334. return buffer;
  335. }
  336. // --------------------------------------------------------------------------------------------------------------------
  337. // memory functions
  338. /*
  339. * Add array values to another array.
  340. */
  341. template<typename T>
  342. static inline
  343. void carla_add(T dest[], const T src[], const std::size_t count) noexcept
  344. {
  345. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  346. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  347. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  348. for (std::size_t i=0; i<count; ++i)
  349. *dest++ += *src++;
  350. }
  351. /*
  352. * Copy array values to another array.
  353. */
  354. template<typename T>
  355. static inline
  356. void carla_copy(T dest[], const T src[], const std::size_t count) noexcept
  357. {
  358. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  359. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  360. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  361. std::memcpy(dest, src, count*sizeof(T));
  362. }
  363. /*
  364. * Fill an array with a fixed value.
  365. */
  366. template<typename T>
  367. static inline
  368. void carla_fill(T data[], const T& value, const std::size_t count) noexcept
  369. {
  370. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  371. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  372. if (value == 0)
  373. {
  374. std::memset(data, 0, count*sizeof(T));
  375. }
  376. else
  377. {
  378. for (std::size_t i=0; i<count; ++i)
  379. *data++ = value;
  380. }
  381. }
  382. /*
  383. * Clear a byte array.
  384. */
  385. static inline
  386. void carla_zeroBytes(uint8_t bytes[], const std::size_t count) noexcept
  387. {
  388. CARLA_SAFE_ASSERT_RETURN(bytes != nullptr,);
  389. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  390. std::memset(bytes, 0, count*sizeof(uint8_t));
  391. }
  392. /*
  393. * Clear a char array.
  394. */
  395. static inline
  396. void carla_zeroChars(char chars[], const std::size_t count) noexcept
  397. {
  398. CARLA_SAFE_ASSERT_RETURN(chars != nullptr,);
  399. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  400. std::memset(chars, 0, count*sizeof(char));
  401. }
  402. /*
  403. * Clear a pointer array.
  404. */
  405. template<typename T>
  406. static inline
  407. void carla_zeroPointers(T* ptrs[], const std::size_t count) noexcept
  408. {
  409. CARLA_SAFE_ASSERT_RETURN(ptrs != nullptr,);
  410. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  411. std::memset(ptrs, 0, count*sizeof(T*));
  412. }
  413. /*
  414. * Clear a single struct.
  415. */
  416. template <typename T>
  417. static inline
  418. void carla_zeroStruct(T& s) noexcept
  419. {
  420. std::memset(&s, 0, sizeof(T));
  421. }
  422. /*
  423. * Clear a struct array.
  424. */
  425. template <typename T>
  426. static inline
  427. void carla_zeroStructs(T structs[], const std::size_t count) noexcept
  428. {
  429. CARLA_SAFE_ASSERT_RETURN(structs != nullptr,);
  430. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  431. std::memset(structs, 0, count*sizeof(T));
  432. }
  433. /*
  434. * Copy a single struct.
  435. */
  436. template <typename T>
  437. static inline
  438. void carla_copyStruct(T& dest, const T& src) noexcept
  439. {
  440. std::memcpy(&dest, &src, sizeof(T));
  441. }
  442. /*
  443. * Copy a struct array.
  444. */
  445. template <typename T>
  446. static inline
  447. void carla_copyStructs(T dest[], const T src[], const std::size_t count) noexcept
  448. {
  449. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  450. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  451. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  452. std::memcpy(dest, src, count*sizeof(T));
  453. }
  454. // --------------------------------------------------------------------------------------------------------------------
  455. #endif // CARLA_UTILS_HPP_INCLUDED