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.

589 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_setenv
  258. /*
  259. * Set environment variable 'key' to 'value'.
  260. */
  261. static inline
  262. void carla_setenv(const char* const key, const char* const value) noexcept
  263. {
  264. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  265. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  266. #ifdef CARLA_OS_WIN
  267. try {
  268. ::SetEnvironmentVariableA(key, value);
  269. } CARLA_SAFE_EXCEPTION("carla_setenv");
  270. #else
  271. ::setenv(key, value, 1);
  272. #endif
  273. }
  274. /*
  275. * Unset environment variable 'key'.
  276. */
  277. static inline
  278. void carla_unsetenv(const char* const key) noexcept
  279. {
  280. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  281. #ifdef CARLA_OS_WIN
  282. try {
  283. ::SetEnvironmentVariableA(key, nullptr);
  284. } CARLA_SAFE_EXCEPTION("carla_unsetenv");
  285. #else
  286. ::unsetenv(key);
  287. #endif
  288. }
  289. // --------------------------------------------------------------------------------------------------------------------
  290. // carla_strdup
  291. /*
  292. * Custom 'strdup' function.
  293. * Returned value is always valid, and must be freed with "delete[] var".
  294. * May throw.
  295. */
  296. static inline
  297. const char* carla_strdup(const char* const strBuf)
  298. {
  299. CARLA_SAFE_ASSERT(strBuf != nullptr);
  300. const std::size_t bufferLen = (strBuf != nullptr) ? std::strlen(strBuf) : 0;
  301. char* const buffer = new char[bufferLen+1];
  302. if (bufferLen > 0)
  303. std::memcpy(buffer, strBuf, bufferLen);
  304. buffer[bufferLen] = '\0';
  305. return buffer;
  306. }
  307. /*
  308. * Custom 'strdup' function.
  309. * Calls "std::free(strBuf)".
  310. * Returned value is always valid, and must be freed with "delete[] var".
  311. * May throw.
  312. */
  313. static inline
  314. const char* carla_strdup_free(char* const strBuf)
  315. {
  316. const char* const buffer(carla_strdup(strBuf));
  317. std::free(strBuf);
  318. return buffer;
  319. }
  320. /*
  321. * Custom 'strdup' function, safe version.
  322. * Returned value may be null. It must be freed with "delete[] var".
  323. */
  324. static inline
  325. const char* carla_strdup_safe(const char* const strBuf) noexcept
  326. {
  327. CARLA_SAFE_ASSERT_RETURN(strBuf != nullptr, nullptr);
  328. const std::size_t bufferLen = std::strlen(strBuf);
  329. char* buffer;
  330. try {
  331. buffer = new char[bufferLen+1];
  332. } CARLA_SAFE_EXCEPTION_RETURN("carla_strdup_safe", nullptr);
  333. if (bufferLen > 0)
  334. std::memcpy(buffer, strBuf, bufferLen);
  335. buffer[bufferLen] = '\0';
  336. return buffer;
  337. }
  338. // --------------------------------------------------------------------------------------------------------------------
  339. // memory functions
  340. /*
  341. * Add array values to another array.
  342. */
  343. template<typename T>
  344. static inline
  345. void carla_add(T dest[], const T src[], const std::size_t count) noexcept
  346. {
  347. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  348. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  349. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  350. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  351. for (std::size_t i=0; i<count; ++i)
  352. *dest++ += *src++;
  353. }
  354. /*
  355. * Add array values to another array, with a multiplication factor.
  356. */
  357. template<typename T>
  358. static inline
  359. void carla_addWithMultiply(T dest[], const T src[], const T& multiplier, const std::size_t count) noexcept
  360. {
  361. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  362. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  363. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  364. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  365. for (std::size_t i=0; i<count; ++i)
  366. *dest++ += *src++ * multiplier;
  367. }
  368. /*
  369. * Copy array values to another array.
  370. */
  371. template<typename T>
  372. static inline
  373. void carla_copy(T dest[], const T src[], const std::size_t count) noexcept
  374. {
  375. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  376. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  377. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  378. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  379. std::memcpy(dest, src, count*sizeof(T));
  380. }
  381. /*
  382. * Copy array values to another array, with a multiplication factor.
  383. */
  384. template<typename T>
  385. static inline
  386. void carla_copyWithMultiply(T dest[], const T src[], const T& multiplier, const std::size_t count) noexcept
  387. {
  388. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  389. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  390. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  391. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  392. for (std::size_t i=0; i<count; ++i)
  393. *dest++ = *src++ * multiplier;
  394. }
  395. /*
  396. * Fill an array with a fixed value.
  397. */
  398. template<typename T>
  399. static inline
  400. void carla_fill(T data[], const T& value, const std::size_t count) noexcept
  401. {
  402. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  403. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  404. if (value == 0)
  405. {
  406. std::memset(data, 0, count*sizeof(T));
  407. }
  408. else
  409. {
  410. for (std::size_t i=0; i<count; ++i)
  411. *data++ = value;
  412. }
  413. }
  414. /*
  415. * Multiply an array with a fixed value.
  416. */
  417. template<typename T>
  418. static inline
  419. void carla_multiply(T data[], const T& multiplier, const std::size_t count) noexcept
  420. {
  421. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  422. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  423. if (multiplier == 0)
  424. {
  425. std::memset(data, 0, count*sizeof(T));
  426. }
  427. else
  428. {
  429. for (std::size_t i=0; i<count; ++i)
  430. *data++ *= multiplier;
  431. }
  432. }
  433. /*
  434. * Clear a byte array.
  435. */
  436. static inline
  437. void carla_zeroBytes(uint8_t bytes[], const std::size_t count) noexcept
  438. {
  439. CARLA_SAFE_ASSERT_RETURN(bytes != nullptr,);
  440. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  441. std::memset(bytes, 0, count*sizeof(uint8_t));
  442. }
  443. /*
  444. * Clear a char array.
  445. */
  446. static inline
  447. void carla_zeroChars(char chars[], const std::size_t count) noexcept
  448. {
  449. CARLA_SAFE_ASSERT_RETURN(chars != nullptr,);
  450. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  451. std::memset(chars, 0, count*sizeof(char));
  452. }
  453. /*
  454. * Clear a pointer array.
  455. */
  456. template<typename T>
  457. static inline
  458. void carla_zeroPointers(T* ptrs[], const std::size_t count) noexcept
  459. {
  460. CARLA_SAFE_ASSERT_RETURN(ptrs != nullptr,);
  461. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  462. std::memset(ptrs, 0, count*sizeof(T*));
  463. }
  464. /*
  465. * Clear a single struct.
  466. */
  467. template <typename T>
  468. static inline
  469. void carla_zeroStruct(T& s) noexcept
  470. {
  471. std::memset(&s, 0, sizeof(T));
  472. }
  473. /*
  474. * Clear a struct array.
  475. */
  476. template <typename T>
  477. static inline
  478. void carla_zeroStructs(T structs[], const std::size_t count) noexcept
  479. {
  480. CARLA_SAFE_ASSERT_RETURN(structs != nullptr,);
  481. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  482. std::memset(structs, 0, count*sizeof(T));
  483. }
  484. /*
  485. * Copy a single struct.
  486. */
  487. template <typename T>
  488. static inline
  489. void carla_copyStruct(T& dest, const T& src) noexcept
  490. {
  491. std::memcpy(&dest, &src, sizeof(T));
  492. }
  493. /*
  494. * Copy a struct array.
  495. */
  496. template <typename T>
  497. static inline
  498. void carla_copyStructs(T dest[], const T src[], const std::size_t count) noexcept
  499. {
  500. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  501. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  502. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  503. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  504. std::memcpy(dest, src, count*sizeof(T));
  505. }
  506. // --------------------------------------------------------------------------------------------------------------------
  507. #endif // CARLA_UTILS_HPP_INCLUDED