changeset 403:d5ec1174b707

Massive cleanup
author David Demelier <markand@malikania.fr>
date Mon, 05 Oct 2015 14:27:19 +0200
parents c21f37c9cd4a
children 9ab878fb9fa2
files .hgignore C++/modules/Base64/Base64.cpp C++/modules/Base64/Base64.h C++/modules/Converter/Converter.cpp C++/modules/Converter/Converter.h C++/modules/Date/Date.cpp C++/modules/Date/Date.h C++/modules/Directory/Directory.cpp C++/modules/Directory/Directory.h C++/modules/Driver/Driver.cpp C++/modules/Driver/Driver.h C++/modules/Driver/DriverPostgres.cpp C++/modules/Driver/DriverPostgres.h C++/modules/Dynlib/Dynlib.cpp C++/modules/Dynlib/Dynlib.h C++/modules/Flags/Flags.h C++/modules/Hash/Hash.cpp C++/modules/Hash/Hash.h C++/modules/Ini/Ini.cpp C++/modules/Ini/Ini.h C++/modules/Json/Json.cpp C++/modules/Json/Json.h C++/modules/OptionParser/OptionParser.cpp C++/modules/OptionParser/OptionParser.h C++/modules/Socket/Socket.cpp C++/modules/Socket/Socket.h C++/modules/Socket/SocketAddress.cpp C++/modules/Socket/SocketAddress.h C++/modules/Socket/SocketListener.cpp C++/modules/Socket/SocketListener.h C++/modules/Socket/SocketSsl.cpp C++/modules/Socket/SocketSsl.h C++/modules/Treenode/TreeNode.h C++/modules/Unicode/Unicode.cpp C++/modules/Unicode/Unicode.h C++/modules/Xdg/Xdg.cpp C++/modules/Xdg/Xdg.h C++/modules/Zip/ZipArchive.cpp C++/modules/Zip/ZipArchive.h C++/tests/Base64/main.cpp C++/tests/Directory/main.cpp C++/tests/Dynlib/main.cpp C++/tests/Flags/main.cpp C++/tests/Hash/main.cpp C++/tests/Ini/main.cpp C++/tests/Js/main.cpp C++/tests/Json/main.cpp C++/tests/OptionParser/main.cpp C++/tests/Socket/main.cpp C++/tests/Treenode/main.cpp C++/tests/Unicode/main.cpp C++/tests/Xdg/main.cpp C++/tests/Zip/main.cpp CMakeLists.txt extern/CMakeLists.txt extern/duktape/CMakeLists.txt extern/gtest/CMakeLists.txt tools/CMakeLists.txt tools/cat/CMakeLists.txt tools/cat/cat.cpp tools/linktool/CMakeLists.txt tools/mkunicode/CMakeLists.txt tools/mkunicode/Unicode-before.cpp tools/mkunicode/Unicode.h
diffstat 64 files changed, 60 insertions(+), 1260 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Mon Oct 05 13:22:20 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-_build_
--- a/C++/modules/Base64/Base64.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Base64/Base64.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Base64.cpp -- base64 encoding and decoding
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Base64/Base64.h	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Base64/Base64.h	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Base64.h -- base64 encoding and decoding
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Converter/Converter.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Converter/Converter.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Converter.cpp -- iconv based converter
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Converter/Converter.h	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Converter/Converter.h	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Converter.h -- iconv based converter
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Date/Date.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Date/Date.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Date.cpp -- date and time manipulation
  *
- * Copyright (c) 2011, 2012, 2013 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2011-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Date/Date.h	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Date/Date.h	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Date.h -- date and time manipulation
  *
