/**
 * @file
 * @brief Posixregex, descriptors and sockets.
 */
#ifndef UI_UTIL_POSIXREGEX_HPP
#define UI_UTIL_POSIXREGEX_HPP

// STDC++
#include <string>

// POSIX C
#include <regex.h>

// C++ libraries
#include <ui-utilcpp/Exception.hpp>

namespace UI {
namespace Util {

/** @example Regex.cpp Example on how to use the PosixRegex class. */

/** @brief Wrapper class for POSIX.2 regex functions.
 *
 * @note For the future, one might rather use the libboost's regexx implementation.
 *
 * @see regex(3)
 * @bug Not fully encapsulated; flags must be given using the values from regex.h; Catched
 * exception code must be compared against the reg_errcode_t defined in regex.h.
 * @bug Does not support multiple matches (seems this does not work anyway currently)
 * @bug Does not support clear text error reporting as via regerror.
 */
class PosixRegex
{
private:
	std::string getErrorMessage(int result) const;

public:
	/** @brief Exceptions we might throw. */
	typedef CodeException<reg_errcode_t> Exception;

	/** @brief Helper class representing match data. */
	class Match
	{
	public:
		Match(): matches(false), begin(0), end(0) {}
		/** Do we have a match? */
		bool matches;
		/** If yes: where it begins */
		unsigned begin;
		/** If yes: where it ends */
		unsigned end;
	};

	/**
	 * @param regex The regular expression
	 * @param cflags Flags as described in regex(3)
	 */
	PosixRegex(std::string const & regex, int cflags=0);

	/** */
	~PosixRegex();

	/** @brief Check if text matches, and return the (first) match.
	 *
	 * @param text Text to examine.
	 * @param eflags Flags as described in regex(3).
	 * @returns First match found; if no match, match.matches will be false.
	 */
	Match runMatch(std::string const & text, int eflags=0);

	/** @brief Check if text matches.
	 *
	 * @param text Text to examine.
	 * @param eflags Flags as described in regex(3).
	 * @returns True if match found; else false.
	 */
	bool run(std::string const & text, int eflags=0);

private:
	regex_t preg_;
};

}}
#endif
