Browse Source

Continue full checkup, add code comments

tags/1.9.4
falkTX 11 years ago
parent
commit
76c10d4834
7 changed files with 330 additions and 81 deletions
  1. +3
    -2
      source/tests/Makefile
  2. +2
    -0
      source/tests/Print.cpp
  3. +34
    -1
      source/tests/Utils.cpp
  4. +19
    -59
      source/utils/CarlaLibUtils.hpp
  5. +201
    -19
      source/utils/CarlaString.hpp
  6. +3
    -0
      source/utils/CarlaUtils.hpp
  7. +68
    -0
      source/utils/Utils.cpp

+ 3
- 2
source/tests/Makefile View File

@@ -11,6 +11,7 @@ include ../Makefile.mk
BUILD_CXX_FLAGS += -I../backend -I../includes -I../modules -I../modules/distrho -I../utils
BUILD_CXX_FLAGS += -DWANT_NATIVE -DWANT_LADSPA -DWANT_DSSI -DWANT_LV2 -DWANT_VST -DWANT_AU -DWANT_CSOUND -DWANT_FLUIDSYNTH -DWANT_LINUXSAMPLER
BUILD_CXX_FLAGS += -DWANT_OPENGL -DWANT_AUDIOFILE -DWANT_MIDIFILE -DWANT_ZYNADDSUBFX -DWANT_ZYNADDSUBFX_UI
BUILD_CXX_FLAGS += -std=c++11 -Wzero-as-null-pointer-constant
BUILD_CXX_FLAGS += -isystem /opt/kxstudio/include
# BUILD_CXX_FLAGS += -isystem /usr/include/qt5
# BUILD_CXX_FLAGS += -I/opt/mingw32/include
@@ -18,7 +19,7 @@ BUILD_CXX_FLAGS += -isystem /opt/kxstudio/include
ANSI_CXX_FLAGS = -DBUILD_ANSI_TEST -DVESTIGE_HEADER
ANSI_CXX_FLAGS += -ansi -pedantic -pedantic-errors -Wunused-parameter -Wuninitialized -Wno-vla
ANSI_CXX_FLAGS += -Wcast-qual -Wconversion -Wsign-conversion -Wlogical-op -Waggregate-return
ANSI_CXX_FLAGS += -std=c++11 -Wzero-as-null-pointer-constant
# ANSI_CXX_FLAGS += -std=c++11 -Wzero-as-null-pointer-constant

TARGETS = CarlaString Print RtList Utils

@@ -47,7 +48,7 @@ RtList: RtList.cpp ../utils/RtList.hpp ../modules/rtmempool.a
# valgrind ./RtList

Utils: Utils.cpp
$(CXX) $^ $(BUILD_CXX_FLAGS) $(ANSI_CXX_FLAGS) $(LINK_FLAGS) -o $@
$(CXX) $^ $(BUILD_CXX_FLAGS) $(ANSI_CXX_FLAGS) -std=c++11 -Wzero-as-null-pointer-constant $(LINK_FLAGS) -ldl -o $@
# valgrind ./Utils

# --------------------------------------------------------------


+ 2
- 0
source/tests/Print.cpp View File

@@ -25,3 +25,5 @@ int main()
carla_stderr2("STDERR2");
return 0;
}

#include "../utils/Utils.cpp"

+ 34
- 1
source/tests/Utils.cpp View File

@@ -16,6 +16,10 @@
*/

#include "CarlaUtils.hpp"
#include "CarlaLibUtils.hpp"
#include "CarlaJuceUtils.hpp"

#include "CarlaString.hpp"

#include <cassert>
#include <cstdlib>
@@ -27,6 +31,20 @@ struct MyStruct {
void* ptr;
};

class MyLeakCheckedClass
{
public:
MyLeakCheckedClass() {}
~MyLeakCheckedClass() {}
private:
char pad[100];
int i;
double d;
void* ptr;

CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MyLeakCheckedClass)
};

int main()
{
// misc functions
@@ -34,7 +52,11 @@ int main()
bool2str(true);
pass();

// string print functions, handled in Print
// string print functions
carla_debug("DEBUG");
carla_stdout("STDOUT");
carla_stderr("STDERR");
carla_stderr2("STDERR2");

// carla_*sleep
carla_sleep(1);
@@ -156,6 +178,17 @@ int main()
carla_copyStruct<MyStruct>(d, c, 2);
}

