+const char*
+Kumu::Version()
+{
+ return PACKAGE_VERSION;
+}
+
+
+//------------------------------------------------------------------------------------------
+
+// Result_t Internals
+
+struct map_entry_t
+{
+ int rcode;
+ Kumu::Result_t* result;
+};
+
+const ui32_t MapMax = 1024;
+const ui32_t MapSize = MapMax * (sizeof(struct map_entry_t));
+static bool s_MapInit = false;
+static struct map_entry_t s_ResultMap[MapSize];
+
+//
+const Kumu::Result_t&
+Kumu::Result_t::Find(int v)
+{
+ if ( v == 0 )
+ return RESULT_OK;
+
+ for ( ui32_t i = 0; s_ResultMap[i].result != 0 && i < MapMax; i++ )
+ {
+ if ( s_ResultMap[i].rcode == v )
+ return *s_ResultMap[i].result;
+ }
+
+ return RESULT_UNKNOWN;
+}
+
+//
+Kumu::Result_t
+Kumu::Result_t::Delete(int v)
+{
+ if ( v >= RESULT_NOTAFILE.Value() )
+ {
+ DefaultLogSink().Error("Cannot delete core result code: %ld\n", v);
+ return RESULT_FAIL;
+ }
+
+ for ( ui32_t i = 0; s_ResultMap[i].result != 0 && i < MapMax; i++ )
+ {
+ if ( s_ResultMap[i].rcode == v )
+ {
+ s_ResultMap[i].rcode = 0;
+ s_ResultMap[i++].result = 0;
+
+ for ( ; s_ResultMap[i].result != 0 && i < MapMax; i++ )
+ s_ResultMap[i-1] = s_ResultMap[i];
+
+ return RESULT_OK;
+ }
+ }
+
+ return RESULT_FALSE;
+}
+
+
+//
+Kumu::Result_t::Result_t(int v, const char* l) : value(v), label(l)
+{
+ assert(l);
+ assert(value < (int)MapMax);
+
+ if ( v == 0 )
+ return;
+
+ if ( ! s_MapInit )
+ {
+ s_MapInit = true;
+ s_ResultMap[0].rcode = v;
+ s_ResultMap[0].result = this;
+ s_ResultMap[1].rcode = 0;
+ s_ResultMap[1].result = 0;
+ return;
+ }
+
+ ui32_t i = 0;
+ while ( s_ResultMap[i].result != 0 && i < MapMax )
+ {
+ if ( s_ResultMap[i].rcode == v && s_ResultMap[i].result != 0 )
+ return;
+
+ i++;
+ }
+
+ assert(i+2 < MapMax);
+
+ s_ResultMap[i].rcode = v;
+ s_ResultMap[i].result = this;
+ s_ResultMap[i+1].rcode = 0;
+ s_ResultMap[i+1].result = 0;
+ return;
+}
+
+Kumu::Result_t::~Result_t() {}
+
+
+//------------------------------------------------------------------------------------------
+// DTrace internals
+
+static int s_DTraceSequence = 0;
+
+Kumu::DTrace_t::DTrace_t(const char* Label, Kumu::Result_t* Watch, int Line, const char* File)
+ : m_Label(Label), m_Watch(Watch), m_Line(Line), m_File(File)
+{
+ m_Sequence = s_DTraceSequence++;
+ DefaultLogSink().Debug("@enter %s[%d] (%s at %d)\n", m_Label, m_Sequence, m_File, m_Line);
+}
+
+Kumu::DTrace_t::~DTrace_t()
+{
+ if ( m_Watch != 0 )
+ DefaultLogSink().Debug("@exit %s[%d]: %s\n", m_Label, m_Sequence, m_Watch->Label());
+ else
+ DefaultLogSink().Debug("@exit %s[%d]\n", m_Label, m_Sequence);
+}
+