- * Copyright (c) 2011, 2012, 2013 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2011-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Directory/Directory.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Directory/Directory.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Directory.cpp -- open and read directories
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Directory/Directory.h	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Directory/Directory.h	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Directory.h -- open and read directories
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Driver/Driver.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-/*
- * Driver.cpp -- generic SQL driver access
- *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <stdexcept>
-#include <sstream>
-
-#include "Driver.h"
-
-/* ---------------------------------------------------------
- * DriverQuery class
- * ---------------------------------------------------------*/
-
-DriverQuery::DriverQuery(Ptr impl)
-	: m_impl(impl)
-{
-}
-
-void DriverQuery::assertRequest(int row, const std::string &column, DriverColumn wanted)
-{
-	std::ostringstream oss;
-
-	// Out of bounds?
-	if (row < 0 || row >= countRows()) {
-		oss << "Invalid row index " << row;
-		oss << ", expected [0.." << countRows() << "]";
-
-		throw std::runtime_error(oss.str());
-	}
-
-	// Not found or bad column?
-	if (type(column) != wanted) {
-		oss << "Invalid or not found column `" << column << "'";
-
-		throw std::runtime_error(oss.str());
-	}
-}
-
-DriverQuery::~DriverQuery()
-{
-}
-
-DriverColumn DriverQuery::type(const std::string &column) const
-{
-	return m_impl->type(column);
-}
-
-int DriverQuery::countRows()
-{
-	return m_impl->countRows();
-}
-
-int DriverQuery::countColumns()
-{
-	return m_impl->countColumns();
-}
-
-bool DriverQuery::isNull(int row, const std::string &column)
-{
-	return m_impl->isNull(row, column);
-}
-
-void DriverQuery::dump()
-{
-	m_impl->dump();
-}
-
-/* --------------------------------------------------------
- * DriverRequest class
- * -------------------------------------------------------- */
-
-DriverRequest::DriverRequest(Ptr impl, const std::string &command)
-	: m_pos(0)
-	, m_params(0)
-	, m_command(command)
-	, m_impl(impl)
-{
-	int i = -1;
-
-	while ((i = command.find('#', i + 1)) != std::string::npos)
-		++ m_params;
-}
-
-DriverRequest::~DriverRequest()
-{
-}
-
-void DriverRequest::assertCorrect()
-{
-	if (m_params <= 0)
-		throw std::runtime_error("no more arguments to set");
-}
-
-void DriverRequest::setValue(const std::string &value)
-{
-	assertCorrect();
-
-	m_pos = m_command.find('#', m_pos);
-	m_command.replace(m_pos, 1, value);
-	m_pos += value.length();
-	m_params --;
-}
-
-DriverRequest::operator std::string()
-{
-	return m_command;
-}
-
-/* --------------------------------------------------------
- * Driver class
- * -------------------------------------------------------- */
-
-void Driver::connect(const Params &params)
-{
-	m_impl->connect(params);
-}
-
-DriverRequest Driver::prepare(const std::string &command)
-{
-	return m_impl->prepare(command);
-}
-
-DriverQuery Driver::query(const std::string &sql)
-{
-	return m_impl->query(sql);
-}
-
-DriverQuery Driver::query(DriverRequest request)
-{
-	return query(static_cast<std::string>(request));
-}
-
-std::string Driver::description() const
-{
-	return m_impl->description();
-}
-
-std::string Driver::version() const
-{
-	return m_impl->version();
-}
--- a/C++/modules/Driver/Driver.h	Mon Oct 05 13:22:20 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,529 +0,0 @@
-/*
- * Driver.h -- generic SQL driver access
- *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _DRIVER_H_
-#define _DRIVER_H_
-
-#include <ctime>
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <type_traits>
-
-/**
- * @enum DriverColumn
- * @brief The column type request
- *
- * Used for the drivers.
- */
-enum class DriverColumn {
-	Invalid,			//! not found
-	Boolean,			//! bool or 0 / 1
-	Date,				//! date see Common/Date.h
-	Double,				//! double
-	Integer,			//! 32 or 64 bit int
-	String,				//! varchar to std::string
-};
-
-template <typename T>
-struct DriverTypeInfo : std::false_type { };
-
-/**
- * @class Query
- * @brief Class for querying the database
- *
- * That class is returned when a SQL query succeed. It can retrieve the
- * number of rows, columns and retrieve the results independantly from the
- * driver.
- *
- * @see Driver::query
- */
-class DriverQuery {
-public:
-	friend struct DriverTypeInfo<bool>;
-	friend struct DriverTypeInfo<time_t>;
-	friend struct DriverTypeInfo<double>;
-	friend struct DriverTypeInfo<int>;
-	friend struct DriverTypeInfo<std::string>;
-
-	class Impl {
-	public:
-		/**
-		 * Get a bool.
-		 *
-		 * @param row the row number
-		 * @param column the column
-		 * @return the value
-		 */
-		virtual bool getBoolean(int row, const std::string &column) = 0;
-
-		/**
-		 * Get a Date.
-		 *
-		 * @param row the row number
-		 * @param column the column
-		 * @return the value
-		 */
-		virtual time_t getDate(int row, const std::string &column) = 0;
-
-		/**
-		 * Get a double.
-		 *
-		 * @param row the row number
-		 * @param column the column
-		 * @return the value
-		 */
-		virtual double getDouble(int row, const std::string &column) = 0;
-
-		/**
-		 * Get a integer.
-		 *
-		 * @param row the row number
-		 * @param column the column
-		 * @return the value
-		 */
-		virtual int getInt(int row, const std::string &column) = 0;
-
-		/**
-		 * Get a string.
-		 *
-		 * @param row the row number
-		 * @param column the column
-		 * @return the value
-		 */
-		virtual std::string getString(int row, const std::string &column) = 0;
-
-		/**
-		 * Returns the type of a named column.
-		 *
-		 * @param column the column name
-		 * @return the type
-		 */
-		virtual DriverColumn type(const std::string &column) const = 0;
-
-		/**
-		 * Tells how many rows has been fetched.
-		 *
-		 * @return the number of rows
-		 */
-		virtual int countRows() = 0;
-
-		/**
-		 * Tells how many number of columns are present for each
-		 * row.
-		 *
-		 * @return the number of columns
-		 */
-		virtual int countColumns() = 0;
-
-		/**
-		 * Tells if the column is null or not.
-		 *
-		 * @param row the row number
-		 * @param column the column
-		 * @return an true if null
-		 */
-		virtual bool isNull(int row, const std::string &column) = 0;
-
-		/**
-		 * Dump all rows and columns.
-		 */
-		virtual void dump() = 0;
-	};
-
-	using Ptr	= std::shared_ptr<Impl>;
-
-private:
-	/**
-	 * Check if the request is valid and throws an exception
-	 * on error.
-	 *
-	 * @param row the row number
-	 * @param column the column name
-	 * @param type
-	 * @throw Error on error
-	 */
-	void assertRequest(int row, const std::string &column, DriverColumn type);
-
-protected:
-	Ptr		m_impl;
-
-public:
-	DriverQuery(Ptr impl);
-
-	/**
-	 * Default destructor.
-	 */
-	virtual ~DriverQuery();
-
-	/**
-	 * Get a variable from a row and column.
-	 *
-	 * Specialization available:
-	 *	- bool
-	 *	- Date
-	 *	- double
-	 *	- int
-	 *	- std::string
-	 *
-	 * @param row the row number (starts from 0)
-	 * @param column the the column name
-	 * @return the value
-	 * @throw Query::Error on error
-	 */
-	template <class T>
-	T get(int row, const std::string &column)
-	{
-		static_assert(DriverTypeInfo<T>::value, "unsupported type");
-
-		assertRequest(row, column, DriverTypeInfo<T>::type);
-	
-		return DriverTypeInfo<T>::get(*this, row, column);
-	}
-
-	/**
-	 * Returns the type of a named column.
-	 *
-	 * @param column the column name
-	 * @return the type
-	 */
-	DriverColumn type(const std::string &column) const;
-
-	/**
-	 * Tells how many rows has been fetched.
-	 *
-	 * @return the number of rows
-	 */
-	int countRows();
-
-	/**
-	 * Tells how many number of columns are present for each
-	 * row.
-	 *
-	 * @return the number of columns
-	 */
-	int countColumns();
-
-	/**
-	 * Tells if the column is null or not.
-	 *
-	 * @param row the row number
-	 * @param column the column
-	 * @return an true if null
-	 */
-	bool isNull(int row, const std::string &column);
-
-	/**
-	 * Dump all rows and columns.
-	 */
-	void dump();
-};
-
-/**
- * @class Request
- * @brief A secure helper for creating requests
- *
- * This helps creating class with SQL injection security and such.
- */
-class DriverRequest {
-public:
-	friend struct DriverTypeInfo<bool>;
-	friend struct DriverTypeInfo<time_t>;
-	friend struct DriverTypeInfo<double>;
-	friend struct DriverTypeInfo<int>;
-	friend struct DriverTypeInfo<std::string>;
-
-	class Impl {
-	public:
-		/**
-		 * Bind a boolean.
-		 *
-		 * @param value the boolean
-		 * @return the string to use
-		 */
-		virtual std::string bindBoolean(bool value) = 0;
-
-		/**
-		 * Bind a date.
-		 *
-		 * @param value the date
-		 * @return the string to use
-		 */
-		virtual std::string bindDate(time_t value) = 0;
-
-		/**
-		 * Bind a double.
-		 *
-		 * @param value the double
-		 * @return the string to use
-		 */
-		virtual std::string bindDouble(double value) = 0;
-
-		/**
-		 * Bind an integer.
-		 *
-		 * @param value the integer
-		 * @return the string to use
-		 */
-		virtual std::string bindInteger(int value) = 0;
-
-		/**
-		 * Bind a string.
-		 *
-		 * @param value the string
-		 * @return the string to use
-		 */
-		virtual std::string bindString(std::string value) = 0;
-	};
-
-	using Ptr	= std::shared_ptr<Impl>;
-
-private:
-	size_t		m_pos;
-	int		m_params;
-	std::string	m_command;
-	Ptr		m_impl;
-
-	void assertCorrect();
-
-	void setValue(const std::string &value);
-
-public:
-	DriverRequest(Ptr impl, const std::string &command);
-
-	/**
-	 * Default destructor.
-	 */
-	virtual ~DriverRequest();
-
-	/**
-	 * Bind a value.
-	 *
-	 * @param value the value
-	 */
-	template <typename T>
-	void bind(T value)
-	{
-		static_assert(DriverTypeInfo<T>::value, "unsupported type");
-
-		setValue(DriverTypeInfo<T>::bind(value));
-	}
-
-	/**
-	 * Convert the request to string.
-	 *
-	 * @return the request as a string
-	 */
-	operator std::string();
-};
-
-/**
- * @class Driver
- * @brief A generic SQL driver
- *
- * This class is used to connect to a database and execute SQL queries. It
- * does not include any DBMS code and just call virtual functions for
- * a simpler integration of new DBMS drivers.
- */
-class Driver {
-public:
-	class Impl;
-
-	using Params	= std::unordered_map<std::string, std::string>;
-	using Ptr	= std::shared_ptr<Impl>;
-
-	class Impl {
-	public:
-		/**
-		 * Create a synchronous connection, it waits and block until
-		 * the connection is made up to a specified timeout max.
-		 *
-		 * @param params a list of parameters.
-		 */
-		virtual void connect(const Params &params) = 0;
-
-		/**
-		 * Prepare a request with the specified SQL command.
-		 *
-		 * @param command the SQL command to parse and bind
-		 * @return a request to use with query
-		 * @see query
-		 */
-		virtual DriverRequest prepare(const std::string &command) = 0;
-	
-		/**
-		 * Execute a query.
-		 *
-		 * @param query the SQL command
-		 * @return a result
-		 * @throw Query::Error on failure
-		 */
-		virtual DriverQuery query(const std::string &command) = 0;
-
-		/**
-		 * Get the driver connection description.
-		 *
-		 * @return the description
-		 */
-		virtual std::string description() const = 0;
-
-		/**
-		 * Get the driver version as a string.
-		 *
-		 * @return the version
-		 */
-		virtual std::string version() const = 0;
-	};
-
-protected:
-	Ptr		m_impl;
-
-public:
-	Driver() = default;
-
-	/**
-	 * Virtual destructor.
-	 */
-	virtual ~Driver() = default;
-
-	/**
-	 * Wrapper for std::string variant.
-	 *
-	 * @param request the request to use
-	 * @return a result
-	 * @throw Query::Error on failure
-	 */
-	DriverQuery query(DriverRequest request);
-
-	/**
-	 * Create a synchronous connection, it waits and block until
-	 * the connection is made up to a specified timeout max.
-	 *
-	 * @param params a list of parameters.
-	 */
-	void connect(const Params &params);
-
-	/**
-	 * Prepare a request with the specified SQL command.
-	 *
-	 * @param command the SQL command to parse and bind
-	 * @return a request to use with query
-	 * @see query
-	 */
-	DriverRequest prepare(const std::string &command);
-
-	/**
-	 * Execute a query.
-	 *
-	 * @param query the SQL command
-	 * @return a result
-	 * @throw Query::Error on failure
-	 */
-	DriverQuery query(const std::string &command);
-
-	/**
-	 * Get the driver connection description.
-	 *
-	 * @return the description
-	 */
-	std::string description() const;
-
-	/**
-	 * Get the driver version as a string.
-	 *
-	 * @return the version
-	 */
-	std::string version() const;
-};
-
-template <>
-struct DriverTypeInfo<bool> : std::true_type {
-	static const DriverColumn	type = DriverColumn::Boolean;
-
-	static bool get(DriverQuery &query, int row, const std::string &column)
-	{
-		return query.m_impl->getBoolean(row, column);
-	}
-
-	static void bind(DriverRequest &request, bool value)
-	{
-		request.m_impl->bindBoolean(value);
-	}
-};
-
-template <>
-struct DriverTypeInfo<time_t> : std::true_type {
-	static const DriverColumn	type = DriverColumn::Date;
-
-	static time_t get(DriverQuery &query, int row, const std::string &column)
-	{
-		return query.m_impl->getDate(row, column);
-	}
-
-	static void bind(DriverRequest &request, time_t value)
-	{
-		request.m_impl->bindDate(value);
-	}
-};
-
-template <>
-struct DriverTypeInfo<double> : std::true_type {
-	static const DriverColumn	type = DriverColumn::Double;
-
-	static double get(DriverQuery &query, int row, const std::string &column)
-	{
-		return query.m_impl->getDouble(row, column);
-	}
-
-	static void bind(DriverRequest &request, double value)
-	{
-		request.m_impl->bindDouble(value);
-	}
-};
-
-template <>
-struct DriverTypeInfo<int> : std::true_type {
-	static const DriverColumn	type = DriverColumn::Integer;
-
-	static int get(DriverQuery &query, int row, const std::string &column)
-	{
-		return query.m_impl->getInt(row, column);
-	}
-
-	static void bind(DriverRequest &request, int value)
-	{
-		request.m_impl->bindInteger(value);
-	}
-};
-
-template <>
-struct DriverTypeInfo<std::string> : std::true_type {
-	static const DriverColumn	type = DriverColumn::String;
-
-	static std::string get(DriverQuery &query, int row, const std::string &column)
-	{
-		return query.m_impl->getString(row, column);
-	}
-
-	static void bind(DriverRequest &request, const std::string &value)
-	{
-		request.m_impl->bindString(value);
-	}
-};
-
-#endif // !_DRIVER_H_
--- a/C++/modules/Driver/DriverPostgres.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,482 +0,0 @@
-/*
- * DriverPostgres.cpp -- PostgreSQL driver
- *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <cerrno>
-#include <cstring>
-#include <iostream>
-#include <stdexcept>
-#include <sstream>
-#include <vector>
-
-#include <libpq-fe.h>
-
-#include "DriverPostgres.h"
-
-namespace {
-
-using PostgresResult	= std::shared_ptr<PGresult>;
-using PostgresConn	= std::shared_ptr<PGconn>;
-
-}
-
-/**
- * @class QueryPostgres
- * @brief Query implementation for PostgreSQL.
- */
-class QueryPostgresImpl : public DriverQuery::Impl {
-private:
-	PostgresConn	m_connection;
-	PostgresResult	m_result;
-
-public:
-	/**
-	 * Constructor used by DriverPostgres
-	 *
-	 * @param result the result
-	 */
-	QueryPostgresImpl(PostgresConn conn, PostgresResult result);
-
-	/**
-	 * @copydoc Query::getBoolean
-	 */
-	virtual bool getBoolean(int row, const std::string &column);
-
-	/**
-	 * @copydoc Query::getDate
-	 */
-	virtual time_t getDate(int row, const std::string &column);
-
-	/**
-	 * @copydoc Query::getDouble
-	 */
-	virtual double getDouble(int row, const std::string &column);
-
-	/**
-	 * @copydoc Query::getInt
-	 */
-	virtual int getInt(int row, const std::string &column);
-
-	/**
-	 * @copydoc Query::getString
-	 */
-	virtual std::string getString(int row, const std::string &column);
-
-	/**
-	 * @copydoc Query::type
-	 */
-	virtual DriverColumn type(const std::string &column) const;
-
-	/**
-	 * @copydoc Query::countRows
-	 */
-	virtual int countRows();
-
-	/**
-	 * @copydoc Query::countColumns
-	 */
-	virtual int countColumns();
-
-	/**
-	 * @copydoc Query::isNull
-	 */
-	virtual bool isNull(int row, const std::string &column);
-
-	/**
-	 * @copydoc Query::dump
-	 */
-	virtual void dump();
-};
-
-QueryPostgresImpl::QueryPostgresImpl(PostgresConn conn, PostgresResult result)
-	: m_connection(conn)
-	, m_result(result)
-{
-}
-
-DriverColumn QueryPostgresImpl::type(const std::string &column) const
-{
-	DriverColumn type;
-	int pqType, index;
-	
-	index = PQfnumber(m_result.get(), column.c_str());
-	pqType = PQftype(m_result.get(), index);
-	switch (pqType) {
-	case 16:
-		type = DriverColumn::Boolean;
-		break;
-	case 1082:
-	case 1083:
-	case 1114:
-	case 1184:
-		type = DriverColumn::Date;
-		break;
-	case 1700:
-	case 700:
-	case 701:
-		type = DriverColumn::Double;
-		break;
-	case 20:
-	case 21:
-	case 23:
-		type = DriverColumn::Integer;
-		break;
-	case 25:
-	case 1042:
-	case 1043:
-		type = DriverColumn::String;
-		break;
-	default:
-		type = DriverColumn::Invalid;
-	}
-
-	return type;
-}
-
-int QueryPostgresImpl::countRows()
-{
-	return PQntuples(m_result.get());
-}
-
-int QueryPostgresImpl::countColumns()
-{
-	return PQnfields(m_result.get());
-}
-
-bool QueryPostgresImpl::isNull(int row, const std::string &column)
-{
-	int idx = PQfnumber(m_result.get(), column.c_str());
-
-	return PQgetisnull(m_result.get(), row, idx) == 1;
-}
-
-void QueryPostgresImpl::dump(void)
-{
-	std::cout << "Dumping PostgreSQL result, ";
-	std::cout << countRows() << " rows, ";
-	std::cout << countColumns() << " columns" << std::endl;
-
-	for (int r = 0; r < countRows(); ++r) {
-		std::cout << "Dumping row " << r << std::endl;
-		std::cout << "==============================" << std::endl;
-
-		for (int c = 0; c < countColumns(); ++c) {
-			std::cout << "\t" << PQfname(m_result.get(), c);
-			std::cout << " = " << PQgetvalue(m_result.get(), r, c) << std::endl;
-		}
-	}
-}
-
-bool QueryPostgresImpl::getBoolean(int row, const std::string &column)
-{
-	int idx = PQfnumber(m_result.get(), column.c_str());
-	std::string code = PQgetvalue(m_result.get(), row, idx);
-
-	return code[0] == 't';
-}
-
-time_t QueryPostgresImpl::getDate(int row, const std::string &column)
-{
-	int idx = PQfnumber(m_result.get(), column.c_str());
-	time_t timestamp = std::time(nullptr);
-
-	try {
-		std::ostringstream oss;
-		std::string value, req;
-
-		value = PQgetvalue(m_result.get(), row, idx);
-
-		/*
-		 * Convert the date using the SQL function so that user does
-		 * not require any explicit conversion itself.
-		 */
-		printf("%s\n", value.c_str());
-		oss << "Select EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE '";
-		oss << value;
-		oss << "') AS RESULT";
-		req = oss.str();
-
-		auto info = PQexec(m_connection.get(), oss.str().c_str());
-		auto status = PQresultStatus(info);
-
-		if (info != nullptr && (status == PGRES_COMMAND_OK ||
-		    status == PGRES_TUPLES_OK))
-		{
-			timestamp = atoi(PQgetvalue(info, 0, 0));
-			PQclear(info);
-		}
-	} catch (...) { }
-
-	return timestamp;
-}
-
-double QueryPostgresImpl::getDouble(int row, const std::string &column)
-{
-	int idx = PQfnumber(m_result.get(), column.c_str());
-
-	return std::stod(PQgetvalue(m_result.get(), row, idx));
-}
-
-int QueryPostgresImpl::getInt(int row, const std::string &column)
-{
-	int idx = PQfnumber(m_result.get(), column.c_str());
-
-	return std::stoi(PQgetvalue(m_result.get(), row, idx));
-}
-
-std::string QueryPostgresImpl::getString(int row, const std::string &column)
-{
-	int idx = PQfnumber(m_result.get(), column.c_str());
-
-	return std::string(PQgetvalue(m_result.get(), row, idx));
-}
-
-/* --------------------------------------------------------
- * Request PostgreSQL Impl
- * -------------------------------------------------------- */
-
-/**
- * @class RequestPostgres
- * @brief Request implementation for PostgreSQL.
- */
-class RequestPostgres : public DriverRequest::Impl {
-private:
-	std::shared_ptr<PGconn> m_connection;
-
-protected:
-	/**
-	 * @copydoc Request::bindBoolean
-	 */
-	virtual std::string bindBoolean(bool value);
-
-	/**
-	 * @copydoc Request::bindDate
-	 */
-	virtual std::string bindDate(time_t value);
-
-	/**
-	 * @copydoc Request::bindDouble
-	 */
-	virtual std::string bindDouble(double value);
-
-	/**
-	 * @copydoc Request::bindInteger
-	 */
-	virtual std::string bindInteger(int value);
-
-	/**
-	 * @copydoc Request::bindString
-	 */
-	virtual std::string bindString(std::string value);
-
-public:
-	/**
-	 * Construct a request for PostgreSQL.
-	 *
-	 * @param conn the connection
-	 * @param command the command
-	 */
-	RequestPostgres(PostgresConn &conn);
-};
-
-RequestPostgres::RequestPostgres(PostgresConn &conn)
-{
-	m_connection = conn;
-}
-
-std::string RequestPostgres::bindBoolean(bool value)
-{
-	return (value) ? "'t'" : "'f'";
-}
-
-std::string RequestPostgres::bindDate(time_t value)
-{
-	std::ostringstream oss;
-
-	oss << "to_timestamp(" << value << ")";
-
-	return oss.str();
-}
-
-std::string RequestPostgres::bindDouble(double value)
-{
-	return std::to_string(value);
-}
-
-std::string RequestPostgres::bindInteger(int value)
-{
-	return std::to_string(value);
-}
-
-std::string RequestPostgres::bindString(std::string value)
-{
-	std::string result;
-	char *tmp;
-
-	tmp = PQescapeLiteral(m_connection.get(), value.c_str(), value.length());
-	if (tmp == nullptr)
-		return "";
-
-	result = std::string(tmp);
-	PQfreemem(tmp);
-
-	return result;
-}
-
-/* --------------------------------------------------------
- * Driver PostgreSQL impl
- * -------------------------------------------------------- */
-
-/**
- * @class DriverPostgres
- * @brief Driver implementation for PostgreSQL.
- */
-class DriverPostgresImpl : public Driver::Impl {
-private:
-	PostgresConn m_connection;
-
-	/**
-	 * Convert the Params from the config
-	 * to the PostgreSQL string.
-	 *
-	 * @param settings the table
-	 * @return a string to be used
-	 */
-	std::string convert(Driver::Params &settings);
-
-public:
-	/**
-	 * @copydoc Driver::connect
-	 */
-	virtual void connect(const Driver::Params &params);
-
-	/**
-	 * @copydoc Driver::prepare
-	 */
-	virtual DriverRequest prepare(const std::string &command);
-
-	/**
-	 * @copydoc Driver::query
-	 */
-	virtual DriverQuery query(const std::string &command);
-
-	/**
-	 * @copydoc Driver::description
-	 */
-	virtual std::string description() const;
-
-	/**
-	 * @copydoc Driver::version
-	 */
-	virtual std::string version() const;
-};
-
-std::string DriverPostgresImpl::convert(Driver::Params &params)
-{
-	std::ostringstream oss;
-	std::vector<std::string> required { "host", "port", "user", "database", "password" };
-
-	for (auto s : required)
-		if (params.count(s) <= 0)
-			throw std::runtime_error("missing parameter " + s);
-
-	oss << "host = " << params["host"] << " ";
-	oss << "port = " << params["port"] << " ";
-	oss << "user = " << params["user"] << " ";
-	oss << "dbname = " << params["database"] << " ";
-	oss << "password = " << params["password"];
-
-	return oss.str();
-}
-
-void DriverPostgresImpl::connect(const Driver::Params &params)
-{
-	auto copy = params;
-	auto conn = PQconnectdb(convert(copy).c_str());
-
-	if (conn == nullptr)
-		throw std::runtime_error(std::strerror(ENOMEM));
-
-	if (PQstatus(conn) == CONNECTION_BAD) {
-		auto error = PQerrorMessage(conn);
-		PQfinish(conn);
-
-		throw std::runtime_error(error);
-	}
-
-	m_connection = std::shared_ptr<PGconn>(conn, PQfinish);
-}
-
-DriverRequest DriverPostgresImpl::prepare(const std::string &command)
-{
-	return DriverRequest(std::make_shared<RequestPostgres>(m_connection), command);
-}
-
-DriverQuery DriverPostgresImpl::query(const std::string &cmd)
-{
-	PGresult *info;
-
-	// If NULL, the libpq said no memory
-	info = PQexec(m_connection.get(), cmd.c_str());
-	if (info == nullptr)
-		throw std::runtime_error(strerror(ENOMEM));
-
-	// If an error occured
-	int errorCode = PQresultStatus(info);
-	if (errorCode != PGRES_COMMAND_OK && errorCode != PGRES_TUPLES_OK) {
-		auto error = PQresultErrorMessage(info);
-		PQclear(info);
-
-		throw std::runtime_error(error);
-	}
-
-	auto result = std::shared_ptr<PGresult>(info, PQclear);
-	auto impl = std::make_shared<QueryPostgresImpl>(m_connection, result);
-
-	return DriverQuery(impl);
-}
-
-std::string DriverPostgresImpl::description() const
-{
-	std::ostringstream oss;
-
-	oss << "Connected on PostgreSQL database: " << std::endl;
-	oss << "  host: " << PQhost(m_connection.get()) << std::endl;
-	oss << "  port: " << PQport(m_connection.get()) << std::endl;
-	oss << "  user: " << PQuser(m_connection.get()) << std::endl;
-	oss << "  database: " << PQdb(m_connection.get()) << std::endl;
-
-	return oss.str();
-}
-
-std::string DriverPostgresImpl::version() const
-{
-	std::ostringstream oss;
-
-	oss << "PostgreSQL driver (version " << PQlibVersion() << ")";
-
-	return oss.str();
-}
-
-/* --------------------------------------------------------
- * Driver PostgreSQL
- * -------------------------------------------------------- */
-
-DriverPostgres::DriverPostgres()
-{
-	m_impl = std::make_shared<DriverPostgresImpl>();
-}
--- a/C++/modules/Driver/DriverPostgres.h	Mon Oct 05 13:22:20 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * DriverPostgres.h -- PostgreSQL driver
- *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * http://www.postgresql.org/docs/9.2/static/libpq-connect.html#LIBPQ-PARAMKEYWORDS
- */
-
-#ifndef _DRIVER_PG_H_
-#define _DRIVER_PG_H_
-
-#include "Driver.h"
-
-class DriverPostgres : public Driver {
-public:
-	DriverPostgres();
-};
-
-#endif // !_DRIVER_PG_H_
--- a/C++/modules/Dynlib/Dynlib.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Dynlib/Dynlib.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * DynLib.cpp -- portable shared library loader
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Dynlib/Dynlib.h	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Dynlib/Dynlib.h	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * DynLib.h -- portable shared library loader
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Flags/Flags.h	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Flags/Flags.h	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Flags.h -- safe wrapper for enum flags
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Hash/Hash.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Hash/Hash.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Hash.cpp -- hash functions
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Hash/Hash.h	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Hash/Hash.h	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Hash.h -- hash functions
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Ini/Ini.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Ini/Ini.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Ini.cpp -- .ini file parsing
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Ini/Ini.h	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Ini/Ini.h	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Ini.h -- .ini file parsing
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Json/Json.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Json/Json.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Json.cpp -- jansson C++11 wrapper
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Json/Json.h	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Json/Json.h	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Json.h -- jansson C++11 wrapper
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/OptionParser/OptionParser.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/OptionParser/OptionParser.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * OptionParser.cpp -- command line option parser
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/OptionParser/OptionParser.h	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/OptionParser/OptionParser.h	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * OptionParser.h -- command line option parser
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Socket/Socket.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Socket/Socket.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Socket.cpp -- portable C++ socket wrappers
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Socket/Socket.h	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Socket/Socket.h	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Socket.h -- portable C++ socket wrappers
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Socket/SocketAddress.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Socket/SocketAddress.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * SocketAddress.cpp -- socket addresses management
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Socket/SocketAddress.h	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Socket/SocketAddress.h	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * SocketAddress.h -- socket addresses management
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Socket/SocketListener.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Socket/SocketListener.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * SocketListener.cpp -- portable select() wrapper
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Socket/SocketListener.h	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Socket/SocketListener.h	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * SocketListener.h -- portable select() wrapper
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Socket/SocketSsl.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Socket/SocketSsl.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * SocketSsl.cpp -- OpenSSL extension for sockets
  *
