Browse Source

Check lv2-utils, found some leaks; Implement some juce stuff

tags/1.9.4
falkTX 10 years ago
parent
commit
cc4707c31b
5 changed files with 197 additions and 88 deletions
  1. +4
    -1
      source/modules/lilv/lilv-0.18.0/lilv/lilvmm.hpp
  2. +44
    -2
      source/tests/CarlaUtils.cpp
  3. +1
    -1
      source/tests/Makefile
  4. +130
    -66
      source/utils/CarlaLv2Utils.hpp
  5. +18
    -18
      source/utils/CarlaStringList.hpp

+ 4
- 1
source/modules/lilv/lilv-0.18.0/lilv/lilvmm.hpp View File

@@ -145,7 +145,10 @@ struct ScalePoints {
struct Nodes {
LILV_WRAP_COLL(Nodes, Node, nodes);
LILV_WRAP1(bool, nodes, contains, const Node, node);
LILV_WRAP0(Node, nodes, get_first);

inline Node get_first() const {
return Node((const LilvNode*)lilv_nodes_get_first(me));
}
};

struct UI {


+ 44
- 2
source/tests/CarlaUtils.cpp View File

@@ -19,16 +19,20 @@
# error Build this file with debug ON please
#endif

#undef HAVE_JUCE
#define HAVE_JUCE

#include "CarlaUtils.hpp"
#include "CarlaMathUtils.hpp"

#undef NULL
#define NULL nullptr

#include "CarlaBackendUtils.hpp"
#include "CarlaEngineUtils.hpp"

#include "CarlaLadspaUtils.hpp"
#include "CarlaDssiUtils.hpp"
#include "CarlaLv2Utils.hpp"

// used in dssi utils
#include "juce_core.h"
@@ -39,7 +43,6 @@
// #include "CarlaBridgeUtils.hpp"
// #include "CarlaJuceUtils.hpp"
// #include "CarlaLibUtils.hpp"
// #include "CarlaLv2Utils.hpp"
// #include "CarlaOscUtils.hpp"
// #include "CarlaShmUtils.hpp"
// #include "CarlaStateUtils.hpp"
@@ -545,6 +548,44 @@ static void test_CarlaDssiUtils() noexcept
}
}

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

static LV2_URID test_lv2_uridMap(LV2_URID_Map_Handle, const char*)
{
return 1;
}

static void test_CarlaLv2Utils() noexcept
{
Lv2WorldClass& lv2World(Lv2WorldClass::getInstance());
lv2World.initIfNeeded();

// getPlugin
const LilvPlugin* const plugin(lv2World.getPlugin("urn:juced:DrumSynth"));
CARLA_SAFE_ASSERT(plugin != nullptr);

// getState
LV2_URID_Map uridMap = { nullptr, test_lv2_uridMap };
LilvState* const state(lv2World.getState("http://arcticanaudio.com/plugins/thefunction#preset001", &uridMap));
CARLA_SAFE_ASSERT(state != nullptr);
if (state != nullptr) lilv_state_free(state);

// load a bunch of plugins to stress test lilv
delete lv2_rdf_new("http://arcticanaudio.com/plugins/thefunction", true);
delete lv2_rdf_new("http://kunz.corrupt.ch/products/tal-noisemaker", true);
delete lv2_rdf_new("http://calf.sourceforge.net/plugins/Reverb", true);
delete lv2_rdf_new("http://www.openavproductions.com/fabla", true);
delete lv2_rdf_new("http://invadarecords.com/plugins/lv2/meter", true);
//delete lv2_rdf_new("http://gareus.org/oss/lv2/meters#spectr30stereo", true);
delete lv2_rdf_new("http://synthv1.sourceforge.net/lv2", true);
delete lv2_rdf_new("urn:juced:DrumSynth", true);

// misc
is_lv2_port_supported(0x0);
is_lv2_feature_supported("test1");
is_lv2_ui_feature_supported("test2");
}

// -----------------------------------------------------------------------
// main

@@ -558,6 +599,7 @@ int main()

test_CarlaLadspaUtils();
test_CarlaDssiUtils();
test_CarlaLv2Utils();

