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.

613 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. }
  110. std::fflush(output);
  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. #ifndef DEBUG
  128. if (output != stdout)
  129. #endif
  130. std::fflush(output);
  131. ::va_end(args);
  132. } CARLA_CATCH_UNWIND catch (...) {}
  133. }
  134. /*
  135. * Print a string to stderr with newline.
  136. */
  137. static inline
  138. void carla_stderr(const char* const fmt, ...) noexcept
  139. {
  140. static FILE* const output = __carla_fopen("/tmp/carla.stderr.log", stderr);
  141. try {
  142. ::va_list args;
  143. ::va_start(args, fmt);
  144. std::vfprintf(output, fmt, args);
  145. std::fprintf(output, "\n");
  146. #ifndef DEBUG
  147. if (output != stderr)
  148. #endif
  149. std::fflush(output);
  150. ::va_end(args);
  151. } CARLA_CATCH_UNWIND catch (...) {}
  152. }
  153. /*
  154. * Print a string to stderr with newline (red color).
  155. */
  156. static inline
  157. void carla_stderr2(const char* const fmt, ...) noexcept
  158. {
  159. static FILE* const output = __carla_fopen("/tmp/carla.stderr2.log", stderr);
  160. try {
  161. ::va_list args;
  162. ::va_start(args, fmt);
  163. if (output == stderr)
  164. {
  165. std::fprintf(output, "\x1b[31m");
  166. std::vfprintf(output, fmt, args);
  167. std::fprintf(output, "\x1b[0m\n");
  168. }
  169. else
  170. {
  171. std::vfprintf(output, fmt, args);
  172. std::fprintf(output, "\n");
  173. }
  174. std::fflush(output);
  175. ::va_end(args);
  176. } CARLA_CATCH_UNWIND catch (...) {}
  177. }
  178. // --------------------------------------------------------------------------------------------------------------------
  179. // carla_safe_assert*
  180. /*
  181. * Print a safe assertion error message.
  182. */
  183. static inline
  184. void carla_safe_assert(const char* const assertion, const char* const file, const int line) noexcept
  185. {
  186. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i", assertion, file, line);
  187. }
  188. /*
  189. * Print a safe assertion error message, with 1 extra signed integer value.
  190. */
  191. static inline
  192. void carla_safe_assert_int(const char* const assertion, const char* const file,
  193. const int line, const int value) noexcept
  194. {
  195. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, value %i", assertion, file, line, value);
  196. }
  197. /*
  198. * Print a safe assertion error message, with 1 extra unsigned integer value.
  199. */
  200. static inline
  201. void carla_safe_assert_uint(const char* const assertion, const char* const file,
  202. const int line, const uint value) noexcept
  203. {
  204. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, value %u", assertion, file, line, value);
  205. }
  206. /*
  207. * Print a safe assertion error message, with 2 extra signed integer values.
  208. */
  209. static inline
  210. void carla_safe_assert_int2(const char* const assertion, const char* const file,
  211. const int line, const int v1, const int v2) noexcept
  212. {
  213. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, v1 %i, v2 %i", assertion, file, line, v1, v2);
  214. }
  215. /*
  216. * Print a safe assertion error message, with 2 extra unsigned integer values.
  217. */
  218. static inline
  219. void carla_safe_assert_uint2(const char* const assertion, const char* const file,
  220. const int line, const uint v1, const uint v2) noexcept
  221. {
  222. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, v1 %u, v2 %u", assertion, file, line, v1, v2);
  223. }
  224. /*
  225. * Print a safe assertion error message, with a custom error message.
  226. */
  227. static inline
  228. void carla_custom_safe_assert(const char* const message,
  229. const char* const assertion, const char* const file, const int line) noexcept
  230. {
  231. carla_stderr2("Carla assertion failure: %s, condition \"%s\" in file %s, line %i", message, assertion, file, line);
  232. }
  233. // --------------------------------------------------------------------------------------------------------------------
  234. // carla_safe_exception*
  235. /*
  236. * Print a safe exception error message.
  237. */
  238. static inline
  239. void carla_safe_exception(const char* const exception, const char* const file, const int line) noexcept
  240. {
  241. carla_stderr2("Carla exception caught: \"%s\" in file %s, line %i", exception, file, line);
  242. }
  243. // --------------------------------------------------------------------------------------------------------------------
  244. // carla_*sleep
  245. /*
  246. * Sleep for 'secs' seconds.
  247. */
  248. static inline
  249. void carla_sleep(const uint secs) noexcept
  250. {
  251. CARLA_SAFE_ASSERT_RETURN(secs > 0,);
  252. try {
  253. #ifdef CARLA_OS_WIN
  254. ::Sleep(secs * 1000);
  255. #else
  256. ::sleep(secs);
  257. #endif
  258. } CARLA_SAFE_EXCEPTION("carla_sleep");
  259. }
  260. /*
  261. * Sleep for 'msecs' milliseconds.
  262. */
  263. static inline
  264. void carla_msleep(const uint msecs) noexcept
  265. {
  266. CARLA_SAFE_ASSERT_RETURN(msecs > 0,);
  267. try {
  268. #ifdef CARLA_OS_WIN
  269. ::Sleep(msecs);
  270. #else
  271. ::usleep(msecs * 1000);
  272. #endif
  273. } CARLA_SAFE_EXCEPTION("carla_msleep");
  274. }
  275. // --------------------------------------------------------------------------------------------------------------------
  276. // carla_setenv
  277. /*
  278. * Set environment variable 'key' to 'value'.
  279. */
  280. static inline
  281. void carla_setenv(const char* const key, const char* const value) noexcept
  282. {
  283. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  284. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  285. #ifdef CARLA_OS_WIN
  286. try {
  287. ::SetEnvironmentVariableA(key, value);
  288. } CARLA_SAFE_EXCEPTION("carla_setenv");
  289. #else
  290. ::setenv(key, value, 1);
  291. #endif
  292. }
  293. /*
  294. * Unset environment variable 'key'.
  295. */
  296. static inline
  297. void carla_unsetenv(const char* const key) noexcept
  298. {
  299. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  300. #ifdef CARLA_OS_WIN
  301. try {
  302. ::SetEnvironmentVariableA(key, nullptr);
  303. } CARLA_SAFE_EXCEPTION("carla_unsetenv");
  304. #else
  305. ::unsetenv(key);
  306. #endif
  307. }
  308. // --------------------------------------------------------------------------------------------------------------------
  309. // carla_strdup
  310. /*
  311. * Custom 'strdup' function.
  312. * Returned value is always valid, and must be freed with "delete[] var".
  313. * May throw.
  314. */
  315. static inline
  316. const char* carla_strdup(const char* const strBuf)
  317. {
  318. CARLA_SAFE_ASSERT(strBuf != nullptr);
  319. const std::size_t bufferLen = (strBuf != nullptr) ? std::strlen(strBuf) : 0;
  320. char* const buffer = new char[bufferLen+1];
  321. if (bufferLen > 0)
  322. std::memcpy(buffer, strBuf, bufferLen);
  323. buffer[bufferLen] = '\0';
  324. return buffer;
  325. }
  326. /*
  327. * Custom 'strdup' function.
  328. * Calls "std::free(strBuf)".
  329. * Returned value is always valid, and must be freed with "delete[] var".
  330. * May throw.
  331. */
  332. static inline
  333. const char* carla_strdup_free(char* const strBuf)
  334. {
  335. const char* const buffer(carla_strdup(strBuf));
  336. std::free(strBuf);
  337. return buffer;
  338. }
  339. /*
  340. * Custom 'strdup' function, safe version.
  341. * Returned value may be null. It must be freed with "delete[] var".
  342. */
  343. static inline
  344. const char* carla_strdup_safe(const char* const strBuf) noexcept
  345. {
  346. CARLA_SAFE_ASSERT_RETURN(strBuf != nullptr, nullptr);
  347. const std::size_t bufferLen = std::strlen(strBuf);
  348. char* buffer;
  349. try {
  350. buffer = new char[bufferLen+1];
  351. } CARLA_SAFE_EXCEPTION_RETURN("carla_strdup_safe", nullptr);
  352. if (bufferLen > 0)
  353. std::memcpy(buffer, strBuf, bufferLen);
  354. buffer[bufferLen] = '\0';
  355. return buffer;
  356. }
  357. // --------------------------------------------------------------------------------------------------------------------
  358. // memory functions
  359. /*
  360. * Add array values to another array.
  361. */
  362. template<typename T>
  363. static inline
  364. void carla_add(T dest[], const T src[], const std::size_t count) noexcept
  365. {
  366. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  367. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  368. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  369. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  370. for (std::size_t i=0; i<count; ++i)
  371. *dest++ += *src++;
  372. }
  373. /*
  374. * Add array values to another array, with a multiplication factor.
  375. */
  376. template<typename T>
  377. static inline
  378. void carla_addWithMultiply(T dest[], const T src[], const T& multiplier, const std::size_t count) noexcept
  379. {
  380. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  381. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  382. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  383. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  384. for (std::size_t i=0; i<count; ++i)
  385. *dest++ += *src++ * multiplier;
  386. }
  387. /*
  388. * Copy array values to another array.
  389. */
  390. template<typename T>
  391. static inline
  392. void carla_copy(T dest[], const T src[], const std::size_t count) noexcept
  393. {
  394. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  395. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  396. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  397. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  398. std::memcpy(dest, src, count*sizeof(T));
  399. }
  400. /*
  401. * Copy array values to another array, with a multiplication factor.
  402. */
  403. template<typename T>
  404. static inline
  405. void carla_copyWithMultiply(T dest[], const T src[], const T& multiplier, 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. for (std::size_t i=0; i<count; ++i)
  412. *dest++ = *src++ * multiplier;
  413. }
  414. /*
  415. * Fill an array with a fixed value.
  416. */
  417. template<typename T>
  418. static inline
  419. void carla_fill(T data[], const T& value, const std::size_t count) noexcept
  420. {
  421. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  422. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  423. if (value == 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++ = value;
  431. }
  432. }
  433. /*
  434. * Multiply an array with a fixed value.
  435. */
  436. template<typename T>
  437. static inline
  438. void carla_multiply(T data[], const T& multiplier, const std::size_t count) noexcept
  439. {
  440. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  441. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  442. if (multiplier == 0)
  443. {
  444. std::memset(data, 0, count*sizeof(T));
  445. }
  446. else
  447. {
  448. for (std::size_t i=0; i<count; ++i)
  449. *data++ *= multiplier;
  450. }
  451. }
  452. /*
  453. * Clear a byte array.
  454. */
  455. static inline
  456. void carla_zeroBytes(uint8_t bytes[], const std::size_t count) noexcept
  457. {
  458. CARLA_SAFE_ASSERT_RETURN(bytes != nullptr,);
  459. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  460. std::memset(bytes, 0, count*sizeof(uint8_t));
  461. }
  462. /*
  463. * Clear a char array.
  464. */
  465. static inline
  466. void carla_zeroChars(char chars[], const std::size_t count) noexcept
  467. {
  468. CARLA_SAFE_ASSERT_RETURN(chars != nullptr,);
  469. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  470. std::memset(chars, 0, count*sizeof(char));
  471. }
  472. /*
  473. * Clear a pointer array.
  474. */
  475. template<typename T>
  476. static inline
  477. void carla_zeroPointers(T* ptrs[], const std::size_t count) noexcept
  478. {
  479. CARLA_SAFE_ASSERT_RETURN(ptrs != nullptr,);
  480. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  481. std::memset(ptrs, 0, count*sizeof(T*));
  482. }
  483. /*
  484. * Clear a single struct.
  485. */
  486. template <typename T>
  487. static inline
  488. void carla_zeroStruct(T& s) noexcept
  489. {
  490. std::memset(&s, 0, sizeof(T));
  491. }
  492. /*
  493. * Clear a struct array.
  494. */
  495. template <typename T>
  496. static inline
  497. void carla_zeroStructs(T structs[], const std::size_t count) noexcept
  498. {
  499. CARLA_SAFE_ASSERT_RETURN(structs != nullptr,);
  500. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  501. std::memset(structs, 0, count*sizeof(T));
  502. }
  503. /*
  504. * Copy a single struct.
  505. */
  506. template <typename T>
  507. static inline
  508. void carla_copyStruct(T& dest, const T& src) noexcept
  509. {
  510. std::memcpy(&dest, &src, sizeof(T));
  511. }
  512. /*
  513. * Copy a struct array.
  514. */
  515. template <typename T>
  516. static inline
  517. void carla_copyStructs(T dest[], const T src[], const std::size_t count) noexcept
  518. {
  519. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  520. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  521. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  522. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  523. std::memcpy(dest, src, count*sizeof(T));
  524. }
  525. // --------------------------------------------------------------------------------------------------------------------
  526. #endif // CARLA_UTILS_HPP_INCLUDED