- * Copyright (c) 2013, David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Socket/SocketSsl.h	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Socket/SocketSsl.h	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * SocketSsl.h -- OpenSSL extension for sockets
  *
- * Copyright (c) 2013, David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Treenode/TreeNode.h	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Treenode/TreeNode.h	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * TreeNode.h -- C++14 pointer-free N-ary tree
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Unicode/Unicode.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Unicode/Unicode.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Unicode.cpp -- UTF-8 to UTF-32 conversions and various operations
  *
- * Copyright (c) 2013, 2014, 2015 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Unicode/Unicode.h	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Unicode/Unicode.h	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Unicode.h -- UTF-8 to UTF-32 conversions and various operations
  *
- * Copyright (c) 2013, 2014, 2015 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Xdg/Xdg.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Xdg/Xdg.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Xdg.cpp -- XDG directory specifications
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Xdg/Xdg.h	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Xdg/Xdg.h	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Xdg.h -- XDG directory specifications
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Zip/ZipArchive.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Zip/ZipArchive.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * ZipArchive.cpp -- wrapper around libzip
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/modules/Zip/ZipArchive.h	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/modules/Zip/ZipArchive.h	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * ZipArchive.h -- wrapper around libzip
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/tests/Base64/main.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/tests/Base64/main.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- main test file for Base64
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/tests/Directory/main.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/tests/Directory/main.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test directory
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/tests/Dynlib/main.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/tests/Dynlib/main.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * TestDynLib.cpp -- test the dynamic library loader
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/tests/Flags/main.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/tests/Flags/main.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- main test file for Flags
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/tests/Hash/main.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/tests/Hash/main.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test the hash cryptographic functions
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/tests/Ini/main.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/tests/Ini/main.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- main test file for Ini
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/tests/Js/main.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/tests/Js/main.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * TestJsUnicode.cpp -- test irccd JS functions
  *
