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.

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