// Leak check
{
MyLeakCheckedClass a;
MyLeakCheckedClass* const b(new MyLeakCheckedClass);
delete b;
}

// String
{
}

return 0;
}



+ 19
- 59
source/utils/CarlaLibUtils.hpp View File

@@ -20,71 +20,31 @@

#include "CarlaUtils.hpp"

#ifndef CARLA_OS_WIN
# include <dlfcn.h>
#endif

// -----------------------------------------------------------------------
// library related calls

static inline
void* lib_open(const char* const filename)
{
CARLA_SAFE_ASSERT_RETURN(filename != nullptr, nullptr);

#ifdef CARLA_OS_WIN
return (void*)LoadLibraryA(filename);
#else
return dlopen(filename, RTLD_NOW|RTLD_LOCAL);
#endif
}

static inline
bool lib_close(void* const lib)
{
CARLA_SAFE_ASSERT_RETURN(lib != nullptr, false);

#ifdef CARLA_OS_WIN
return FreeLibrary((HMODULE)lib);
#else
return (dlclose(lib) == 0);
#endif
}

static inline
void* lib_symbol(void* const lib, const char* const symbol)
{
CARLA_SAFE_ASSERT_RETURN(lib != nullptr, nullptr);
CARLA_SAFE_ASSERT_RETURN(symbol != nullptr, nullptr);

#ifdef CARLA_OS_WIN
return (void*)GetProcAddress((HMODULE)lib, symbol);
#else
return dlsym(lib, symbol);
#endif
}

static inline
const char* lib_error(const char* const filename)
{
CARLA_SAFE_ASSERT_RETURN(filename != nullptr, nullptr);

#ifdef CARLA_OS_WIN
static char libError[2048+1];
carla_zeroChar(libError, 2048+1);
/*
* Open 'filename' library (must not be NULL).
* May return NULL, in which case "lib_error" has the error.
*/
void* lib_open(const char* const filename);

LPVOID winErrorString;
DWORD winErrorCode = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, winErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&winErrorString, 0, nullptr);
/*
* Close a previously opened library (must not be NULL).
* If false is returned,"lib_error" has the error.
*/
bool lib_close(void* const lib);

std::snprintf(libError, 2048, "%s: error code %li: %s", filename, winErrorCode, (const char*)winErrorString);
LocalFree(winErrorString);
/*
* Get a library symbol (must not be NULL).
* May return NULL if the symbol is not found.
*/
void* lib_symbol(void* const lib, const char* const symbol);

return libError;
#else
return dlerror();
#endif
}
/*
* Return the last operation error ('filename' must not be NULL).
*/
const char* lib_error(const char* const filename);

// -----------------------------------------------------------------------



+ 201
- 19
source/utils/CarlaString.hpp View File

@@ -20,6 +20,8 @@

#include "CarlaJuceUtils.hpp"

#include <cstdio> // for *printf

// -----------------------------------------------------------------------
// CarlaString class

@@ -29,24 +31,36 @@ public:
// -------------------------------------------------------------------
// constructors (no explicit conversions allowed)

/*
* Empty string.
*/
explicit CarlaString()
{
_init();
_dup(nullptr);
}

/*
* Simple char string.
*/
explicit CarlaString(char* const strBuf)
{
_init();
_dup(strBuf);
}

/*
* Simple const char string.
*/
explicit CarlaString(const char* const strBuf)
{
_init();
_dup(strBuf);
}

/*
* Integer.
*/
explicit CarlaString(const int value)
{
char strBuf[0xff+1];
@@ -57,6 +71,9 @@ public:
_dup(strBuf);
}

/*
* Unsigned integer, possibly in hexadecimal.
*/
explicit CarlaString(const unsigned int value, const bool hexadecimal = false)
{
char strBuf[0xff+1];
@@ -67,6 +84,9 @@ public:
_dup(strBuf);
}

/*
* Long integer.
*/
explicit CarlaString(const long int value)
{
char strBuf[0xff+1];
@@ -77,6 +97,9 @@ public:
_dup(strBuf);
}

/*
* Long unsigned integer, possibly hexadecimal.
*/
explicit CarlaString(const unsigned long int value, const bool hexadecimal = false)
{
char strBuf[0xff+1];
@@ -87,6 +110,9 @@ public:
_dup(strBuf);
}