return 0;
}


+ 1
- 1
source/tests/Makefile View File

@@ -69,7 +69,7 @@ CarlaString: CarlaString.cpp ../utils/CarlaString.hpp

CarlaUtils: CarlaUtils.cpp ../utils/*.hpp
$(CXX) $< $(PEDANTIC_CXX_FLAGS) -o $@ \
../modules/juce_core.a -ldl -lpthread -lrt \
../modules/juce_core.a ../modules/lilv.a -ldl -lpthread -lrt \
$(shell pkg-config --cflags --libs QtCore) -isystem /usr/include/qt4
valgrind --leak-check=full ./$@



+ 130
- 66
source/utils/CarlaLv2Utils.hpp View File

@@ -61,7 +61,11 @@
#include "lilv/lilvmm.hpp"
#include "sratom/sratom.h"

#include <QtCore/QStringList>
#ifdef HAVE_JUCE
# include "juce_core.h"
#else
# include <QtCore/QStringList>
#endif

// -----------------------------------------------------------------------
// Define namespaces and missing prefixes
@@ -344,7 +348,7 @@ public:
return lv2World;
}

void init()
void initIfNeeded()
{
if (! needsInit)
return;
@@ -356,6 +360,7 @@ public:
const LilvPlugin* getPlugin(const LV2_URI uri) const
{
CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0', nullptr);
CARLA_SAFE_ASSERT_RETURN(! needsInit, nullptr);

const LilvPlugins* const cPlugins(lilv_world_get_all_plugins(this->me));

@@ -385,10 +390,11 @@ public:
return cPlugin;
}

const LilvState* getState(const LV2_URI uri, const LV2_URID_Map* const uridMap) const
LilvState* getState(const LV2_URI uri, const LV2_URID_Map* const uridMap) const
{
CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0', nullptr);
CARLA_SAFE_ASSERT_RETURN(uridMap != nullptr, nullptr);
CARLA_SAFE_ASSERT_RETURN(! needsInit, nullptr);

LilvNode* const uriNode(Lilv::World::new_uri(uri));

@@ -398,7 +404,7 @@ public:
return nullptr;
}

const LilvState* const cState(lilv_state_new_from_world(this->me, uridMap, uriNode));
LilvState* const cState(lilv_state_new_from_world(this->me, uridMap, uriNode));
lilv_node_free(uriNode);

if (cState == nullptr)
@@ -424,7 +430,7 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit)
Lv2WorldClass& lv2World(Lv2WorldClass::getInstance());

if (doInit)
lv2World.init();
lv2World.initIfNeeded();

const LilvPlugin* const cPlugin(lv2World.getPlugin(uri));

@@ -519,6 +525,8 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit)
if (typeNodes.contains(lv2World.class_waveshaper))
rdfDescriptor->Type[0] |= LV2_PLUGIN_WAVESHAPER;
}

lilv_nodes_free(const_cast<LilvNodes*>(typeNodes.me));
}

// -------------------------------------------------------------------
@@ -545,6 +553,8 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit)
if (const char* const license = licenseNodes.get_first().as_string())
rdfDescriptor->License = carla_strdup(license);
}

lilv_nodes_free(const_cast<LilvNodes*>(licenseNodes.me));
}

// -------------------------------------------------------------------
@@ -558,6 +568,17 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit)

if (replaceNode.is_uri())
{
#ifdef HAVE_JUCE
const juce::String replaceURI(replaceNode.as_uri());

if (replaceURI.startsWith("urn:"))
{
const int uniqueId(replaceURI.getTrailingIntValue());

if (uniqueId > 0)
rdfDescriptor->UniqueID = static_cast<ulong>(uniqueId);
}
#else
const QString replaceURI(replaceNode.as_uri());

if (replaceURI.startsWith("urn:"))
@@ -570,8 +591,11 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit)
if (ok && uniqueId != 0)
rdfDescriptor->UniqueID = uniqueId;
}
#endif
}
}

lilv_nodes_free(const_cast<LilvNodes*>(replaceNodes.me));
}

// -------------------------------------------------------------------
@@ -660,6 +684,9 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit)
carla_stderr("lv2_rdf_new(\"%s\") - port '%s' is of atom type but has unsupported data '%s'", uri, rdfPort->Name, node.as_uri());
#endif
}

lilv_nodes_free(const_cast<LilvNodes*>(bufferTypeNodes.me));
lilv_nodes_free(const_cast<LilvNodes*>(supportNodes.me));
}
else if (lilvPort.is_a(lv2World.port_event))
{
@@ -794,11 +821,9 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit)
// -----------------------------------------------------------
// Set Port Designation
{
Lilv::Nodes designationNodes(lilvPort.get_value(lv2World.designation));

if (designationNodes.size() > 0)
if (LilvNode* const designationNode = lilv_port_get(lilvPort.parent, lilvPort.me, lv2World.designation.me))
{
if (const char* const designation = designationNodes.get_first().as_string())
if (const char* const designation = lilv_node_as_string(designationNode))
{
if (std::strcmp(designation, LV2_CORE__control) == 0)
rdfPort->Designation = LV2_PORT_DESIGNATION_CONTROL;
@@ -833,19 +858,16 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit)
else
carla_stderr("lv2_rdf_new(\"%s\") - got unknown port designation '%s'", uri, designation);
}
lilv_node_free(designationNode);
}
}

// -----------------------------------------------------------
// Set Port MIDI Map
{
Lilv::Nodes midiMapNodes(lilvPort.get_value(lv2World.mm_defaultControl));

if (midiMapNodes.size() > 0)
if (LilvNode* const midiMapNode = lilv_port_get(lilvPort.parent, lilvPort.me, lv2World.mm_defaultControl.me))
{
Lilv::Node midiMapNode(midiMapNodes.get_first());

if (midiMapNode.is_blank())
if (lilv_node_is_blank(midiMapNode))
{
Lilv::Nodes midiMapTypeNodes(lv2World.find_nodes(midiMapNode, lv2World.mm_controlType, nullptr));
Lilv::Nodes midiMapNumberNodes(lv2World.find_nodes(midiMapNode, lv2World.mm_controlNumber, nullptr));
@@ -864,7 +886,12 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit)
rdfPort->MidiMap.Number = static_cast<uint32_t>(midiMapNumberNodes.get_first().as_int());
}
}

lilv_nodes_free(const_cast<LilvNodes*>(midiMapTypeNodes.me));
lilv_nodes_free(const_cast<LilvNodes*>(midiMapNumberNodes.me));
}

lilv_node_free(midiMapNode);
}

// TODO - also check using new official MIDI API too
@@ -873,43 +900,36 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit)
// -----------------------------------------------------------
// Set Port Points
{
Lilv::Nodes valueNodes(lilvPort.get_value(lv2World.value_default));

if (valueNodes.size() > 0)
if (LilvNode* const defNode = lilv_port_get(lilvPort.parent, lilvPort.me, lv2World.value_default.me))
{
rdfPort->Points.Hints |= LV2_PORT_POINT_DEFAULT;
rdfPort->Points.Default = valueNodes.get_first().as_float();
rdfPort->Points.Default = lilv_node_as_float(defNode);
lilv_node_free(defNode);
}

valueNodes = lilvPort.get_value(lv2World.value_minimum);

if (valueNodes.size() > 0)
if (LilvNode* const minNode = lilv_port_get(lilvPort.parent, lilvPort.me, lv2World.value_minimum.me))
{
rdfPort->Points.Hints |= LV2_PORT_POINT_MINIMUM;
rdfPort->Points.Minimum = valueNodes.get_first().as_float();
rdfPort->Points.Minimum = lilv_node_as_float(minNode);
lilv_node_free(minNode);
}

valueNodes = lilvPort.get_value(lv2World.value_maximum);

if (valueNodes.size() > 0)
if (LilvNode* const maxNode = lilv_port_get(lilvPort.parent, lilvPort.me, lv2World.value_maximum.me))
{
rdfPort->Points.Hints |= LV2_PORT_POINT_MAXIMUM;
rdfPort->Points.Maximum = valueNodes.get_first().as_float();
rdfPort->Points.Maximum = lilv_node_as_float(maxNode);
lilv_node_free(maxNode);
}
}

// -----------------------------------------------------------
// Set Port Unit
{
Lilv::Nodes unitUnitNodes(lilvPort.get_value(lv2World.unit_unit));

if (unitUnitNodes.size() > 0)
if (LilvNode* const unitUnitNode = lilv_port_get(lilvPort.parent, lilvPort.me, lv2World.unit_unit.me))
{
Lilv::Node unitUnitNode(unitUnitNodes.get_first());

if (unitUnitNode.is_uri())
if (lilv_node_is_uri(unitUnitNode))
{
if (const char* const unitUnit = unitUnitNode.as_uri())
if (const char* const unitUnit = lilv_node_as_uri(unitUnitNode))
{
rdfPort->Unit.Hints |= LV2_PORT_UNIT_UNIT;

@@ -965,83 +985,85 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit)
carla_stderr("lv2_rdf_new(\"%s\") - got unknown unit unit '%s'", uri, unitUnit);
}
}
lilv_node_free(unitUnitNode);
}

// FIXME

Lilv::Nodes unitNameNodes(lilvPort.get_value(lv2World.unit_name));

if (unitNameNodes.size() > 0)
if (LilvNode* const unitNameNode = lilv_port_get(lilvPort.parent, lilvPort.me, lv2World.unit_name.me))
{
if (const char* const unitName = unitNameNodes.get_first().as_string())
if (const char* const unitName = lilv_node_as_string(unitNameNode))
{
rdfPort->Unit.Hints |= LV2_PORT_UNIT_NAME;
rdfPort->Unit.Name = carla_strdup(unitName);
}
lilv_node_free(unitNameNode);
}

Lilv::Nodes unitRenderNodes(lilvPort.get_value(lv2World.unit_render));

if (unitRenderNodes.size() > 0)
if (LilvNode* const unitRenderNode = lilv_port_get(lilvPort.parent, lilvPort.me, lv2World.unit_render.me))
{
if (const char* const unitRender = unitRenderNodes.get_first().as_string())
if (const char* const unitRender = lilv_node_as_string(unitRenderNode))
{
rdfPort->Unit.Hints |= LV2_PORT_UNIT_RENDER;
rdfPort->Unit.Render = carla_strdup(unitRender);
}
lilv_node_free(unitRenderNode);
}

Lilv::Nodes unitSymbolNodes(lilvPort.get_value(lv2World.unit_symbol));

if (unitSymbolNodes.size() > 0)
if (LilvNode* const unitSymbolNode = lilv_port_get(lilvPort.parent, lilvPort.me, lv2World.unit_symbol.me))
{
if (const char* const unitSymbol = unitSymbolNodes.get_first().as_string())
if (const char* const unitSymbol = lilv_node_as_string(unitSymbolNode))
{
rdfPort->Unit.Hints |= LV2_PORT_UNIT_SYMBOL;
rdfPort->Unit.Symbol = carla_strdup(unitSymbol);
}
lilv_node_free(unitSymbolNode);
}
}

// -----------------------------------------------------------
// Set Port Minimum Size
{
Lilv::Nodes minimumSizeNodes(lilvPort.get_value(lv2World.rz_minSize));

if (minimumSizeNodes.size() > 0)
if (LilvNode* const minimumSizeNode = lilv_port_get(lilvPort.parent, lilvPort.me, lv2World.rz_minSize.me))
{
const int minimumSize(minimumSizeNodes.get_first().as_int());
const int minimumSize(lilv_node_as_int(minimumSizeNode));

if (minimumSize > 0)
rdfPort->MinimumSize = static_cast<uint32_t>(minimumSize);
else
carla_safe_assert_int("minimumSize > 0", __FILE__, __LINE__, minimumSize);

lilv_node_free(minimumSizeNode);
}
}

// -----------------------------------------------------------
// Set Port Scale Points

Lilv::ScalePoints lilvScalePoints(lilvPort.get_scale_points());

if (lilvScalePoints.size() > 0)
{
rdfPort->ScalePointCount = lilvScalePoints.size();
rdfPort->ScalePoints = new LV2_RDF_PortScalePoint[rdfPort->ScalePointCount];
Lilv::ScalePoints lilvScalePoints(lilvPort.get_scale_points());

uint32_t h = 0;
LILV_FOREACH(scale_points, it, lilvScalePoints)
if (lilvScalePoints.size() > 0)
{
CARLA_SAFE_ASSERT_BREAK(h < rdfPort->ScalePointCount);
rdfPort->ScalePointCount = lilvScalePoints.size();
rdfPort->ScalePoints = new LV2_RDF_PortScalePoint[rdfPort->ScalePointCount];

Lilv::ScalePoint lilvScalePoint(lilvScalePoints.get(it));
LV2_RDF_PortScalePoint* const rdfScalePoint(&rdfPort->ScalePoints[h++]);
uint32_t h = 0;
LILV_FOREACH(scale_points, it, lilvScalePoints)
{
CARLA_SAFE_ASSERT_BREAK(h < rdfPort->ScalePointCount);

if (const char* const label = Lilv::Node(lilvScalePoint.get_label()).as_string())
rdfScalePoint->Label = carla_strdup(label);
Lilv::ScalePoint lilvScalePoint(lilvScalePoints.get(it));
LV2_RDF_PortScalePoint* const rdfScalePoint(&rdfPort->ScalePoints[h++]);

rdfScalePoint->Value = Lilv::Node(lilvScalePoint.get_value()).as_float();
if (const char* const label = Lilv::Node(lilvScalePoint.get_label()).as_string())
rdfScalePoint->Label = carla_strdup(label);

rdfScalePoint->Value = Lilv::Node(lilvScalePoint.get_value()).as_float();
}
}

lilv_nodes_free(const_cast<LilvNodes*>(lilvScalePoints.me));
}
}
}
@@ -1056,12 +1078,30 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit)
if (presetNodes.size() > 0)
{
// create a list of preset URIs (for checking appliesTo, sorting and unique-ness)
// FIXME - check appliesTo?

#ifdef HAVE_JUCE
juce::StringArray presetListURIs;

LILV_FOREACH(nodes, it, presetNodes)
{
Lilv::Node presetNode(presetNodes.get(it));

juce::String presetURI(presetNode.as_uri());

if (presetURI.trim().isNotEmpty())
presetListURIs.addIfNotAlreadyThere(presetURI);
}

presetListURIs.sortNatural();

rdfDescriptor->PresetCount = static_cast<uint32_t>(presetListURIs.size());
#else
QStringList presetListURIs;

LILV_FOREACH(nodes, it, presetNodes)
{
Lilv::Node presetNode(presetNodes.get(it));
// FIXME - check appliesTo?

QString presetURI(presetNode.as_uri());

@@ -1071,8 +1111,10 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit)

presetListURIs.sort();

// create presets with unique URIs
rdfDescriptor->PresetCount = static_cast<uint32_t>(presetListURIs.count());
#endif

// create presets with unique URIs
rdfDescriptor->Presets = new LV2_RDF_Preset[rdfDescriptor->PresetCount];

// set preset data
@@ -1085,7 +1127,11 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit)

if (const char* const presetURI = presetNode.as_uri())
{
#ifdef HAVE_JUCE
const int index(presetListURIs.indexOf(juce::String(presetURI)));
#else
const int index(presetListURIs.indexOf(QString(presetURI)));
#endif
CARLA_SAFE_ASSERT_CONTINUE(index >= 0);

LV2_RDF_Preset* const rdfPreset(&rdfDescriptor->Presets[index]);
@@ -1102,10 +1148,14 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit)
if (const char* const label = presetLabelNodes.get_first().as_string())
rdfPreset->Label = carla_strdup(label);
}

lilv_nodes_free(const_cast<LilvNodes*>(presetLabelNodes.me));
}
}
}
}

lilv_nodes_free(const_cast<LilvNodes*>(presetNodes.me));
}

// -------------------------------------------------------------------
@@ -1135,7 +1185,11 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit)
else
rdfFeature->URI = nullptr;
}

lilv_nodes_free(const_cast<LilvNodes*>(lilvFeatureNodesR.me));
}

lilv_nodes_free(const_cast<LilvNodes*>(lilvFeatureNodes.me));
}

// -------------------------------------------------------------------
@@ -1170,6 +1224,8 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit)
for (uint32_t x=h; x < rdfDescriptor->ExtensionCount; ++x)
rdfDescriptor->Extensions[x] = nullptr;
}

lilv_nodes_free(const_cast<LilvNodes*>(lilvExtensionDataNodes.me));
}

// -------------------------------------------------------------------
@@ -1256,7 +1312,11 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit)
else
rdfFeature->URI = nullptr;
}

lilv_nodes_free(const_cast<LilvNodes*>(lilvFeatureNodesR.me));
}

lilv_nodes_free(const_cast<LilvNodes*>(lilvFeatureNodes.me));
}

// -------------------------------------------------------
@@ -1288,12 +1348,16 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool doInit)
*rdfExtension = nullptr;
}

for (uint32_t x2=h2; x2 < rdfDescriptor->ExtensionCount; ++x2)
for (uint32_t x2=h2; x2 < rdfUI->ExtensionCount; ++x2)
rdfUI->Extensions[x2] = nullptr;
}

lilv_nodes_free(const_cast<LilvNodes*>(lilvExtensionDataNodes.me));
}
}
}

lilv_nodes_free(const_cast<LilvNodes*>(lilvUIs.me));
}

return rdfDescriptor;


+ 18
- 18
source/utils/CarlaStringList.hpp View File

@@ -28,19 +28,19 @@ class CharStringListPtr
{
public:
CharStringListPtr() noexcept
: charList(nullptr) {}
: fCharList(nullptr) {}

CharStringListPtr(const char* const* const c) noexcept
: charList(c) {}
: fCharList(c) {}

CharStringListPtr(const CharStringListPtr& ptr) noexcept
: charList(nullptr)
: fCharList(nullptr)
{
copy(ptr.charList);
copy(ptr.fCharList);
}

CharStringListPtr(const LinkedList<CarlaString>& list) noexcept
: charList(nullptr)
: fCharList(nullptr)
{
copy(list);
}
@@ -52,20 +52,20 @@ public:

operator const char* const*() const noexcept
{
return charList;
return fCharList;
}

CharStringListPtr& operator=(const char* const* const c) noexcept
{
clear();
charList = c;
fCharList = c;
return *this;
}

CharStringListPtr& operator=(const CharStringListPtr& ptr) noexcept
{
clear();
copy(ptr.charList);
copy(ptr.fCharList);
return *this;
}

@@ -79,20 +79,20 @@ public:
protected:
void clear() noexcept
{
if (charList == nullptr)
if (fCharList == nullptr)
return;

for (int i=0; charList[i] != nullptr; ++i)
delete[] charList[i];
for (int i=0; fCharList[i] != nullptr; ++i)
delete[] fCharList[i];

delete[] charList;
charList = nullptr;
delete[] fCharList;
fCharList = nullptr;
}

void copy(const char* const* const c) noexcept
{
CARLA_SAFE_ASSERT_RETURN(c != nullptr,);
CARLA_SAFE_ASSERT_RETURN(charList == nullptr,);
CARLA_SAFE_ASSERT_RETURN(fCharList == nullptr,);

size_t count = 0;
for (; c[count] != nullptr; ++count) {}
@@ -116,12 +116,12 @@ protected:
}

tmpList[count] = nullptr;
charList = tmpList;
fCharList = tmpList;
}

void copy(const LinkedList<CarlaString>& list) noexcept
{
CARLA_SAFE_ASSERT_RETURN(charList == nullptr,);
CARLA_SAFE_ASSERT_RETURN(fCharList == nullptr,);

const size_t count(list.count());
CARLA_SAFE_ASSERT_RETURN(count > 0,);
@@ -147,11 +147,11 @@ protected:
}

tmpList[count] = nullptr;
charList = tmpList;
fCharList = tmpList;
}

private:
const char* const* charList;
const char* const* fCharList;
};

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


Loading…
Cancel
Save