- * Copyright (c) 2013, 2014, 2015 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/tests/Json/main.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/tests/Json/main.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test the jansson wrapper
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/tests/OptionParser/main.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/tests/OptionParser/main.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- main test file for OptionParser
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/tests/Socket/main.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/tests/Socket/main.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test sockets
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/tests/Treenode/main.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/tests/Treenode/main.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- main test file for TreeNode
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/tests/Unicode/main.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/tests/Unicode/main.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- main test file for Utf8
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/tests/Xdg/main.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/tests/Xdg/main.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- main test file for XDG
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/C++/tests/Zip/main.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/C++/tests/Zip/main.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * main.cpp -- test the zip wrapper functions
  *
- * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/CMakeLists.txt	Mon Oct 05 13:22:20 2015 +0200
+++ b/CMakeLists.txt	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- code building for common code
 #
-# Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+# Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -20,7 +20,7 @@
 # This CMakeLists build system is primarily used for testing all
 # modules.
 #
-cmake_minimum_required(VERSION 2.8.11)
+cmake_minimum_required(VERSION 3.0)
 project(code)
 
 set(CMAKE_MODULE_PATH ${code_SOURCE_DIR}/cmake)
--- a/extern/CMakeLists.txt	Mon Oct 05 13:22:20 2015 +0200
+++ b/extern/CMakeLists.txt	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- code building for common code
 #
-# Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+# Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/extern/duktape/CMakeLists.txt	Mon Oct 05 13:22:20 2015 +0200
+++ b/extern/duktape/CMakeLists.txt	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- code building for common code
 #
-# Copyright (c) 2013, 2014, 2015 David Demelier <markand@malikania.fr>
+# Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/extern/gtest/CMakeLists.txt	Mon Oct 05 13:22:20 2015 +0200
+++ b/extern/gtest/CMakeLists.txt	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- code building for common code
 #
-# Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+# Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tools/CMakeLists.txt	Mon Oct 05 13:22:20 2015 +0200
+++ b/tools/CMakeLists.txt	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- code building for common code
 #
-# Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+# Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tools/cat/CMakeLists.txt	Mon Oct 05 13:22:20 2015 +0200
+++ b/tools/cat/CMakeLists.txt	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- code building for common code
 #
-# Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+# Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tools/cat/cat.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/tools/cat/cat.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * cccat.cpp -- very basic cat replacement for portability
  *
- * Copyright (c) 2013, 2014, 2015 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/tools/linktool/CMakeLists.txt	Mon Oct 05 13:22:20 2015 +0200
+++ b/tools/linktool/CMakeLists.txt	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- code building for common code
 #
-# Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+# Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tools/mkunicode/CMakeLists.txt	Mon Oct 05 13:22:20 2015 +0200
+++ b/tools/mkunicode/CMakeLists.txt	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 #
 # CMakeLists.txt -- code building for common code
 #
-# Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
+# Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
 #
 # Permission to use, copy, modify, and/or distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
--- a/tools/mkunicode/Unicode-before.cpp	Mon Oct 05 13:22:20 2015 +0200
+++ b/tools/mkunicode/Unicode-before.cpp	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Unicode.cpp -- UTF-8 to UTF-32 conversions and various operations
  *
- * Copyright (c) 2013, 2014, 2015 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
--- a/tools/mkunicode/Unicode.h	Mon Oct 05 13:22:20 2015 +0200
+++ b/tools/mkunicode/Unicode.h	Mon Oct 05 14:27:19 2015 +0200
@@ -1,7 +1,7 @@
 /*
  * Unicode.h -- UTF-8 to UTF-32 conversions and various operations
  *
- * Copyright (c) 2013, 2014, 2015 David Demelier <markand@malikania.fr>
+ * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above