/*
* Single-precision floating point number.
*/
explicit CarlaString(const float value)
{
char strBuf[0xff+1];
@@ -97,6 +123,9 @@ public:
_dup(strBuf);
}

/*
* Double-precision floating point number.
*/
explicit CarlaString(const double value)
{
char strBuf[0xff+1];
@@ -110,6 +139,9 @@ public:
// -------------------------------------------------------------------
// non-explicit constructor

/*
* Create string from another string.
*/
CarlaString(const CarlaString& str)
{
_init();
@@ -119,6 +151,9 @@ public:
// -------------------------------------------------------------------
// destructor

/*
* Destructor.
*/
~CarlaString()
{
CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,);
@@ -130,21 +165,33 @@ public:
// -------------------------------------------------------------------
// public methods

/*
* Get length of the string.
*/
size_t length() const noexcept
{
return fBufferLen;
}

/*
* Check if the string is empty.
*/
bool isEmpty() const noexcept
{
return (fBufferLen == 0);
}

/*
* Check if the string is not empty.
*/
bool isNotEmpty() const noexcept
{
return (fBufferLen != 0);
}

/*
* Check if the string contains another string, optionally ignoring case.
*/
bool contains(const char* const strBuf, const bool ignoreCase = false) const
{
CARLA_SAFE_ASSERT_RETURN(strBuf != nullptr, false);
@@ -164,11 +211,17 @@ public:
return (std::strstr(fBuffer, strBuf) != nullptr);
}

/*
* Overloaded function.
*/
bool contains(const CarlaString& str, const bool ignoreCase = false) const
{
return contains(str.fBuffer, ignoreCase);
}

/*
* Check if character at 'pos' is a digit.
*/
bool isDigit(const size_t pos) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(pos < fBufferLen, false);
@@ -176,6 +229,9 @@ public:
return (fBuffer[pos] >= '0' && fBuffer[pos] <= '9');
}

/*
* Check if the string starts with the character 'c'.
*/
bool startsWith(const char c) const
{
CARLA_SAFE_ASSERT_RETURN(c != '\0', false);
@@ -183,6 +239,9 @@ public:
return (fBufferLen > 0 && fBuffer[0] == c);
}

/*
* Check if the string starts with the string 'prefix'.
*/
bool startsWith(const char* const prefix) const
{
CARLA_SAFE_ASSERT_RETURN(prefix != nullptr, false);
@@ -195,6 +254,9 @@ public:
return (std::strncmp(fBuffer + (fBufferLen-prefixLen), prefix, prefixLen) == 0);
}

/*
* Check if the string ends with the character 'c'.
*/
bool endsWith(const char c) const
{
CARLA_SAFE_ASSERT_RETURN(c != '\0', false);
@@ -202,6 +264,9 @@ public:
return (fBufferLen > 0 && fBuffer[fBufferLen] == c);
}

/*
* Check if the string ends with the string 'suffix'.
*/
bool endsWith(const char* const suffix) const
{
CARLA_SAFE_ASSERT_RETURN(suffix != nullptr, false);
@@ -214,36 +279,110 @@ public:
return (std::strncmp(fBuffer + (fBufferLen-suffixLen), suffix, suffixLen) == 0);
}

void clear() noexcept
/*
* Find the first occurrence of character 'c' in the string.
* Returns "length()" if the character is not found.
*/
size_t find(const char c, bool* const found = nullptr) const noexcept
{
truncate(0);
}
if (fBufferLen == 0 || c == '\0')
{
if (found != nullptr)
*found = false;
return fBufferLen;
}

size_t find(const char c) const noexcept
{
for (size_t i=0; i < fBufferLen; ++i)
{
if (fBuffer[i] == c)
{
if (found != nullptr)
*found = true;
return i;
}
}

if (found != nullptr)
*found = false;
return fBufferLen;
}

/*
* Find the first occurrence of string 'strBuf' in the string.
* Returns "length()" if the string is not found.
*/
size_t find(const char* const strBuf, bool* const found = nullptr) const
{
if (fBufferLen == 0 || strBuf != nullptr || strBuf[0] != '\0')
{
if (found != nullptr)
*found = false;
return fBufferLen;
}

if (char* const subStrBuf = std::strstr(fBuffer, strBuf))
{
const ssize_t ret(subStrBuf - fBuffer);

if (ret < 0)
{
// should never happen!
carla_stderr2("Carla assertion failure: \"ret >= 0\" in file %s, line %i, value %i", __FILE__, __LINE__, ret);

if (found != nullptr)
*found = false;
return fBufferLen;
}

if (found != nullptr)
*found = true;
return static_cast<size_t>(ret);
}

return 0;
if (found != nullptr)
*found = false;
return fBufferLen;
}

size_t rfind(const char c) const noexcept
/*
* Find the last occurrence of character 'c' in the string.
* Returns "length()" if the character is not found.
*/
size_t rfind(const char c, bool* const found = nullptr) const noexcept
{
if (fBufferLen == 0 || c == '\0')
{
if (found != nullptr)
*found = false;
return fBufferLen;
}

for (size_t i=fBufferLen; i > 0; --i)
{
if (fBuffer[i-1] == c)
{
if (found != nullptr)
*found = true;
return i-1;
}
}

return 0;
if (found != nullptr)
*found = false;
return fBufferLen;
}

size_t rfind(const char* const strBuf) const
/*
* Find the last occurrence of string 'strBuf' in the string.
* Returns "length()" if the string is not found.
*/
size_t rfind(const char* const strBuf, bool* const found = nullptr) const
{
CARLA_SAFE_ASSERT_RETURN(strBuf != nullptr && strBuf[0] != '\0', fBufferLen);
if (found != nullptr)
*found = false;

if (fBufferLen == 0 || strBuf != nullptr || strBuf[0] != '\0')
return fBufferLen;

size_t ret = fBufferLen+1;
const char* tmpBuf = fBuffer;
@@ -251,7 +390,11 @@ public:
for (size_t i=0; i < fBufferLen; ++i)
{
if (std::strstr(tmpBuf, strBuf) == nullptr)
{
if (found != nullptr)
*found = true;
break;
}

--ret;
++tmpBuf;
@@ -260,6 +403,17 @@ public:
return (ret > fBufferLen) ? fBufferLen : fBufferLen-ret;
}

/*
* Clear the string.
*/
void clear() noexcept
{
truncate(0);
}

/*
* Replace all occurrences of character 'before' with character 'after'.
*/
void replace(const char before, const char after)
{
CARLA_SAFE_ASSERT_RETURN(before != '\0' && after != '\0',);
@@ -273,6 +427,9 @@ public:
}
}

/*
* Truncate the string to size 'n'.
*/
void truncate(const size_t n) noexcept
{
if (n >= fBufferLen)
@@ -284,6 +441,9 @@ public:
fBufferLen = n;
}

/*
* Convert all non-basic characters to '_'.
*/
void toBasic() noexcept
{
for (size_t i=0; i < fBufferLen; ++i)
@@ -301,6 +461,9 @@ public:
}
}

