aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/README3
-rw-r--r--contrib/chained/README.md60
-rw-r--r--contrib/chained/examples/CMakeLists.txt40
-rw-r--r--contrib/chained/examples/CreateProjectFiles.bat7
-rw-r--r--contrib/chained/examples/README.md43
-rw-r--r--contrib/chained/examples/example.cfg52
-rw-r--r--contrib/chained/examples/example1.cpp52
-rw-r--r--contrib/chained/examples/example2.cpp71
-rw-r--r--contrib/chained/examples/example3.cpp66
-rw-r--r--contrib/chained/examples/examples.cpp69
-rw-r--r--contrib/chained/libconfig_chained.h542
-rwxr-xr-xcontrib/cmake/1_configure.sh5
-rwxr-xr-xcontrib/cmake/2_make.sh4
-rw-r--r--contrib/cmake/CMakeFiles/CMakeCCompiler.cmake36
-rw-r--r--contrib/cmake/CMakeFiles/CMakeCXXCompiler.cmake36
-rw-r--r--contrib/cmake/CMakeFiles/CMakeSystem.cmake15
-rw-r--r--contrib/cmake/CMakeFiles/CompilerIdC/CMakeCCompilerId.c182
-rw-r--r--contrib/cmake/CMakeFiles/CompilerIdCXX/CMakeCXXCompilerId.cpp169
-rw-r--r--contrib/cmake/CMakeLists.txt22
-rw-r--r--contrib/cmake/cmake_work/FindConfig++.cmake23
-rw-r--r--contrib/cmake/cmake_work/FindConfig.cmake23
-rw-r--r--contrib/cmake/cmake_work/cmake_uninstall.cmake.in36
-rw-r--r--contrib/cmake/src/CMakeLists.txt6
-rw-r--r--contrib/cmake/src/main.cpp13
-rw-r--r--contrib/copy_setting.c161
-rw-r--r--contrib/libconfig-ruby/README76
-rw-r--r--contrib/libconfig-ruby/Rakefile17
-rw-r--r--contrib/libconfig-ruby/ext/extconf.rb11
-rw-r--r--contrib/libconfig-ruby/ext/rconfig.c700
-rw-r--r--contrib/ls-config/LICENSE339
-rw-r--r--contrib/ls-config/README.md21
-rw-r--r--contrib/ls-config/debian/README9
-rw-r--r--contrib/ls-config/debian/changelog5
-rw-r--r--contrib/ls-config/debian/compat1
-rw-r--r--contrib/ls-config/debian/control17
-rw-r--r--contrib/ls-config/debian/copyright33
-rw-r--r--contrib/ls-config/debian/files1
-rw-r--r--contrib/ls-config/debian/ls-config.1103
-rw-r--r--contrib/ls-config/debian/ls-config.debhelper.log48
-rw-r--r--contrib/ls-config/debian/ls-config.install6
-rw-r--r--contrib/ls-config/debian/ls-config.substvars1
-rw-r--r--contrib/ls-config/debian/ls-config/DEBIAN/control12
-rw-r--r--contrib/ls-config/debian/ls-config/DEBIAN/md5sums2
-rwxr-xr-xcontrib/ls-config/debian/ls-config/DEBIAN/postinst39
-rw-r--r--contrib/ls-config/debian/ls-config/usr/share/doc/ls-config/changelog.gzbin0 -> 146 bytes
-rw-r--r--contrib/ls-config/debian/ls-config/usr/share/doc/ls-config/copyright33
-rw-r--r--contrib/ls-config/debian/manpages1
-rw-r--r--contrib/ls-config/debian/postinst68
-rwxr-xr-xcontrib/ls-config/debian/rules13
-rw-r--r--contrib/ls-config/debian/source/format1
-rw-r--r--contrib/ls-config/doc/bash.api.txt75
-rw-r--r--contrib/ls-config/doc/bin.api.txt75
-rw-r--r--contrib/ls-config/doc/changlog.txt26
-rw-r--r--contrib/ls-config/doc/errorcodes.txt20
-rw-r--r--contrib/ls-config/lslib-core199
-rw-r--r--contrib/ls-config/makefile7
-rw-r--r--contrib/ls-config/sample/config23
-rwxr-xr-xcontrib/ls-config/sample/script68
-rw-r--r--contrib/ls-config/src/ls-config.c1345
-rw-r--r--contrib/ls-config/src/makefile34
-rw-r--r--contrib/ls-config/src/po/en_GB.po289
-rw-r--r--contrib/ls-config/src/po/ls-config.pot287
-rw-r--r--contrib/ls-config/src/po/makefile34
-rw-r--r--contrib/ls-config/src/po/pl_PL.po292
64 files changed, 6067 insertions, 0 deletions
diff --git a/contrib/README b/contrib/README
new file mode 100644
index 0000000..7437f0c
--- /dev/null
+++ b/contrib/README
@@ -0,0 +1,3 @@
+These files are not maintained by me; they are user
+contributions. They are not guaranteed to work with this release of
+libconfig.
diff --git a/contrib/chained/README.md b/contrib/chained/README.md
new file mode 100644
index 0000000..9a7ebea
--- /dev/null
+++ b/contrib/chained/README.md
@@ -0,0 +1,60 @@
+# Method Chained libconfig #
+
+**Exception free + header only + method chained + config files**
+
+Provides reading the configuration and defining the configuration specification at once.
+
+### Features ###
+
+ * default values
+ * limits (min/max)
+ * mandatory/optional values
+ * help text output for expected config format on specification violation
+ * capturing and outputting expected configuration specification/defaults
+
+While it is possible to write a config file with this extension using the configuration specification capturing feature, it is not intended to be used as a full fledged config writer.
+
+### Example ###
+
+```C++
+#include <libconfig_chained.h>
+
+using namespace std;
+using namespace libconfig;
+
+int main(int argc, char **argv)
+{
+ Config cfg;
+ cfg.readFile("example.cfg");
+ ChainedSetting cs(cfg.getRoot());
+
+ string name = cs["name"].defaultValue("<name>").isMandatory();
+ string abstract = cs["abstract"].defaultValue("<unknown>");
+ double longitude = cs["longitude"].min(-180.0).max(180.0).isMandatory();
+ double latitude = cs["latitude"].min(-90.0).max(90.0).isMandatory();
+
+ if (cs.isAnyMandatorySettingMissing())
+ {
+ cerr << "Cannot proceed until all mandatory settings are set." << endl;
+ }
+}
+```
+
+Console Output:
+```sh
+'longitude' setting is out of valid bounds (max: 180). Value was: 1200.35
+Missing 'latitude' setting in configuration file.
+Cannot proceed until all mandatory settings are set.
+```
+
+---
+
+### How to integrate into your project ###
+
+ 1. Link the libconfig++.[lib/la/a] library as usual (see standard use of libconfig++).
+ * Replace any includes of libconfig.h++ by libconfig_chained.h.
+ * Use method chained candy as displayed above.
+
+---
+
+Create an issue for any questions or suggestions. Alternatively email me at github [at) hemofektik.de \ No newline at end of file
diff --git a/contrib/chained/examples/CMakeLists.txt b/contrib/chained/examples/CMakeLists.txt
new file mode 100644
index 0000000..936c2b3
--- /dev/null
+++ b/contrib/chained/examples/CMakeLists.txt
@@ -0,0 +1,40 @@
+cmake_minimum_required(VERSION 2.8)
+
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/")
+
+project (ChainedLibconfigExample)
+file(GLOB SOURCES *.cpp *.h ../*.h ../*.md)
+
+if(MSVC)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
+else()
+ find_package(libconfig)
+endif()
+
+if(CMAKE_COMPILER_IS_GNUCXX)
+ #set(CMAKE_BUILD_TYPE Debug)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+endif()
+
+include_directories(
+ ${CMAKE_SOURCE_DIR}/../../../lib/
+)
+
+if(MSVC)
+ link_libraries (
+ ${CMAKE_SOURCE_DIR}/../../../Debug/libconfig++.lib
+ )
+else()
+link_libraries (
+ ${LIBCONFIG_LIBRARY}
+)
+endif()
+
+
+add_executable (
+ ChainedLibconfigExample
+# WIN32 # Only if you don't want the DOS prompt to appear in the background in Windows
+# MACOSX_BUNDLE
+ ${SOURCES} # We could've listed the source files here directly instead of using a variable to store them
+ #${INCLUDES}
+)
diff --git a/contrib/chained/examples/CreateProjectFiles.bat b/contrib/chained/examples/CreateProjectFiles.bat
new file mode 100644
index 0000000..b306ea1
--- /dev/null
+++ b/contrib/chained/examples/CreateProjectFiles.bat
@@ -0,0 +1,7 @@
+@echo off
+rmdir sln /S/Q
+mkdir sln
+cd sln
+cmake -G "Visual Studio 15 2017" ..
+
+pause \ No newline at end of file
diff --git a/contrib/chained/examples/README.md b/contrib/chained/examples/README.md
new file mode 100644
index 0000000..bab629b
--- /dev/null
+++ b/contrib/chained/examples/README.md
@@ -0,0 +1,43 @@
+
+### Running the examples ###
+
+Expected Console Output:
+
+```C++
+<<< Example 1 >>>
+
+'longitude' setting is out of valid bounds (max: 180). Value was: 1200.35
+Missing 'latitude' setting in configuration file.
+Cannot proceed until all mandatory settings are set.
+
+
+<<< Example 2 >>>
+
+TITLE AUTHOR PRICE QTY
+Treasure Island Robert Louis Stevenson $ 29.99 5
+Snow Crash Neal Stephenson $ 9.99 8
+
+
+<<< Example 3 >>>
+
+'longitude' setting is out of valid bounds (max: 180). Value was: 1200.35
+Missing 'latitude' setting in configuration file.
+Cannot proceed until all mandatory settings are set.
+
+Expected Config Layout:
+
+// -- begin --
+name = "<name>";
+abstract = "<unknown>";
+longitude = 0.0;
+latitude = 0.0;
+inventory =
+{
+ movies = ( );
+ books = (
+ {
+ title = "bookXYZ";
+ } );
+};
+// --- end ---
+``` \ No newline at end of file
diff --git a/contrib/chained/examples/example.cfg b/contrib/chained/examples/example.cfg
new file mode 100644
index 0000000..f3c6c3a
--- /dev/null
+++ b/contrib/chained/examples/example.cfg
@@ -0,0 +1,52 @@
+// An example configuration file that stores information about a store.
+
+// Basic store information:
+name = "Books, Movies & More";
+longitude = 1200.345678;
+
+// Store inventory:
+inventory =
+{
+ books = ( { title = "Treasure Island";
+ author = "Robert Louis Stevenson";
+ price = 29.99;
+ qty = 5; },
+ { title = "Snow Crash";
+ author = "Neal Stephenson";
+ price = 9.99;
+ qty = 8; },
+ { title = "Das Kapital";
+ price = 0.0;
+ qty = 100000; }
+ );
+
+ movies = ( { title = "Brazil";
+ media = "DVD";
+ price = 19.99;
+ qty = 11; },
+ { title = "The City of Lost Children";
+ media = "DVD";
+ price = 18.99;
+ qty = 5; },
+ { title = "Memento";
+ media = "Blu-Ray";
+ price = 24.99;
+ qty = 20;
+ },
+ { title = "Howard the Duck"; }
+ );
+};
+
+// Store hours:
+hours =
+{
+ mon = { open = 9; close = 18; };
+ tue = { open = 9; close = 18; };
+ wed = { open = 9; close = 18; };
+ thu = { open = 9; close = 18; };
+ fri = { open = 9; close = 20; };
+ sat = { open = 9; close = 20; };
+ sun = { open = 11; close = 16; };
+};
+
+lost_bag = ( 1234.5678, "Napkin", [1, 2, 3] );
diff --git a/contrib/chained/examples/example1.cpp b/contrib/chained/examples/example1.cpp
new file mode 100644
index 0000000..593bbd6
--- /dev/null
+++ b/contrib/chained/examples/example1.cpp
@@ -0,0 +1,52 @@
+/* ----------------------------------------------------------------------------
+ libconfig - A library for processing structured configuration files
+ libconfig chained - Extension for reading the configuration and defining
+ the configuration specification at once.
+ Copyright (C) 2016 Richard Schubert
+
+ This file is part of libconfig contributions.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License
+ as published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, see
+ <http://www.gnu.org/licenses/>.
+ ----------------------------------------------------------------------------
+*/
+
+#include <iostream>
+#include <iomanip>
+#include <cstdlib>
+#include "../libconfig_chained.h"
+
+using namespace std;
+using namespace libconfig;
+
+// This example reads basic information from config file
+// and reacts on missing mandatory values.
+
+void example1(Config& cfg)
+{
+ ChainedSetting cs(cfg.getRoot());
+
+ string name = cs["name"].defaultValue("<name>").isMandatory();
+ string abstract = cs["abstract"].defaultValue("<unknown>");
+ double longitude = cs["longitude"].min(-180.0).max(180.0).isMandatory();
+ double latitude = cs["latitude"].min(-90.0).max(90.0).isMandatory();
+
+ if (cs.isAnyMandatorySettingMissing())
+ {
+ cerr << "Cannot proceed until all mandatory settings are set." << endl;
+ return;
+ }
+
+ // from here on all read config values are valid
+}
diff --git a/contrib/chained/examples/example2.cpp b/contrib/chained/examples/example2.cpp
new file mode 100644
index 0000000..6ff227d
--- /dev/null
+++ b/contrib/chained/examples/example2.cpp
@@ -0,0 +1,71 @@
+/* ----------------------------------------------------------------------------
+ libconfig - A library for processing structured configuration files
+ libconfig chained - Extension for reading the configuration and defining
+ the configuration specification at once.
+ Copyright (C) 2016 Richard Schubert
+
+ This file is part of libconfig contributions.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License
+ as published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, see
+ <http://www.gnu.org/licenses/>.
+ ----------------------------------------------------------------------------
+*/
+
+#include <iostream>
+#include <iomanip>
+#include <cstdlib>
+#include "../libconfig_chained.h"
+
+using namespace std;
+using namespace libconfig;
+
+// This example reads complex types from config file using method chains.
+
+void example2(Config& cfg)
+{
+ ChainedSetting cs(cfg.getRoot());
+
+ auto books = cs["inventory"]["books"];
+ if (!books.exists())
+ {
+ cerr << "No book section available." << endl;
+ return;
+ }
+
+ cout << setw(30) << left << "TITLE" << " "
+ << setw(30) << left << "AUTHOR" << " "
+ << setw(6) << left << "PRICE" << " "
+ << "QTY"
+ << endl;
+
+ const int count = books.getLength();
+ for(int i = 0; i < count; ++i)
+ {
+ auto book = books[i];
+
+ string title = book["title"];
+ string author = book["author"];
+ double price = book["price"].min(0.0);
+ int qty = book["qty"].min(0);
+
+ // Only output the record if all of the expected fields are present.
+ if(book.isAnySettingMissing()) continue;
+
+ cout << setw(30) << left << title << " "
+ << setw(30) << left << author << " "
+ << '$' << setw(6) << right << price << " "
+ << qty
+ << endl;
+ }
+}
diff --git a/contrib/chained/examples/example3.cpp b/contrib/chained/examples/example3.cpp
new file mode 100644
index 0000000..52d0e32
--- /dev/null
+++ b/contrib/chained/examples/example3.cpp
@@ -0,0 +1,66 @@
+/* ----------------------------------------------------------------------------
+ libconfig - A library for processing structured configuration files
+ libconfig chained - Extension for reading the configuration and defining
+ the configuration specification at once.
+ Copyright (C) 2016 Richard Schubert
+
+ This file is part of libconfig contributions.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License
+ as published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, see
+ <http://www.gnu.org/licenses/>.
+ ----------------------------------------------------------------------------
+*/
+
+#include <iostream>
+#include <iomanip>
+#include <cstdlib>
+#include "../libconfig_chained.h"
+
+using namespace std;
+using namespace libconfig;
+
+// This example reads basic information from config file
+// and prints out the expected configuration specification.
+
+void example3(Config& cfg)
+{
+ ChainedSetting cs(cfg.getRoot());
+
+ Config tmpCfgSpec;
+ tmpCfgSpec.setOptions(Config::OptionOpenBraceOnSeparateLine | Config::OptionSemicolonSeparators);
+ tmpCfgSpec.setTabWidth(3);
+ cs.captureExpectedSpecification(&tmpCfgSpec);
+
+ string name = cs["name"].defaultValue("<name>").isMandatory();
+ string abstract = cs["abstract"].defaultValue("<unknown>");
+ double longitude = cs["longitude"].min(-180.0).max(180.0).isMandatory();
+ double latitude = cs["latitude"].min(-90.0).max(90.0).isMandatory();
+
+ ChainedSetting movie0 = cs["inventory"]["movies"][0];
+ string book0tile = cs["inventory"]["books"][0]["title"].defaultValue("bookXYZ");
+
+ if (cs.isAnyMandatorySettingMissing())
+ {
+ cerr << "Cannot proceed until all mandatory settings are set." << endl << endl;
+
+ auto cfgSpec = cs.getCapturedSpecification("tmpCfgSpec.cfg");
+ cerr << "Expected Config Layout: " << endl << endl;
+ cerr << "// -- begin --" << endl;
+ cerr << cfgSpec;
+ cerr << "// --- end ---" << endl << endl;
+ return;
+ }
+
+ // from here on all read config values are valid
+}
diff --git a/contrib/chained/examples/examples.cpp b/contrib/chained/examples/examples.cpp
new file mode 100644
index 0000000..ca2ba2d
--- /dev/null
+++ b/contrib/chained/examples/examples.cpp
@@ -0,0 +1,69 @@
+/* ----------------------------------------------------------------------------
+ libconfig - A library for processing structured configuration files
+ libconfig chained - Extension for reading the configuration and defining
+ the configuration specification at once.
+ Copyright (C) 2016 Richard Schubert
+
+ This file is part of libconfig contributions.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License
+ as published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, see
+ <http://www.gnu.org/licenses/>.
+ ----------------------------------------------------------------------------
+*/
+
+#include <iostream>
+#include <iomanip>
+#include <cstdlib>
+#include <libconfig.h++>
+
+using namespace std;
+using namespace libconfig;
+
+// This is the main entry point for all examples.
+// The examples will be called consecutively.
+
+void example1(Config& cfg);
+void example2(Config& cfg);
+void example3(Config& cfg);
+
+int main(int argc, char **argv)
+{
+ Config cfg;
+
+ // Read the file. If there is an error, report it and exit.
+ try
+ {
+ cfg.readFile("../example.cfg");
+ }
+ catch(const FileIOException&)
+ {
+ std::cerr << "I/O error while reading file. " << std::endl;
+ return(EXIT_FAILURE);
+ }
+ catch(const ParseException& pex)
+ {
+ std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine()
+ << " - " << pex.getError() << std::endl;
+ return(EXIT_FAILURE);
+ }
+
+ cout << endl << endl << "<<< Example 1 >>>" << endl << endl;
+ example1(cfg);
+ cout << endl << endl << "<<< Example 2 >>>" << endl << endl;
+ example2(cfg);
+ cout << endl << endl << "<<< Example 3 >>>" << endl << endl;
+ example3(cfg);
+
+ return(EXIT_SUCCESS);
+}
diff --git a/contrib/chained/libconfig_chained.h b/contrib/chained/libconfig_chained.h
new file mode 100644
index 0000000..3ff2b46
--- /dev/null
+++ b/contrib/chained/libconfig_chained.h
@@ -0,0 +1,542 @@
+/* ----------------------------------------------------------------------------
+ libconfig - A library for processing structured configuration files
+ libconfig chained - Extension for reading the configuration and defining
+ the configuration specification at once.
+ Copyright (C) 2016 Richard Schubert
+
+ This file is part of libconfig contributions.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License
+ as published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, see
+ <http://www.gnu.org/licenses/>.
+ ----------------------------------------------------------------------------
+*/
+
+#pragma once
+#ifndef _CHAINED_LIBCONFIG_H_
+#define _CHAINED_LIBCONFIG_H_
+
+#include <libconfig.h++>
+#include <cassert>
+#include <fstream>
+#include <sstream>
+#include <iostream>
+
+namespace libconfig
+{
+ class ChainedSetting
+ {
+ struct Variant
+ {
+ private:
+ bool isSet;
+ Setting::Type type;
+
+ bool value_bool;
+ int64_t value_int;
+ double value_float;
+ std::string value_string;
+
+ public:
+
+ Variant()
+ : isSet(false)
+ , type(Setting::TypeNone)
+ {
+ }
+ Variant(bool value)
+ {
+ value_bool = value;
+ isSet = true;
+ type = Setting::TypeBoolean;
+ }
+ Variant(int32_t value)
+ {
+ value_int = value;
+ isSet = true;
+ type = Setting::TypeInt;
+ }
+ Variant(int64_t value)
+ {
+ value_int = value;
+ isSet = true;
+ type = Setting::TypeInt64;
+ }
+ Variant(double value)
+ {
+ value_float = value;
+ isSet = true;
+ type = Setting::TypeFloat;
+ }
+ Variant(std::string& value)
+ {
+ value_string = value;
+ isSet = true;
+ type = Setting::TypeString;
+ }
+ Variant(const char* value)
+ {
+ value_string = value;
+ isSet = true;
+ type = Setting::TypeString;
+ }
+
+ operator bool() const { return value_bool; }
+ operator int() const { return (int)value_int; }
+ operator unsigned int() const { return (unsigned int)value_int; }
+ operator long() const { return (long)value_int; }
+ operator unsigned long() const { return (unsigned long)value_int; }
+ operator long long() const { return (long long)value_int; }
+ operator unsigned long long() const { return (unsigned long long)value_int; }
+ operator double() const { return value_float; }
+ operator float() const { return (float)value_float; }
+ operator std::string() const { return value_string; }
+
+ const bool IsSet() const
+ {
+ return isSet;
+ }
+
+ const Setting::Type GetType() const
+ {
+ return type;
+ }
+ };
+
+ public:
+
+ // Starting point for method chained libconfig.
+ // Pass a custom ostream to intercept any error messages (useful for Applications with UI).
+ ChainedSetting(Setting& setting, std::ostream& err = std::cerr)
+ : name(setting.isRoot() ? "<root>" : (setting.getName() ? setting.getName() : ""))
+ , index(setting.getIndex())
+ , parent(NULL)
+ , setting(&setting)
+ , err(err)
+ , isSettingMandatory(false)
+ , anySettingIsMissing(false)
+ , anyMandatorySettingIsMissing(false)
+ , capturedSpecification(NULL)
+ , capturedSetting(NULL)
+ {
+ }
+
+ // Starts capturing any configuration readings into the temporary config object.
+ void captureExpectedSpecification(Config* temporaryConfigSpecification)
+ {
+ capturedSpecification = temporaryConfigSpecification;
+ capturedSetting = &capturedSpecification->getRoot();
+ }
+
+ // Returns the captured configuration specification,
+ // premised captureExpectedSpecification() was called earlier.
+ // The path parameter is needed to write the configuration
+ // to disk before it can be read into a usable string.
+ std::string getCapturedSpecification(const std::string& tempFilePath)
+ {
+ try
+ {
+ capturedSpecification->writeFile(tempFilePath.c_str());
+ }
+ catch (const FileIOException&)
+ {
+ err << "I/O error while writing temporary setting file: " << tempFilePath << std::endl;
+ return "";
+ }
+
+ std::ifstream t(tempFilePath);
+ if (!t.is_open())
+ {
+ err << "I/O error while reading temporary setting file: " << tempFilePath << std::endl;
+ return "";
+ }
+ std::stringstream buffer;
+ buffer << t.rdbuf();
+
+ capturedSpecification = NULL;
+
+ return buffer.str();
+ }
+
+ // Defines the default value for this setting if missing from config file.
+ template<typename T>
+ ChainedSetting& defaultValue(T defaultValue)
+ {
+ defaultVal = defaultValue;
+ return *this;
+ }
+
+ // Defines the inclusive minimum value for this setting.
+ // A lesser value set in a configuration file will be clamped to this limit.
+ template<typename T>
+ ChainedSetting& min(T min)
+ {
+ minVal = min;
+ return *this;
+ }
+
+ // Defines the inclusive maximum value for this setting.
+ // A greater value set in a configuration file will be clamped to this limit.
+ template<typename T>
+ ChainedSetting& max(T max)
+ {
+ maxVal = max;
+ return *this;
+ }
+
+ // Defines this setting to be mandatory.
+ // Any mandatory value missing in the configuration file will raise an error.
+ // Use isAnyMandatorySettingMissing() to check for any violations.
+ ChainedSetting& isMandatory()
+ {
+ isSettingMandatory = true;
+ if (parent) parent->isMandatory();
+ return *this;
+ }
+
+ template<typename T>
+ operator T()
+ {
+ auto requestedType = GetRequestedType<T>();
+ CheckType(defaultVal, requestedType);
+ CheckType(minVal, requestedType);
+ CheckType(maxVal, requestedType);
+
+ CaptureSetting<T>(requestedType);
+
+ if (!setting)
+ {
+ if (isSettingMandatory)
+ {
+ AlertMandatorySettingMissing<T>();
+ }
+ PropagateAnySettingIsMissing();
+
+ return GetDefaultValue<T>();
+ }
+
+ try
+ {
+ T value = *setting;
+ if (minVal.IsSet())
+ {
+ T min = minVal;
+ if (value < min)
+ {
+ err << "'" << setting->getPath() << "' setting is out of valid bounds (min: " << min << "). Value was: " << value << std::endl;
+ value = min;
+ }
+ }
+ if (maxVal.IsSet())
+ {
+ T max = maxVal;
+ if (value > max)
+ {
+ err << "'" << setting->getPath() << "' setting is out of valid bounds (max: " << max << "). Value was: " << value << std::endl;
+ value = max;
+ }
+ }
+ return value;
+ }
+ catch (const SettingTypeException& tex)
+ {
+ err << "'" << tex.getPath() << "' setting is of wrong type." << std::endl;
+ }
+
+ return GetDefaultValue<T>();
+ }
+
+ ChainedSetting operator[](const char *name)
+ {
+ CaptureSetting<Setting>(Setting::TypeGroup);
+
+ if (!setting)
+ {
+ return ChainedSetting(name, this);
+ }
+
+ if(setting->exists(name))
+ {
+ return ChainedSetting((*setting)[name], this);
+ }
+ else
+ {
+ return ChainedSetting(name, this);
+ }
+ }
+
+ inline ChainedSetting operator[](const std::string &name)
+ {
+ return(operator[](name.c_str()));
+ }
+
+ ChainedSetting operator[](int index)
+ {
+ // This could also be an TypeArray but we cannot be sure here.
+ // By using TypeList we ensure it will always work.
+ CaptureSetting<Setting>(Setting::TypeList);
+
+ if (!setting)
+ {
+ return ChainedSetting(index, this);
+ }
+
+ if (index >= 0 && index < setting->getLength())
+ {
+ return ChainedSetting((*setting)[index], this);
+ }
+ else
+ {
+ return ChainedSetting(index, this);
+ }
+ }
+
+ int getLength() const
+ {
+ return setting ? setting->getLength() : 0;
+ }
+
+ Setting::Type getType() const
+ {
+ return setting ? setting->getType() : Setting::TypeNone;
+ }
+
+ // Indicates whether this setting is present in the read configuration file.
+ bool exists() const
+ {
+ return setting != NULL;
+ }
+
+ bool isAnyMandatorySettingMissing() const
+ {
+ return anyMandatorySettingIsMissing;
+ }
+
+ bool isAnySettingMissing() const
+ {
+ return anySettingIsMissing;
+ }
+
+ void clearAnySettingMissingFlag()
+ {
+ anySettingIsMissing = false;
+ }
+
+ private:
+
+ ChainedSetting(Setting& setting, ChainedSetting* parent)
+ : name(setting.isRoot() ? "<root>" : (setting.getName() ? setting.getName() : ""))
+ , index(setting.getIndex())
+ , parent(parent)
+ , setting(&setting)
+ , err(parent->err)
+ , isSettingMandatory(false)
+ , anySettingIsMissing(false)
+ , anyMandatorySettingIsMissing(false)
+ , capturedSpecification(NULL)
+ , capturedSetting(NULL)
+ {
+ }
+
+ ChainedSetting(const std::string& name, ChainedSetting* parent)
+ : name(name)
+ , index(-1)
+ , parent(parent)
+ , setting(NULL)
+ , err(parent->err)
+ , isSettingMandatory(false)
+ , anySettingIsMissing(true)
+ , anyMandatorySettingIsMissing(false)
+ , capturedSpecification(NULL)
+ , capturedSetting(NULL)
+ {
+ }
+
+ ChainedSetting(int index, ChainedSetting* parent)
+ : name("")
+ , index(index)
+ , parent(parent)
+ , setting(NULL)
+ , err(parent->err)
+ , isSettingMandatory(false)
+ , anySettingIsMissing(true)
+ , anyMandatorySettingIsMissing(false)
+ , capturedSpecification(NULL)
+ , capturedSetting(NULL)
+ {
+ }
+
+ template<typename T>
+ void ConditionalSetCapturedDefaultValue()
+ {
+ *capturedSetting = GetDefaultValue<T>();
+ }
+
+
+
+ template<typename T>
+ void CaptureSetting(Setting::Type type)
+ {
+ if (!capturedSetting && parent && parent->capturedSetting)
+ {
+ if (name.length() > 0)
+ {
+ if (!parent->capturedSetting->exists(name))
+ {
+ capturedSetting = &parent->capturedSetting->add(name, type);
+ }
+ else
+ {
+ capturedSetting = &(*parent->capturedSetting)[name.c_str()];
+ }
+ }
+ else
+ {
+ if (index < parent->capturedSetting->getLength())
+ {
+ capturedSetting = &(*parent->capturedSetting)[0];
+ }
+ else
+ {
+ assert(index == parent->capturedSetting->getLength()); // you requested an index while omitting at least one of its previous siblings
+ capturedSetting = &parent->capturedSetting->add(type);
+ }
+ }
+
+ ConditionalSetCapturedDefaultValue<T>();
+ }
+ }
+
+
+ std::string GetPath() const
+ {
+ if (setting)
+ {
+ return setting->getPath();
+ }
+
+ std::string path = (name.length() > 0) ? name : "[" + std::to_string(index) + "]";
+ if (parent)
+ {
+ auto parentPath = parent->GetPath();
+ return (parentPath.length() > 0) ? (parentPath + ((name.length() == 0) ? "" : ".") + path) : path;
+ }
+ return path;
+ }
+
+ void PropagateAnySettingIsMissing()
+ {
+ anySettingIsMissing = true;
+ if (parent)
+ {
+ parent->PropagateAnySettingIsMissing();
+ }
+ }
+
+ void PropagateAnyMandatorySettingIsMissing()
+ {
+ anyMandatorySettingIsMissing = true;
+ if (parent)
+ {
+ parent->PropagateAnyMandatorySettingIsMissing();
+ }
+ }
+
+ template<typename T>
+ void AlertMandatorySettingMissing()
+ {
+ PropagateAnyMandatorySettingIsMissing();
+
+ err << "Missing '" << GetPath() << "' setting in configuration file." << std::endl;
+ }
+
+ template<typename T>
+ T GetUnsetDefaultValue() const
+ {
+ return (T)0;
+ }
+
+
+
+ template<typename T>
+ T GetDefaultValue() const
+ {
+ if (defaultVal.IsSet())
+ {
+ return (T)defaultVal;
+ }
+
+ return GetUnsetDefaultValue<T>();
+ }
+
+ template<typename T>
+ Setting::Type GetRequestedType() const
+ {
+ // TODO @ Hemofektik: Check whether the outcommented line is still needed. static_assert(false) is checked on compile time and, well, asserts :)
+ // static_assert(false, "should never happen, unless you requested an unsupported type");
+ return Setting::TypeNone;
+ }
+
+
+ void CheckType(const Variant& variant, Setting::Type expectedType) const
+ {
+ if (!variant.IsSet()) return;
+ if(expectedType != variant.GetType())
+ {
+ assert(false); // fix your code to match the whole chain of this setting to one single type!
+ err << "'" << GetPath() << "' setting limits or default value is of incompatible type." << std::endl;
+ }
+ }
+
+ std::string name;
+ int index;
+ ChainedSetting* parent;
+ Setting* setting;
+ std::ostream& err;
+ Variant defaultVal;
+ Variant minVal;
+ Variant maxVal;
+ bool isSettingMandatory;
+ bool anySettingIsMissing;
+ bool anyMandatorySettingIsMissing;
+ Config* capturedSpecification;
+ Setting* capturedSetting;
+ };
+
+ template<>
+ inline
+ void ChainedSetting::ConditionalSetCapturedDefaultValue<Setting>() { }
+
+ template<>
+ inline
+ std::string ChainedSetting::GetUnsetDefaultValue() const
+ {
+ return "";
+ }
+
+
+ template<> inline Setting::Type ChainedSetting::GetRequestedType<int8_t>() const { return Setting::TypeInt; }
+ template<> inline Setting::Type ChainedSetting::GetRequestedType<uint8_t>() const { return Setting::TypeInt; }
+ template<> inline Setting::Type ChainedSetting::GetRequestedType<int16_t>() const { return Setting::TypeInt; }
+ template<> inline Setting::Type ChainedSetting::GetRequestedType<uint16_t>() const { return Setting::TypeInt; }
+ template<> inline Setting::Type ChainedSetting::GetRequestedType<int32_t>() const { return Setting::TypeInt; }
+ template<> inline Setting::Type ChainedSetting::GetRequestedType<uint32_t>() const { return Setting::TypeInt; }
+ template<> inline Setting::Type ChainedSetting::GetRequestedType<int64_t>() const { return Setting::TypeInt64; }
+ template<> inline Setting::Type ChainedSetting::GetRequestedType<uint64_t>() const { return Setting::TypeInt64; }
+ template<> inline Setting::Type ChainedSetting::GetRequestedType<float>() const { return Setting::TypeFloat; }
+ template<> inline Setting::Type ChainedSetting::GetRequestedType<double>() const { return Setting::TypeFloat; }
+ template<> inline Setting::Type ChainedSetting::GetRequestedType<std::string>() const { return Setting::TypeString; }
+ template<> inline Setting::Type ChainedSetting::GetRequestedType<bool>() const { return Setting::TypeBoolean; }
+}
+
+#endif \ No newline at end of file
diff --git a/contrib/cmake/1_configure.sh b/contrib/cmake/1_configure.sh
new file mode 100755
index 0000000..fe678f8
--- /dev/null
+++ b/contrib/cmake/1_configure.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+mkdir release
+cd release
+cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_BUILD_TYPE=Release ..
diff --git a/contrib/cmake/2_make.sh b/contrib/cmake/2_make.sh
new file mode 100755
index 0000000..1717d77
--- /dev/null
+++ b/contrib/cmake/2_make.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+cd release
+make \ No newline at end of file
diff --git a/contrib/cmake/CMakeFiles/CMakeCCompiler.cmake b/contrib/cmake/CMakeFiles/CMakeCCompiler.cmake
new file mode 100644
index 0000000..26afd10
--- /dev/null
+++ b/contrib/cmake/CMakeFiles/CMakeCCompiler.cmake
@@ -0,0 +1,36 @@
+SET(CMAKE_C_COMPILER "/usr/bin/gcc")
+SET(CMAKE_C_COMPILER_ARG1 "")
+SET(CMAKE_C_COMPILER_ID "GNU")
+SET(CMAKE_C_PLATFORM_ID "Linux")
+SET(CMAKE_AR "/usr/bin/ar")
+SET(CMAKE_RANLIB "/usr/bin/ranlib")
+SET(CMAKE_COMPILER_IS_GNUCC 1)
+SET(CMAKE_C_COMPILER_LOADED 1)
+SET(CMAKE_COMPILER_IS_MINGW )
+SET(CMAKE_COMPILER_IS_CYGWIN )
+IF(CMAKE_COMPILER_IS_CYGWIN)
+ SET(CYGWIN 1)
+ SET(UNIX 1)
+ENDIF(CMAKE_COMPILER_IS_CYGWIN)
+
+SET(CMAKE_C_COMPILER_ENV_VAR "CC")
+
+IF(CMAKE_COMPILER_IS_MINGW)
+ SET(MINGW 1)
+ENDIF(CMAKE_COMPILER_IS_MINGW)
+SET(CMAKE_C_COMPILER_ID_RUN 1)
+SET(CMAKE_C_SOURCE_FILE_EXTENSIONS c)
+SET(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
+SET(CMAKE_C_LINKER_PREFERENCE 10)
+
+# Save compiler ABI information.
+SET(CMAKE_C_SIZEOF_DATA_PTR "4")
+SET(CMAKE_C_COMPILER_ABI "ELF")
+
+IF(CMAKE_C_SIZEOF_DATA_PTR)
+ SET(CMAKE_SIZEOF_VOID_P "${CMAKE_C_SIZEOF_DATA_PTR}")
+ENDIF(CMAKE_C_SIZEOF_DATA_PTR)
+
+IF(CMAKE_C_COMPILER_ABI)
+ SET(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_C_COMPILER_ABI}")
+ENDIF(CMAKE_C_COMPILER_ABI)
diff --git a/contrib/cmake/CMakeFiles/CMakeCXXCompiler.cmake b/contrib/cmake/CMakeFiles/CMakeCXXCompiler.cmake
new file mode 100644
index 0000000..62c36c9
--- /dev/null
+++ b/contrib/cmake/CMakeFiles/CMakeCXXCompiler.cmake
@@ -0,0 +1,36 @@
+SET(CMAKE_CXX_COMPILER "/usr/bin/c++")
+SET(CMAKE_CXX_COMPILER_ARG1 "")
+SET(CMAKE_CXX_COMPILER_ID "GNU")
+SET(CMAKE_CXX_PLATFORM_ID "Linux")
+SET(CMAKE_AR "/usr/bin/ar")
+SET(CMAKE_RANLIB "/usr/bin/ranlib")
+SET(CMAKE_COMPILER_IS_GNUCXX 1)
+SET(CMAKE_CXX_COMPILER_LOADED 1)
+SET(CMAKE_COMPILER_IS_MINGW )
+SET(CMAKE_COMPILER_IS_CYGWIN )
+IF(CMAKE_COMPILER_IS_CYGWIN)
+ SET(CYGWIN 1)
+ SET(UNIX 1)
+ENDIF(CMAKE_COMPILER_IS_CYGWIN)
+
+SET(CMAKE_CXX_COMPILER_ENV_VAR "CXX")
+
+IF(CMAKE_COMPILER_IS_MINGW)
+ SET(MINGW 1)
+ENDIF(CMAKE_COMPILER_IS_MINGW)
+SET(CMAKE_CXX_COMPILER_ID_RUN 1)
+SET(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;H;o;O;obj;OBJ;def;DEF;rc;RC)
+SET(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm)
+SET(CMAKE_CXX_LINKER_PREFERENCE 30)
+
+# Save compiler ABI information.
+SET(CMAKE_CXX_SIZEOF_DATA_PTR "4")
+SET(CMAKE_CXX_COMPILER_ABI "ELF")
+
+IF(CMAKE_CXX_SIZEOF_DATA_PTR)
+ SET(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}")
+ENDIF(CMAKE_CXX_SIZEOF_DATA_PTR)
+
+IF(CMAKE_CXX_COMPILER_ABI)
+ SET(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}")
+ENDIF(CMAKE_CXX_COMPILER_ABI)
diff --git a/contrib/cmake/CMakeFiles/CMakeSystem.cmake b/contrib/cmake/CMakeFiles/CMakeSystem.cmake
new file mode 100644
index 0000000..24477a5
--- /dev/null
+++ b/contrib/cmake/CMakeFiles/CMakeSystem.cmake
@@ -0,0 +1,15 @@
+
+
+SET(CMAKE_SYSTEM "Linux-2.6.31-20-generic-pae")
+SET(CMAKE_SYSTEM_NAME "Linux")
+SET(CMAKE_SYSTEM_VERSION "2.6.31-20-generic-pae")
+SET(CMAKE_SYSTEM_PROCESSOR "i686")
+
+SET(CMAKE_HOST_SYSTEM "Linux-2.6.31-20-generic-pae")
+SET(CMAKE_HOST_SYSTEM_NAME "Linux")
+SET(CMAKE_HOST_SYSTEM_VERSION "2.6.31-20-generic-pae")
+SET(CMAKE_HOST_SYSTEM_PROCESSOR "i686")
+
+SET(CMAKE_CROSSCOMPILING "FALSE")
+
+SET(CMAKE_SYSTEM_LOADED 1)
diff --git a/contrib/cmake/CMakeFiles/CompilerIdC/CMakeCCompilerId.c b/contrib/cmake/CMakeFiles/CompilerIdC/CMakeCCompilerId.c
new file mode 100644
index 0000000..7fd0088
--- /dev/null
+++ b/contrib/cmake/CMakeFiles/CompilerIdC/CMakeCCompilerId.c
@@ -0,0 +1,182 @@
+#ifdef __cplusplus
+# error "A C++ compiler has been selected for C."
+#endif
+
+#if defined(__18CXX)
+# define ID_VOID_MAIN
+#endif
+
+#if defined(__INTEL_COMPILER) || defined(__ICC)
+# define COMPILER_ID "Intel"
+
+#elif defined(__BORLANDC__)
+# define COMPILER_ID "Borland"
+
+#elif defined(__WATCOMC__)
+# define COMPILER_ID "Watcom"
+
+#elif defined(__SUNPRO_C)
+# define COMPILER_ID "SunPro"
+
+#elif defined(__HP_cc)
+# define COMPILER_ID "HP"
+
+#elif defined(__DECC)
+# define COMPILER_ID "Compaq"
+
+#elif defined(__IBMC__)
+# define COMPILER_ID "VisualAge"
+
+#elif defined(__PGI)
+# define COMPILER_ID "PGI"
+
+#elif defined(__GNUC__)
+# define COMPILER_ID "GNU"
+
+#elif defined(_MSC_VER)
+# define COMPILER_ID "MSVC"
+
+#elif defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__)
+/* Analog Devices C++ compiler for Blackfin, TigerSHARC and
+ SHARC (21000) DSPs */
+# define COMPILER_ID "ADSP"
+
+/* IAR Systems compiler for embedded systems.
+ http://www.iar.com
+ Not supported yet by CMake
+#elif defined(__IAR_SYSTEMS_ICC__)
+# define COMPILER_ID "IAR" */
+
+/* sdcc, the small devices C compiler for embedded systems,
+ http://sdcc.sourceforge.net */
+#elif defined(SDCC)
+# define COMPILER_ID "SDCC"
+
+#elif defined(_COMPILER_VERSION)
+# define COMPILER_ID "MIPSpro"
+
+/* This compiler is either not known or is too old to define an
+ identification macro. Try to identify the platform and guess that
+ it is the native compiler. */
+#elif defined(__sgi)
+# define COMPILER_ID "MIPSpro"
+
+#elif defined(__hpux) || defined(__hpua)
+# define COMPILER_ID "HP"
+
+#else /* unknown compiler */
+# define COMPILER_ID ""
+
+#endif
+
+/* Construct the string literal in pieces to prevent the source from
+ getting matched. Store it in a pointer rather than an array
+ because some compilers will just produce instructions to fill the
+ array rather than assigning a pointer to a static array. */
+char* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
+
+/* Identify known platforms by name. */
+#if defined(__linux) || defined(__linux__) || defined(linux)
+# define PLATFORM_ID "Linux"
+
+#elif defined(__CYGWIN__)
+# define PLATFORM_ID "Cygwin"
+
+#elif defined(__MINGW32__)
+# define PLATFORM_ID "MinGW"
+
+#elif defined(__APPLE__)
+# define PLATFORM_ID "Darwin"
+
+#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+# define PLATFORM_ID "Windows"
+
+#elif defined(__FreeBSD__) || defined(__FreeBSD)
+# define PLATFORM_ID "FreeBSD"
+
+#elif defined(__NetBSD__) || defined(__NetBSD)
+# define PLATFORM_ID "NetBSD"
+
+#elif defined(__OpenBSD__) || defined(__OPENBSD)
+# define PLATFORM_ID "OpenBSD"
+
+#elif defined(__sun) || defined(sun)
+# define PLATFORM_ID "SunOS"
+
+#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
+# define PLATFORM_ID "AIX"
+
+#elif defined(__sgi) || defined(__sgi__) || defined(_SGI)
+# define PLATFORM_ID "IRIX"
+
+#elif defined(__hpux) || defined(__hpux__)
+# define PLATFORM_ID "HP-UX"
+
+#elif defined(__HAIKU) || defined(__HAIKU__) || defined(_HAIKU)
+# define PLATFORM_ID "Haiku"
+/* Haiku also defines __BEOS__ so we must
+ put it prior to the check for __BEOS__
+*/
+
+#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
+# define PLATFORM_ID "BeOS"
+
+#elif defined(__QNX__) || defined(__QNXNTO__)
+# define PLATFORM_ID "QNX"
+
+#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
+# define PLATFORM_ID "Tru64"
+
+#elif defined(__riscos) || defined(__riscos__)
+# define PLATFORM_ID "RISCos"
+
+#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
+# define PLATFORM_ID "SINIX"
+
+#elif defined(__UNIX_SV__)
+# define PLATFORM_ID "UNIX_SV"
+
+#elif defined(__bsdos__)
+# define PLATFORM_ID "BSDOS"
+
+#elif defined(_MPRAS) || defined(MPRAS)
+# define PLATFORM_ID "MP-RAS"
+
+#elif defined(__osf) || defined(__osf__)
+# define PLATFORM_ID "OSF1"
+
+#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
+# define PLATFORM_ID "SCO_SV"
+
+#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
+# define PLATFORM_ID "ULTRIX"
+
+#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
+# define PLATFORM_ID "Xenix"
+
+#else /* unknown platform */
+# define PLATFORM_ID ""
+
+#endif
+
+/* Construct the string literal in pieces to prevent the source from
+ getting matched. Store it in a pointer rather than an array
+ because some compilers will just produce instructions to fill the
+ array rather than assigning a pointer to a static array. */
+char* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
+
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef ID_VOID_MAIN
+void main() {}
+#else
+int main(int argc, char* argv[])
+{
+ int require = 0;
+ require += info_compiler[argc];
+ require += info_platform[argc];
+ (void)argv;
+ return require;
+}
+#endif
diff --git a/contrib/cmake/CMakeFiles/CompilerIdCXX/CMakeCXXCompilerId.cpp b/contrib/cmake/CMakeFiles/CompilerIdCXX/CMakeCXXCompilerId.cpp
new file mode 100644
index 0000000..f8c041f
--- /dev/null
+++ b/contrib/cmake/CMakeFiles/CompilerIdCXX/CMakeCXXCompilerId.cpp
@@ -0,0 +1,169 @@
+/* This source file must have a .cpp extension so that all C++ compilers
+ recognize the extension without flags. Borland does not know .cxx for
+ example. */
+#ifndef __cplusplus
+# error "A C compiler has been selected for C++."
+#endif
+
+#if defined(__COMO__)
+# define COMPILER_ID "Comeau"
+
+#elif defined(__INTEL_COMPILER) || defined(__ICC)
+# define COMPILER_ID "Intel"
+
+#elif defined(__BORLANDC__)
+# define COMPILER_ID "Borland"
+
+#elif defined(__WATCOMC__)
+# define COMPILER_ID "Watcom"
+
+#elif defined(__SUNPRO_CC)
+# define COMPILER_ID "SunPro"
+
+#elif defined(__HP_aCC)
+# define COMPILER_ID "HP"
+
+#elif defined(__DECCXX)
+# define COMPILER_ID "Compaq"
+
+#elif defined(__IBMCPP__)
+# define COMPILER_ID "VisualAge"
+
+#elif defined(__PGI)
+# define COMPILER_ID "PGI"
+
+#elif defined(__GNUC__)
+# define COMPILER_ID "GNU"
+
+#elif defined(_MSC_VER)
+# define COMPILER_ID "MSVC"
+
+#elif defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__)
+/* Analog Devices C++ compiler for Blackfin, TigerSHARC and
+ SHARC (21000) DSPs */
+# define COMPILER_ID "ADSP"
+
+#elif defined(_COMPILER_VERSION)
+# define COMPILER_ID "MIPSpro"
+
+/* This compiler is either not known or is too old to define an
+ identification macro. Try to identify the platform and guess that
+ it is the native compiler. */
+#elif defined(__sgi)
+# define COMPILER_ID "MIPSpro"
+
+#elif defined(__hpux) || defined(__hpua)
+# define COMPILER_ID "HP"
+
+#else /* unknown compiler */
+# define COMPILER_ID ""
+
+#endif
+
+/* Construct the string literal in pieces to prevent the source from
+ getting matched. Store it in a pointer rather than an array
+ because some compilers will just produce instructions to fill the
+ array rather than assigning a pointer to a static array. */
+char* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
+
+/* Identify known platforms by name. */
+#if defined(__linux) || defined(__linux__) || defined(linux)
+# define PLATFORM_ID "Linux"
+
+#elif defined(__CYGWIN__)
+# define PLATFORM_ID "Cygwin"
+
+#elif defined(__MINGW32__)
+# define PLATFORM_ID "MinGW"
+
+#elif defined(__APPLE__)
+# define PLATFORM_ID "Darwin"
+
+#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+# define PLATFORM_ID "Windows"
+
+#elif defined(__FreeBSD__) || defined(__FreeBSD)
+# define PLATFORM_ID "FreeBSD"
+
+#elif defined(__NetBSD__) || defined(__NetBSD)
+# define PLATFORM_ID "NetBSD"
+
+#elif defined(__OpenBSD__) || defined(__OPENBSD)
+# define PLATFORM_ID "OpenBSD"
+
+#elif defined(__sun) || defined(sun)
+# define PLATFORM_ID "SunOS"
+
+#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
+# define PLATFORM_ID "AIX"
+
+#elif defined(__sgi) || defined(__sgi__) || defined(_SGI)
+# define PLATFORM_ID "IRIX"
+
+#elif defined(__hpux) || defined(__hpux__)
+# define PLATFORM_ID "HP-UX"
+
+#elif defined(__HAIKU) || defined(__HAIKU__) || defined(_HAIKU)
+# define PLATFORM_ID "Haiku"
+/* Haiku also defines __BEOS__ so we must
+ put it prior to the check for __BEOS__
+*/
+
+#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
+# define PLATFORM_ID "BeOS"
+
+#elif defined(__QNX__) || defined(__QNXNTO__)
+# define PLATFORM_ID "QNX"
+
+#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
+# define PLATFORM_ID "Tru64"
+
+#elif defined(__riscos) || defined(__riscos__)
+# define PLATFORM_ID "RISCos"
+
+#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
+# define PLATFORM_ID "SINIX"
+
+#elif defined(__UNIX_SV__)
+# define PLATFORM_ID "UNIX_SV"
+
+#elif defined(__bsdos__)
+# define PLATFORM_ID "BSDOS"
+
+#elif defined(_MPRAS) || defined(MPRAS)
+# define PLATFORM_ID "MP-RAS"
+
+#elif defined(__osf) || defined(__osf__)
+# define PLATFORM_ID "OSF1"
+
+#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
+# define PLATFORM_ID "SCO_SV"
+
+#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
+# define PLATFORM_ID "ULTRIX"
+
+#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
+# define PLATFORM_ID "Xenix"
+
+#else /* unknown platform */
+# define PLATFORM_ID ""
+
+#endif
+
+/* Construct the string literal in pieces to prevent the source from
+ getting matched. Store it in a pointer rather than an array
+ because some compilers will just produce instructions to fill the
+ array rather than assigning a pointer to a static array. */
+char* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
+
+
+/*--------------------------------------------------------------------------*/
+
+int main(int argc, char* argv[])
+{
+ int require = 0;
+ require += info_compiler[argc];
+ require += info_platform[argc];
+ (void)argv;
+ return require;
+}
diff --git a/contrib/cmake/CMakeLists.txt b/contrib/cmake/CMakeLists.txt
new file mode 100644
index 0000000..716888f
--- /dev/null
+++ b/contrib/cmake/CMakeLists.txt
@@ -0,0 +1,22 @@
+#cmake_minimum_required(VERSION 2.8)
+
+PROJECT(libconfig_test_app)
+
+add_subdirectory(src)
+
+#add cmake script files
+set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_work")
+
+#check if libconfig is present (FindConfig.cmake and FindConfig++.cmake files)
+FIND_PACKAGE(Config REQUIRED)
+FIND_PACKAGE(Config++ REQUIRED)
+
+#add undelete support
+CONFIGURE_FILE(
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake_work/cmake_uninstall.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/cmake_work/cmake_uninstall.cmake"
+ IMMEDIATE @ONLY)
+ADD_CUSTOM_TARGET(uninstall
+ "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_work/cmake_uninstall.cmake")
+
+
diff --git a/contrib/cmake/cmake_work/FindConfig++.cmake b/contrib/cmake/cmake_work/FindConfig++.cmake
new file mode 100644
index 0000000..f6d11a3
--- /dev/null
+++ b/contrib/cmake/cmake_work/FindConfig++.cmake
@@ -0,0 +1,23 @@
+FIND_PATH(CONFIG++_INCLUDE_DIR libconfig.h++ /usr/include /usr/local/include)
+
+FIND_LIBRARY(CONFIG++_LIBRARY NAMES config++ PATH /usr/lib /usr/local/lib)
+
+IF (CONFIG++_INCLUDE_DIR AND CONFIG++_LIBRARY)
+ SET(CONFIG++_FOUND TRUE)
+ENDIF ( CONFIG++_INCLUDE_DIR AND CONFIG++_LIBRARY)
+
+IF (CONFIG++_FOUND)
+ IF (NOT CONFIG++_FIND_QUIETLY)
+ MESSAGE(STATUS "Found Config++: ${CONFIG++_LIBRARY}")
+ ENDIF (NOT CONFIG++_FIND_QUIETLY)
+ELSE(CONFIG++_FOUND)
+ IF (Config++_FIND_REQUIRED)
+ IF(NOT CONFIG++_INCLUDE_DIR)
+ MESSAGE(FATAL_ERROR "Could not find LibConfig++ header file!")
+ ENDIF(NOT CONFIG++_INCLUDE_DIR)
+
+ IF(NOT CONFIG++_LIBRARY)
+ MESSAGE(FATAL_ERROR "Could not find LibConfig++ library file!")
+ ENDIF(NOT CONFIG++_LIBRARY)
+ ENDIF (Config++_FIND_REQUIRED)
+ENDIF (CONFIG++_FOUND) \ No newline at end of file
diff --git a/contrib/cmake/cmake_work/FindConfig.cmake b/contrib/cmake/cmake_work/FindConfig.cmake
new file mode 100644
index 0000000..5361d96
--- /dev/null
+++ b/contrib/cmake/cmake_work/FindConfig.cmake
@@ -0,0 +1,23 @@
+FIND_PATH(CONFIG_INCLUDE_DIR libconfig.h /usr/include /usr/local/include)
+
+FIND_LIBRARY(CONFIG_LIBRARY NAMES config PATH /usr/lib /usr/local/lib)
+
+IF (CONFIG_INCLUDE_DIR AND CONFIG_LIBRARY)
+ SET(CONFIG_FOUND TRUE)
+ENDIF ( CONFIG_INCLUDE_DIR AND CONFIG_LIBRARY)
+
+IF (CONFIG_FOUND)
+ IF (NOT CONFIG_FIND_QUIETLY)
+ MESSAGE(STATUS "Found Config: ${CONFIG_LIBRARY}")
+ ENDIF (NOT CONFIG_FIND_QUIETLY)
+ELSE(CONFIG_FOUND)
+ IF (Config_FIND_REQUIRED)
+ IF(NOT CONFIG_INCLUDE_DIR)
+ MESSAGE(FATAL_ERROR "Could not find LibConfig header file!")
+ ENDIF(NOT CONFIG_INCLUDE_DIR)
+
+ IF(NOT CONFIG_LIBRARY)
+ MESSAGE(FATAL_ERROR "Could not find LibConfig library file!")
+ ENDIF(NOT CONFIG_LIBRARY)
+ ENDIF (Config_FIND_REQUIRED)
+ENDIF (CONFIG_FOUND) \ No newline at end of file
diff --git a/contrib/cmake/cmake_work/cmake_uninstall.cmake.in b/contrib/cmake/cmake_work/cmake_uninstall.cmake.in
new file mode 100644
index 0000000..10a2937
--- /dev/null
+++ b/contrib/cmake/cmake_work/cmake_uninstall.cmake.in
@@ -0,0 +1,36 @@
+# Copyright 2006-2008 The FLWOR Foundation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+ MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
+ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
+
+FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
+STRING(REGEX REPLACE "\n" ";" files "${files}")
+FOREACH(file ${files})
+ MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
+ IF(EXISTS "$ENV{DESTDIR}${file}")
+ EXEC_PROGRAM(
+ "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
+ OUTPUT_VARIABLE rm_out
+ RETURN_VALUE rm_retval
+ )
+ IF("${rm_retval}" STREQUAL 0)
+ ELSE("${rm_retval}" STREQUAL 0)
+ MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
+ ENDIF("${rm_retval}" STREQUAL 0)
+ ELSE(EXISTS "$ENV{DESTDIR}${file}")
+ MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
+ ENDIF(EXISTS "$ENV{DESTDIR}${file}")
+ENDFOREACH(file)
diff --git a/contrib/cmake/src/CMakeLists.txt b/contrib/cmake/src/CMakeLists.txt
new file mode 100644
index 0000000..b10b7da
--- /dev/null
+++ b/contrib/cmake/src/CMakeLists.txt
@@ -0,0 +1,6 @@
+PROJECT(libconfig_test_app)
+
+ADD_EXECUTABLE(libconfig_test_app main.cpp)
+
+target_link_libraries(libconfig_test_app config++)
+
diff --git a/contrib/cmake/src/main.cpp b/contrib/cmake/src/main.cpp
new file mode 100644
index 0000000..a563249
--- /dev/null
+++ b/contrib/cmake/src/main.cpp
@@ -0,0 +1,13 @@
+#include <iostream>
+#include <fstream>
+#include <libconfig.h++>
+
+using namespace std;
+using namespace libconfig;
+
+int main ( int argc, char **argv )
+{
+ Config cfg;
+
+ return (0);
+} \ No newline at end of file
diff --git a/contrib/copy_setting.c b/contrib/copy_setting.c
new file mode 100644
index 0000000..1b20e59
--- /dev/null
+++ b/contrib/copy_setting.c
@@ -0,0 +1,161 @@
+void config_setting_copy_simple(config_setting_t * parent, const config_setting_t * src);
+void config_setting_copy_elem(config_setting_t * parent, const config_setting_t * src);
+
+void config_setting_copy_aggregate(config_setting_t * parent, const config_setting_t * src);
+int config_setting_copy(config_setting_t * parent, const config_setting_t * src);
+
+void config_setting_copy_simple(config_setting_t * parent, const config_setting_t * src)
+{
+ if(config_setting_is_aggregate(src))
+ {
+ config_setting_copy_aggregate(parent, src);
+ }
+ else
+ {
+ config_setting_t * set;
+
+ set = config_setting_add(parent, config_setting_name(src), config_setting_type(src));
+
+ if(CONFIG_TYPE_INT == config_setting_type(src))
+ {
+ config_setting_set_int(set, config_setting_get_int(src));
+ config_setting_set_format(set, src->format);
+ }
+ else if(CONFIG_TYPE_INT64 == config_setting_type(src))
+ {
+ config_setting_set_int64(set, config_setting_get_int64(src));
+ config_setting_set_format(set, src->format);
+ }
+ else if(CONFIG_TYPE_FLOAT == config_setting_type(src))
+ config_setting_set_float(set, config_setting_get_float(src));
+ else if(CONFIG_TYPE_STRING == config_setting_type(src))
+ config_setting_set_string(set, config_setting_get_string(src));
+ else if(CONFIG_TYPE_BOOL == config_setting_type(src))
+ config_setting_set_bool(set, config_setting_get_bool(src));
+ }
+}
+
+void config_setting_copy_elem(config_setting_t * parent, const config_setting_t * src)
+{
+ config_setting_t * set;
+
+ set = NULL;
+ if(config_setting_is_aggregate(src))
+ config_setting_copy_aggregate(parent, src);
+ else if(CONFIG_TYPE_INT == config_setting_type(src))
+ {
+ set = config_setting_set_int_elem(parent, -1, config_setting_get_int(src));
+ config_setting_set_format(set, src->format);
+ }
+ else if(CONFIG_TYPE_INT64 == config_setting_type(src))
+ {
+ set = config_setting_set_int64_elem(parent, -1, config_setting_get_int64(src));
+ config_setting_set_format(set, src->format);
+ }
+ else if(CONFIG_TYPE_FLOAT == config_setting_type(src))
+ set = config_setting_set_float_elem(parent, -1, config_setting_get_float(src));
+ else if(CONFIG_TYPE_STRING == config_setting_type(src))
+ set = config_setting_set_string_elem(parent, -1, config_setting_get_string(src));
+ else if(CONFIG_TYPE_BOOL == config_setting_type(src))
+ set = config_setting_set_bool_elem(parent, -1, config_setting_get_bool(src));
+}
+
+void config_setting_copy_aggregate(config_setting_t * parent, const config_setting_t * src)
+{
+ config_setting_t * newAgg;
+ int i, n;
+
+ newAgg = config_setting_add(parent, config_setting_name(src), config_setting_type(src));
+
+ n = config_setting_length(src);
+ for(i = 0; i < n; i++)
+ {
+ if(config_setting_is_group(src))
+ {
+ config_setting_copy_simple(newAgg, config_setting_get_elem(src, i));
+ }
+ else
+ {
+ config_setting_copy_elem(newAgg, config_setting_get_elem(src, i));
+ }
+ }
+}
+
+int config_setting_copy(config_setting_t * parent, const config_setting_t * src)
+{
+ if((!config_setting_is_group(parent)) &&
+ (!config_setting_is_list(parent)))
+ return CONFIG_FALSE;
+
+ if(config_setting_is_aggregate(src))
+ {
+ config_setting_copy_aggregate(parent, src);
+ }
+ else
+ {
+ config_setting_copy_simple(parent, src);
+ }
+
+ return CONFIG_TRUE;
+}
+
+
+//Some sample code
+
+//-----------------------------------------------------------------------------
+int main(int argc, char *argv[])
+//-----------------------------------------------------------------------------
+{
+ config_t cfgSrc;
+ config_t cfgSrcCopy;
+ config_t cfgDst;
+
+
+ config_init(&cfgSrc);
+ config_init(&cfgSrcCopy);
+ config_init(&cfgDst);
+
+ if(CONFIG_FALSE == config_read_file(&cfgSrc, "/data/menu/cfgSrc.cfg"))
+ {
+ fprintf(stderr, "Failed to open cfgSrc.cfg\n");
+ }
+ if(CONFIG_FALSE == config_read_file(&cfgDst, "/data/menu/cfgDst.cfg"))
+ {
+ fprintf(stderr, "Failed to open cfgDst.cfg\n");
+ }
+
+ /*
+ printf("Dump cfgSrc.cfg\n");
+ DumpCfgSetting(config_root_setting(&cfgSrc));
+
+ printf("Dump cfgDst.cfg\n");
+ DumpCfgSetting(config_root_setting(&cfgDst));
+ */
+
+ config_setting_t * src;
+ config_setting_t * dst;
+
+ dst = config_lookup(&cfgDst, "grp1");
+
+ if((0 != (dst = config_lookup(&cfgDst, "grp1"))) &&
+ (0 != (src = config_lookup(&cfgSrc, "application.window"))))
+ //(0 != (src = config_lookup(&cfgSrc, "list"))))
+
+ {
+ if(CONFIG_FALSE == config_setting_copy(dst, src))
+ {
+ printf("Failed to copy src to dst\n");
+ }
+ }
+
+ config_setting_copy(config_root_setting(&cfgSrcCopy), config_root_setting(&cfgSrc));
+
+ config_write_file(&cfgDst, "/data/menu/cfgDstMod.cfg");
+ config_write_file(&cfgSrcCopy, "/data/menu/cfgSrcCpy.cfg");
+ config_write_file(&cfgSrc, "/data/menu/cfgSrcOrig.cfg");
+
+ config_destroy(&cfgSrc);
+ config_destroy(&cfgDst);
+
+ return 0;
+}
diff --git a/contrib/libconfig-ruby/README b/contrib/libconfig-ruby/README
new file mode 100644
index 0000000..1a45477
--- /dev/null
+++ b/contrib/libconfig-ruby/README
@@ -0,0 +1,76 @@
+# << Usage >>
+
+# you can feed this README to irb and see the result
+# $ irb README
+
+# IMPORTANT NOTICE:
+# be careful with big *fixnum* (plain int) values in configs
+# int is 32 bit, but ruby fixnum is only 31!
+# For example, 2100000000 will be read as -47483648.
+
+require 'rconfig'
+c = Config.new
+
+c.read!('test.cfg')
+# => IOError
+c.read('test.cfg')
+# => false
+
+p c['some_var']
+# => SettingNotFoundError
+# note: Config#lookup is alias for Config#[]
+
+c.append 'fixnum', Config::Fixnum.new(150)
+# #<Config::Fixnum...>
+
+f1 = Config::Fixnum.new(1)
+c.append 'another_fixnum', f1
+
+f2 = Config::Fixnum.new(256)
+c.append 'next_fixnum', f2
+
+p c.size
+# => 3
+
+c.delete(f1) # by element
+c.delete(0) # by index
+c.delete('next_fixnum') # by name
+# note: (at now) you cannot delete nested elements by Config#delete
+# you can do c['nested.element'].parent.delete(c['nested.element'])
+
+p c.size
+# => 0
+
+l = Config::List.new
+c.append 'the_list', l
+
+l.append Config::String.new("abcdef")
+l << Config::Float.new(3.14)
+# note: Config::List#append and Config::Array#append both have
+# aliases Config::[Aggregate]#<<
+
+p l.name
+# => "the_list"
+
+p l.index
+# => 0
+
+p l.root?
+# => false
+
+p l.size
+# => 3
+
+l[0].format = Config::FORMAT_HEX
+
+p l[1].value
+# => 3.14
+
+l[1].value = 2.71828
+
+c.write 'test.cfg'
+
+# you will get test.cfg with following contents:
+#
+# the_list = ( "abcdef", 2.71828, 0x2A );
+#
diff --git a/contrib/libconfig-ruby/Rakefile b/contrib/libconfig-ruby/Rakefile
new file mode 100644
index 0000000..f1b7845
--- /dev/null
+++ b/contrib/libconfig-ruby/Rakefile
@@ -0,0 +1,17 @@
+require 'rubygems'
+require 'rubygems/package_task'
+
+spec = Gem::Specification.new do |s|
+ s.name = "rconfig"
+ s.version = "1.0.1"
+ s.author = "Peter Zotov"
+ s.email = "whitequark@whitequark.ru"
+ s.platform = Gem::Platform::RUBY
+ s.summary = "libconfig bindings"
+ s.files = [ File.join('ext', 'extconf.rb'), File.join('ext', 'rconfig.c') ].to_a
+ s.extensions = 'ext/extconf.rb'
+end
+
+Gem::PackageTask.new(spec) do |pkg|
+end
+
diff --git a/contrib/libconfig-ruby/ext/extconf.rb b/contrib/libconfig-ruby/ext/extconf.rb
new file mode 100644
index 0000000..e6d65ca
--- /dev/null
+++ b/contrib/libconfig-ruby/ext/extconf.rb
@@ -0,0 +1,11 @@
+#!/usr/bin/ruby
+require "mkmf"
+
+unless pkg_config('libconfig')
+ puts 'failure: need libconfig'
+ exit 1
+end
+
+have_func('rb_block_call', 'ruby/ruby.h')
+
+create_makefile("rconfig")
diff --git a/contrib/libconfig-ruby/ext/rconfig.c b/contrib/libconfig-ruby/ext/rconfig.c
new file mode 100644
index 0000000..fa0bc96
--- /dev/null
+++ b/contrib/libconfig-ruby/ext/rconfig.c
@@ -0,0 +1,700 @@
+#include <ruby.h>
+#include <libconfig.h>
+
+static VALUE cConfig, cConfigBaseSetting, cConfigSetting, cConfigAggregate;
+static VALUE cConfigFormatDefault, cConfigFormatHex;
+static VALUE cConfigFixnum, cConfigBignum, cConfigFloat, cConfigBoolean, cConfigString;
+static VALUE cConfigGroup, cConfigList, cConfigArray;
+
+static VALUE rSettingNameRegexp;
+static VALUE aConfigSettings, aConfigScalars, aConfigAggregates;
+static VALUE eConfigParseError, eSettingNotFoundError, eSettingFormatError, eSettingNameError;
+
+static VALUE rconfig_wrap_value(config_setting_t* setting)
+{
+ switch(config_setting_type(setting)) {
+ case CONFIG_TYPE_INT:
+ return LONG2FIX(config_setting_get_int(setting));
+
+ case CONFIG_TYPE_INT64:
+ return rb_ll2inum(config_setting_get_int64(setting));
+
+ case CONFIG_TYPE_FLOAT:
+ return rb_float_new(config_setting_get_float(setting));
+
+ case CONFIG_TYPE_STRING:
+ return rb_str_new2(config_setting_get_string(setting));
+
+ case CONFIG_TYPE_BOOL:
+ return config_setting_get_bool(setting) ? Qtrue : Qfalse;
+
+ default:
+ rb_bug("unknown value type %d", config_setting_type(setting));
+ }
+}
+
+static void rconfig_free_setting(config_setting_t* setting)
+{
+ // dummy
+}
+
+static VALUE rconfig_prepare_setting(config_setting_t* setting)
+{
+ VALUE wrapper = Data_Wrap_Struct(rb_cObject, 0, rconfig_free_setting, setting);
+ config_setting_set_hook(setting, (void*) wrapper);
+ return wrapper;
+}
+
+static void rconfig_destroy_setting(void* hook)
+{
+ if(hook != NULL) {
+ VALUE wrapper = (VALUE) hook;
+ rb_iv_set(wrapper, "@setting", Qnil);
+ }
+}
+
+static VALUE rconfig_wrap_setting(config_setting_t* setting)
+{
+ VALUE rbSetting = rconfig_prepare_setting(setting);
+
+ switch(config_setting_type(setting)) {
+ case CONFIG_TYPE_INT:
+ return rb_funcall(cConfigFixnum, rb_intern("new"), 2, LONG2FIX(config_setting_get_int(setting)), rbSetting);
+
+ case CONFIG_TYPE_INT64:
+ return rb_funcall(cConfigBignum, rb_intern("new"), 2, rb_ll2inum(config_setting_get_int64(setting)), rbSetting);
+
+ case CONFIG_TYPE_FLOAT:
+ return rb_funcall(cConfigFloat, rb_intern("new"), 2, rb_float_new(config_setting_get_float(setting)), rbSetting);
+
+ case CONFIG_TYPE_STRING:
+ return rb_funcall(cConfigString, rb_intern("new"), 2, rb_str_new2(config_setting_get_string(setting)), rbSetting);
+
+ case CONFIG_TYPE_BOOL:
+ return rb_funcall(cConfigBoolean, rb_intern("new"), 2, config_setting_get_bool(setting) ? Qtrue : Qfalse, rbSetting);
+
+ case CONFIG_TYPE_ARRAY:
+ return rb_funcall(cConfigArray, rb_intern("new"), 2, Qnil, rbSetting);
+
+ case CONFIG_TYPE_LIST:
+ return rb_funcall(cConfigList, rb_intern("new"), 1, rbSetting);
+
+ case CONFIG_TYPE_GROUP:
+ return rb_funcall(cConfigGroup, rb_intern("new"), 1, rbSetting);
+
+ default:
+ rb_bug("[r] unknown setting type %d", config_setting_type(setting));
+ }
+}
+
+static void rconfig_update_setting(config_setting_t* setting, VALUE value)
+{
+ switch(config_setting_type(setting)) {
+ case CONFIG_TYPE_INT:
+ config_setting_set_int(setting, FIX2LONG(value));
+ break;
+
+ case CONFIG_TYPE_INT64:
+ if(TYPE(value) == T_BIGNUM)
+ config_setting_set_int64(setting, rb_big2ll(value));
+ else // T_FIXNUM
+ config_setting_set_int64(setting, FIX2INT(value));
+ break;
+
+ case CONFIG_TYPE_FLOAT:
+// ruby1.9 check
+#if HAVE_RB_BLOCK_CALL
+ config_setting_set_float(setting, RFLOAT_VALUE(value));
+#else
+ config_setting_set_float(setting, RFLOAT_VALUE(value));
+#endif
+ break;
+
+ case CONFIG_TYPE_STRING:
+ config_setting_set_string(setting, RSTRING_PTR(value));
+ break;
+
+ case CONFIG_TYPE_BOOL:
+ config_setting_set_bool(setting, value == Qtrue);
+ break;
+
+ default:
+ rb_bug("[w] unknown setting type %d", config_setting_type(setting));
+ }
+}
+
+static void rconfig_check_setting_type(VALUE object, VALUE value)
+{
+ if(rb_obj_class(object) == cConfigFixnum) {
+ Check_Type(value, T_FIXNUM);
+ } else if(rb_obj_class(object) == cConfigBignum) {
+ if(TYPE(value) != T_BIGNUM && TYPE(value) != T_FIXNUM)
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Fixnum or Bignum)", rb_obj_classname(value));
+ } else if(rb_obj_class(object) == cConfigFloat) {
+ Check_Type(value, T_FLOAT);
+ } else if(rb_obj_class(object) == cConfigString) {
+ Check_Type(value, T_STRING);
+ } else if(rb_obj_class(object) == cConfigBoolean) {
+ if(value != Qtrue && value != Qfalse)
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected boolean)", rb_obj_classname(value));
+ } else {
+ rb_raise(rb_eException, "never use Config::Setting itself");
+ }
+}
+
+static int rconfig_do_append(config_setting_t* setting, VALUE target, VALUE name)
+{
+ int type;
+ if(rb_obj_class(target) == cConfigFixnum)
+ type = CONFIG_TYPE_INT;
+ else if(rb_obj_class(target) == cConfigBignum)
+ type = CONFIG_TYPE_INT64;
+ else if(rb_obj_class(target) == cConfigFloat)
+ type = CONFIG_TYPE_FLOAT;
+ else if(rb_obj_class(target) == cConfigString)
+ type = CONFIG_TYPE_STRING;
+ else if(rb_obj_class(target) == cConfigBoolean)
+ type = CONFIG_TYPE_BOOL;
+ else if(rb_obj_class(target) == cConfigGroup)
+ type = CONFIG_TYPE_GROUP;
+ else if(rb_obj_class(target) == cConfigList)
+ type = CONFIG_TYPE_LIST;
+ else if(rb_obj_class(target) == cConfigArray)
+ type = CONFIG_TYPE_ARRAY;
+ else
+ rb_bug("unknown setting class %s", rb_obj_classname(target));
+
+ config_setting_t* new_setting;
+ if(name == Qnil) {
+ new_setting = config_setting_add(setting, NULL, type);
+ } else {
+ Check_Type(name, T_STRING);
+ new_setting = config_setting_add(setting, RSTRING_PTR(name), type);
+ }
+
+ if(new_setting == NULL)
+ return 0;
+
+ VALUE rbNewSetting = rconfig_prepare_setting(new_setting);
+ rb_iv_set(target, "@setting", rbNewSetting);
+
+ if(rb_ary_includes(aConfigScalars, rb_obj_class(target)) == Qtrue)
+ rconfig_update_setting(new_setting, rb_iv_get(target, "@value"));
+
+ if(rb_ary_includes(aConfigAggregates, rb_obj_class(target)) == Qtrue) {
+ if(rb_obj_class(target) == cConfigGroup) {
+ VALUE hash = rb_iv_get(target, "@hash");
+ VALUE children = rb_funcall(hash, rb_intern("keys"), 0);
+ int i;
+ for(i = 0; i < RARRAY_LEN(children); i++) {
+ VALUE key = RARRAY_PTR(children)[i];
+ rconfig_do_append(new_setting, rb_hash_aref(hash, key), key);
+ }
+ } else {
+ VALUE children = rb_iv_get(target, "@list");
+ int i;
+ for(i = 0; i < RARRAY_LEN(children); i++) {
+ rconfig_do_append(new_setting, RARRAY_PTR(children)[i], Qnil);
+ }
+ }
+ }
+
+ return 1;
+}
+
+static VALUE rbConfigBaseSetting_initialize(VALUE self, VALUE setting)
+{
+ if(setting != Qnil)
+ Check_Type(setting, T_DATA);
+ rb_iv_set(self, "@setting", setting);
+
+ return self;
+}
+
+static VALUE rbConfigBaseSetting_name(VALUE self)
+{
+ if(rb_iv_get(self, "@setting") != Qnil) {
+ config_setting_t* setting = NULL;
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
+ return rb_str_new2(config_setting_name(setting));
+ } else {
+ return Qnil;
+ }
+}
+
+static VALUE rbConfigBaseSetting_parent(VALUE self)
+{
+ if(rb_iv_get(self, "@setting") != Qnil) {
+ config_setting_t* setting = NULL;
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
+ return rconfig_wrap_setting(config_setting_parent(setting));
+ } else {
+ return Qnil;
+ }
+}
+
+static VALUE rbConfigBaseSetting_is_root(VALUE self)
+{
+ if(rb_iv_get(self, "@setting") != Qnil) {
+ config_setting_t* setting = NULL;
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
+ return config_setting_is_root(setting) ? Qtrue : Qfalse;
+ } else {
+ return Qnil;
+ }
+}
+
+static VALUE rbConfigBaseSetting_index(VALUE self)
+{
+ if(rb_iv_get(self, "@setting") != Qnil) {
+ config_setting_t* setting = NULL;
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
+ return INT2FIX(config_setting_index(setting));
+ } else {
+ return Qnil;
+ }
+}
+
+static VALUE rbConfigBaseSetting_line(VALUE self)
+{
+ if(rb_iv_get(self, "@setting") != Qnil) {
+ config_setting_t* setting = NULL;
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
+ return INT2FIX(config_setting_source_line(setting));
+ } else {
+ return Qnil;
+ }
+}
+
+static VALUE rbConfigSetting_initialize(int argc, VALUE* argv, VALUE self)
+{
+ VALUE value, setting;
+ rb_scan_args(argc, argv, "11", &value, &setting);
+
+ rb_call_super(1, &setting);
+
+ rconfig_check_setting_type(self, value);
+ rb_iv_set(self, "@value", value);
+
+ if(rb_iv_get(self, "@setting") != Qnil) {
+ config_setting_t* c_setting = NULL;
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, c_setting);
+ rb_iv_set(self, "@format", INT2FIX(config_setting_get_format(c_setting)));
+ } else {
+ rb_iv_set(self, "@format", cConfigFormatDefault);
+ }
+
+ return self;
+}
+
+static VALUE rbConfigSetting_get_value(VALUE self)
+{
+ if(rb_iv_get(self, "@setting") != Qnil) {
+ config_setting_t* setting;
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
+ return rconfig_wrap_value(setting);
+ } else {
+ return rb_iv_get(self, "@value");
+ }
+}
+
+static VALUE rbConfigSetting_set_value(VALUE self, VALUE new_value)
+{
+ rconfig_check_setting_type(self, new_value);
+
+ if(rb_iv_get(self, "@setting") != Qnil) {
+ config_setting_t* setting;
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
+ rconfig_update_setting(setting, new_value);
+ }
+
+ rb_iv_set(self, "@value", new_value);
+
+ return new_value;
+}
+
+static VALUE rbConfigSetting_get_format(VALUE self)
+{
+ if(rb_iv_get(self, "@setting") != Qnil) {
+ config_setting_t* setting;
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
+ return INT2FIX(config_setting_get_format(setting));
+ } else {
+ return rb_iv_get(self, "format");
+ }
+}
+
+static VALUE rbConfigSetting_set_format(VALUE self, VALUE new_format)
+{
+ if(rb_iv_get(self, "@setting") != Qnil) {
+ config_setting_t* setting;
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
+ if(!config_setting_set_format(setting, FIX2INT(new_format)))
+ rb_raise(eSettingFormatError, "invalid setting format %d", FIX2INT(new_format));
+ }
+
+ rb_iv_set(self, "@format", new_format);
+
+ return new_format;
+}
+
+static VALUE rbConfigAggregate_get(VALUE self, VALUE index);
+
+static VALUE rbConfigAggregate_initialize(int argc, VALUE* argv, VALUE self)
+{
+ VALUE setting = Qnil;
+ if(rb_obj_class(self) == cConfigGroup || rb_obj_class(self) == cConfigList) {
+ rb_scan_args(argc, argv, "01", &setting);
+ } else if(rb_obj_class(self) == cConfigArray) {
+ VALUE type = Qnil;
+ rb_scan_args(argc, argv, "02", &type, &setting);
+
+ if(type != Qnil && rb_ary_includes(aConfigScalars, type) != Qtrue)
+ rb_raise(rb_eTypeError, "invalid setting array type %s", rb_class2name(type));
+
+ rb_iv_set(self, "@type", type);
+ } else {
+ rb_raise(rb_eException, "never create Config::Aggregate itself");
+ }
+
+ rb_call_super(1, &setting);
+
+ rb_iv_set(self, "@list", rb_ary_new());
+ if(rb_obj_class(self) == cConfigGroup)
+ rb_iv_set(self, "@hash", rb_hash_new());
+
+ if(setting != Qnil && rb_obj_class(self) == cConfigArray) {
+ config_setting_t* c_setting;
+ Data_Get_Struct(setting, config_setting_t, c_setting);
+ if(config_setting_length(c_setting) > 0)
+ rb_iv_set(self, "@type", rb_obj_class(rbConfigAggregate_get(self, INT2FIX(0))));
+ }
+
+ return self;
+}
+
+static VALUE rbConfigAggregate_size(VALUE self)
+{
+ config_setting_t* setting = NULL;
+ if(rb_iv_get(self, "@setting") != Qnil)
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
+
+ if(setting)
+ return INT2FIX(config_setting_length(setting));
+ else
+ return INT2FIX(RARRAY_LEN(rb_iv_get(self, "@list")));
+}
+
+static VALUE rbConfigAggregate_get(VALUE self, VALUE index)
+{
+ config_setting_t* setting = NULL;
+ if(rb_iv_get(self, "@setting") != Qnil)
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
+
+ VALUE rbTarget = Qnil;
+
+ if(TYPE(index) == T_STRING && rb_obj_class(self) == cConfigGroup) {
+ if(setting) {
+ config_setting_t* target = config_setting_get_member(setting, RSTRING_PTR(index));
+ if(target)
+ rbTarget = rconfig_wrap_setting(target);
+ } else {
+ rbTarget = rb_hash_aref(rb_iv_get(self, "@hash"), index);
+ }
+ } else if(TYPE(index) == T_FIXNUM) {
+ if(setting) {
+ config_setting_t* target = config_setting_get_elem(setting, FIX2INT(index));
+ if(target)
+ rbTarget = rconfig_wrap_setting(target);
+ } else {
+ rbTarget = rb_ary_entry(rb_iv_get(self, "@list"), FIX2INT(index));
+ }
+ } else {
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected String or Fixnum)", rb_obj_classname(index));
+ }
+
+ if(rbTarget == Qnil)
+ if(TYPE(index) == T_STRING)
+ rb_raise(eSettingNotFoundError, "setting `%s' not found", RSTRING_PTR(index));
+ else
+ rb_raise(eSettingNotFoundError, "setting [%d] not found", FIX2INT(index));
+
+ return rbTarget;
+}
+
+static VALUE rbConfigAggregate_append(VALUE self, VALUE target)
+{
+ config_setting_t* setting = NULL;
+ if(rb_iv_get(self, "@setting") != Qnil)
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
+
+ Check_Type(target, T_OBJECT);
+
+ VALUE type = rb_iv_get(self, "@type");
+ if(rb_obj_class(self) == cConfigArray) {
+ if(type != Qnil && type != rb_obj_class(target))
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", rb_obj_classname(target), rb_class2name(type));
+ if(type == Qnil && rb_ary_includes(aConfigScalars, rb_obj_class(target)) != Qtrue)
+ rb_raise(rb_eTypeError, "invalid setting array type %s", rb_obj_classname(target));
+ }
+
+ if(rb_ary_includes(aConfigSettings, rb_obj_class(target)) == Qtrue) {
+ if(setting)
+ rconfig_do_append(setting, target, Qnil);
+ rb_ary_push(rb_iv_get(self, "@list"), target);
+ } else {
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Config::BaseSetting)", rb_obj_classname(target));
+ }
+
+ if(rb_obj_class(self) == cConfigArray && type == Qnil)
+ rb_iv_set(self, "@type", rb_obj_class(target));
+
+ return target;
+}
+
+static VALUE rbConfigGroup_append(VALUE self, VALUE name, VALUE target)
+{
+ Check_Type(name, T_STRING);
+ Check_Type(target, T_OBJECT);
+
+ config_setting_t* setting = NULL;
+ if(rb_iv_get(self, "@setting") != Qnil)
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
+
+ if(rb_ary_includes(aConfigSettings, rb_obj_class(target)) == Qtrue) {
+ if(rb_reg_match(rSettingNameRegexp, name) == Qnil)
+ rb_raise(eSettingNameError, "setting name `%s' contains invalid characters", RSTRING_PTR(name));
+ if(setting) {
+ if(!rconfig_do_append(setting, target, name))
+ rb_raise(eSettingNameError, "setting `%s' already exists", RSTRING_PTR(name));
+ } else if(rb_hash_aref(rb_iv_get(self, "@hash"), name) != Qnil) {
+ rb_raise(eSettingNameError, "setting `%s' already exists", RSTRING_PTR(name));
+ }
+ rb_ary_push(rb_iv_get(self, "@list"), target);
+ rb_hash_aset(rb_iv_get(self, "@hash"), name, target);
+ } else {
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Config::BaseSetting)", rb_obj_classname(target));
+ }
+
+ return target;
+}
+
+static VALUE rbConfigAggregate_delete(VALUE self, VALUE target)
+{
+ config_setting_t* setting = NULL;
+ if(rb_iv_get(self, "@setting") != Qnil)
+ Data_Get_Struct(rb_iv_get(self, "@setting"), config_setting_t, setting);
+
+ VALUE hash = rb_iv_get(self, "@hash"), list = rb_iv_get(self, "@list");
+
+ if(TYPE(target) == T_STRING && rb_obj_class(self) == cConfigGroup) {
+ if(setting)
+ config_setting_remove(setting, RSTRING_PTR(target));
+
+ rb_ary_delete_at(list, rb_hash_aref(hash, target));
+ rb_hash_delete(hash, target);
+ } else if(TYPE(target) == T_FIXNUM) {
+ int index = FIX2INT(target);
+ if(setting)
+ config_setting_remove_elem(setting, index);
+
+ if(rb_obj_class(self) == cConfigGroup)
+ rb_hash_delete(hash, rbConfigBaseSetting_name(rb_ary_entry(list, index)));
+ rb_ary_delete_at(list, index);
+ } else if(rb_ary_includes(aConfigSettings, rb_obj_class(target)) == Qtrue) {
+ VALUE name = rbConfigBaseSetting_name(target);
+ if(setting)
+ config_setting_remove(setting, RSTRING_PTR(name));
+
+ if(rb_obj_class(self) == cConfigGroup)
+ rb_hash_delete(hash, name);
+ rb_ary_delete(list, target);
+ } else {
+ if(rb_obj_class(self) == cConfigGroup)
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected String, Fixnum or Config::BaseSetting)", rb_obj_classname(target));
+ else
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Fixnum or Config::BaseSetting)", rb_obj_classname(target));
+ }
+
+ return Qnil;
+}
+
+static VALUE rbConfig_initialize(VALUE self)
+{
+ config_t* config = (config_t*) malloc(sizeof(config_t));
+ config_init(config);
+ config_set_destructor(config, &rconfig_destroy_setting);
+
+ VALUE rbConfig = Data_Wrap_Struct(rb_cObject, 0, config_destroy, config);
+ rb_iv_set(self, "@config", rbConfig);
+
+ return self;
+}
+
+static VALUE rbConfig_read_bang(VALUE self, VALUE path)
+{
+ Check_Type(path, T_STRING);
+
+ config_t* config;
+ Data_Get_Struct(rb_iv_get(self, "@config"), config_t, config);
+
+ if(!config_read_file(config, RSTRING_PTR(path))) {
+ if(config_error_line(config) == 0)
+ rb_raise(rb_eIOError, "cannot load config: I/O error");
+ else
+ rb_raise(eConfigParseError, "cannot parse config on line %d: `%s'",
+ config_error_line(config), config_error_text(config));
+ }
+
+ return Qtrue;
+}
+
+static VALUE rbConfig_write_bang(VALUE self, VALUE path)
+{
+ Check_Type(path, T_STRING);
+
+ config_t* config;
+ Data_Get_Struct(rb_iv_get(self, "@config"), config_t, config);
+
+ if(!config_write_file(config, RSTRING_PTR(path)))
+ rb_raise(rb_eIOError, "cannot save config: I/O error");
+
+ return Qtrue;
+}
+
+static VALUE rbConfig_read(VALUE self, VALUE path)
+{
+ Check_Type(path, T_STRING);
+
+ config_t* config;
+ Data_Get_Struct(rb_iv_get(self, "@config"), config_t, config);
+
+ return config_read_file(config, RSTRING_PTR(path)) ? Qtrue : Qfalse;
+}
+
+static VALUE rbConfig_write(VALUE self, VALUE path)
+{
+ Check_Type(path, T_STRING);
+
+ config_t* config;
+ Data_Get_Struct(rb_iv_get(self, "@config"), config_t, config);
+
+ return config_write_file(config, RSTRING_PTR(path)) ? Qtrue : Qfalse;
+}
+
+static VALUE rbConfig_root(VALUE self)
+{
+ config_t* config;
+ Data_Get_Struct(rb_iv_get(self, "@config"), config_t, config);
+
+ return rconfig_wrap_setting(config_root_setting(config));
+}
+
+static VALUE rbConfig_lookup(VALUE self, VALUE handle)
+{
+ if(TYPE(handle) == T_STRING) {
+ config_t* config;
+ Data_Get_Struct(rb_iv_get(self, "@config"), config_t, config);
+
+ config_setting_t* setting;
+ setting = config_lookup(config, RSTRING_PTR(handle));
+
+ if(setting == NULL)
+ rb_raise(eSettingNotFoundError, "setting `%s' not found", RSTRING_PTR(handle));
+
+ return rconfig_wrap_setting(setting);
+ } else if(TYPE(handle) == T_FIXNUM) {
+ return rbConfigAggregate_get(rbConfig_root(self), handle);
+ } else {
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected String or Fixnum)", rb_obj_classname(handle));
+ }
+}
+
+static VALUE rbConfig_append(VALUE self, VALUE name, VALUE target)
+{
+ return rbConfigGroup_append(rbConfig_root(self), name, target);
+}
+
+static VALUE rbConfig_delete(VALUE self, VALUE name)
+{
+ return rbConfigAggregate_delete(rbConfig_root(self), name);
+}
+
+static VALUE rbConfig_size(VALUE self)
+{
+ return rbConfigAggregate_size(rbConfig_root(self));
+}
+
+void Init_rconfig()
+{
+ cConfig = rb_define_class("Config", rb_cObject);
+ rb_define_method(cConfig, "initialize", rbConfig_initialize, 0);
+ rb_define_method(cConfig, "read!", rbConfig_read_bang, 1);
+ rb_define_method(cConfig, "write!", rbConfig_write_bang, 1);
+ rb_define_method(cConfig, "read", rbConfig_read, 1);
+ rb_define_method(cConfig, "write", rbConfig_write, 1);
+ rb_define_method(cConfig, "root", rbConfig_root, 0);
+ rb_define_method(cConfig, "lookup", rbConfig_lookup, 1);
+ rb_define_method(cConfig, "[]", rbConfig_lookup, 1);
+ rb_define_method(cConfig, "append", rbConfig_append, 2);
+ rb_define_method(cConfig, "delete", rbConfig_delete, 1);
+ rb_define_method(cConfig, "size", rbConfig_size, 0);
+
+ cConfigBaseSetting = rb_define_class_under(cConfig, "BaseSetting", rb_cObject);
+ rb_define_method(cConfigBaseSetting, "initialize", rbConfigBaseSetting_initialize, 1);
+ rb_define_method(cConfigBaseSetting, "name", rbConfigBaseSetting_name, 0);
+ rb_define_method(cConfigBaseSetting, "parent", rbConfigBaseSetting_parent, 0);
+ rb_define_method(cConfigBaseSetting, "root?", rbConfigBaseSetting_is_root, 0);
+ rb_define_method(cConfigBaseSetting, "index", rbConfigBaseSetting_index, 0);
+ rb_define_method(cConfigBaseSetting, "line", rbConfigBaseSetting_line, 0);
+
+ cConfigSetting = rb_define_class_under(cConfig, "Setting", cConfigBaseSetting);
+ rb_define_method(cConfigSetting, "initialize", rbConfigSetting_initialize, -1);
+ rb_define_method(cConfigSetting, "value", rbConfigSetting_get_value, 0);
+ rb_define_method(cConfigSetting, "value=", rbConfigSetting_set_value, 1);
+ rb_define_method(cConfigSetting, "format", rbConfigSetting_get_format, 0);
+ rb_define_method(cConfigSetting, "format=", rbConfigSetting_set_format, 1);
+
+ cConfigFormatDefault = INT2FIX(CONFIG_FORMAT_DEFAULT);
+ rb_define_const(cConfig, "FORMAT_DEFAULT", cConfigFormatDefault);
+ cConfigFormatHex = INT2FIX(CONFIG_FORMAT_HEX);
+ rb_define_const(cConfig, "FORMAT_HEX", cConfigFormatHex);
+
+ cConfigFixnum = rb_define_class_under(cConfig, "Fixnum", cConfigSetting);
+ cConfigBignum = rb_define_class_under(cConfig, "Bignum", cConfigSetting);
+ cConfigFloat = rb_define_class_under(cConfig, "Float", cConfigSetting);
+ cConfigBoolean = rb_define_class_under(cConfig, "Boolean", cConfigSetting);
+ cConfigString = rb_define_class_under(cConfig, "String", cConfigSetting);
+
+ cConfigAggregate = rb_define_class_under(cConfig, "Aggregate", cConfigBaseSetting);
+ rb_define_method(cConfigAggregate, "initialize", rbConfigAggregate_initialize, -1);
+ rb_define_method(cConfigAggregate, "size", rbConfigAggregate_size, 0);
+ rb_define_method(cConfigAggregate, "get", rbConfigAggregate_get, 1);
+ rb_define_method(cConfigAggregate, "[]", rbConfigAggregate_get, 1);
+ rb_define_method(cConfigAggregate, "delete", rbConfigAggregate_delete, 1);
+
+ cConfigGroup = rb_define_class_under(cConfig, "Group", cConfigAggregate);
+ rb_define_method(cConfigGroup, "append", rbConfigGroup_append, 2);
+ cConfigArray = rb_define_class_under(cConfig, "Array", cConfigAggregate);
+ rb_define_method(cConfigArray, "append", rbConfigAggregate_append, 1);
+ rb_define_method(cConfigArray, "<<", rbConfigAggregate_append, 1);
+ cConfigList = rb_define_class_under(cConfig, "List", cConfigAggregate);
+ rb_define_method(cConfigList, "append", rbConfigAggregate_append, 1);
+ rb_define_method(cConfigList, "<<", rbConfigAggregate_append, 1);
+
+ aConfigScalars = rb_ary_new3(5, cConfigFixnum, cConfigBignum, cConfigFloat, cConfigBoolean, cConfigString);
+ aConfigAggregates = rb_ary_new3(3, cConfigGroup, cConfigArray, cConfigList);
+ aConfigSettings = rb_ary_plus(aConfigScalars, aConfigAggregates);
+
+ rb_define_const(cConfig, "SCALARS", aConfigScalars);
+ rb_define_const(cConfig, "AGGREGATES", aConfigAggregates);
+ rb_define_const(cConfig, "SETTINGS", aConfigSettings);
+
+ char* settingNameRegexp = "^[A-Za-z*][A-Za-z\\-_*]*$";
+ rSettingNameRegexp = rb_reg_new(settingNameRegexp, strlen(settingNameRegexp), 0);
+
+ eConfigParseError = rb_define_class("ConfigParseError", rb_eException);
+ eSettingNotFoundError = rb_define_class("SettingNotFoundError", rb_eException);
+ eSettingFormatError = rb_define_class("SettingFormatError", rb_eException);
+ eSettingNameError = rb_define_class("SettingNameError", rb_eException);
+}
diff --git a/contrib/ls-config/LICENSE b/contrib/ls-config/LICENSE
new file mode 100644
index 0000000..85c08c5
--- /dev/null
+++ b/contrib/ls-config/LICENSE
@@ -0,0 +1,339 @@
+GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ Simple program to use libconfig9 configuration files in bash scripts
+ Copyright (C) 2013 lucas-net-pl
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ {signature of Ty Coon}, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/contrib/ls-config/README.md b/contrib/ls-config/README.md
new file mode 100644
index 0000000..3f08515
--- /dev/null
+++ b/contrib/ls-config/README.md
@@ -0,0 +1,21 @@
+ls-config
+=========
+
+Simple program to use libconfig9 configuration files in bash scripts
+
+You can use libconfig9 files directly by invoking ls-config, or in bash scripts
+by sourcing lslib-core and then using simple cfg_* functions. In this case
+You must set LS_EXEC to 1 before sourcing lslib-core
+
+Existing error codes available in: doc/ folder.
+
+Sample usage available in: sample/ folder.
+
+Languages:
+- english
+- polish
+
+We need some help to build packaging for different systems, and with translations
+to other languages.
+
+Full changelog available in doc/changelog.txt
diff --git a/contrib/ls-config/debian/README b/contrib/ls-config/debian/README
new file mode 100644
index 0000000..6b2318f
--- /dev/null
+++ b/contrib/ls-config/debian/README
@@ -0,0 +1,9 @@
+The Debian Package ls-config
+----------------------------
+
+This package allow to use libconfig9 style configuration files
+in bash scripts
+
+Comments regarding the Package
+
+ -- Łukasz A. Grabowski <www@lucas.net.pl> Fri, 11 Oct 2013 21:07:07 +0200
diff --git a/contrib/ls-config/debian/changelog b/contrib/ls-config/debian/changelog
new file mode 100644
index 0000000..051f81b
--- /dev/null
+++ b/contrib/ls-config/debian/changelog
@@ -0,0 +1,5 @@
+ls-config (1.0.3) stable; urgency=low
+
+ * Initial Release.
+
+ -- Łukasz A. Grabowski <www@lucas.net.pl> Fri, 11 Oct 2013 21:07:07 +0200
diff --git a/contrib/ls-config/debian/compat b/contrib/ls-config/debian/compat
new file mode 100644
index 0000000..45a4fb7
--- /dev/null
+++ b/contrib/ls-config/debian/compat
@@ -0,0 +1 @@
+8
diff --git a/contrib/ls-config/debian/control b/contrib/ls-config/debian/control
new file mode 100644
index 0000000..76b3a3c
--- /dev/null
+++ b/contrib/ls-config/debian/control
@@ -0,0 +1,17 @@
+Source: ls-config
+Section: main
+Priority: standard
+Maintainer: Łukasz A. Grabowski <www@lucas.net.pl>
+Build-Depends: debhelper (>= 8.0.0), libconfig9
+Standards-Version: 3.9.3
+Homepage: http://www.lucas.net.pl
+Vcs-Git: https://github.com/lucas-net-pl/ls-config.git
+Vcs-Browser: https://github.com/lucas-net-pl/ls-config
+
+Package: ls-config
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: Simple program allo use libconfig style conf in bash
+ This software allo to use libconfig9 style configuration files
+ in bash scripts by invoke this soft. It contain bash library too,
+ witch easying this job.
diff --git a/contrib/ls-config/debian/copyright b/contrib/ls-config/debian/copyright
new file mode 100644
index 0000000..d0d8adf
--- /dev/null
+++ b/contrib/ls-config/debian/copyright
@@ -0,0 +1,33 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: ls-config
+Source: https://github.com/lucas-net-pl/ls-config
+
+Files: *
+Copyright: 2013 Łukasz A. Grabowski <www@lucas.net.pl>
+License: GPL-2.0+
+
+Files: debian/*
+Copyright: 2013 Łukasz A. Grabowski <www@lucas.net.pl>
+License: GPL-2.0+
+
+License: GPL-2.0+
+ This package is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ .
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>
+ .
+ On Debian systems, the complete text of the GNU General
+ Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
+
+# Please also look if there are files or directories which have a
+# different copyright/license attached and list them here.
+# Please avoid to pick license terms that are more restrictive than the
+# packaged work, as it may make Debian's contributions unacceptable upstream.
diff --git a/contrib/ls-config/debian/files b/contrib/ls-config/debian/files
new file mode 100644
index 0000000..1d67630
--- /dev/null
+++ b/contrib/ls-config/debian/files
@@ -0,0 +1 @@
+ls-config_1.0.3_i386.deb main standard
diff --git a/contrib/ls-config/debian/ls-config.1 b/contrib/ls-config/debian/ls-config.1
new file mode 100644
index 0000000..d5a404a
--- /dev/null
+++ b/contrib/ls-config/debian/ls-config.1
@@ -0,0 +1,103 @@
+.\"Created with GNOME Manpages Editor
+.\"https://github.com/lucas-net-pl/ls-config
+
+.\"Replace <program> with the program name, x with the Section Number
+.TH ls-config x "1" "" "Linux User's Manual"
+
+.SH NAME
+ls-config \- program to use libconfig9 configuration files in bash scripts
+
+..SH SYNOPSIS
+.B ls-config
+[\fB\-f\fR \fIFILE\fR]
+.RI [ options ]
+.br
+
+.SH DESCRIPTION
+You can use libcongig9 files directly invoking ls-config.
+
+Remember to call ls-config always with -f parameter,
+wich give ls-config inormation wich config file use.
+
+Then this program operate in three based modes:
+-g (get) for reading values (default)
+-s (set) for store values
+-h (help) for display help message
+both parameter (-g and -s) nedd to give it variable path
+(internal configuration variable path)
+
+.SH OPTIONS
+.TP
+.BR \-f ", " \-\-file =\fIFILE\fR
+Configuration file to handle.
+.TP
+.BR \-s ", " \-\-set =\fIPATH\fR
+Set configuration variable of given path.
+.TP
+.BR \-d ", " \-\-data =\fIDATA\fR
+Configuration variable value (only with -s)
+.TP
+.BR \-p ", " \-\-type =\fITYPE\fR
+Configuration value type
+.TP
+.BR \-g ", " \-\-get =\fIPATH\fR
+Get configuration variable of given path.
+.TP
+.BR \-n ", " \-\-names
+Printout variables names.
+.TP
+.BR \-t ", " \-\-types
+ Printout variables types.
+.TP
+.BR \-v ", " \-\-values
+Printout variables values.
+.TP
+.BR \-i ", " \-\-indexes
+Printout variables indexes.
+.TP
+.BR \-c ", " \-\-count
+Printout elements count (only: array, list, group).
+.TP
+.BR \-b ", " \-\-bool\-string
+Printout boolean variables as text.
+.TP
+.BR \-q ", " \-\-quiet
+ Quiet output to use in scripts.
+.TP
+.BR \-h ", " \-\-help
+Print this help message.
+.TP
+Variable \fITYPE\fRs:
+ group - variables group,
+ array - array of variables,
+ list - list of variables,
+ int - integer number,
+ int64 - 64bit integer number,
+ float - float point number,
+ bool - boolean value,
+ string - character string.
+
+.SH NOTES
+
+Exiting eerror codes:
+
+ 0 - exit with no error
+ 1 - Cen't access witch right mode (read or write) configuration file.
+ 2 - (not used),
+ 3 - Variable of given path not found (path not found).
+ 4 - Variable path not given.
+ 5 - Can't remove root element (cused if someone try to unset it)
+ 6 - Can't find parent element
+ 7 - Variable unset failed.
+ 8 - Configuration file write failed.
+ 9 - Variable value not given.
+ 10 - Inconsistent value type (caused if set exisitng variablen and give type another then saved).
+ 11 - Variable set failed.
+ 12 - Incorrect data format.
+ 13 - Variable type not given (in som cases tu set variable, giving his type are necesery).
+ 14 - Inlegal data type (caused if user give type thet not known for libconfig9).
+ 15 - Bad name of variable (curently chcecking only if enpty stringa are given).
+ 16 - Inavlid configuration variable path.
+ 17 - New named configuration variable can be added only to group element.
+ 18 - Prohibited data type (caused when use type then connot be use in given case).
+
diff --git a/contrib/ls-config/debian/ls-config.debhelper.log b/contrib/ls-config/debian/ls-config.debhelper.log
new file mode 100644
index 0000000..ce685bc
--- /dev/null
+++ b/contrib/ls-config/debian/ls-config.debhelper.log
@@ -0,0 +1,48 @@
+dh_auto_configure
+dh_auto_build
+dh_auto_test
+dh_prep
+dh_installdirs
+dh_auto_install
+dh_install
+dh_installdocs
+dh_installchangelogs
+dh_installexamples
+dh_installman
+dh_installcatalogs
+dh_installcron
+dh_installdebconf
+dh_installemacsen
+dh_installifupdown
+dh_installinfo
+dh_pysupport
+dh_installinit
+dh_installmenu
+dh_installmime
+dh_installmodules
+dh_installlogcheck
+dh_installlogrotate
+dh_installpam
+dh_installppp
+dh_installudev
+dh_installwm
+dh_installxfonts
+dh_installgsettings
+dh_bugfiles
+dh_ucf
+dh_lintian
+dh_gconf
+dh_icons
+dh_perl
+dh_usrlocal
+dh_link
+dh_compress
+dh_fixperms
+dh_strip
+dh_makeshlibs
+dh_shlibdeps
+dh_installdeb
+dh_gencontrol
+dh_md5sums
+dh_builddeb
+dh_builddeb
diff --git a/contrib/ls-config/debian/ls-config.install b/contrib/ls-config/debian/ls-config.install
new file mode 100644
index 0000000..fe2d035
--- /dev/null
+++ b/contrib/ls-config/debian/ls-config.install
@@ -0,0 +1,6 @@
+ls-config usr/share/ls/lib/
+lslib-core usr/share/ls/lib/
+src/locale/* usr/share/locale/
+doc/* usr/share/doc/ls-config/
+sample/* usr/share/doc/ls-config/sample/
+README.md usr/share/doc/ls-config/README.txt \ No newline at end of file
diff --git a/contrib/ls-config/debian/ls-config.substvars b/contrib/ls-config/debian/ls-config.substvars
new file mode 100644
index 0000000..abd3ebe
--- /dev/null
+++ b/contrib/ls-config/debian/ls-config.substvars
@@ -0,0 +1 @@
+misc:Depends=
diff --git a/contrib/ls-config/debian/ls-config/DEBIAN/control b/contrib/ls-config/debian/ls-config/DEBIAN/control
new file mode 100644
index 0000000..a931f92
--- /dev/null
+++ b/contrib/ls-config/debian/ls-config/DEBIAN/control
@@ -0,0 +1,12 @@
+Package: ls-config
+Version: 1.0.3
+Architecture: i386
+Maintainer: Łukasz A. Grabowski <www@lucas.net.pl>
+Installed-Size: 27
+Section: unknown
+Priority: extra
+Homepage: http://www.lucas.net.pl
+Description: Simple program allo use libconfig style conf in bash
+ This software allo to use libconfig9 style configuration files
+ in bash scripts by invoke this soft. It contain bash library too,
+ witch easying this job.
diff --git a/contrib/ls-config/debian/ls-config/DEBIAN/md5sums b/contrib/ls-config/debian/ls-config/DEBIAN/md5sums
new file mode 100644
index 0000000..9362fd5
--- /dev/null
+++ b/contrib/ls-config/debian/ls-config/DEBIAN/md5sums
@@ -0,0 +1,2 @@
+17ee68fa6924ad7f69ca91bee808281b usr/share/doc/ls-config/changelog.gz
+962fc567b180716388e62add5c6bfae5 usr/share/doc/ls-config/copyright
diff --git a/contrib/ls-config/debian/ls-config/DEBIAN/postinst b/contrib/ls-config/debian/ls-config/DEBIAN/postinst
new file mode 100755
index 0000000..9b2ee7b
--- /dev/null
+++ b/contrib/ls-config/debian/ls-config/DEBIAN/postinst
@@ -0,0 +1,39 @@
+#!/bin/sh
+# postinst script for ls-config
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <postinst> `configure' <most-recently-configured-version>
+# * <old-postinst> `abort-upgrade' <new version>
+# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+# <new-version>
+# * <postinst> `abort-remove'
+# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+# <failed-install-package> <version> `removing'
+# <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ configure)
+ ;;
+
+ abort-upgrade|abort-remove|abort-deconfigure)
+ ;;
+
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+
+
+exit 0
diff --git a/contrib/ls-config/debian/ls-config/usr/share/doc/ls-config/changelog.gz b/contrib/ls-config/debian/ls-config/usr/share/doc/ls-config/changelog.gz
new file mode 100644
index 0000000..4a16b74
--- /dev/null
+++ b/contrib/ls-config/debian/ls-config/usr/share/doc/ls-config/changelog.gz
Binary files differ
diff --git a/contrib/ls-config/debian/ls-config/usr/share/doc/ls-config/copyright b/contrib/ls-config/debian/ls-config/usr/share/doc/ls-config/copyright
new file mode 100644
index 0000000..d0d8adf
--- /dev/null
+++ b/contrib/ls-config/debian/ls-config/usr/share/doc/ls-config/copyright
@@ -0,0 +1,33 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: ls-config
+Source: https://github.com/lucas-net-pl/ls-config
+
+Files: *
+Copyright: 2013 Łukasz A. Grabowski <www@lucas.net.pl>
+License: GPL-2.0+
+
+Files: debian/*
+Copyright: 2013 Łukasz A. Grabowski <www@lucas.net.pl>
+License: GPL-2.0+
+
+License: GPL-2.0+
+ This package is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ .
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>
+ .
+ On Debian systems, the complete text of the GNU General
+ Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
+
+# Please also look if there are files or directories which have a
+# different copyright/license attached and list them here.
+# Please avoid to pick license terms that are more restrictive than the
+# packaged work, as it may make Debian's contributions unacceptable upstream.
diff --git a/contrib/ls-config/debian/manpages b/contrib/ls-config/debian/manpages
new file mode 100644
index 0000000..6672d62
--- /dev/null
+++ b/contrib/ls-config/debian/manpages
@@ -0,0 +1 @@
+debian/ls-config.1
diff --git a/contrib/ls-config/debian/postinst b/contrib/ls-config/debian/postinst
new file mode 100644
index 0000000..ba5d0df
--- /dev/null
+++ b/contrib/ls-config/debian/postinst
@@ -0,0 +1,68 @@
+#!/bin/sh
+# postinst script for ls-config
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <postinst> `configure' <most-recently-configured-version>
+# * <old-postinst> `abort-upgrade' <new version>
+# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+# <new-version>
+# * <postinst> `abort-remove'
+# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+# <failed-install-package> <version> `removing'
+# <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+config_path() {
+ local CHK="$(echo ":$PATH:" | grep ":/usr/share/ls/lib:")"
+ if [ "$CHK" != "" ]; then
+ return 0;
+ fi;
+ local BIFS="$IFS"
+ IFS=$'\n'
+ local PR="$(</etc/profile)"
+ local NF=""
+ local L
+ for L in $PR
+ do
+ CHK="$(echo "$L" | sed -E 's/^([\ \t]+)//g')"
+ CHK="${CHK:0:5}"
+ NF="$NF$IFS$L"
+ if [ "$CHK" = "PATH=" ]; then
+ NF="$NF$IFS#Configuration path for ls scripting"
+ NF="$NF$IFS"
+ NF="${NF}PATH=\"\$PATH:/usr/share/ls/lib\"$IFS"
+ fi;
+ done
+ NF="$NF$IFS"
+ IFS="$BIFS"
+ echo "$NF" > /etc/profile
+}
+
+case "$1" in
+ configure)
+ if [ ! -e "/etc/ls" ]; then
+ mkdir -p "/etc/ls/"
+ config_path
+ fi;
+ ;;
+
+ abort-upgrade|abort-remove|abort-deconfigure)
+ ;;
+
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/contrib/ls-config/debian/rules b/contrib/ls-config/debian/rules
new file mode 100755
index 0000000..b760bee
--- /dev/null
+++ b/contrib/ls-config/debian/rules
@@ -0,0 +1,13 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+%:
+ dh $@
diff --git a/contrib/ls-config/debian/source/format b/contrib/ls-config/debian/source/format
new file mode 100644
index 0000000..89ae9db
--- /dev/null
+++ b/contrib/ls-config/debian/source/format
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/contrib/ls-config/doc/bash.api.txt b/contrib/ls-config/doc/bash.api.txt
new file mode 100644
index 0000000..762f600
--- /dev/null
+++ b/contrib/ls-config/doc/bash.api.txt
@@ -0,0 +1,75 @@
+Instalation:
+------------
+
+First of all, You must place ls-config binary and lslib-core bash
+script in the same directory (default: /usr/share/ls/lib)
+
+Next in lslib-core header chcange configuration:
+PACD tu point to parent directory of paced files
+then LIBD must point relative (tu PACD) to directory
+whrere script placed
+
+Usage:
+------
+
+In You bash script, first of all define LS_EXEC variable,
+and set his value to 1. (It protect lslib-core) to run
+standalone
+
+Next, source library:
+source /usr/share/ls/lib/lslib-core
+
+After thet You can use following function:
+
+Functions:
+----------
+
+cfg_g $PATH - this echo variable value of given PATH
+ and return error code
+cfg_t $PATH - this echo variable type of given PATH
+ and return error code
+cfg_c $PATH - this echo cout of variable elements
+ and return error code
+cfg_s $PATH $DATA [$TYPE] - this set variable of given PATH or create new
+ variable valuse are set to DATA, and if this
+ create new variable, variable will be type TYPE
+cfg_u $PATH - this unset (remove) variable of given PATH
+ and return error code
+cfg_f_g $FILE $PATH - same as cfg_g, but operate on given FILE
+cfg_f_t $FILE $PATH - same as cfg_t, but operate on given FILE
+cfg_f_c $FILE $PATH - same as cfg_c, but operate on given FILE
+cfg_f_s $FILE $PATH $DATA [$TYPE] - same as cfg_s, but operate on given FILE
+cfg_f_u $FILE $PATH - same as cfg_u, but operate on given FILE
+
+Configuration files:
+--------------------
+
+By default configuration file are placed in /etc/ls/
+with the same name as script file name
+(used in cfg_g, cfg_t, cfg_c, cfg_s, cfg_u)
+
+But if You need, You can use any location of configuration file
+by using cfg_f_* functions, giving configuration file location as
+first argument
+
+Detailed configuration file shema are publicated on:
+http://www.hyperrealm.com/libconfig/
+And his gramar on:
+http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-Files
+
+there are only short describe:
+configuration = setting-list | empty
+setting-list = setting | setting-list setting
+setting = name (":" | "=") value (";" | "," | empty)
+value = scalar-value | array | list | group
+value-list = value | value-list "," value
+scalar-value = boolean | integer | integer64 | hex | hex64 | float | string
+scalar-value-list = scalar-value | scalar-value-list "," scalar-value
+array = "[" (scalar-value-list | empty) "]"
+list = "(" (value-list | empty) ")"
+group = "{" (setting-list | empty) "}"
+empty =
+
+smaple configuration file and script are available on sample/ directory
+config - samble configuration file
+script - sample script, then read info variable from config file
diff --git a/contrib/ls-config/doc/bin.api.txt b/contrib/ls-config/doc/bin.api.txt
new file mode 100644
index 0000000..55baaf2
--- /dev/null
+++ b/contrib/ls-config/doc/bin.api.txt
@@ -0,0 +1,75 @@
+Instalation:
+------------
+
+First place somewhere ls-config binary, or make it from source
+
+Then if You woud like use it with national translation, then You muas build
+it form source and then copy *.mo files according to You system
+
+Usage:
+------
+
+Remember to call ls-config always with -f parameter,
+wich give ls-config inormation wich config file use.
+
+Then this program operate in three based modes:
+-g (get) for reading values (default)
+-s (set) for store values
+-h (help) for display help message
+both parameter (-g and -s) nedd to give it variable path
+(internal configuration variable path)
+
+for exapmle read info value from config file:
+ls-config -f config -g info
+
+Then You can set this value to another
+ls-config -f config -s info -d "Somethint to write"
+
+But when You wand to addn new configutation variable you must
+specify his type:
+ls-config -f config -s someint -d 10 -p int
+
+You can remove (unset) variable too. This is subfunstion of setting:
+ls-config -f config -s someint -u
+
+When reading You cent use following flag:
+-v - read only variable valut
+-t - read only variable type
+-c - read only variable element count (sense only in types: array, list, group)
+-i - read only variable index (sense only in type: array, list)
+-n - read only variable name
+
+and sometimes usable
+-q - to wori in quiet mode usable in scripts.
+
+For example to read variable somevar type, where variable in group foo:
+ls-config -f config -g "foo.somevar" -t
+
+For detailed list of parametera (long options available too) run ls-config
+in help mode:
+ls-config -h
+
+Configuraiton files:
+--------------------
+
+Detailed configuration file shema are publicated on:
+http://www.hyperrealm.com/libconfig/
+And his gramar on:
+http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-Files
+
+there are only short describe:
+configuration = setting-list | empty
+setting-list = setting | setting-list setting
+setting = name (":" | "=") value (";" | "," | empty)
+value = scalar-value | array | list | group
+value-list = value | value-list "," value
+scalar-value = boolean | integer | integer64 | hex | hex64 | float | string
+scalar-value-list = scalar-value | scalar-value-list "," scalar-value
+array = "[" (scalar-value-list | empty) "]"
+list = "(" (value-list | empty) ")"
+group = "{" (setting-list | empty) "}"
+empty =
+
+smaple configuration file and script are available on sample/ directory
+config - samble configuration file
+script - sample script, then read info variable from config file
diff --git a/contrib/ls-config/doc/changlog.txt b/contrib/ls-config/doc/changlog.txt
new file mode 100644
index 0000000..937e737
--- /dev/null
+++ b/contrib/ls-config/doc/changlog.txt
@@ -0,0 +1,26 @@
+Version 1.0.3
+-------------
+
+Fully commented code,
+Startin with documentation
+
+bugfixes
+- fix some badly returned exit codes
+- remove duplicate error messages
+- l10n textdomain corrected
+- extend sample configuration file to be full representative
+- some corrections in sample script (adding directly usaga)
+
+new features
+- adding documentation files (api)
+
+Version 1.0.1
+-------------
+
+Internaly translated tu englich
+
+
+Verison 1.0.0
+-------------
+
+First publicated and working version \ No newline at end of file
diff --git a/contrib/ls-config/doc/errorcodes.txt b/contrib/ls-config/doc/errorcodes.txt
new file mode 100644
index 0000000..303ef58
--- /dev/null
+++ b/contrib/ls-config/doc/errorcodes.txt
@@ -0,0 +1,20 @@
+ 0 - exit with no error
+ 1 - Cen't access witch right mode (read or write) configuration file.
+ 2 - (not used),
+ 3 - Variable of given path not found (path not found).
+ 4 - Variable path not given.
+ 5 - Can't remove root element (cused if someone try to unset it)
+ 6 - Can't find parent element
+ 7 - Variable unset failed.
+ 8 - Configuration file write failed.
+ 9 - Variable value not given.
+10 - Inconsistent value type (caused if set exisitng variablen and give type another then saved).
+11 - Variable set failed.
+12 - Incorrect data format.
+13 - Variable type not given (in som cases tu set variable, giving his type are necesery).
+14 - Inlegal data type (caused if user give type thet not known for libconfig9).
+15 - Bad name of variable (curently chcecking only if enpty stringa are given).
+16 - Inavlid configuration variable path.
+17 - New named configuration variable can be added only to group element.
+18 - Prohibited data type (caused when use type then connot be use in given case).
+
diff --git a/contrib/ls-config/lslib-core b/contrib/ls-config/lslib-core
new file mode 100644
index 0000000..6ef21fa
--- /dev/null
+++ b/contrib/ls-config/lslib-core
@@ -0,0 +1,199 @@
+#!/bin/bash
+
+#title :lslib-core
+#description :core library for LS scripts
+#author :Łukasz A. Grabowski <www@lucas.net.pl>
+#date :20130928
+#version :1.0.3
+#notes :
+#bash_version :4.2.37(1)-release
+#copywrite :Copyright (C) 2013 Łukasz A. Grabowski
+#license :This program is free software: you can redistribute
+# :it and/or modify it under the terms of the GNU General
+# :Public License as published by the Free Software
+# :Foundation, either version 2 of the License or
+# :any later version.
+# :
+# :This program is distributed in the hope that it will
+# :be useful, but WITHOUT ANY WARRANTY; without even the
+# :implied warranty of MERCHANTABILITY or FITNESS FOR
+# :A PARTICULAR PURPOSE. See the GNU General Public
+# :License for more details.
+# :
+# :You should have received a copy of the GNU General
+# :Public License along with this program. If not, see
+# :http://www.gnu.org/licenses/.
+#=======================================================================
+
+#################
+# Configuration #
+#################
+
+PACD="/usr/share/ls" #main directory for LS scripts
+LIBD="lib" #library dir for LS scripts
+
+#######################
+# Predefined and init #
+#######################
+
+if [ -z "$LS_EXEC" ]; then
+ echo "This script are only for inclusion in LS packet scripts. Don't use it itself." 1>&2
+ exit 1
+fi
+
+##############################
+# configuration read / write #
+##############################
+
+#get configuration
+# cfg_g PATH
+cfg_g() {
+ local PTH=""
+ if [ $# -gt 0 ]; then
+ local PTH="$1";
+ fi;
+ local DAT
+ local ERR
+ DAT="$($PACD/$LIBD/ls-config -f "$CFGFN" -qv --get="$PTH")"
+ ERR=$?
+ echo "$DAT"
+ return $ERR
+}
+
+#get configuration type
+# cfg_t PATH
+cfg_t() {
+ local PTH=""
+ if [ $# -gt 0 ]; then
+ local PTH="$1";
+ fi;
+ local DAT
+ local ERR
+ DAT="$($PACD/$LIBD/ls-config -f "$CFGFN" -qt --get="$PTH")"
+ ERR=$?
+ echo "$DAT"
+ return $ERR
+}
+
+#get configuration items count
+# cfg_c PATH
+cfg_c() {
+ local PTH=""
+ if [ $# -gt 0 ]; then
+ local PTH="$1";
+ fi;
+ local DAT
+ local ERR
+ DAT="$($PACD/$LIBD/ls-config -f "$CFGFN" -qc --get="$PTH")"
+ ERR=$?
+ echo "$DAT"
+ return $ERR
+}
+
+#set configuration
+# cfg_s PATH DATA [TYPE=string]
+cfg_s() {
+ local PTH=""
+ if [ $# -gt 0 ]; then
+ local PTH="$1";
+ fi;
+ local DATA=""
+ if [ $# -gt 1 ]; then
+ local DATA="$2";
+ fi;
+ local TYPE="string"
+ if [ $# -gt 2 ]; then
+ local TYPE="$3";
+ fi;
+ local DAT
+ local ERR
+ DAT="$($PACD/$LIBD/ls-config -f "$CFGFN" -q --set="$PTH" --data="$DATA" --type="$TYPE")"
+ ERR=$?
+ echo "$DAT"
+ return $ERR
+}
+
+#remove configuration
+# cfg_u PATH
+cfg_u() {
+ local PTH=""
+ if [ $# -gt 0 ]; then
+ local PTH="$1";
+ fi;
+ local DAT
+ local ERR
+ DAT="$($PACD/$LIBD/ls-config -f "$CFGFN" -q --set="$PTH" --unset)"
+ ERR=$?
+ return $ERR
+}
+
+cfg_f_g() {
+ local BCFN="$CFGFN"
+ local EX
+ CFGFN="$1"
+ shift
+ cfg_g "$@"
+ EX=$?
+ CFGFN="$BCFN"
+ return $EX
+}
+
+cfg_f_t() {
+ local BCFN="$CFGFN"
+ local EX
+ CFGFN="$1"
+ shift
+ cfg_t "$@"
+ EX=$?
+ CFGFN="$BCFN"
+ return $EX
+}
+
+cfg_f_c() {
+ local BCFN="$CFGFN"
+ local EX
+ CFGFN="$1"
+ shift
+ cfg_c "$@"
+ EX=$?
+ CFGFN="$BCFN"
+ return $EX
+}
+
+cfg_f_s() {
+ local BCFN="$CFGFN"
+ local EX
+ CFGFN="$1"
+ shift
+ cfg_s "$@"
+ EX=$?
+ CFGFN="$BCFN"
+ return $EX
+}
+
+cfg_f_u() {
+ local BCFN="$CFGFN"
+ local EX
+ CFGFN="$1"
+ shift
+ cfg_u "$@"
+ EX=$?
+ CFGFN="$BCFN"
+ return $EX
+}
+
+
+######################
+# base variable init #
+######################
+
+#package name
+SCRFN="$(basename "$0")"
+
+#configuriation directory and file
+if [ -z "$CFGD" ]; then
+ CFGD="/etc/ls"
+fi;
+CFGFN="$CFGD/$SCRFN"
+
+
diff --git a/contrib/ls-config/makefile b/contrib/ls-config/makefile
new file mode 100644
index 0000000..7f20267
--- /dev/null
+++ b/contrib/ls-config/makefile
@@ -0,0 +1,7 @@
+all:
+ make -C src
+
+clean:
+ make -C src clean
+
+
diff --git a/contrib/ls-config/sample/config b/contrib/ls-config/sample/config
new file mode 100644
index 0000000..abe7dda
--- /dev/null
+++ b/contrib/ls-config/sample/config
@@ -0,0 +1,23 @@
+grp :
+{
+ value = 10;
+ name = "sample";
+};
+lst = (
+ {
+ name = "sample";
+ },
+ {
+ comment = "sample secong group";
+ val = 10.2;
+ } );
+info = "more info about types in libconfig9 documentations";
+arr = [ 10, 20, 30 ];
+integer = 100;
+longint = 100L;
+flo = 100.01;
+boolean :
+{
+ truevalue = true;
+ falsevalue = false;
+};
diff --git a/contrib/ls-config/sample/script b/contrib/ls-config/sample/script
new file mode 100755
index 0000000..70fe124
--- /dev/null
+++ b/contrib/ls-config/sample/script
@@ -0,0 +1,68 @@
+#!/bin/bash
+
+#title :script
+#description :this script only demonstrate usage of ls-config
+#author :Łukasz A. Grabowski <www@lucas.net.pl>
+#date :20130928
+#version :1.0.3
+#notes :This only read one value from configuration file
+# :this script MUST be run from subdirectory of dir
+# :where ls-config (bin) and lslib-core are stored
+# :to place script in other places You must reconfigure paths
+#bash_version :4.2.37(1)-release
+#copywrite :Copyright (C) 2013 Łukasz A. Grabowski
+#license :This program is free software: you can redistribute
+# :it and/or modify it under the terms of the GNU General
+# :Public License as published by the Free Software
+# :Foundation, either version 2 of the License or
+# :any later version.
+# :
+# :This program is distributed in the hope that it will
+# :be useful, but WITHOUT ANY WARRANTY; without even the
+# :implied warranty of MERCHANTABILITY or FITNESS FOR
+# :A PARTICULAR PURPOSE. See the GNU General Public
+# :License for more details.
+# :
+# :You should have received a copy of the GNU General
+# :Public License along with this program. If not, see
+# :http://www.gnu.org/licenses/.
+#=======================================================================
+
+
+#set app flag
+LS_EXEC=1
+
+#set configuration directory
+CFGD="./"
+
+#source bash library to manipulate config
+source ../lslib-core
+
+#path direcrories onlny for this sample
+PACD="../"
+LIBD=""
+#end path
+
+#read data from configuration file
+TEST=$(cfg_f_g "config" "info")
+ERR="$?"
+
+#show data
+echo "Info value: $TEST"
+echo "Reading error: $ERR"
+
+#show other method of reading value:
+
+#output space and info
+echo ""
+echo "Reading using binary:"
+
+#read data from configuration file
+TEST=$(${PACD}ls-config -f config --get="info" -vq)
+ERR="$?"
+
+#show data
+echo "Info value: $TEST"
+echo "Reading error: $ERR"
+
+exit 0;
diff --git a/contrib/ls-config/src/ls-config.c b/contrib/ls-config/src/ls-config.c
new file mode 100644
index 0000000..4db8966
--- /dev/null
+++ b/contrib/ls-config/src/ls-config.c
@@ -0,0 +1,1345 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <locale.h>
+#include <libintl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <math.h>
+#include <libconfig.h>
+
+#define PACKAGE "LS bash config"
+#define VERSION "1.0.3"
+
+// global flags
+struct flags {
+ int quiet; //quiet output
+ int names; //set for printout config variables names
+ int types; //set for printout config variables types
+ int values; //set for printout config variables values
+ int indexes; //set for printout config variables indexes
+ int counter; //set for printout config varibales counting (for grout, list, array. in other cases it return 1)
+ int unset; //unset valriable
+ int boolstring; //set for output bool variable (0|1) as test (false|true)
+ int mode; //1 - for setting variable, 0 - for get hist data
+ int error; //error status handling
+};
+
+//take valur from input and comvert it to int
+//TODO: Read long too
+int getNumber() {
+ char buf[1000];
+ int test,val;
+ unsigned int inp;
+ fgets(buf, sizeof buf, stdin);
+ test = sscanf(buf, "%u", &inp);
+ val = (int) inp;
+ if(val < 0) val *= -1;
+ if(test > 0) return val;
+ return (int) 0;
+}
+
+//printout help messsage
+void printHelp() {
+ printf(gettext("Configuration file handling\n"));
+ printf("\n");
+ printf(gettext("Usage: ls-config [OPTION]\n"));
+ printf(gettext("Reading and writening data from configuration files\n"));
+ printf(gettext("in libconfig9 format.\n"));
+ printf("\n");
+ printf(gettext("CAUTION: using without given config file are cause error!\n"));
+ printf("\n");
+ printf(gettext("Available options:\n"));
+ printf(gettext(" -f, --file=FILE Configuration file to handle.\n"));
+ printf("\n");
+ printf(gettext(" -s, --set=PATH Set configuration variable of given path.\n"));
+ printf(gettext(" -d, --data=DATA Configuration variable value (only with -s)\n"));
+ printf(gettext(" -p, --type=TYPE Configuration value type\n"));
+ printf("\n");
+ printf(gettext(" -g, --get=PATH Get configuration variable of given path.\n"));
+ printf(gettext(" -n, --names Printout variables names.\n"));
+ printf(gettext(" -t, --types Printout variables types.\n"));
+ printf(gettext(" -v, --values Printout variables values.\n"));
+ printf(gettext(" -i, --indexes Printout variables indexes.\n"));
+ printf(gettext(" -c, --count Printout elements count (only: array, list, group).\n"));
+ printf(gettext(" -b, --bool-string Printout boolean variables as text.\n"));
+ printf("\n");
+ printf(gettext(" -q, --quiet Quiet output to use in scripts.\n"));
+ printf(gettext(" -h, --help Print this help message.\n"));
+ printf("\n");
+ printf(gettext("TYPE: Variable types:\n"));
+ printf(gettext(" group - variables group,\n"));
+ printf(gettext(" array - array of variables,\n"));
+ printf(gettext(" list - list of variables,\n"));
+ printf(gettext(" int - integer number,\n"));
+ printf(gettext(" int64 - 64bit integer number,\n"));
+ printf(gettext(" float - float point number,\n"));
+ printf(gettext(" bool - boolean value,\n"));
+ printf(gettext(" string - character string.\n"));
+ printf("\n");
+ printf("(c) 2013 by LucaS web sutio - http://www.lucas.net.pl\n");
+ printf("Author: Łukasz A. Grabowski\n");
+ printf(gettext("Licence: "));
+ printf("GPL v2.\n");
+ exit(0);
+};
+
+//set configuration int value
+int set_config_int(config_setting_t *setting, char *dataString, struct flags optflags) {
+ long bufl; //int (long) to get from input data string
+ int buf, scs; //config int, success status
+ char *erp; //error output
+
+ //convert input data to int
+ errno = 0;
+ bufl = strtol(dataString, &erp, 0);
+ if(((errno == ERANGE && (bufl == LONG_MAX || bufl == LONG_MIN)) || (errno != 0 && bufl == 0)) || (erp == dataString) || bufl > INT_MAX || bufl < INT_MIN) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Incorrect data format.\n"));
+ return 12;
+ };
+ buf = (int)bufl;
+
+ //set configuration variable
+ scs = config_setting_set_int(setting, buf);
+ if(scs == CONFIG_FALSE) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ return 0;
+};
+
+//set configuration int64 value
+int set_config_int64(config_setting_t *setting, char *dataString, struct flags optflags) {
+ long bufl; //long to get from input data string
+ int scs; //success status
+ char *erp; //error output
+
+ //convert input data to long
+ errno = 0;
+ bufl = strtol(dataString, &erp, 0);
+ if(((errno == ERANGE && (bufl == LONG_MAX || bufl == LONG_MIN)) || (errno != 0 && bufl == 0)) || (erp == dataString)) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Incorrect data format.\n"));
+ return 12;
+ };
+
+ //set configuration variable
+ scs = config_setting_set_int64(setting, bufl);
+ if(scs == CONFIG_FALSE) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ return 0;
+};
+
+//set configuration float value
+int set_config_float(config_setting_t *setting, char *dataString, struct flags optflags) {
+ double buff; //double (float) to get from input data string
+ int scs; //success status
+ char *erp; //error output
+
+ //convert input data to double
+ errno = 0;
+ buff = strtod(dataString, &erp);
+ if(((errno == ERANGE && (buff == HUGE_VALF || buff == HUGE_VALL)) || (errno != 0 && buff == 0)) || (erp == dataString)) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Incorrect data format.\n"));
+ return 12;
+ }
+
+ //set configuration variable
+ scs = config_setting_set_float(setting, buff);
+ if(scs == CONFIG_FALSE) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ return 0;
+};
+
+//set configuration boolean value
+int set_config_bool(config_setting_t *setting, char *dataString, struct flags optflags) {
+ int scs, buf; //success status, input convert burrer
+
+ //convert input data
+ //chceck both 1/0 and true/false string
+ buf = -1;
+ if(!strcmp(dataString, "1") || !strcmp(dataString, "true") || !strcmp(dataString, "TRUE")) buf = 1;
+ if(!strcmp(dataString, "0") || !strcmp(dataString, "false") || !strcmp(dataString, "FALSE")) buf = 0;
+ if(buf < 0) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Incorrect data format.\n"));
+ return 12;
+ }
+
+ //set configuration variable
+ scs = config_setting_set_bool(setting, buf);
+ if(scs == CONFIG_FALSE) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ return 0;
+};
+
+//configuratnion variable path look like: foo.bar.car
+//this fuction return string giving path to parent element (foo.bar)
+char* path_parent(char *dataPath) {
+ char *str_ptr, *last_ptr, *newpath, *dot="."; //tokenized buffer, last buffer, new parent path, separator
+ newpath = malloc(1);
+ memset(newpath, 0, 1);
+ last_ptr = malloc(1);
+ memset(last_ptr, 0, 1);
+
+ //tokenize string and save last token
+ str_ptr = strtok(dataPath, ".");
+ last_ptr = (char*)realloc(last_ptr, (strlen(str_ptr)+1)*sizeof(char));
+ strcpy(last_ptr, str_ptr);
+
+ //loop overt path to build new path without last element
+ while(str_ptr != NULL) {
+ str_ptr = strtok(NULL, ".");
+ if(str_ptr != NULL) {
+ if(strlen(last_ptr) > 0 ) {
+ newpath = (char*)realloc(newpath, (strlen(newpath)+strlen(last_ptr)+2)*sizeof(char));
+ strcat(newpath, dot);
+ strcat(newpath, last_ptr);
+ };
+ last_ptr = (char*)realloc(last_ptr, (strlen(str_ptr)+1)*sizeof(char));
+ strcpy(last_ptr, str_ptr);
+ } else {
+ last_ptr = (char*)realloc(last_ptr, (1)*sizeof(char));
+ memset(last_ptr, 0, 1);
+ };
+ };
+ free(dataPath);
+
+ //if new path empty thren return null
+ if(strlen(newpath) == 0) {
+ free(newpath);
+ newpath = NULL;
+ };
+ return newpath;
+};
+
+//get element name from configuration variable path
+//e.g.: from foo.bar return bar
+char* path_name(char *dataPath) {
+ char *str_ptr, *name, *tk; //tokenized buffer, element name, copy of dataPath
+ name = malloc(1);
+
+ //make copy of dataPath
+ tk = malloc((strlen(dataPath)+1)*sizeof(char));
+ memset(name, 0, 1);
+ strcpy(tk, dataPath);
+
+ //tokenize dataPath
+ str_ptr = strtok(tk, ".");
+
+ //loop over tokenize pathh to get last element
+ while(str_ptr != NULL) {
+ name = (char*)realloc(name, (strlen(str_ptr)+1)*sizeof(char));
+ strcpy(name, str_ptr);
+ str_ptr = strtok(NULL, ".");
+ };
+ free(tk);
+
+ //if no element name then return null
+ if(strlen(name) == 0) {
+ free(name);
+ name = NULL;
+ };
+ return name;
+};
+
+//set configuration path
+//@return int success
+//@param configFile - name (with path) of configuration fille
+//@param dataPath - path of configuration variable (in config file)
+//@param optflags - global options flags
+//@param dataString - data to store in configuration variable in string format
+//@param dataType - type of variable to save
+int set_config(char *configFile, char *dataPath, struct flags optflags, char *dataString, char *dataType) {
+ config_t cfg; //libcongig configuration handler
+ config_setting_t *setting, *ss; //libconfig element handrer: mant, and subset (uset for multielement types)
+ config_init(&cfg);
+ int scs, dt, dattyp; //sucess statu, data type
+ char *npath; // new variable configuration path path
+
+ //open and read configuration file
+ if(!config_read_file(&cfg, configFile)) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Can't read configuration file.\n"));
+ return 1;
+ };
+
+ //if no data path or data string then cause error
+ if(dataPath == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Conviguration variable path not given.\n"));
+ return 4;
+ };
+ if(dataString == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Configuration variable value not given.\n"));
+ return 9;
+ };
+
+ //find configuration variable of given path
+ setting = config_lookup(&cfg, dataPath);
+ if(setting == NULL) {
+ //if variable of given path not found get element name and partent path,
+ //then try to create it
+ npath = path_name(dataPath);
+ dataPath = path_parent(dataPath);
+ if(dataPath == NULL) {
+ setting = config_root_setting(&cfg);
+ } else {
+ setting = config_lookup(&cfg, dataPath);
+ };
+ if(setting == NULL) {
+ //if parent not exists exit with error
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Inavlid configuration variable path.\n"));
+ return 16;
+ };
+ //chceck type of parent element (named alement can be added only to group element)
+ dt = config_setting_type(setting);
+ if(dt != CONFIG_TYPE_GROUP) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! New named configuration variable can be added only to group element.\n"));
+ return 17;
+ };
+ //check if new element type are given
+ if(dataType == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Configuration variable type not given.\n"));
+ return 13;
+ };
+ //now get type based on his name
+ if(!strcmp(dataType, "int")) {
+ dattyp = CONFIG_TYPE_INT;
+ } else if(!strcmp(dataType, "int64")) {
+ dattyp = CONFIG_TYPE_INT64;
+ } else if(!strcmp(dataType, "float")) {
+ dattyp = CONFIG_TYPE_FLOAT;
+ } else if(!strcmp(dataType, "string")) {
+ dattyp = CONFIG_TYPE_STRING;
+ } else if(!strcmp(dataType, "bool")) {
+ dattyp = CONFIG_TYPE_BOOL;
+ } else if(!strcmp(dataType, "array")) {
+ dattyp = CONFIG_TYPE_ARRAY;
+ } else if(!strcmp(dataType, "list")) {
+ dattyp = CONFIG_TYPE_LIST;
+ } else if(!strcmp(dataType, "group")) {
+ dattyp = CONFIG_TYPE_GROUP;
+ } else {
+ //if given type no mutch eny then cause error and exit
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Inlegal data type.\n"));
+ return 14;
+ };
+ //add new element to configuration file
+ ss = config_setting_add(setting, npath, dattyp);
+ if(ss == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ scs = 0;
+ //and based on new type set his value
+ switch(dattyp) {
+ case CONFIG_TYPE_INT:
+ scs = set_config_int(ss, dataString, optflags);
+ break;
+ case CONFIG_TYPE_INT64:
+ scs = set_config_int64(ss, dataString, optflags);
+ break;
+ case CONFIG_TYPE_FLOAT:
+ scs = set_config_float(ss, dataString, optflags);
+ break;
+ case CONFIG_TYPE_STRING:
+ scs = config_setting_set_string(ss, dataString);
+ if(scs == CONFIG_FALSE) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ scs = 11;
+ } else scs = 0;
+ break;
+ case CONFIG_TYPE_BOOL:
+ scs = set_config_bool(ss, dataString, optflags);
+ break;
+ };
+ if(scs > 0) {
+ //if occurs some error wihe setting variable value exit with error
+ config_destroy(&cfg);
+ return scs;
+ };
+ } else {
+ //but if we found element of given path, try to set his value
+ //first of all determinate type of value
+ dt = config_setting_type(setting);
+ switch(dt) {
+ case CONFIG_TYPE_INT:
+ if(dataType != NULL && strcmp(dataType, "int")) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
+ return 10;
+ };
+ //then set value
+ scs = set_config_int(setting, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ case CONFIG_TYPE_INT64:
+ if(dataType != NULL && strcmp(dataType, "int64")) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
+ return 10;
+ };
+ //then set value
+ scs = set_config_int64(setting, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ case CONFIG_TYPE_FLOAT:
+ if(dataType != NULL && strcmp(dataType, "float")) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
+ return 10;
+ };
+ //then set value
+ scs = set_config_float(setting, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ case CONFIG_TYPE_STRING:
+ if(dataType != NULL && strcmp(dataType, "string")) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
+ return 10;
+ };
+ //then set value
+ scs = config_setting_set_string(setting, dataString);
+ if(scs == CONFIG_FALSE) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ break;
+ case CONFIG_TYPE_BOOL:
+ if(dataType != NULL && strcmp(dataType, "bool")) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
+ return 10;
+ };
+ //then set value
+ scs = set_config_bool(setting, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ case CONFIG_TYPE_ARRAY:
+ //if array are empty we can set alement of any scalar type
+ if(config_setting_length(setting) == 0) {
+ //but we must have his type
+ if(dataType == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Configuration variable type not given.\n"));
+ return 13;
+ };
+ if(!strcmp(dataType, "int")) {
+ dattyp = CONFIG_TYPE_INT;
+ } else if(!strcmp(dataType, "int64")) {
+ dattyp = CONFIG_TYPE_INT64;
+ } else if(!strcmp(dataType, "float")) {
+ dattyp = CONFIG_TYPE_FLOAT;
+ } else if(!strcmp(dataType, "string")) {
+ dattyp = CONFIG_TYPE_STRING;
+ } else if(!strcmp(dataType, "bool")) {
+ dattyp = CONFIG_TYPE_BOOL;
+ } else {
+ //only scalar type availabe
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Prohibited data type.\n"));
+ return 18;
+ };
+ //first of all we must add new element to array
+ ss = config_setting_add(setting, NULL, dattyp);
+ if(ss == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ //then based on his type set value
+ switch(dattyp) {
+ case CONFIG_TYPE_INT:
+ scs = set_config_int(ss, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ case CONFIG_TYPE_INT64:
+ scs = set_config_int64(ss, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ case CONFIG_TYPE_FLOAT:
+ scs = set_config_float(ss, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ case CONFIG_TYPE_STRING:
+ scs = config_setting_set_string(ss, dataString);
+ if(scs == CONFIG_FALSE) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ break;
+ case CONFIG_TYPE_BOOL:
+ scs = set_config_bool(ss, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ };
+ } else {
+ //but if we have some element in array, we can add only element of same type
+ //so, because all element in arry must be same type, we get type of first element
+ //and based on it set new element
+ dattyp = config_setting_type(config_setting_get_elem(setting, 0));
+ switch(dattyp) {
+ case CONFIG_TYPE_INT:
+ if(dataType != NULL && strcmp(dataType, "int")) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
+ return 10;
+ };
+ //add new element
+ ss = config_setting_add(setting, NULL, dattyp);
+ if(ss == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ //then set his value
+ scs = set_config_int(ss, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ case CONFIG_TYPE_INT64:
+ if(dataType != NULL && strcmp(dataType, "int64")) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
+ return 10;
+ };
+ //add new element
+ ss = config_setting_add(setting, NULL, dattyp);
+ if(ss == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ //then set his value
+ scs = set_config_int64(ss, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ case CONFIG_TYPE_FLOAT:
+ if(dataType != NULL && strcmp(dataType, "float")) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
+ return 10;
+ };
+ //add new element
+ ss = config_setting_add(setting, NULL, dattyp);
+ if(ss == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ //then set his value
+ scs = set_config_float(ss, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ case CONFIG_TYPE_STRING:
+ if(dataType != NULL && strcmp(dataType, "string")) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
+ return 10;
+ };
+ //add new element
+ ss = config_setting_add(setting, NULL, dattyp);
+ if(ss == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ //then set his value
+ scs = config_setting_set_string(ss, dataString);
+ if(scs == CONFIG_FALSE) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ break;
+ case CONFIG_TYPE_BOOL:
+ if(dataType != NULL && strcmp(dataType, "bool")) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! inconsistent value type.\n"));
+ return 10;
+ };
+ //add new element
+ ss = config_setting_add(setting, NULL, dattyp);
+ if(ss == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ //then set his value
+ scs = set_config_bool(ss, dataString, optflags);
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ break;
+ };
+ };
+ break;
+ case CONFIG_TYPE_LIST:
+ //in case adding element to list, we can add any type of element
+ if(dataType == NULL) {
+ //but we must konwn his type
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Configuration variable type not given.\n"));
+ return 13;
+ };
+ if(!strcmp(dataType, "int")) {
+ dattyp = CONFIG_TYPE_INT;
+ } else if(!strcmp(dataType, "int64")) {
+ dattyp = CONFIG_TYPE_INT64;
+ } else if(!strcmp(dataType, "float")) {
+ dattyp = CONFIG_TYPE_FLOAT;
+ } else if(!strcmp(dataType, "string")) {
+ dattyp = CONFIG_TYPE_STRING;
+ } else if(!strcmp(dataType, "bool")) {
+ dattyp = CONFIG_TYPE_BOOL;
+ } else if(!strcmp(dataType, "array")) {
+ dattyp = CONFIG_TYPE_ARRAY;
+ } else if(!strcmp(dataType, "list")) {
+ dattyp = CONFIG_TYPE_LIST;
+ } else if(!strcmp(dataType, "group")) {
+ dattyp = CONFIG_TYPE_GROUP;
+ } else {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Inlegal data type.\n"));
+ return 14;
+ };
+ //add new element of given type
+ ss = config_setting_add(setting, NULL, dattyp);
+ if(ss == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ //now, based on type, set element value
+ scs = 0;
+ switch(dattyp) {
+ case CONFIG_TYPE_INT:
+ scs = set_config_int(ss, dataString, optflags);
+ break;
+ case CONFIG_TYPE_INT64:
+ scs = set_config_int64(ss, dataString, optflags);
+ break;
+ case CONFIG_TYPE_FLOAT:
+ scs = set_config_int64(ss, dataString, optflags);
+ break;
+ case CONFIG_TYPE_STRING:
+ scs = config_setting_set_string(ss, dataString);
+ if(scs == CONFIG_FALSE) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ scs = 0;
+ break;
+ case CONFIG_TYPE_BOOL:
+ scs = set_config_int64(ss, dataString, optflags);
+ break;
+ };
+ if(scs > 0) {
+ config_destroy(&cfg);
+ return scs;
+ };
+ //finaly outpt index of new added element
+ if(optflags.quiet == 0) {
+ printf(gettext("Added element index: %d\n"), config_setting_index(ss));
+ } else {
+ printf("%d", config_setting_index(ss));
+ };
+ break;
+ case CONFIG_TYPE_GROUP:
+ //to group we can add any type of element, but we must have his name
+ if(dataType == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Configuration variable type not given.\n"));
+ return 13;
+ };
+ if(strlen(dataString) < 1) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Bad name of configuration variable.\n"));
+ return 15;
+ };
+ //determinate type of new variable
+ if(!strcmp(dataType, "int")) {
+ dattyp = CONFIG_TYPE_INT;
+ } else if(!strcmp(dataType, "int64")) {
+ dattyp = CONFIG_TYPE_INT64;
+ } else if(!strcmp(dataType, "float")) {
+ dattyp = CONFIG_TYPE_FLOAT;
+ } else if(!strcmp(dataType, "string")) {
+ dattyp = CONFIG_TYPE_STRING;
+ } else if(!strcmp(dataType, "bool")) {
+ dattyp = CONFIG_TYPE_BOOL;
+ } else if(!strcmp(dataType, "array")) {
+ dattyp = CONFIG_TYPE_ARRAY;
+ } else if(!strcmp(dataType, "list")) {
+ dattyp = CONFIG_TYPE_LIST;
+ } else if(!strcmp(dataType, "group")) {
+ dattyp = CONFIG_TYPE_GROUP;
+ } else {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Inlegal data type.\n"));
+ return 14;
+ };
+ //then add new alement
+ ss = config_setting_add(setting, dataString, dattyp);
+ if(ss == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable set failed.\n"));
+ return 11;
+ };
+ //in case of adding new element to group we not set his value
+ //(value field of input are used to get variable name)
+ //We only output index of new added element
+ if(optflags.quiet == 0) {
+ printf(gettext("Added element index: %d\n"), config_setting_index(ss));
+ } else {
+ printf("%d", config_setting_index(ss));
+ };
+ break;
+ };
+ }
+
+ //Finaly write configuration file
+ scs = config_write_file(&cfg, configFile);
+ if(scs == CONFIG_FALSE) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Configuration file write failed.\n"));
+ return 8;
+ };
+ config_destroy(&cfg);
+ return 0;
+};
+
+//unset configuration path
+//(remove variable from configuration file)
+//@return int success
+//@param char* configFile - the name (with path) of configuration file
+//@param char* configPath - path to configuration valriable to remove (unset)
+//@param struct flags optflags - global flags
+int unset_config(char *configFile, char *dataPath, struct flags optflags) {
+ config_t cfg; //configuration file handler
+ config_setting_t *setting, *par; //configuration valriale handler, and paren variable handler
+ int idx, scs; //index of variable, sucess status
+ //open configuration file
+ config_init(&cfg);
+ if(!config_read_file(&cfg, configFile)) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Can't read configuration file.\n"));
+ return 1;
+ };
+ //chceck if data path given
+ if(dataPath == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Conviguration variable path not given.\n"));
+ return 4;
+ };
+ //now find variable of given path
+ setting = config_lookup(&cfg, dataPath);
+ if(setting == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Given variable path not found.\n"));
+ return 3;
+ };
+ //get element index
+ idx = config_setting_index(setting);
+ if(idx < 0) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Can't remove root element.\n"));
+ return 5;
+ };
+ //now find parent element
+ par = config_setting_parent(setting);
+ if(par == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Can't find parent element.\n"));
+ return 6;
+ };
+ //then remove element
+ scs = config_setting_remove_elem(par, idx);
+ if(scs == CONFIG_FALSE) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Variable unset failed.\n"));
+ return 7;
+ };
+ //Finaly write configuration file
+ scs = config_write_file(&cfg, configFile);
+ if(scs == CONFIG_FALSE) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Configuration file write failed.\n"));
+ return 8;
+ };
+ config_destroy(&cfg);
+ return 0;
+};
+
+//get configuratioin variable
+//(read it from configuration file)
+//@return char* variable value
+//@param char* configFile - configuration file name (with path)
+//@param cher* dataPath - configuration variable path (in file)
+//@param struct flags optflags - global flags
+int read_config(char *configFile, char *dataPath, struct flags optflags) {
+ config_t cfg; //configuration file handler
+ config_setting_t *setting, *ss; //configuration element handler, and helper handler (config element too)
+ int comaset, varindex, varcounter; //helper flat for buid output strings, varibale index, counter
+ unsigned int maxel, i; //max elements, and loop index
+ char buffer[256]; //reading buffer
+ const char *cbuffer;
+ const char *coma=";"; //output string variable separator
+ int ibuffer, ssize; //value int buffer
+ char *dataName, *dataTypeName, *dataValueString; //name of variable, type of variable, value of variable
+ int dataType, st; //internale variable type
+ //initialize values
+ dataValueString = malloc(1);
+ dataTypeName = malloc(1);
+ memset(dataValueString, 0, 1);
+ memset(dataTypeName, 0, 1);
+ varindex = 0;
+ varcounter = 0;
+ //open and read configuration file
+ config_init(&cfg);
+ if(!config_read_file(&cfg, configFile)) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Can't read configuration file.\n"));
+ return 1;
+ };
+ //now find variable element of given path
+ if(dataPath == NULL) {
+ //if path not givne load root element (default)
+ setting = config_root_setting(&cfg);
+ } else {
+ setting = config_lookup(&cfg, dataPath);
+ };
+ if(setting == NULL) {
+ config_destroy(&cfg);
+ if(optflags.quiet == 0) printf(gettext("ERROR! Given variable path not found.\n"));
+ return 3;
+ };
+ //read variable name
+ dataName = config_setting_name(setting);
+ if(dataName == NULL) dataName = "NULL"; //in case variable have no name convert to string representation
+ //read variable type
+ dataType = config_setting_type(setting);
+ //next conver type to human readable and read variable value based on his type
+ //and in cases in type not scalar read index and coutn variables
+ switch(dataType) {
+ case CONFIG_TYPE_INT:
+ dataTypeName = (char*)realloc(dataTypeName, 4*sizeof(char));
+ strcpy(dataTypeName, "int");
+ sprintf(buffer, "%d", config_setting_get_int(setting));
+ dataValueString = (char*)realloc(dataValueString, (strlen(buffer)+1)*sizeof(char));
+ strcpy(dataValueString, buffer);
+ break;
+ case CONFIG_TYPE_INT64:
+ dataTypeName = (char*)realloc(dataTypeName, 6*sizeof(char));
+ strcpy(dataTypeName, "int64");
+ sprintf(buffer, "%lld", config_setting_get_int64(setting));
+ dataValueString = (char*)realloc(dataValueString, (strlen(buffer)+1)*sizeof(char));
+ strcpy(dataValueString, buffer);
+ break;
+ case CONFIG_TYPE_FLOAT:
+ dataTypeName = (char*)realloc(dataTypeName, 9*sizeof(char));
+ strcpy(dataTypeName, "float");
+ sprintf(buffer, "%f", config_setting_get_float(setting));
+ dataValueString = (char*)realloc(dataValueString, (strlen(buffer)+1)*sizeof(char));
+ strcpy(dataValueString, buffer);
+ break;
+ case CONFIG_TYPE_STRING:
+ dataTypeName = (char*)realloc(dataTypeName, 7*sizeof(char));
+ strcpy(dataTypeName, "string");
+ cbuffer = config_setting_get_string(setting);
+ dataValueString = (char*)realloc(dataValueString, (strlen(cbuffer)+1)*sizeof(char));
+ strcpy(dataValueString, cbuffer);
+ break;
+ case CONFIG_TYPE_BOOL:
+ dataTypeName = (char*)realloc(dataTypeName, 5*sizeof(char));
+ strcpy(dataTypeName, "bool");
+ if(optflags.boolstring == 1) {
+ //if expect bool as string, convert it to human readable
+ ibuffer = config_setting_get_bool(setting);
+ if(ibuffer == CONFIG_TRUE) {
+ dataValueString = (char*)realloc(dataValueString, 5*sizeof(char));
+ strcpy(dataValueString, "true");
+ } else {
+ dataValueString = (char*)realloc(dataValueString, 6*sizeof(char));
+ strcpy(dataValueString, "false");
+ }
+ } else {
+ //else output as digit
+ sprintf(buffer, "%d", config_setting_get_bool(setting));
+ dataValueString = (char*)realloc(dataValueString, (strlen(buffer)+1)*sizeof(char));
+ strcpy(dataValueString, buffer);
+ };
+ break;
+ case CONFIG_TYPE_ARRAY:
+ dataTypeName = (char*)realloc(dataTypeName, 6*sizeof(char));
+ strcpy(dataTypeName, "array");
+ //get element count
+ maxel = (unsigned int)config_setting_length(setting);
+ comaset = 0;
+ //and loop over all elements
+ for(i = 0; i < maxel; i++) {
+ //get element
+ ss = config_setting_get_elem(setting, i);
+ if(ss != NULL) {
+ st = config_setting_type(ss);
+ switch(st) {
+ case CONFIG_TYPE_INT:
+ sprintf(buffer, "%d", config_setting_get_int(ss));
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, buffer);
+ break;
+ case CONFIG_TYPE_INT64:
+ sprintf(buffer, "%lld", config_setting_get_int64(ss));
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, buffer);
+ break;
+ case CONFIG_TYPE_FLOAT:
+ sprintf(buffer, "%f", config_setting_get_float(ss));
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, buffer);
+ break;
+ case CONFIG_TYPE_STRING:
+ ssize = (int)strlen(config_setting_get_string(ss));
+
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+ssize+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, config_setting_get_string(ss));
+ break;
+ case CONFIG_TYPE_BOOL:
+ if(optflags.boolstring == 1) {
+ ibuffer = config_setting_get_bool(ss);
+ if(ibuffer == CONFIG_TRUE) {
+ //if bool must be outputed as humen readable - convert it
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+4+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, "true");
+ } else {
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+5+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, "false");
+ }
+ } else {
+ //else output as digit
+ sprintf(buffer, "%d", config_setting_get_bool(ss));
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, buffer);
+ };
+ break;
+ case CONFIG_TYPE_ARRAY:
+ //if array contains array output as kwyword ARRAY
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+7)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, "ARRAY");
+ break;
+ case CONFIG_TYPE_LIST:
+ //if array contains list output as keyword LIST
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+6)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, "LIST");
+ break;
+ case CONFIG_TYPE_GROUP:
+ //if array contains group output as keywort GROUP
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+7)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, "GROUP");
+ break;
+ };
+ comaset = 1;
+ };
+ };
+ break;
+ case CONFIG_TYPE_LIST:
+ dataTypeName = (char*)realloc(dataTypeName, 5*sizeof(char));
+ strcpy(dataTypeName, "list");
+ //get element count
+ maxel = (unsigned int)config_setting_length(setting);
+ //end loop over all elements
+ comaset = 0;
+ for(i = 0; i < maxel; i++) {
+ ss = config_setting_get_elem(setting, i);
+ if(ss != NULL) {
+ st = config_setting_type(ss);
+ switch(st) {
+ case CONFIG_TYPE_INT:
+ sprintf(buffer, "%d", config_setting_get_int(ss));
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, buffer);
+ break;
+ case CONFIG_TYPE_INT64:
+ sprintf(buffer, "%lld", config_setting_get_int64(ss));
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, buffer);
+ break;
+ case CONFIG_TYPE_FLOAT:
+ sprintf(buffer, "%f", config_setting_get_float(ss));
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, buffer);
+ break;
+ case CONFIG_TYPE_STRING:
+ ssize = (int)strlen(config_setting_get_string(ss));
+
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+ssize+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, config_setting_get_string(ss));
+ break;
+ case CONFIG_TYPE_BOOL:
+ if(optflags.boolstring == 1) {
+ ibuffer = config_setting_get_bool(ss);
+ if(ibuffer == CONFIG_TRUE) {
+ //if bool must be printout as humanreadable - convert it
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+4+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, "true");
+ } else {
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+5+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, "false");
+ }
+ } else {
+ //else output as int
+ sprintf(buffer, "%d", config_setting_get_bool(ss));
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+strlen(buffer)+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, buffer);
+ };
+ break;
+ case CONFIG_TYPE_ARRAY:
+ //if list contain array output as keyword ARRAY
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+7)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, "ARRAY");
+ break;
+ case CONFIG_TYPE_LIST:
+ //if list contain list output as keyword LIST
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+6)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, "LIST");
+ break;
+ case CONFIG_TYPE_GROUP:
+ //if list contain group output as keyword GROUP
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+7)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, "GROUP");
+ break;
+ };
+ comaset = 1;
+ };
+ };
+ break;
+ case CONFIG_TYPE_GROUP:
+ dataTypeName = (char*)realloc(dataTypeName, 6*sizeof(char));
+ strcpy(dataTypeName, "group");
+ //get elementc count
+ maxel = (unsigned int)config_setting_length(setting);
+ //and loop over all elements
+ //but in group case, we return inside variables names
+ comaset = 0;
+ for(i = 0; i < maxel; i++) {
+ ss = config_setting_get_elem(setting, i);
+ if(ss != NULL) {
+ ssize = (int)strlen(config_setting_name(ss));
+ dataValueString = (char*)realloc(dataValueString, (strlen(dataValueString)+ssize+2)*sizeof(char));
+ if(comaset == 1) strcat(dataValueString, coma);
+ strcat(dataValueString, config_setting_name(ss));
+ comaset = 1;
+ };
+ };
+ break;
+ };
+
+ //last we get readed variable index, and element count
+ varindex = config_setting_index(setting);
+ varcounter = config_setting_length(setting);
+
+ //and finaly output data
+ if(optflags.names == 1 && optflags.quiet == 0) printf(gettext("Variable name: %s\n"), dataName);
+ if(optflags.names == 1 && optflags.quiet == 1) printf("%s", dataName);
+ if((optflags.types == 1 && optflags.quiet == 1) && optflags.names == 1) printf(":");
+ if(optflags.types == 1 && optflags.quiet == 0) printf(gettext("Variable type: %s\n"), dataTypeName);
+ if(optflags.types == 1 && optflags.quiet == 1) printf("%s", dataTypeName);
+ if((optflags.values == 1 && optflags.quiet == 1) && (optflags.names == 1 || optflags.types == 1)) printf(":");
+ if(optflags.values == 1 && optflags.quiet == 0) printf(gettext("Variable value: %s\n"), dataValueString);
+ if(optflags.values == 1 && optflags.quiet == 1) printf("%s", dataValueString);
+ if((optflags.indexes == 1 && optflags.quiet == 1) && (optflags.names == 1 || optflags.types == 1 || optflags.values == 1)) printf(":");
+ if(optflags.indexes == 1 && optflags.quiet == 0) printf(gettext("Variable index: %d\n"), varindex);
+ if(optflags.indexes == 1 && optflags.quiet == 1) printf("%d", varindex);
+ if((optflags.counter == 1 && optflags.quiet == 1) && (optflags.names == 1 || optflags.types == 1 || optflags.values == 1 || optflags.indexes == 1)) printf(":");
+ if(optflags.counter == 1 && optflags.quiet == 0) printf(gettext("Variable elements count: %d\n"), varcounter);
+ if(optflags.counter == 1 && optflags.quiet == 1) printf("%d", varcounter);
+ if(optflags.quiet == 1) printf("\n");
+
+ config_destroy(&cfg);
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ //firs set locale and domain to work with internationalization
+ setlocale(LC_ALL, "");
+ bindtextdomain("ls-config", "/usr/share/locale");
+ textdomain("ls-config");
+
+ //then declare and init values
+ int opt,test; //used for read innput: option, and testing
+ int fd; //file descriptor
+ char *sinp, *dataPath=NULL, *dataString=NULL, *dataType=NULL; //string input, configuration variable path, input data, variable type
+ char *configFile=NULL; //config file name (with path)
+ struct flags optflags = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //global flags initialize
+ int excode; //program exit code
+ excode = 0;
+
+ sinp = malloc(sizeof(char) * 256);
+
+ //long options reading
+ struct option long_options[] = {
+ /* These options set a flag. */
+ {"quiet", no_argument, &optflags.quiet, 1},
+ {"names", no_argument, &optflags.names, 1},
+ {"types", no_argument, &optflags.types, 1},
+ {"values", no_argument, &optflags.values, 1},
+ {"indexes", no_argument, &optflags.indexes, 1},
+ {"count", no_argument, &optflags.counter, 1},
+ {"unset", no_argument, &optflags.unset, 1},
+ {"bool-string", no_argument, &optflags.boolstring, 1},
+ /* These options don't set a flag.
+ We distinguish them by their indices. */
+ {"help", no_argument, 0, 'h'},
+ {"set", required_argument, 0, 's'},
+ {"get", optional_argument, 0, 'g'},
+ {"data", required_argument, 0, 'd'},
+ {"type", required_argument, 0, 'p'},
+ {"file", required_argument, 0, 'f'},
+ {0, 0, 0, 0}
+ };
+
+ //next collect all input (given as options to program)
+ while(1) {
+ int option_index = 0;
+ opt = getopt_long (argc, argv, "qntvicubs:g:d:p:hf:", long_options, &option_index);
+
+ if(opt == -1) break;
+
+ switch (opt) {
+ case 0:
+ /* If this option set a flag, do nothing else now. */
+ if(long_options[option_index].flag != 0) break;
+ if(strcmp(long_options[option_index].name, "set") == 0 && optarg) {
+ test = sscanf(optarg, "%s", sinp);
+ if(test > 0) {
+ dataPath = (char*)malloc((strlen(sinp)+1)*sizeof(char));
+ strcpy(dataPath, sinp);
+ };
+ optflags.mode = 1;
+ };
+ if(strcmp(long_options[option_index].name, "get") == 0 && optarg) {
+ test = sscanf(optarg, "%s", sinp);
+ if(test > 0) {
+ dataPath = (char*)malloc((strlen(sinp)+1)*sizeof(char));
+ strcpy(dataPath, sinp);
+ };
+ optflags.mode = 0;
+ };
+ if(strcmp(long_options[option_index].name, "data") == 0 && optarg) {
+ test = sscanf(optarg, "%[^\n]s", sinp);
+ if(test > 0) {
+ dataString = (char*)malloc((strlen(sinp)+1)*sizeof(char));
+ strcpy(dataString, sinp);
+ };
+ };
+ if(strcmp(long_options[option_index].name, "type") == 0 && optarg) {
+ test = sscanf(optarg, "%s", sinp);
+ if(test > 0) {
+ dataType = (char*)malloc((strlen(sinp)+1)*sizeof(char));
+ strcpy(dataType, sinp);
+ };
+ };
+ if(strcmp(long_options[option_index].name, "file") == 0 && optarg) {
+ test = sscanf(optarg, "%[^\n]s", sinp);
+ if(test > 0) {
+ configFile = (char*)malloc((strlen(sinp)+1)*sizeof(char));
+ strcpy(configFile, sinp);
+ };
+ };
+ break;
+ case 'q':
+ optflags.quiet = 1;
+ break;
+ case 'n':
+ optflags.names = 1;
+ break;
+ case 't':
+ optflags.types = 1;
+ break;
+ case 'v':
+ optflags.values = 1;
+ break;
+ case 'i':
+ optflags.indexes = 1;
+ break;
+ case 'c':
+ optflags.counter = 1;
+ break;
+ case 'u':
+ optflags.unset = 1;
+ break;
+ case 'b':
+ optflags.boolstring = 1;
+ break;
+ case 's':
+ if(optarg) {
+ test = sscanf(optarg, "%s", sinp);
+ if(test > 0) {
+ dataPath = (char*)malloc((strlen(sinp)+1)*sizeof(char));
+ strcpy(dataPath, sinp);
+ };
+ optflags.mode = 1;
+ };
+ break;
+ case 'g':
+ if(optarg) {
+ test = sscanf(optarg, "%s", sinp);
+ if(test > 0) {
+ dataPath = (char*)malloc((strlen(sinp)+1)*sizeof(char));
+ strcpy(dataPath, sinp);
+ };
+ };
+ optflags.mode = 0;
+ break;
+ case 'd':
+ if(optarg) {
+ test = sscanf(optarg, "%[^\n]s", sinp);
+ if(test > 0) {
+ dataString = (char*)malloc((strlen(sinp)+1)*sizeof(char));
+ strcpy(dataString, sinp);
+ };
+ };
+ break;
+ case 'p':
+ if(optarg) {
+ test = sscanf(optarg, "%s", sinp);
+ if(test > 0) {
+ dataType = (char*)malloc((strlen(sinp)+1)*sizeof(char));
+ strcpy(dataType, sinp);
+ };
+ };
+ break;
+ case 'h':
+ //free input buffer and printout help message
+ free(sinp);
+ printHelp(); //this function contain exit from program
+ break;
+ case 'f':
+ test = sscanf(optarg, "%[^\n]s", sinp);
+ if(test > 0) {
+ configFile = (char*)malloc((strlen(sinp)+1)*sizeof(char));
+ strcpy(configFile, sinp);
+ };
+ break;
+ case '?':
+ break;
+ default:
+ break;
+ }
+ };
+
+ //first of all we must ensure, then configuration file are available with right access mode
+ if(optflags.mode == 0 && access(configFile, R_OK) < 0) optflags.error = 1;
+ if(optflags.mode == 1) {
+ fd = open(configFile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+ if(fd < 0) {
+ optflags.error = 1;
+ };
+ close(fd);
+ };
+ if(optflags.error > 0) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Can't read configuration file.\n"));
+ free(sinp);
+ free(configFile);
+ exit(1);
+ };
+
+ //now if we want to set variable, we must have his path
+ if(optflags.mode == 1 && dataPath == NULL) {
+ if(optflags.quiet == 0) printf(gettext("ERROR! Conviguration variable path not given.\n"));
+ free(sinp);
+ free(configFile);
+ exit(4);
+ };
+
+ //if no output data requested, set to default output
+ if(optflags.names == 0 && optflags.types == 0 && optflags.values == 0 && optflags.indexes == 0 && optflags.counter == 0) {
+ optflags.names = 1;
+ optflags.types = 1;
+ optflags.values = 1;
+ };
+
+ //now we invode main work of this software based on request type (set, unset of get)
+ if(optflags.mode == 0) excode = read_config(configFile, dataPath, optflags);
+ if(optflags.mode == 1 && optflags.unset == 1) excode = unset_config(configFile, dataPath, optflags);
+ if(optflags.mode == 1 && optflags.unset == 0) excode = set_config(configFile, dataPath, optflags, dataString, dataType);
+
+ //then finalize free resources and exit returnig excode
+ free(sinp);
+ free(configFile);
+ exit(excode);
+}
+
diff --git a/contrib/ls-config/src/makefile b/contrib/ls-config/src/makefile
new file mode 100644
index 0000000..d04a773
--- /dev/null
+++ b/contrib/ls-config/src/makefile
@@ -0,0 +1,34 @@
+CC=gcc
+CFLAGS=-O2 -Wall
+#Use for DEVELOP mode:
+#DEVFLAGS=-g -D __DEVEL__
+#Use for PRODUCTION mode:
+DEVFLAGS=-s -fomit-frame-pointer
+
+all: ls-config langs
+
+ls-config: ls-config.c ls-config.pot
+ $(CC) $(CFLAGS) $(DEVFLAGS) -o ../ls-config ls-config.c -L../lib -lm -lconfig
+
+ls-config.pot:
+ xgettext -d ls-config -o po/ls-config.pot ls-config.c
+
+langs:
+ make -C po
+
+install:
+ mkdir -p /usr/share/ls/lib
+ chown root:adm /usr/share/ls/lib
+ cp ../ls-config /usr/share/ls/lib/
+ chown root:adm /usr/share/ls/lib
+ chmod 755 /usr/share/ls/lib/ls-config
+ make -C po install
+
+clean:
+ make -C po clean
+
+remove:
+ rm -f /usr/share/ls/lib/ls-config
+ make -C po remove
+
+
diff --git a/contrib/ls-config/src/po/en_GB.po b/contrib/ls-config/src/po/en_GB.po
new file mode 100644
index 0000000..d16bfdf
--- /dev/null
+++ b/contrib/ls-config/src/po/en_GB.po
@@ -0,0 +1,289 @@
+# Language en-GB translations for PACKAGE package.
+# Copyright (C) 2013 THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# Łukasz A. Grabowski <lucas@lucas.net.pl>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: 1.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-10-06 19:23+0200\n"
+"PO-Revision-Date: 2013-09-09 23:56+0200\n"
+"Last-Translator: Łukasz A. Grabowski <lucas@lucas.net.pl>\n"
+"Language-Team: Language en-GB\n"
+"Language: en-GB\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ls-config.c:49
+#, c-format
+msgid "Configuration file handling\n"
+msgstr "Configuration file handling\n"
+
+#: ls-config.c:51
+#, c-format
+msgid "Usage: ls-config [OPTION]\n"
+msgstr "Usage: ls-config [OPTION]\n"
+
+#: ls-config.c:52
+#, c-format
+msgid "Reading and writening data from configuration files\n"
+msgstr "Reading and writening data from configuration files\n"
+
+#: ls-config.c:53
+#, c-format
+msgid "in libconfig9 format.\n"
+msgstr "in libconfig9 format.\n"
+
+#: ls-config.c:55
+#, c-format
+msgid "CAUTION: using without given config file are cause error!\n"
+msgstr "CAUTION: using without given config file are cause error!\n"
+
+#: ls-config.c:57
+#, c-format
+msgid "Available options:\n"
+msgstr "Available options:\n"
+
+#: ls-config.c:58
+#, c-format
+msgid " -f, --file=FILE Configuration file to handle.\n"
+msgstr " -f, --file=FILE Configuration file to handle.\n"
+
+#: ls-config.c:60
+#, c-format
+msgid " -s, --set=PATH Set configuration variable of given path.\n"
+msgstr " -s, --set=PATH Set configuration variable of given path.\n"
+
+#: ls-config.c:61
+#, c-format
+msgid " -d, --data=DATA Configuration variable value (only with -s)\n"
+msgstr " -d, --data=DATA Configuration variable value (only with -s)\n"
+
+#: ls-config.c:62
+#, c-format
+msgid " -p, --type=TYPE Configuration value type\n"
+msgstr " -p, --type=TYPE Configuration value type\n"
+
+#: ls-config.c:64
+#, c-format
+msgid " -g, --get=PATH Get configuration variable of given path.\n"
+msgstr " -g, --get=PATH Get configuration variable of given path.\n"
+
+#: ls-config.c:65
+#, c-format
+msgid " -n, --names Printout variables names.\n"
+msgstr " -n, --names Printout variables names.\n"
+
+#: ls-config.c:66
+#, c-format
+msgid " -t, --types Printout variables types.\n"
+msgstr " -t, --types Printout variables types.\n"
+
+#: ls-config.c:67
+#, c-format
+msgid " -v, --values Printout variables values.\n"
+msgstr " -v, --values Printout variables values.\n"
+
+#: ls-config.c:68
+#, c-format
+msgid " -i, --indexes Printout variables indexes.\n"
+msgstr " -i, --indexes Printout variables indexes.\n"
+
+#: ls-config.c:69
+#, c-format
+msgid ""
+" -c, --count Printout elements count (only: array, list, "
+"group).\n"
+msgstr ""
+" -c, --count Printout elements count (only: array, list, "
+"group).\n"
+
+#: ls-config.c:70
+#, c-format
+msgid " -b, --bool-string Printout boolean variables as text.\n"
+msgstr " -b, --bool-string Printout boolean variables as text.\n"
+
+#: ls-config.c:72
+#, c-format
+msgid " -q, --quiet Quiet output to use in scripts.\n"
+msgstr " -q, --quiet Quiet output to use in scripts.\n"
+
+#: ls-config.c:73
+#, c-format
+msgid " -h, --help Print this help message.\n"
+msgstr " -h, --help Print this help message.\n"
+
+#: ls-config.c:75
+#, c-format
+msgid "TYPE: Variable types:\n"
+msgstr "TYPE: Variable types:\n"
+
+#: ls-config.c:76
+#, c-format
+msgid " group - variables group,\n"
+msgstr " group - variables group,\n"
+
+#: ls-config.c:77
+#, c-format
+msgid " array - array of variables,\n"
+msgstr " array - array of variables (same scalar type),\n"
+
+#: ls-config.c:78
+#, c-format
+msgid " list - list of variables,\n"
+msgstr " list - list of variables,\n"
+
+#: ls-config.c:79
+#, c-format
+msgid " int - integer number,\n"
+msgstr " int - integer number,\n"
+
+#: ls-config.c:80
+#, c-format
+msgid " int64 - 64bit integer number,\n"
+msgstr " int64 - 64bit integer number,\n"
+
+#: ls-config.c:81
+#, c-format
+msgid " float - float point number,\n"
+msgstr " float - float point number,\n"
+
+#: ls-config.c:82
+#, c-format
+msgid " bool - boolean value,\n"
+msgstr " bool - boolean value,\n"
+
+#: ls-config.c:83
+#, c-format
+msgid " string - character string.\n"
+msgstr " string - character string.\n"
+
+#: ls-config.c:87
+#, c-format
+msgid "Licence: "
+msgstr "Licence: "
+
+#: ls-config.c:102 ls-config.c:126 ls-config.c:149 ls-config.c:172
+#, c-format
+msgid "ERROR! Incorrect data format.\n"
+msgstr "ERROR! Incorrect data format.\n"
+
+#: ls-config.c:110 ls-config.c:133 ls-config.c:156 ls-config.c:179
+#: ls-config.c:346 ls-config.c:364 ls-config.c:431 ls-config.c:477
+#: ls-config.c:507 ls-config.c:535 ls-config.c:555 ls-config.c:575
+#: ls-config.c:595 ls-config.c:602 ls-config.c:616 ls-config.c:662
+#: ls-config.c:681 ls-config.c:739
+#, c-format
+msgid "ERROR! Variable set failed.\n"
+msgstr "ERROR! Variable set failed.\n"
+
+#: ls-config.c:272 ls-config.c:779 ls-config.c:855 ls-config.c:1314
+#, c-format
+msgid "ERROR! Can't read configuration file.\n"
+msgstr "ERROR! Can't read configuration file.\n"
+
+#: ls-config.c:279 ls-config.c:785 ls-config.c:1322
+#, c-format
+msgid "ERROR! Conviguration variable path not given.\n"
+msgstr "ERROR! Conviguration variable path not given.\n"
+
+#: ls-config.c:284
+#, c-format
+msgid "ERROR! Configuration variable value not given.\n"
+msgstr "ERROR! Configuration variable value not given.\n"
+
+#: ls-config.c:303
+#, c-format
+msgid "ERROR! Inavlid configuration variable path.\n"
+msgstr "ERROR! Inavlid configuration variable path.\n"
+
+#: ls-config.c:310
+#, c-format
+msgid ""
+"ERROR! New named configuration variable can be added only to group element.\n"
+msgstr ""
+"ERROR! New named configuration variable can be added only to group element.\n"
+
+#: ls-config.c:316 ls-config.c:454 ls-config.c:634 ls-config.c:705
+#, c-format
+msgid "ERROR! Configuration variable type not given.\n"
+msgstr "ERROR! Configuration variable type not given.\n"
+
+#: ls-config.c:339 ls-config.c:655 ls-config.c:732
+#, c-format
+msgid "ERROR! Inlegal data type.\n"
+msgstr "ERROR! Inlegal data type.\n"
+
+#: ls-config.c:385 ls-config.c:398 ls-config.c:411 ls-config.c:424
+#: ls-config.c:438 ls-config.c:528 ls-config.c:548 ls-config.c:568
+#: ls-config.c:588 ls-config.c:609
+#, c-format
+msgid "ERROR! inconsistent value type.\n"
+msgstr "ERROR! inconsistent value type.\n"
+
+#: ls-config.c:470
+#, c-format
+msgid "ERROR! Prohibited data type.\n"
+msgstr "ERROR! Prohibited data type.\n"
+
+#: ls-config.c:696 ls-config.c:746
+#, c-format
+msgid "Added element index: %d\n"
+msgstr "Added element index: %d\n"
+
+#: ls-config.c:710
+#, c-format
+msgid "ERROR! Bad name of configuration variable.\n"
+msgstr "ERROR! Bad name of configuration variable.\n"
+
+#: ls-config.c:758 ls-config.c:820
+#, c-format
+msgid "ERROR! Configuration file write failed.\n"
+msgstr "ERROR! Configuration file write failed.\n"
+
+#: ls-config.c:792 ls-config.c:867
+#, c-format
+msgid "ERROR! Given variable path not found.\n"
+msgstr "ERROR! Given variable path not found.\n"
+
+#: ls-config.c:799
+#, c-format
+msgid "ERROR! Can't remove root element.\n"
+msgstr "ERROR! Can't remove root element.\n"
+
+#: ls-config.c:806
+#, c-format
+msgid "ERROR! Can't find parent element.\n"
+msgstr "ERROR! Can't find parent element.\n"
+
+#: ls-config.c:813
+#, c-format
+msgid "ERROR! Variable unset failed.\n"
+msgstr "ERROR! Variable unset failed.\n"
+
+#: ls-config.c:1115
+#, c-format
+msgid "Variable name: %s\n"
+msgstr "Variable name: %s\n"
+
+#: ls-config.c:1118
+#, c-format
+msgid "Variable type: %s\n"
+msgstr "Variable type: %s\n"
+
+#: ls-config.c:1121
+#, c-format
+msgid "Variable value: %s\n"
+msgstr "Variable value: %s\n"
+
+#: ls-config.c:1124
+#, c-format
+msgid "Variable index: %d\n"
+msgstr "Variable index: %d\n"
+
+#: ls-config.c:1127
+#, c-format
+msgid "Variable elements count: %d\n"
+msgstr "Variable elements count: %d\n"
diff --git a/contrib/ls-config/src/po/ls-config.pot b/contrib/ls-config/src/po/ls-config.pot
new file mode 100644
index 0000000..d6800e2
--- /dev/null
+++ b/contrib/ls-config/src/po/ls-config.pot
@@ -0,0 +1,287 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-10-11 22:00+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ls-config.c:49
+#, c-format
+msgid "Configuration file handling\n"
+msgstr ""
+
+#: ls-config.c:51
+#, c-format
+msgid "Usage: ls-config [OPTION]\n"
+msgstr ""
+
+#: ls-config.c:52
+#, c-format
+msgid "Reading and writening data from configuration files\n"
+msgstr ""
+
+#: ls-config.c:53
+#, c-format
+msgid "in libconfig9 format.\n"
+msgstr ""
+
+#: ls-config.c:55
+#, c-format
+msgid "CAUTION: using without given config file are cause error!\n"
+msgstr ""
+
+#: ls-config.c:57
+#, c-format
+msgid "Available options:\n"
+msgstr ""
+
+#: ls-config.c:58
+#, c-format
+msgid " -f, --file=FILE Configuration file to handle.\n"
+msgstr ""
+
+#: ls-config.c:60
+#, c-format
+msgid " -s, --set=PATH Set configuration variable of given path.\n"
+msgstr ""
+
+#: ls-config.c:61
+#, c-format
+msgid " -d, --data=DATA Configuration variable value (only with -s)\n"
+msgstr ""
+
+#: ls-config.c:62
+#, c-format
+msgid " -p, --type=TYPE Configuration value type\n"
+msgstr ""
+
+#: ls-config.c:64
+#, c-format
+msgid " -g, --get=PATH Get configuration variable of given path.\n"
+msgstr ""
+
+#: ls-config.c:65
+#, c-format
+msgid " -n, --names Printout variables names.\n"
+msgstr ""
+
+#: ls-config.c:66
+#, c-format
+msgid " -t, --types Printout variables types.\n"
+msgstr ""
+
+#: ls-config.c:67
+#, c-format
+msgid " -v, --values Printout variables values.\n"
+msgstr ""
+
+#: ls-config.c:68
+#, c-format
+msgid " -i, --indexes Printout variables indexes.\n"
+msgstr ""
+
+#: ls-config.c:69
+#, c-format
+msgid ""
+" -c, --count Printout elements count (only: array, list, "
+"group).\n"
+msgstr ""
+
+#: ls-config.c:70
+#, c-format
+msgid " -b, --bool-string Printout boolean variables as text.\n"
+msgstr ""
+
+#: ls-config.c:72
+#, c-format
+msgid " -q, --quiet Quiet output to use in scripts.\n"
+msgstr ""
+
+#: ls-config.c:73
+#, c-format
+msgid " -h, --help Print this help message.\n"
+msgstr ""
+
+#: ls-config.c:75
+#, c-format
+msgid "TYPE: Variable types:\n"
+msgstr ""
+
+#: ls-config.c:76
+#, c-format
+msgid " group - variables group,\n"
+msgstr ""
+
+#: ls-config.c:77
+#, c-format
+msgid " array - array of variables,\n"
+msgstr ""
+
+#: ls-config.c:78
+#, c-format
+msgid " list - list of variables,\n"
+msgstr ""
+
+#: ls-config.c:79
+#, c-format
+msgid " int - integer number,\n"
+msgstr ""
+
+#: ls-config.c:80
+#, c-format
+msgid " int64 - 64bit integer number,\n"
+msgstr ""
+
+#: ls-config.c:81
+#, c-format
+msgid " float - float point number,\n"
+msgstr ""
+
+#: ls-config.c:82
+#, c-format
+msgid " bool - boolean value,\n"
+msgstr ""
+
+#: ls-config.c:83
+#, c-format
+msgid " string - character string.\n"
+msgstr ""
+
+#: ls-config.c:87
+#, c-format
+msgid "Licence: "
+msgstr ""
+
+#: ls-config.c:102 ls-config.c:126 ls-config.c:149 ls-config.c:172
+#, c-format
+msgid "ERROR! Incorrect data format.\n"
+msgstr ""
+
+#: ls-config.c:110 ls-config.c:133 ls-config.c:156 ls-config.c:179
+#: ls-config.c:346 ls-config.c:364 ls-config.c:431 ls-config.c:477
+#: ls-config.c:507 ls-config.c:535 ls-config.c:555 ls-config.c:575
+#: ls-config.c:595 ls-config.c:602 ls-config.c:616 ls-config.c:662
+#: ls-config.c:681 ls-config.c:739
+#, c-format
+msgid "ERROR! Variable set failed.\n"
+msgstr ""
+
+#: ls-config.c:272 ls-config.c:779 ls-config.c:855 ls-config.c:1314
+#, c-format
+msgid "ERROR! Can't read configuration file.\n"
+msgstr ""
+
+#: ls-config.c:279 ls-config.c:785 ls-config.c:1322
+#, c-format
+msgid "ERROR! Conviguration variable path not given.\n"
+msgstr ""
+
+#: ls-config.c:284
+#, c-format
+msgid "ERROR! Configuration variable value not given.\n"
+msgstr ""
+
+#: ls-config.c:303
+#, c-format
+msgid "ERROR! Inavlid configuration variable path.\n"
+msgstr ""
+
+#: ls-config.c:310
+#, c-format
+msgid ""
+"ERROR! New named configuration variable can be added only to group element.\n"
+msgstr ""
+
+#: ls-config.c:316 ls-config.c:454 ls-config.c:634 ls-config.c:705
+#, c-format
+msgid "ERROR! Configuration variable type not given.\n"
+msgstr ""
+
+#: ls-config.c:339 ls-config.c:655 ls-config.c:732
+#, c-format
+msgid "ERROR! Inlegal data type.\n"
+msgstr ""
+
+#: ls-config.c:385 ls-config.c:398 ls-config.c:411 ls-config.c:424
+#: ls-config.c:438 ls-config.c:528 ls-config.c:548 ls-config.c:568
+#: ls-config.c:588 ls-config.c:609
+#, c-format
+msgid "ERROR! inconsistent value type.\n"
+msgstr ""
+
+#: ls-config.c:470
+#, c-format
+msgid "ERROR! Prohibited data type.\n"
+msgstr ""
+
+#: ls-config.c:696 ls-config.c:746
+#, c-format
+msgid "Added element index: %d\n"
+msgstr ""
+
+#: ls-config.c:710
+#, c-format
+msgid "ERROR! Bad name of configuration variable.\n"
+msgstr ""
+
+#: ls-config.c:758 ls-config.c:820
+#, c-format
+msgid "ERROR! Configuration file write failed.\n"
+msgstr ""
+
+#: ls-config.c:792 ls-config.c:867
+#, c-format
+msgid "ERROR! Given variable path not found.\n"
+msgstr ""
+
+#: ls-config.c:799
+#, c-format
+msgid "ERROR! Can't remove root element.\n"
+msgstr ""
+
+#: ls-config.c:806
+#, c-format
+msgid "ERROR! Can't find parent element.\n"
+msgstr ""
+
+#: ls-config.c:813
+#, c-format
+msgid "ERROR! Variable unset failed.\n"
+msgstr ""
+
+#: ls-config.c:1115
+#, c-format
+msgid "Variable name: %s\n"
+msgstr ""
+
+#: ls-config.c:1118
+#, c-format
+msgid "Variable type: %s\n"
+msgstr ""
+
+#: ls-config.c:1121
+#, c-format
+msgid "Variable value: %s\n"
+msgstr ""
+
+#: ls-config.c:1124
+#, c-format
+msgid "Variable index: %d\n"
+msgstr ""
+
+#: ls-config.c:1127
+#, c-format
+msgid "Variable elements count: %d\n"
+msgstr ""
diff --git a/contrib/ls-config/src/po/makefile b/contrib/ls-config/src/po/makefile
new file mode 100644
index 0000000..0e05bc3
--- /dev/null
+++ b/contrib/ls-config/src/po/makefile
@@ -0,0 +1,34 @@
+DIRS:=$(shell find . -mindepth 1 -maxdepth 1 -name "*.po" -type f | sed -e 's/\(.*\)\..*/\1/')
+PACKAGES = $(DIRS:%=%.lang)
+IPACKAGES = $(DIRS:%=%.inst)
+CPACKAGES = $(DIRS:%=%.cln)
+RPACKAGES = $(DIRS:%=%.remov)
+SHELL := /bin/bash
+
+all: packages
+
+packages: $(PACKAGES)
+
+%.lang: %.po
+ msgmerge -U $< ls-config.pot
+ mkdir -p ../locale/$*/LC_MESSAGES
+ msgfmt -c -v -o ../locale/$*/LC_MESSAGES/ls-config.mo $<
+
+install: $(IPACKAGES)
+
+%.inst:
+ mkdir -p /usr/share/locale/$*/LC_MESSAGES
+ cp -f ../locale/$*/LC_MESSAGES/ls-config.mo /usr/share/locale/$*/LC_MESSAGES
+
+remove: $(RPACKAGES)
+
+%.remov:
+ rm -f /usr/share/locale/$*/LC_MESSAGES/ls-config.mo
+
+clean: $(CPACKAGES) cleandir
+
+%.cln:
+ rm -Rf ../locale/$*
+
+cleandir:
+ rm -Rf ../locale \ No newline at end of file
diff --git a/contrib/ls-config/src/po/pl_PL.po b/contrib/ls-config/src/po/pl_PL.po
new file mode 100644
index 0000000..56d518d
--- /dev/null
+++ b/contrib/ls-config/src/po/pl_PL.po
@@ -0,0 +1,292 @@
+# Language pl-PL translations for PACKAGE package.
+# Copyright (C) 2013 THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# Łukasz A. Grabowski <lucas@lucas.net.pl>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: 1.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-10-06 19:23+0200\n"
+"PO-Revision-Date: 2013-09-09 23:55+0200\n"
+"Last-Translator: Łukasz A. Grabowski <lucas@lucas.net.pl>\n"
+"Language-Team: Language pl-PL\n"
+"Language: pl-PL\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ls-config.c:49
+#, c-format
+msgid "Configuration file handling\n"
+msgstr "Obsluga plików konfiguracyjnych\n"
+
+#: ls-config.c:51
+#, c-format
+msgid "Usage: ls-config [OPTION]\n"
+msgstr "Składnia: ls-config [OPCJA]\n"
+
+#: ls-config.c:52
+#, c-format
+msgid "Reading and writening data from configuration files\n"
+msgstr "Odczytuje i zapisuje pliki konfiguracyjne\n"
+
+#: ls-config.c:53
+#, c-format
+msgid "in libconfig9 format.\n"
+msgstr "w formacie libconfig9.\n"
+
+#: ls-config.c:55
+#, c-format
+msgid "CAUTION: using without given config file are cause error!\n"
+msgstr "UWAGA: użycie bez podania pliku konfiguracyjnego powoduje błąd!\n"
+
+#: ls-config.c:57
+#, c-format
+msgid "Available options:\n"
+msgstr "Dostępne opcje:\n"
+
+#: ls-config.c:58
+#, c-format
+msgid " -f, --file=FILE Configuration file to handle.\n"
+msgstr " -f, --file=PLIK Plik konfiguracyjny do obsłużenia.\n"
+
+#: ls-config.c:60
+#, c-format
+msgid " -s, --set=PATH Set configuration variable of given path.\n"
+msgstr ""
+" -s, --set=SCIEZKA Ustawia zmienną konfiguracyjną o podanej ścieżce.\n"
+
+#: ls-config.c:61
+#, c-format
+msgid " -d, --data=DATA Configuration variable value (only with -s)\n"
+msgstr ""
+" -d, --data=DANE Wartość zmiennej konfiguracyjnej (tylko z -s).\n"
+
+#: ls-config.c:62
+#, c-format
+msgid " -p, --type=TYPE Configuration value type\n"
+msgstr " -p, --type=TYP Typ wartości konfiguracyjnej.\n"
+
+#: ls-config.c:64
+#, c-format
+msgid " -g, --get=PATH Get configuration variable of given path.\n"
+msgstr ""
+" -g, --get=SCIEZKA Pobież zmienną konfiguracyjną o podajen ścieżce.\n"
+
+#: ls-config.c:65
+#, c-format
+msgid " -n, --names Printout variables names.\n"
+msgstr " -n, --names Wypisz nazwy zmiennych.\n"
+
+#: ls-config.c:66
+#, c-format
+msgid " -t, --types Printout variables types.\n"
+msgstr " -t, --types Wypisz typy zmiennych.\n"
+
+#: ls-config.c:67
+#, c-format
+msgid " -v, --values Printout variables values.\n"
+msgstr " -v, --values Wypisz wartości zmiennych.\n"
+
+#: ls-config.c:68
+#, c-format
+msgid " -i, --indexes Printout variables indexes.\n"
+msgstr " -i, --indexes Wypisz indexy zmiennych.\n"
+
+#: ls-config.c:69
+#, c-format
+msgid ""
+" -c, --count Printout elements count (only: array, list, "
+"group).\n"
+msgstr ""
+" -c, --count Wypisz liczy elementów (tylko: array, list, "
+"group).\n"
+
+#: ls-config.c:70
+#, c-format
+msgid " -b, --bool-string Printout boolean variables as text.\n"
+msgstr " -b, --bool-string Wypisz wartości logiczne tekstowo.\n"
+
+#: ls-config.c:72
+#, c-format
+msgid " -q, --quiet Quiet output to use in scripts.\n"
+msgstr " -q, --quiet Ciche wyjście do użcia w skryptach.\n"
+
+#: ls-config.c:73
+#, c-format
+msgid " -h, --help Print this help message.\n"
+msgstr " -h, --help Wyswietla niniejszy opis\n"
+
+#: ls-config.c:75
+#, c-format
+msgid "TYPE: Variable types:\n"
+msgstr "TYP: Typy zmiennej:\n"
+
+#: ls-config.c:76
+#, c-format
+msgid " group - variables group,\n"
+msgstr " group - grupa zmiennych.\n"
+
+#: ls-config.c:77
+#, c-format
+msgid " array - array of variables,\n"
+msgstr " array - tablica zmiennych (tego samego typu podstawowego),\n"
+
+#: ls-config.c:78
+#, c-format
+msgid " list - list of variables,\n"
+msgstr " list - lista zmiennych,\n"
+
+#: ls-config.c:79
+#, c-format
+msgid " int - integer number,\n"
+msgstr " int - liczba całkowita,\n"
+
+#: ls-config.c:80
+#, c-format
+msgid " int64 - 64bit integer number,\n"
+msgstr " int64 - liczba całkowita 64bitowa,\n"
+
+#: ls-config.c:81
+#, c-format
+msgid " float - float point number,\n"
+msgstr " float - liczba zmiennoprzecinkowa,\n"
+
+#: ls-config.c:82
+#, c-format
+msgid " bool - boolean value,\n"
+msgstr " bool - wartość logiczna,\n"
+
+#: ls-config.c:83
+#, c-format
+msgid " string - character string.\n"
+msgstr " string - łąńcuch znakowy.\n"
+
+#: ls-config.c:87
+#, c-format
+msgid "Licence: "
+msgstr "Licencja: "
+
+#: ls-config.c:102 ls-config.c:126 ls-config.c:149 ls-config.c:172
+#, c-format
+msgid "ERROR! Incorrect data format.\n"
+msgstr "BŁĄD! Błędny format danych.\n"
+
+#: ls-config.c:110 ls-config.c:133 ls-config.c:156 ls-config.c:179
+#: ls-config.c:346 ls-config.c:364 ls-config.c:431 ls-config.c:477
+#: ls-config.c:507 ls-config.c:535 ls-config.c:555 ls-config.c:575
+#: ls-config.c:595 ls-config.c:602 ls-config.c:616 ls-config.c:662
+#: ls-config.c:681 ls-config.c:739
+#, c-format
+msgid "ERROR! Variable set failed.\n"
+msgstr "BŁĄD! Nie udało sią ustawić zmiennej.\n"
+
+#: ls-config.c:272 ls-config.c:779 ls-config.c:855 ls-config.c:1314
+#, c-format
+msgid "ERROR! Can't read configuration file.\n"
+msgstr "BŁĄD! Nie można odczytać pliku konfiguracyjnego.\n"
+
+#: ls-config.c:279 ls-config.c:785 ls-config.c:1322
+#, c-format
+msgid "ERROR! Conviguration variable path not given.\n"
+msgstr "BŁĄD! Nie podano ścieżki zmiennej konfiguracyjnej.\n"
+
+#: ls-config.c:284
+#, c-format
+msgid "ERROR! Configuration variable value not given.\n"
+msgstr "BŁĄD! Nie podano wartości zmiennej konfiguracyjnej.\n"
+
+#: ls-config.c:303
+#, c-format
+msgid "ERROR! Inavlid configuration variable path.\n"
+msgstr "BŁĄD! Błędna ścieżka zmiennej konfiguracyjnej.\n"
+
+#: ls-config.c:310
+#, c-format
+msgid ""
+"ERROR! New named configuration variable can be added only to group element.\n"
+msgstr ""
+"BŁĄD! Nowa nazwana zmienna konfiguracyjne może być dodana tylko do grupy.\n"
+
+#: ls-config.c:316 ls-config.c:454 ls-config.c:634 ls-config.c:705
+#, c-format
+msgid "ERROR! Configuration variable type not given.\n"
+msgstr "BŁĄD! Nie podano typu zmiennej konfiguracyjnej.\n"
+
+#: ls-config.c:339 ls-config.c:655 ls-config.c:732
+#, c-format
+msgid "ERROR! Inlegal data type.\n"
+msgstr "BŁĄD! Niepoprawny typ zmiennej.\n"
+
+#: ls-config.c:385 ls-config.c:398 ls-config.c:411 ls-config.c:424
+#: ls-config.c:438 ls-config.c:528 ls-config.c:548 ls-config.c:568
+#: ls-config.c:588 ls-config.c:609
+#, c-format
+msgid "ERROR! inconsistent value type.\n"
+msgstr "BŁĄD! niezgodny typ vartości.\n"
+
+#: ls-config.c:470
+#, c-format
+msgid "ERROR! Prohibited data type.\n"
+msgstr "BŁĄD! Zabronionny typ danych.\n"
+
+#: ls-config.c:696 ls-config.c:746
+#, c-format
+msgid "Added element index: %d\n"
+msgstr "Indeks dodanego elementu: %d\n"
+
+#: ls-config.c:710
+#, c-format
+msgid "ERROR! Bad name of configuration variable.\n"
+msgstr "BŁĄD! Błędna nazwa zmiennej konfiguracyjnej.\n"
+
+#: ls-config.c:758 ls-config.c:820
+#, c-format
+msgid "ERROR! Configuration file write failed.\n"
+msgstr "BŁĄD! Nie udało się zapisać pliku konfiguracyjnego.\n"
+
+#: ls-config.c:792 ls-config.c:867
+#, c-format
+msgid "ERROR! Given variable path not found.\n"
+msgstr "BŁĄD! Nie odnaleziono zmiennej konfiguracyjnej o podanej ścieżce.\n"
+
+#: ls-config.c:799
+#, c-format
+msgid "ERROR! Can't remove root element.\n"
+msgstr "BŁĄD! Nie można usunąć głównego elementu.\n"
+
+#: ls-config.c:806
+#, c-format
+msgid "ERROR! Can't find parent element.\n"
+msgstr "BŁĄD! Nie można odnaleźć elementu nadrzędnego.\n"
+
+#: ls-config.c:813
+#, c-format
+msgid "ERROR! Variable unset failed.\n"
+msgstr "BŁĄD! Nie udało sią usunąć zmiennej.\n"
+
+#: ls-config.c:1115
+#, c-format
+msgid "Variable name: %s\n"
+msgstr "Nazwa zmiennej: %s\n"
+
+#: ls-config.c:1118
+#, c-format
+msgid "Variable type: %s\n"
+msgstr "Typ zmiennej: %s\n"
+
+#: ls-config.c:1121
+#, c-format
+msgid "Variable value: %s\n"
+msgstr "Wartość zmiennej: %s\n"
+
+#: ls-config.c:1124
+#, c-format
+msgid "Variable index: %d\n"
+msgstr "Index zmiennej: %d\n"
+
+#: ls-config.c:1127
+#, c-format
+msgid "Variable elements count: %d\n"
+msgstr "Ilość elementów zmiennej: %d\n"