diff options
Diffstat (limited to 'contrib')
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 Binary files differnew file mode 100644 index 0000000..4a16b74 --- /dev/null +++ b/contrib/ls-config/debian/ls-config/usr/share/doc/ls-config/changelog.gz 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" |