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.

609 lines
15KB

  1. /*
  2. * Carla common utils
  3. * Copyright (C) 2011-2020 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 <cxxabi.h>
  27. # include <cstdint>
  28. #else
  29. # include <stdint.h>
  30. #endif
  31. #ifdef CARLA_OS_WIN
  32. # define WIN32_LEAN_AND_MEAN 1
  33. # include <winsock2.h>
  34. # include <windows.h>
  35. #else
  36. # include <unistd.h>
  37. #endif
  38. // --------------------------------------------------------------------------------------------------------------------
  39. // misc functions
  40. /*
  41. * Return "true" or "false" according to yesNo.
  42. */
  43. static inline
  44. const char* bool2str(const bool yesNo) noexcept
  45. {
  46. return yesNo ? "true" : "false";
  47. }
  48. /*
  49. * Set a string as empty/null.
  50. */
  51. static inline
  52. void nullStrBuf(char* const strBuf) noexcept
  53. {
  54. strBuf[0] = '\0';
  55. }
  56. /*
  57. * Dummy function.
  58. */
  59. static inline
  60. void pass() noexcept {}
  61. // --------------------------------------------------------------------------------------------------------------------
  62. // string print functions
  63. /*
  64. * Internal noexcept-safe fopen function.
  65. */
  66. static inline
  67. FILE* __carla_fopen(const char* const filename, FILE* const fallback) noexcept
  68. {
  69. #ifdef CARLA_OS_LINUX
  70. if (std::getenv("CARLA_CAPTURE_CONSOLE_OUTPUT") == nullptr)
  71. return fallback;
  72. FILE* ret = nullptr;
  73. try {
  74. ret = std::fopen(filename, "a+");
  75. } CARLA_CATCH_UNWIND catch (...) {}
  76. if (ret == nullptr)
  77. ret = fallback;
  78. return ret;
  79. #else
  80. return fallback;
  81. // unused
  82. (void)filename;
  83. #endif
  84. }
  85. /*
  86. * Print a string to stdout with newline (gray color).
  87. * Does nothing if DEBUG is not defined.
  88. */
  89. #ifndef DEBUG
  90. # define carla_debug(...)
  91. #else
  92. static inline
  93. void carla_debug(const char* const fmt, ...) noexcept
  94. {
  95. static FILE* const output = __carla_fopen("/tmp/carla.debug.log", stdout);
  96. try {
  97. ::va_list args;
  98. ::va_start(args, fmt);
  99. if (output == stdout)
  100. {
  101. std::fprintf(output, "\x1b[30;1m");
  102. std::vfprintf(output, fmt, args);
  103. std::fprintf(output, "\x1b[0m\n");
  104. }
  105. else
  106. {
  107. std::vfprintf(output, fmt, args);
  108. std::fprintf(output, "\n");
  109. std::fflush(output);
  110. }
  111. ::va_end(args);
  112. } CARLA_CATCH_UNWIND catch (...) {}
  113. }
  114. #endif
  115. /*
  116. * Print a string to stdout with newline.
  117. */
  118. static inline
  119. void carla_stdout(const char* const fmt, ...) noexcept
  120. {
  121. static FILE* const output = __carla_fopen("/tmp/carla.stdout.log", stdout);
  122. try {
  123. ::va_list args;
  124. ::va_start(args, fmt);
  125. std::vfprintf(output, fmt, args);
  126. std::fprintf(output, "\n");
  127. if (output != stdout)
  128. std::fflush(output);
  129. ::va_end(args);
  130. } CARLA_CATCH_UNWIND catch (...) {}
  131. }
  132. /*
  133. * Print a string to stderr with newline.
  134. */
  135. static inline
  136. void carla_stderr(const char* const fmt, ...) noexcept
  137. {
  138. static FILE* const output = __carla_fopen("/tmp/carla.stderr.log", stderr);
  139. try {
  140. ::va_list args;
  141. ::va_start(args, fmt);
  142. std::vfprintf(output, fmt, args);
  143. std::fprintf(output, "\n");
  144. if (output != stderr)
  145. std::fflush(output);
  146. ::va_end(args);
  147. } CARLA_CATCH_UNWIND catch (...) {}
  148. }
  149. /*
  150. * Print a string to stderr with newline (red color).
  151. */
  152. static inline
  153. void carla_stderr2(const char* const fmt, ...) noexcept
  154. {
  155. static FILE* const output = __carla_fopen("/tmp/carla.stderr2.log", stderr);
  156. try {
  157. ::va_list args;
  158. ::va_start(args, fmt);
  159. if (output == stderr)
  160. {
  161. std::fprintf(output, "\x1b[31m");
  162. std::vfprintf(output, fmt, args);
  163. std::fprintf(output, "\x1b[0m\n");
  164. }
  165. else
  166. {
  167. std::vfprintf(output, fmt, args);
  168. std::fprintf(output, "\n");
  169. std::fflush(output);
  170. }
  171. ::va_end(args);
  172. } CARLA_CATCH_UNWIND catch (...) {}
  173. }
  174. // --------------------------------------------------------------------------------------------------------------------
  175. // carla_safe_assert*
  176. /*
  177. * Print a safe assertion error message.
  178. */
  179. static inline
  180. void carla_safe_assert(const char* const assertion, const char* const file, const int line) noexcept
  181. {
  182. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i", assertion, file, line);
  183. }
  184. /*
  185. * Print a safe assertion error message, with 1 extra signed integer value.
  186. */
  187. static inline
  188. void carla_safe_assert_int(const char* const assertion, const char* const file,
  189. const int line, const int value) noexcept
  190. {
  191. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, value %i", assertion, file, line, value);
  192. }
  193. /*
  194. * Print a safe assertion error message, with 1 extra unsigned integer value.
  195. */
  196. static inline
  197. void carla_safe_assert_uint(const char* const assertion, const char* const file,
  198. const int line, const uint value) noexcept
  199. {
  200. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, value %u", assertion, file, line, value);
  201. }
  202. /*
  203. * Print a safe assertion error message, with 2 extra signed integer values.
  204. */
  205. static inline
  206. void carla_safe_assert_int2(const char* const assertion, const char* const file,
  207. const int line, const int v1, const int v2) noexcept
  208. {
  209. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, v1 %i, v2 %i", assertion, file, line, v1, v2);
  210. }
  211. /*
  212. * Print a safe assertion error message, with 2 extra unsigned integer values.
  213. */
  214. static inline
  215. void carla_safe_assert_uint2(const char* const assertion, const char* const file,
  216. const int line, const uint v1, const uint v2) noexcept
  217. {
  218. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, v1 %u, v2 %u", assertion, file, line, v1, v2);
  219. }
  220. /*
  221. * Print a safe assertion error message, with a custom error message.
  222. */
  223. static inline
  224. void carla_custom_safe_assert(const char* const message,
  225. const char* const assertion, const char* const file, const int line) noexcept
  226. {
  227. carla_stderr2("Carla assertion failure: %s, condition \"%s\" in file %s, line %i", message, assertion, file, line);
  228. }
  229. // --------------------------------------------------------------------------------------------------------------------
  230. // carla_safe_exception*
  231. /*
  232. * Print a safe exception error message.
  233. */
  234. static inline
  235. void carla_safe_exception(const char* const exception, const char* const file, const int line) noexcept
  236. {
  237. carla_stderr2("Carla exception caught: \"%s\" in file %s, line %i", exception, file, line);
  238. }
  239. // --------------------------------------------------------------------------------------------------------------------
  240. // carla_*sleep
  241. /*
  242. * Sleep for 'secs' seconds.
  243. */
  244. static inline
  245. void carla_sleep(const uint secs) noexcept
  246. {
  247. CARLA_SAFE_ASSERT_RETURN(secs > 0,);
  248. try {
  249. #ifdef CARLA_OS_WIN
  250. ::Sleep(secs * 1000);
  251. #else
  252. ::sleep(secs);
  253. #endif
  254. } CARLA_SAFE_EXCEPTION("carla_sleep");
  255. }
  256. /*
  257. * Sleep for 'msecs' milliseconds.
  258. */
  259. static inline
  260. void carla_msleep(const uint msecs) noexcept
  261. {
  262. CARLA_SAFE_ASSERT_RETURN(msecs > 0,);
  263. try {
  264. #ifdef CARLA_OS_WIN
  265. ::Sleep(msecs);
  266. #else
  267. ::usleep(msecs * 1000);
  268. #endif
  269. } CARLA_SAFE_EXCEPTION("carla_msleep");
  270. }
  271. // --------------------------------------------------------------------------------------------------------------------
  272. // carla_setenv
  273. /*
  274. * Set environment variable 'key' to 'value'.
  275. */
  276. static inline
  277. void carla_setenv(const char* const key, const char* const value) noexcept
  278. {
  279. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  280. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  281. #ifdef CARLA_OS_WIN
  282. try {
  283. ::SetEnvironmentVariableA(key, value);
  284. } CARLA_SAFE_EXCEPTION("carla_setenv");
  285. #else
  286. ::setenv(key, value, 1);
  287. #endif
  288. }
  289. /*
  290. * Unset environment variable 'key'.
  291. */
  292. static inline
  293. void carla_unsetenv(const char* const key) noexcept
  294. {
  295. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  296. #ifdef CARLA_OS_WIN
  297. try {
  298. ::SetEnvironmentVariableA(key, nullptr);
  299. } CARLA_SAFE_EXCEPTION("carla_unsetenv");
  300. #else
  301. ::unsetenv(key);
  302. #endif
  303. }
  304. // --------------------------------------------------------------------------------------------------------------------
  305. // carla_strdup
  306. /*
  307. * Custom 'strdup' function.
  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(const char* const strBuf)
  313. {
  314. CARLA_SAFE_ASSERT(strBuf != nullptr);
  315. const std::size_t bufferLen = (strBuf != nullptr) ? std::strlen(strBuf) : 0;
  316. char* const buffer = new char[bufferLen+1];
  317. if (bufferLen > 0)
  318. std::memcpy(buffer, strBuf, bufferLen);
  319. buffer[bufferLen] = '\0';
  320. return buffer;
  321. }
  322. /*
  323. * Custom 'strdup' function.
  324. * Calls "std::free(strBuf)".
  325. * Returned value is always valid, and must be freed with "delete[] var".
  326. * May throw.
  327. */
  328. static inline
  329. const char* carla_strdup_free(char* const strBuf)
  330. {
  331. const char* const buffer(carla_strdup(strBuf));
  332. std::free(strBuf);
  333. return buffer;
  334. }
  335. /*
  336. * Custom 'strdup' function, safe version.
  337. * Returned value may be null. It must be freed with "delete[] var".
  338. */
  339. static inline
  340. const char* carla_strdup_safe(const char* const strBuf) noexcept
  341. {
  342. CARLA_SAFE_ASSERT_RETURN(strBuf != nullptr, nullptr);
  343. const std::size_t bufferLen = std::strlen(strBuf);
  344. char* buffer;
  345. try {
  346. buffer = new char[bufferLen+1];
  347. } CARLA_SAFE_EXCEPTION_RETURN("carla_strdup_safe", nullptr);
  348. if (bufferLen > 0)
  349. std::memcpy(buffer, strBuf, bufferLen);
  350. buffer[bufferLen] = '\0';
  351. return buffer;
  352. }
  353. // --------------------------------------------------------------------------------------------------------------------
  354. // memory functions
  355. /*
  356. * Add array values to another array.
  357. */
  358. template<typename T>
  359. static inline
  360. void carla_add(T dest[], const T src[], const std::size_t count) noexcept
  361. {
  362. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  363. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  364. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  365. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  366. for (std::size_t i=0; i<count; ++i)
  367. *dest++ += *src++;
  368. }
  369. /*
  370. * Add array values to another array, with a multiplication factor.
  371. */
  372. template<typename T>
  373. static inline
  374. void carla_addWithMultiply(T dest[], const T src[], const T& multiplier, const std::size_t count) noexcept
  375. {
  376. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  377. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  378. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  379. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  380. for (std::size_t i=0; i<count; ++i)
  381. *dest++ += *src++ * multiplier;
  382. }
  383. /*
  384. * Copy array values to another array.
  385. */
  386. template<typename T>
  387. static inline
  388. void carla_copy(T dest[], const T src[], const std::size_t count) noexcept
  389. {
  390. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  391. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  392. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  393. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  394. std::memcpy(dest, src, count*sizeof(T));
  395. }
  396. /*
  397. * Copy array values to another array, with a multiplication factor.
  398. */
  399. template<typename T>
  400. static inline
  401. void carla_copyWithMultiply(T dest[], const T src[], const T& multiplier, const std::size_t count) noexcept
  402. {
  403. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  404. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  405. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  406. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  407. for (std::size_t i=0; i<count; ++i)
  408. *dest++ = *src++ * multiplier;
  409. }
  410. /*
  411. * Fill an array with a fixed value.
  412. */
  413. template<typename T>
  414. static inline
  415. void carla_fill(T data[], const T& value, const std::size_t count) noexcept
  416. {
  417. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  418. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  419. if (value == 0)
  420. {
  421. std::memset(data, 0, count*sizeof(T));
  422. }
  423. else
  424. {
  425. for (std::size_t i=0; i<count; ++i)
  426. *data++ = value;
  427. }
  428. }
  429. /*
  430. * Multiply an array with a fixed value.
  431. */
  432. template<typename T>
  433. static inline
  434. void carla_multiply(T data[], const T& multiplier, const std::size_t count) noexcept
  435. {
  436. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  437. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  438. if (multiplier == 0)
  439. {
  440. std::memset(data, 0, count*sizeof(T));
  441. }
  442. else
  443. {
  444. for (std::size_t i=0; i<count; ++i)
  445. *data++ *= multiplier;
  446. }
  447. }
  448. /*
  449. * Clear a byte array.
  450. */
  451. static inline
  452. void carla_zeroBytes(uint8_t bytes[], const std::size_t count) noexcept
  453. {
  454. CARLA_SAFE_ASSERT_RETURN(bytes != nullptr,);
  455. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  456. std::memset(bytes, 0, count*sizeof(uint8_t));
  457. }
  458. /*
  459. * Clear a char array.
  460. */
  461. static inline
  462. void carla_zeroChars(char chars[], const std::size_t count) noexcept
  463. {
  464. CARLA_SAFE_ASSERT_RETURN(chars != nullptr,);
  465. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  466. std::memset(chars, 0, count*sizeof(char));
  467. }
  468. /*
  469. * Clear a pointer array.
  470. */
  471. template<typename T>
  472. static inline
  473. void carla_zeroPointers(T* ptrs[], const std::size_t count) noexcept
  474. {
  475. CARLA_SAFE_ASSERT_RETURN(ptrs != nullptr,);
  476. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  477. std::memset(ptrs, 0, count*sizeof(T*));
  478. }
  479. /*
  480. * Clear a single struct.
  481. */
  482. template <typename T>
  483. static inline
  484. void carla_zeroStruct(T& s) noexcept
  485. {
  486. std::memset(&s, 0, sizeof(T));
  487. }
  488. /*
  489. * Clear a struct array.
  490. */
  491. template <typename T>
  492. static inline
  493. void carla_zeroStructs(T structs[], const std::size_t count) noexcept
  494. {
  495. CARLA_SAFE_ASSERT_RETURN(structs != nullptr,);
  496. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  497. std::memset(structs, 0, count*sizeof(T));
  498. }
  499. /*
  500. * Copy a single struct.
  501. */
  502. template <typename T>
  503. static inline
  504. void carla_copyStruct(T& dest, const T& src) noexcept
  505. {
  506. std::memcpy(&dest, &src, sizeof(T));
  507. }
  508. /*
  509. * Copy a struct array.
  510. */
  511. template <typename T>
  512. static inline
  513. void carla_copyStructs(T dest[], const T src[], const std::size_t count) noexcept
  514. {
  515. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  516. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  517. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  518. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  519. std::memcpy(dest, src, count*sizeof(T));
  520. }
  521. // --------------------------------------------------------------------------------------------------------------------
  522. #endif // CARLA_UTILS_HPP_INCLUDED