/*
* Convert to all ascii characters to lowercase.
*/
void toLower() noexcept
{
#ifndef BUILD_ANSI_TEST
@@ -315,6 +478,9 @@ public:
#endif
}

/*
* Convert to all ascii characters to uppercase.
*/
void toUpper() noexcept
{
#ifndef BUILD_ANSI_TEST
@@ -329,11 +495,17 @@ public:
#endif
}

/*
* Return a duplicate string buffer.
*/
const char* dup() const
{
return carla_strdup(fBuffer);
}

/*
* Direct access to the string buffer.
*/
const char* getBuffer() const
{
return fBuffer;
@@ -426,10 +598,14 @@ public:
// -------------------------------------------------------------------

private:
char* fBuffer;
size_t fBufferLen;
bool fFirstInit;

char* fBuffer; // the actual string buffer
size_t fBufferLen; // string length
bool fFirstInit; // true when first initiated

/*
* Shared init function.
* Called on all constructors.
*/
void _init() noexcept
{
fBuffer = nullptr;
@@ -437,8 +613,14 @@ private:
fFirstInit = true;
}

// allocate string strBuf if not null
// size > 0 only if strBuf is valid
/*
* Helper function.
* Called whenever the string needs to be allocated.
*
* Notes:
* - Allocates string only if first initiated, or 'strBuf' is not null and new string contents are different
* - If 'strBuf' is null 'size' must be 0
*/
void _dup(const char* const strBuf, const size_t size = 0)
{
if (strBuf != nullptr)
@@ -448,7 +630,7 @@ private:
{
if (! fFirstInit)
{
CARLA_ASSERT(fBuffer != nullptr);
CARLA_SAFE_ASSERT(fBuffer != nullptr);
delete[] fBuffer;
}

@@ -464,14 +646,14 @@ private:
}
else
{
CARLA_ASSERT(size == 0);
CARLA_SAFE_ASSERT(size == 0);

// don't recreate null string
if (fFirstInit || fBufferLen != 0)
{
if (! fFirstInit)
{
CARLA_ASSERT(fBuffer != nullptr);
CARLA_SAFE_ASSERT(fBuffer != nullptr);
delete[] fBuffer;
}



+ 3
- 0
source/utils/CarlaUtils.hpp View File

@@ -74,6 +74,7 @@ void carla_stderr2(const char* const fmt, ...);
/*
* Print a safe assertion error message.
*/
inline
void carla_safe_assert(const char* const assertion, const char* const file, const int line)
{
carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i", assertion, file, line);
@@ -82,6 +83,7 @@ void carla_safe_assert(const char* const assertion, const char* const file, cons
/*
* Print a safe assertion error message, with 1 extra integer value.
*/
inline
void carla_safe_assert_int(const char* const assertion, const char* const file, const int line, const int value)
{
carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, value %i", assertion, file, line, value);
@@ -90,6 +92,7 @@ void carla_safe_assert_int(const char* const assertion, const char* const file,
/*
* Print a safe assertion error message, with 2 extra integer values.
*/
inline
void carla_safe_assert_int2(const char* const assertion, const char* const file, const int line, const int v1, const int v2)
{
carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, v1 %i, v2 %i", assertion, file, line, v1, v2);


+ 68
- 0
source/utils/Utils.cpp View File

@@ -20,6 +20,7 @@
// IDE Helper
#ifndef REAL_BUILD
# include "CarlaUtils.hpp"
# include "CarlaLibUtils.hpp"
#endif

#include <cstdarg> // needed for va_*
@@ -31,9 +32,12 @@
# include <winsock2.h> // should be included before "windows.h"
# include <windows.h>
#else
# include <dlfcn.h>
# include <unistd.h>
#endif

// -----------------------------------------------------------------------

#ifdef CARLA_UTILS_HPP_INCLUDED
// -----------------------------------------------------------------------
// string print functions
@@ -143,3 +147,67 @@ const char* carla_strdup_free(char* const strBuf)
return buffer;
}
#endif // CARLA_UTILS_HPP_INCLUDED

// -----------------------------------------------------------------------

#ifdef CARLA_LIB_UTILS_HPP_INCLUDED
// -----------------------------------------------------------------------
// library related calls

void* lib_open(const char* const filename)
{
CARLA_SAFE_ASSERT_RETURN(filename != nullptr, nullptr);

#ifdef CARLA_OS_WIN
return (void*)LoadLibraryA(filename);
#else
return dlopen(filename, RTLD_NOW|RTLD_LOCAL);
#endif
}

bool lib_close(void* const lib)
{
CARLA_SAFE_ASSERT_RETURN(lib != nullptr, false);

#ifdef CARLA_OS_WIN
return FreeLibrary((HMODULE)lib);
#else
return (dlclose(lib) == 0);
#endif
}

void* lib_symbol(void* const lib, const char* const symbol)
{
CARLA_SAFE_ASSERT_RETURN(lib != nullptr, nullptr);
CARLA_SAFE_ASSERT_RETURN(symbol != nullptr, nullptr);

#ifdef CARLA_OS_WIN
return (void*)GetProcAddress((HMODULE)lib, symbol);
#else
return dlsym(lib, symbol);
#endif
}

const char* lib_error(const char* const filename)
{
CARLA_SAFE_ASSERT_RETURN(filename != nullptr, nullptr);

#ifdef CARLA_OS_WIN
static char libError[2048+1];
carla_zeroChar(libError, 2048+1);

LPVOID winErrorString;
DWORD winErrorCode = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, winErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&winErrorString, 0, nullptr);

std::snprintf(libError, 2048, "%s: error code %li: %s", filename, winErrorCode, (const char*)winErrorString);
LocalFree(winErrorString);

return libError;
#else
return dlerror();
#endif
}
#endif // CARLA_LIB_UTILS_HPP_INCLUDED

// -----------------------------------------------------------------------

Loading…
Cancel
Save