Skip to content

Commit

Permalink
Merge pull request #95 from Hemofektik/master
Browse files Browse the repository at this point in the history
Added optional method chained interface
  • Loading branch information
hyperrealm authored Dec 11, 2017
2 parents a5c5592 + 45c3a15 commit 8a361a5
Show file tree
Hide file tree
Showing 10 changed files with 1,002 additions and 0 deletions.
60 changes: 60 additions & 0 deletions contrib/chained/README.md
Original file line number Diff line number Diff line change
@@ -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
40 changes: 40 additions & 0 deletions contrib/chained/examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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}
)
7 changes: 7 additions & 0 deletions contrib/chained/examples/CreateProjectFiles.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@echo off
rmdir sln /S/Q
mkdir sln
cd sln
cmake -G "Visual Studio 15 2017" ..

pause
43 changes: 43 additions & 0 deletions contrib/chained/examples/README.md
Original file line number Diff line number Diff line change
@@ -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 ---
```
52 changes: 52 additions & 0 deletions contrib/chained/examples/example.cfg
Original file line number Diff line number Diff line change
@@ -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] );
52 changes: 52 additions & 0 deletions contrib/chained/examples/example1.cpp
Original file line number Diff line number Diff line change
@@ -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
}
71 changes: 71 additions & 0 deletions contrib/chained/examples/example2.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
}
Loading

0 comments on commit 8a361a5

Please sign in to comment.