1 // SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
2 // SPDX-License-Identifier: GPL-2.0-or-later
4 #ifndef CARLA_UTILS_HPP_INCLUDED
5 #define CARLA_UTILS_HPP_INCLUDED
7 #include "CarlaDefines.h"
15 #ifdef CARLA_PROPER_CPP11_SUPPORT
28 # define WIN32_LEAN_AND_MEAN 1
30 # include <winsock2.h>
37 // --------------------------------------------------------------------------------------------------------------------
41 * Return "true" or "false" according to yesNo.
44 const char* bool2str(const bool yesNo
) noexcept
46 return yesNo
? "true" : "false";
50 * Set a string as empty/null.
53 void nullStrBuf(char* const strBuf
) noexcept
62 void pass() noexcept
{}
64 // --------------------------------------------------------------------------------------------------------------------
65 // string print functions
68 * Internal noexcept-safe fopen function.
71 FILE* __carla_fopen(const char* const filename
, FILE* const fallback
) noexcept
74 if (std::getenv("CARLA_CAPTURE_CONSOLE_OUTPUT") == nullptr)
80 ret
= std::fopen(filename
, "a+");
81 } CARLA_CATCH_UNWIND
catch (...) {}
95 * Print a string to stdout with newline (gray color).
96 * Does nothing if DEBUG is not defined.
99 # define carla_debug(...)
102 void carla_debug(const char* const fmt
, ...) noexcept
104 static FILE* const output
= __carla_fopen("/tmp/carla.debug.log", stdout
);
110 if (output
== stdout
)
113 std::fprintf(output
, "\x1b[37;1m[carla] ");
115 std::fprintf(output
, "\x1b[30;1m[carla] ");
117 std::vfprintf(output
, fmt
, args
);
118 std::fprintf(output
, "\x1b[0m\n");
122 std::fprintf(output
, "[carla] ");
123 std::vfprintf(output
, fmt
, args
);
124 std::fprintf(output
, "\n");
129 } CARLA_CATCH_UNWIND
catch (...) {}
134 * Print a string to stdout with newline.
137 void carla_stdout(const char* const fmt
, ...) noexcept
139 static FILE* const output
= __carla_fopen("/tmp/carla.stdout.log", stdout
);
144 std::fprintf(output
, "[carla] ");
145 std::vfprintf(output
, fmt
, args
);
146 std::fprintf(output
, "\n");
148 if (output
!= stdout
)
152 } CARLA_CATCH_UNWIND
catch (...) {}
156 * Print a string to stderr with newline.
159 void carla_stderr(const char* const fmt
, ...) noexcept
161 static FILE* const output
= __carla_fopen("/tmp/carla.stderr.log", stderr
);
166 std::fprintf(output
, "[carla] ");
167 std::vfprintf(output
, fmt
, args
);
168 std::fprintf(output
, "\n");
170 if (output
!= stderr
)
174 } CARLA_CATCH_UNWIND
catch (...) {}
178 * Print a string to stderr with newline (red color).
181 void carla_stderr2(const char* const fmt
, ...) noexcept
183 static FILE* const output
= __carla_fopen("/tmp/carla.stderr2.log", stderr
);
189 if (output
== stderr
)
191 std::fprintf(output
, "\x1b[31m[carla] ");
192 std::vfprintf(output
, fmt
, args
);
193 std::fprintf(output
, "\x1b[0m\n");
197 std::fprintf(output
, "[carla] ");
198 std::vfprintf(output
, fmt
, args
);
199 std::fprintf(output
, "\n");
204 } CARLA_CATCH_UNWIND
catch (...) {}
207 // --------------------------------------------------------------------------------------------------------------------
208 // carla_safe_assert*
211 * Print a safe assertion error message.
214 void carla_safe_assert(const char* const assertion
, const char* const file
, const int line
) noexcept
216 carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i", assertion
, file
, line
);
220 * Print a safe assertion error message, with 1 extra signed integer value.
223 void carla_safe_assert_int(const char* const assertion
, const char* const file
,
224 const int line
, const int value
) noexcept
226 carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, value %i", assertion
, file
, line
, value
);
230 * Print a safe assertion error message, with 1 extra unsigned integer value.
233 void carla_safe_assert_uint(const char* const assertion
, const char* const file
,
234 const int line
, const uint value
) noexcept
236 carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, value %u", assertion
, file
, line
, value
);
240 * Print a safe assertion error message, with 2 extra signed integer values.
243 void carla_safe_assert_int2(const char* const assertion
, const char* const file
,
244 const int line
, const int v1
, const int v2
) noexcept
246 carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, v1 %i, v2 %i", assertion
, file
, line
, v1
, v2
);
250 * Print a safe assertion error message, with 2 extra unsigned integer values.
253 void carla_safe_assert_uint2(const char* const assertion
, const char* const file
,
254 const int line
, const uint v1
, const uint v2
) noexcept
256 carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, v1 %u, v2 %u", assertion
, file
, line
, v1
, v2
);
260 * Print a safe assertion error message, with a custom error message.
263 void carla_custom_safe_assert(const char* const message
,
264 const char* const assertion
, const char* const file
, const int line
) noexcept
266 carla_stderr2("Carla assertion failure: %s, condition \"%s\" in file %s, line %i", message
, assertion
, file
, line
);
269 // --------------------------------------------------------------------------------------------------------------------
270 // carla_safe_exception*
273 * Print a safe exception error message.
276 void carla_safe_exception(const char* const exception
, const char* const file
, const int line
) noexcept
278 carla_stderr2("Carla exception caught: \"%s\" in file %s, line %i", exception
, file
, line
);
281 // --------------------------------------------------------------------------------------------------------------------
285 * Set environment variable 'key' to 'value'.
288 void carla_setenv(const char* const key
, const char* const value
) noexcept
290 CARLA_SAFE_ASSERT_RETURN(key
!= nullptr && key
[0] != '\0',);
291 CARLA_SAFE_ASSERT_RETURN(value
!= nullptr,);
295 ::SetEnvironmentVariableA(key
, value
);
296 } CARLA_SAFE_EXCEPTION("carla_setenv");
298 ::setenv(key
, value
, 1);
303 * Unset environment variable 'key'.
306 void carla_unsetenv(const char* const key
) noexcept
308 CARLA_SAFE_ASSERT_RETURN(key
!= nullptr && key
[0] != '\0',);
312 ::SetEnvironmentVariableA(key
, nullptr);
313 } CARLA_SAFE_EXCEPTION("carla_unsetenv");
319 // --------------------------------------------------------------------------------------------------------------------
323 * Custom 'strdup' function.
324 * Returned value is always valid, and must be freed with "delete[] var".
328 const char* carla_strdup(const char* const strBuf
)
330 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];
336 std::memcpy(buffer
, strBuf
, bufferLen
);
338 buffer
[bufferLen
] = '\0';
344 * Custom 'strdup' function.
345 * Calls "std::free(strBuf)".
346 * Returned value is always valid, and must be freed with "delete[] var".
350 const char* carla_strdup_free(char* const strBuf
)
352 const char* const buffer
= carla_strdup(strBuf
);
358 * Custom 'strdup' function, safe version.
359 * Returned value may be null. It must be freed with "delete[] var".
362 const char* carla_strdup_safe(const char* const strBuf
) noexcept
364 CARLA_SAFE_ASSERT_RETURN(strBuf
!= nullptr, nullptr);
366 const std::size_t bufferLen
= std::strlen(strBuf
);
370 buffer
= new char[bufferLen
+1];
371 } CARLA_SAFE_EXCEPTION_RETURN("carla_strdup_safe", nullptr);
374 std::memcpy(buffer
, strBuf
, bufferLen
);
376 buffer
[bufferLen
] = '\0';
381 // --------------------------------------------------------------------------------------------------------------------
386 # pragma comment(lib, "shlwapi.lib")
390 int carla_strcasecmp(const char* const str1
, const char* const str2
) noexcept
392 return ::StrCmpIA(str1
, str2
);
396 const char* carla_strcasestr(const char* const haystack
, const char* const needle
) noexcept
398 return ::StrStrIA(haystack
, needle
);
402 ssize_t
carla_strcasecmp(const char* const str1
, const char* const str2
) noexcept
404 return ::strcasecmp(str1
, str2
);
408 const char* carla_strcasestr(const char* const haystack
, const char* const needle
) noexcept
410 return ::strcasestr(haystack
, needle
);
414 // --------------------------------------------------------------------------------------------------------------------
418 * Add array values to another array.
422 void carla_add(T dest
[], const T src
[], const std::size_t count
) noexcept
424 CARLA_SAFE_ASSERT_RETURN(dest
!= nullptr,);
425 CARLA_SAFE_ASSERT_RETURN(src
!= nullptr,);
426 CARLA_SAFE_ASSERT_RETURN(dest
!= src
,);
427 CARLA_SAFE_ASSERT_RETURN(count
> 0,);
429 for (std::size_t i
=0; i
<count
; ++i
)
434 * Add array values to another array, with a multiplication factor.
438 void carla_addWithMultiply(T dest
[], const T src
[], const T
& multiplier
, const std::size_t count
) noexcept
440 CARLA_SAFE_ASSERT_RETURN(dest
!= nullptr,);
441 CARLA_SAFE_ASSERT_RETURN(src
!= nullptr,);
442 CARLA_SAFE_ASSERT_RETURN(dest
!= src
,);
443 CARLA_SAFE_ASSERT_RETURN(count
> 0,);
445 for (std::size_t i
=0; i
<count
; ++i
)
446 dest
[i
] += src
[i
] * multiplier
;
450 * Copy array values to another array.
454 void carla_copy(T dest
[], const T src
[], const std::size_t count
) noexcept
456 CARLA_SAFE_ASSERT_RETURN(dest
!= nullptr,);
457 CARLA_SAFE_ASSERT_RETURN(src
!= nullptr,);
458 CARLA_SAFE_ASSERT_RETURN(dest
!= src
,);
459 CARLA_SAFE_ASSERT_RETURN(count
> 0,);
461 std::memcpy(dest
, src
, count
*sizeof(T
));
465 * Copy array values to another array, with a multiplication factor.
469 void carla_copyWithMultiply(T dest
[], const T src
[], const T
& multiplier
, const std::size_t count
) noexcept
471 CARLA_SAFE_ASSERT_RETURN(dest
!= nullptr,);
472 CARLA_SAFE_ASSERT_RETURN(src
!= nullptr,);
473 CARLA_SAFE_ASSERT_RETURN(dest
!= src
,);
474 CARLA_SAFE_ASSERT_RETURN(count
> 0,);
476 for (std::size_t i
=0; i
<count
; ++i
)
477 dest
[i
] = src
[i
] * multiplier
;
481 * Fill an array with a fixed value.
485 void carla_fill(T data
[], const T
& value
, const std::size_t count
) noexcept
487 CARLA_SAFE_ASSERT_RETURN(data
!= nullptr,);
488 CARLA_SAFE_ASSERT_RETURN(count
> 0,);
492 std::memset(data
, 0, count
*sizeof(T
));
496 for (std::size_t i
=0; i
<count
; ++i
)
502 * Multiply an array with a fixed value.
506 void carla_multiply(T data
[], const T
& multiplier
, const std::size_t count
) noexcept
508 CARLA_SAFE_ASSERT_RETURN(data
!= nullptr,);
509 CARLA_SAFE_ASSERT_RETURN(count
> 0,);
513 std::memset(data
, 0, count
*sizeof(T
));
517 for (std::size_t i
=0; i
<count
; ++i
)
518 data
[i
] *= multiplier
;
523 * Clear a byte array.
526 void carla_zeroBytes(uint8_t bytes
[], const std::size_t count
) noexcept
528 CARLA_SAFE_ASSERT_RETURN(bytes
!= nullptr,);
529 CARLA_SAFE_ASSERT_RETURN(count
> 0,);
531 std::memset(bytes
, 0, count
*sizeof(uint8_t));
535 * Clear a char array.
538 void carla_zeroChars(char chars
[], const std::size_t count
) noexcept
540 CARLA_SAFE_ASSERT_RETURN(chars
!= nullptr,);
541 CARLA_SAFE_ASSERT_RETURN(count
> 0,);
543 std::memset(chars
, 0, count
*sizeof(char));
547 * Clear a pointer array.
551 void carla_zeroPointers(T
* ptrs
[], const std::size_t count
) noexcept
553 CARLA_SAFE_ASSERT_RETURN(ptrs
!= nullptr,);
554 CARLA_SAFE_ASSERT_RETURN(count
> 0,);
556 std::memset(ptrs
, 0, count
*sizeof(T
*));
560 * Clear a single struct.
562 template <typename T
>
564 void carla_zeroStruct(T
& s
) noexcept
566 std::memset(&s
, 0, sizeof(T
));
570 * Clear a struct array.
572 template <typename T
>
574 void carla_zeroStructs(T structs
[], const std::size_t count
) noexcept
576 CARLA_SAFE_ASSERT_RETURN(structs
!= nullptr,);
577 CARLA_SAFE_ASSERT_RETURN(count
> 0,);
579 std::memset(structs
, 0, count
*sizeof(T
));
583 * Copy a single struct.
585 template <typename T
>
587 void carla_copyStruct(T
& dest
, const T
& src
) noexcept
589 std::memcpy(&dest
, &src
, sizeof(T
));
593 * Copy a struct array.
595 template <typename T
>
597 void carla_copyStructs(T dest
[], const T src
[], const std::size_t count
) noexcept
599 CARLA_SAFE_ASSERT_RETURN(dest
!= nullptr,);
600 CARLA_SAFE_ASSERT_RETURN(src
!= nullptr,);
601 CARLA_SAFE_ASSERT_RETURN(dest
!= src
,);
602 CARLA_SAFE_ASSERT_RETURN(count
> 0,);
604 std::memcpy(dest
, src
, count
*sizeof(T
));
607 // --------------------------------------------------------------------------------------------------------------------
609 #endif // CARLA_UTILS_HPP_INCLUDED