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.

623 lines
15KB

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