Merge branch 'master' of gitproxy:cs0rbagomba/cpp_utils

master
Denes Matetelki 13 years ago
commit 4fa576f959

@ -0,0 +1,32 @@
#!/usr/bin/python
import os
import cxxtest
env = Environment( ENV = {
'PATH' : "/usr/lib/colorgcc/bin:" + os.environ['PATH'],
'TERM' : os.environ['TERM'],
'HOME' : os.environ['HOME'],
'CCACHE_PATH' : "/usr/bin",
'CXX' : '/usr/lib/colorgcc/bin/g++',
'CCACHE_LOGFILE' : '/tmp/denes.txt'
#'tools' : ['default', 'cxxtest']
})
env['CXXFLAGS'] = '-Wall -Wextra -pedantic -Wshadow -Weffc++ -std=c++0x -ggdb'
env['CPPPATH'] = 'include'
env['tools'] = ['default', 'cxxtest']
#from pprint import pprint
#pprint (vars(env))
env.SharedLibrary('cpp_utils',
Glob('src/*.cpp'),
LIBS = ['pthread', 'rt'] )
#env.Program('test/test',
#'test/generated_main.cpp',
#LIBS = ['cpp_utils'],
#LIBPATH = '.')
env.CxxTest('target')

1548
doxyfile

File diff suppressed because it is too large Load Diff

@ -19,7 +19,7 @@ public:
NONE, NONE,
STRING, STRING,
INT, INT,
DOUBLE, FLOAT,
BOOL BOOL
}; };
@ -28,7 +28,8 @@ public:
REQUIRED REQUIRED
}; };
/** @param description Exmplanation, before the usage lines. /** @param description Exmplanation of the purpose of the program,
* before the usage lines.
* @param epilog Lines after the usage and options. Usually contact e-mail. * @param epilog Lines after the usage and options. Usually contact e-mail.
* @param addHelp Add a "-h,--help" option. * @param addHelp Add a "-h,--help" option.
*/ */
@ -39,12 +40,14 @@ public:
/** @brief Adds an argument which the object will accept. /** @brief Adds an argument which the object will accept.
* *
* @param name short and/or long form: "-f,--foo" * @param name short and/or long form: "-f,--foo"
* The value can be retreived with this string passed to the argAs... functions.
* @param help Description of the argument, printed when --help is given. * @param help Description of the argument, printed when --help is given.
* @param type Type of the paramterer, required by the argument. * @param type Type of the paramterer, required by the argument.
* @param valueRequired Parameter requiered/optional after the argument. * @param valueRequired Parameter requiered/optional after the argument.
* @param valueName Default is the type. But some short text can be better. * @param valueName Default is the type. But some short text can be better.
* @param choices Comma separeted list of strings: "yes,no,maybe" * @param choices Comma separeted list of strings without whitespaces:
* or a range accepted numbers: NUM..NUM * "yes,no,maybe"
* or a range accepted numbers: "INT..INT", "DOUBLE..DOUBLE"
*/ */
void addArgument(const std::string name, void addArgument(const std::string name,
const std::string help, const std::string help,
@ -55,14 +58,13 @@ public:
/** @brief Parse command line arguments according to the accepted arguments. /** @brief Parse command line arguments according to the accepted arguments.
* *
* Wrapper around the other version of parseArgs. * Wrapper around the list<string> version of parseArgs.
* *
* @param argc Argumetn counter of the main function. * @param argc Argumetn counter of the main function.
* @param argv Argument vector of the main function. * @param argv Argument vector of the main function.
* @throw std::runtime_error When the command line args are bad. * @throw std::runtime_error When the command line args are bad.
* Shall be cought be the client code! * Shall be cought be the client code!
* @throw std::logic_error If the addArgument was bad. * @throw std::logic_error If the addArgument was bad.
* @todo addArgument shall handle this!
*/ */
void parseArgs(const int argc, void parseArgs(const int argc,
const char* argv[]); const char* argv[]);
@ -80,7 +82,7 @@ public:
// arg need to be the same string as in addArgument ( "-h,--help" ) // arg need to be the same string as in addArgument ( "-h,--help" )
bool argAsString(const std::string arg, std::string &value) const; bool argAsString(const std::string arg, std::string &value) const;
bool argAsInt(const std::string arg, int &value) const; bool argAsInt(const std::string arg, int &value) const;
bool argAsDouble(const std::string arg, double &value) const; bool argAsFloat(const std::string arg, float &value) const;
bool argAsBool(const std::string arg, bool &value) const; bool argAsBool(const std::string arg, bool &value) const;
std::string usage() const; std::string usage() const;
@ -88,6 +90,26 @@ public:
private: private:
void validateValue(const ArgParse::ValueType type,
const std::string name,
const std::string choices,
const std::string value) const;
void validateString( const std::string name,
const std::string choices,
const std::string value) const;
void validateInt( const std::string name,
const std::string choices,
const std::string value) const;
void validateFloat( const std::string name,
const std::string choices,
const std::string value) const;
void validateBool( const std::string name,
const std::string choices,
const std::string value) const;
struct Argument { struct Argument {
const std::string m_help; const std::string m_help;
const enum ValueType m_type; const enum ValueType m_type;
@ -109,15 +131,21 @@ private:
class argCompare { class argCompare {
public: public:
// short and long arg shall be compared with same amount of dashes // short and long arg shall be compared with same amount of dashes
// this is needed at the usage, so the order of the params is ok,
// even when a param has short/long/booth name
bool operator()(const std::string a,const std::string b) const; bool operator()(const std::string a,const std::string b) const;
}; };
typedef std::map<std::string, Argument, argCompare> ArgMap; typedef std::map<std::string, Argument, argCompare> ArgMap;
// arg is just the shor or long form: "-h" or "--help" // arg is just the shor or long form: "-h" or "--help"
ArgMap::iterator findElement(const std::string param); ArgMap::iterator findKeyinArgMap(const std::string param);
std::set<std::string> parseCommaSepStringToSet(const std::string s) const; std::set<std::string> choicesStringToSet(const std::string s) const;
std::string typeToString(const ValueType type, const std::string valueName) const;
/** @return with valueName if specified,
or the string version of the type enum otherwise */
std::string typeToString(const ValueType type,
const std::string valueName) const;
std::string m_description; std::string m_description;

@ -0,0 +1,27 @@
#ifndef INET_SOCKET_CLIENT_HPP
#define INET_SOCKET_CLIENT_HPP
#include "socketClient.hpp"
class InetSocketClient : public SocketClient
{
public:
InetSocketClient( const std::string host,
const int port );
~InetSocketClient();
private:
bool connectToPeer(void);
std::string m_host;
int m_port;
struct sockaddr_in m_serverAddr;
};
#endif // INET_SOCKET_CLIENT_HPP

@ -0,0 +1,27 @@
#ifndef LOCAL_SOCKET_CLIENT_HPP
#define LOCAL_SOCKET_CLIENT_HPP
#include "socketClient.hpp"
#include <sys/un.h>
class LocalSocketClient : public SocketClient
{
public:
LocalSocketClient( const std::string sockPath);
~LocalSocketClient();
private:
bool connectToPeer(void);
std::string m_sockPath;
struct sockaddr_un m_remote;
};
#endif // LOCAL_SOCKET_CLIENT_HPP

@ -0,0 +1,36 @@
#ifndef SOCKET_CLIENT_HPP
#define SOCKET_CLIENT_HPP
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
class SocketClient
{
public:
SocketClient( const int addrDomain,
const int socketType);
virtual ~SocketClient();
bool send(const std::string msg);
bool receive(std::string &reply);
protected:
bool connect(void);
virtual bool connectToPeer(void) = 0;
std::string errorToString(const char *s) const;
bool m_connected;
int m_addrDomain;
int m_socketType;
int m_socketfd;
};
#endif // SOCKET_CLIENT_HPP

@ -1,4 +1,4 @@
#include "../include/ArgParse.hpp" #include "ArgParse.hpp"
#include <iostream> #include <iostream>
@ -10,8 +10,8 @@
#include <stdexcept> #include <stdexcept>
#include <stdio.h> #include <cstdio> // sscan
#include <cctype>
ArgParse::ArgParse(const std::string description, ArgParse::ArgParse(const std::string description,
@ -34,20 +34,48 @@ void ArgParse::addArgument(const std::string arg,
const std::string valueName, const std::string valueName,
const std::string choices) const std::string choices)
{ {
if ( arg.at(0) != '-' )
throw std::logic_error(std::string(arg).
append(" shall start with a dash."));
Argument argument(help, type, valueRequired, typeToString(type, valueName), choices, ""); if ( findKeyinArgMap(arg) != m_params.end() )
throw std::logic_error(std::string(arg).
append(" has been given before."));
int i;
if ( type == INT &&
!choices.empty() &&
sscanf( choices.c_str(), "%d..%d", &i, &i ) != 2 )
throw std::logic_error(std::string( arg ).
append(" has syntax error. ").
append("Range expected in a INT..INT format" ));
float f;
if ( type == FLOAT &&
!choices.empty() &&
sscanf( choices.c_str(), "%f..%f", &f, &f ) != 2 )
throw std::logic_error(std::string( arg ).
append(" has syntax error. ").
append("Range expected in a FLOAT..FLOAT format" ));
Argument argument(help,
type,
valueRequired,
typeToString(type, valueName),
choices,
"");
m_params.insert(std::pair<std::string, Argument>(arg, argument)); m_params.insert(std::pair<std::string, Argument>(arg, argument));
} }
bool ArgParse::parseArgs(const int argc, void ArgParse::parseArgs(const int argc,
const char* argv[]) const char* argv[])
{ {
std::list<std::string> argList; std::list<std::string> argList;
for (int i = 0; i < argc; ++i ) for (int i = 0; i < argc; ++i )
argList.push_back(argv[i]); argList.push_back(argv[i]);
return parseArgs(argList); parseArgs(argList);
} }
@ -55,138 +83,154 @@ void ArgParse::parseArgs(const std::list<std::string> argList)
{ {
m_programName = argList.front(); m_programName = argList.front();
// the wrok.
std::list<std::string>::const_iterator it = argList.begin(); std::list<std::string>::const_iterator it = argList.begin();
for (++it; it != argList.end(); ++it ) { for (++it; it != argList.end(); ++it ) {
if ( (*it).at(0) != '-' ) ArgMap::iterator argMapIt = findKeyinArgMap(*it);
throw std::runtime_error(std::string(*it). if ( argMapIt == m_params.end() )
append(" shall start with a dash."));
// inspect each arument
ArgMap::iterator it2 = findElement(*it);
if ( it2 == m_params.end() )
throw std::runtime_error(std::string(*it).append(" is not known.")); throw std::runtime_error(std::string(*it).append(" is not known."));
if ( (*it2).second.m_found ) (*argMapIt).second.m_found = true;
throw std::runtime_error(std::string(*it).
append(" has been given before."));
(*it2).second.m_found = true;
if ( (*it2).second.m_type == NONE ) if ( (*argMapIt).second.m_type == NONE )
continue; continue;
std::list<std::string>::const_iterator next = it; std::list<std::string>::const_iterator next = it;
next++; next++;
if ( next == argList.end() ) { if ( next == argList.end() ) {
if ( (*it2).second.m_valueRequired == REQUIRED ) if ( (*argMapIt).second.m_valueRequired == REQUIRED )
throw std::runtime_error(std::string(*it). throw std::runtime_error(std::string(*it).
append(" requires a parameter.")); append(" requires a parameter."));
if ( (*it2).second.m_valueRequired == OPTIONAL ) if ( (*argMapIt).second.m_valueRequired == OPTIONAL )
continue; continue;
} }
if ( (*it2).second.m_valueRequired == OPTIONAL && if ( (*argMapIt).second.m_valueRequired == OPTIONAL &&
findElement( *next ) != m_params.end() ) findKeyinArgMap( *next ) != m_params.end() )
continue; continue;
switch ( (*it2).second.m_type ) { validateValue( (*argMapIt).second.m_type,
case INT : { (*argMapIt).first,
int temp; (*argMapIt).second.m_choices,
if ( sscanf( next->c_str(), "%d", &temp ) == 0 ) *next );
throw std::runtime_error(std::string( *next ).
append(" is not an integer, required by ").append( *it ));
if ( !(*it2).second.m_choices.empty() ) {
int lowerBound;
int upperBound;
if ( sscanf( (*it2).second.m_choices.c_str(),
"%d..%d", &lowerBound, &upperBound ) != 2 )
throw std::logic_error(std::string( *it ).
append(" has syntax error. ").
append("Range expected in a INT..INT format" ));
if ( temp < lowerBound || temp > upperBound )
throw std::runtime_error(std::string( *it ).
append( " expects an integer in the range of {" ).
append( (*it2).second.m_choices).
append("}") );
}
break;
}
case DOUBLE : {
double temp;
if ( sscanf( next->c_str(), "%f", &temp ) == 0 )
throw std::runtime_error(std::string( *next ).
append(" is not a double, required by ").append(*it));
if ( !(*it2).second.m_choices.empty() ) {
double lowerBound;
double upperBound;
if ( sscanf( (*it2).second.m_choices.c_str(),
"%f..%f", &lowerBound, &upperBound ) != 2 )
throw std::logic_error(std::string( *it ).
append(" has syntax error. ").
append("Range expected in a DOUBLE..DOUBLE format" ));
if ( temp < lowerBound || temp > upperBound )
throw std::runtime_error(std::string( *it ).
append( " expects a double in the range of [" ).
append( (*it2).second.m_choices).
append("}") );
}
break;
}
case BOOL : {
std::string temp = *next;
std::transform(temp.begin(), temp.end(),temp.begin(), ::toupper);
if ( temp != "TRUE" && temp != "FALSE" )
throw std::runtime_error(std::string( *next ).
append(" is not a boolean, required by ").append(*it));
if ( !(*it2).second.m_choices.empty() )
throw std::logic_error(std::string( *next ).
append(" expects a boolean not choices."));
break;
}
case STRING : {
if ( !(*it2).second.m_choices.empty() ) {
std::set<std::string> choices = (*argMapIt).second.m_value = *next;
parseCommaSepStringToSet( (*it2).second.m_choices ); (*argMapIt).second.m_valueHasBeenSet = true;
++it;
}
}
if ( choices.find( *next ) == choices.end() )
throw std::runtime_error(std::string( *next ).
append(" is not in the expected list of choices: {").
append( (*it2).second.m_choices ).
append("}"));
}
break; void ArgParse::validateValue(const ArgParse::ValueType type,
} const std::string name,
const std::string choices,
const std::string value) const
{
switch ( type ) {
case INT :
validateInt(name, choices, value);
break;
case FLOAT :
validateFloat(name, choices, value);
break;
case BOOL :
validateBool(name, choices, value);
break;
case STRING :
validateString(name, choices, value);
break;
default:
break;
}
}
default:
break;
}
void ArgParse::validateString( const std::string name,
const std::string choices,
const std::string value) const
{
if ( !choices.empty() ) {
(*it2).second.m_value = *next; std::set<std::string> choicesSet = choicesStringToSet( choices );
(*it2).second.m_valueHasBeenSet = true;
++it; if ( choicesSet.find( value ) == choicesSet.end() )
throw std::runtime_error(std::string( value ).
append(" is not in the expected list of choices: {").
append( choices ).
append("}, required by ").
append( name ));
}
}
void ArgParse::validateInt( const std::string name,
const std::string choices,
const std::string value) const
{
int temp;
if ( sscanf( value.c_str(), "%d", &temp ) == 0 )
throw std::runtime_error(std::string( value ).
append(" is not an integer, required by ").append( name ));
if ( !choices.empty() ) {
int lowerBound;
int upperBound;
sscanf( choices.c_str(), "%d..%d", &lowerBound, &upperBound );
if ( temp < lowerBound || temp > upperBound )
throw std::runtime_error(std::string( name ).
append( " expects an integer in the range of {" ).
append( choices).
append("}") );
}
}
void ArgParse::validateFloat( const std::string name,
const std::string choices,
const std::string value) const
{
float temp;
if ( sscanf( value.c_str(), "%f", &temp ) == 0 )
throw std::runtime_error(std::string( value ).
append(" is not a float, required by ").append( name ));
if ( !choices.empty() ) {
float lowerBound;
float upperBound;
sscanf( choices.c_str(), "%f..%f", &lowerBound, &upperBound );
if ( temp < lowerBound || temp > upperBound )
throw std::runtime_error(std::string( name ).
append( " expects a float in the range of [" ).
append( choices).
append("}") );
} }
} }
void ArgParse::isArg(const std::string arg) const void ArgParse::validateBool( const std::string name,
const std::string choices,
const std::string value) const
{
std::string temp = value;
std::transform(temp.begin(), temp.end(),temp.begin(), ::toupper);
if ( temp != "TRUE" && temp != "FALSE" )
throw std::runtime_error(std::string( value ).
append(" is not a boolean, required by ").append( name ));
if ( !choices.empty() )
throw std::logic_error(std::string( value ).
append(" expects a boolean not choices."));
}
bool ArgParse::isArg(const std::string arg) const
{ {
ArgMap::const_iterator it = m_params.find(arg); ArgMap::const_iterator it = m_params.find(arg);
it != m_params.end(); return it != m_params.end();
} }
@ -227,7 +271,7 @@ bool ArgParse::argAsInt(const std::string arg, int &value) const
} }
bool ArgParse::argAsDouble(const std::string arg, double &value) const bool ArgParse::argAsFloat(const std::string arg, float &value) const
{ {
if ( !argHasValue(arg) ) if ( !argHasValue(arg) )
return false; return false;
@ -335,7 +379,7 @@ ArgParse::argCompare::operator()(const std::string a,const std::string b) const
std::map<std::string, ArgParse::Argument>::iterator std::map<std::string, ArgParse::Argument>::iterator
ArgParse::findElement(const std::string param) ArgParse::findKeyinArgMap(const std::string param)
{ {
ArgMap::iterator it; ArgMap::iterator it;
for( it = m_params.begin(); it != m_params.end(); ++it) { for( it = m_params.begin(); it != m_params.end(); ++it) {
@ -355,7 +399,7 @@ ArgParse::findElement(const std::string param)
} }
std::set<std::string> std::set<std::string>
ArgParse::parseCommaSepStringToSet(const std::string s) const ArgParse::choicesStringToSet(const std::string s) const
{ {
std::string tmp(s); std::string tmp(s);
std::set<std::string> stringSet; std::set<std::string> stringSet;
@ -386,22 +430,25 @@ ArgParse::parseCommaSepStringToSet(const std::string s) const
return stringSet; return stringSet;
} }
std::string std::string
ArgParse::typeToString(const ValueType type, std::string valueName) const ArgParse::typeToString(const ValueType type, std::string valueName) const
{ {
if ( type != NONE && valueName.empty() ) { if ( !valueName.empty() )
switch ( type ) { return valueName;
case INT :
return "INT"; switch ( type ) {
case DOUBLE : case NONE :
return "DOUBLE"; return "NONE";
break; case STRING :
case BOOL : return "STRING";
return "BOOL"; case INT :
break; return "INT";
default: case FLOAT :
return ""; return "DOUBLE";
} case BOOL :
return "BOOL";
default:
return "";
} }
return valueName;
} }

@ -0,0 +1,46 @@
#include "inetSocketClient.hpp"
#include <iostream>
#include <string.h> // memset, memcpy
InetSocketClient::InetSocketClient(const std::string host,
const int port)
: SocketClient( AF_INET, SOCK_STREAM )
, m_host(host)
, m_port(port)
, m_serverAddr()
{
}
InetSocketClient::~InetSocketClient()
{
}
bool InetSocketClient::connectToPeer()
{
struct hostent *server = gethostbyname(m_host.c_str());
if (server == 0) {
std::cerr << errorToString("ERROR, no such host. ") << std::endl;
return false;
}
m_serverAddr.sin_family = AF_INET;
m_serverAddr.sin_port = htons(m_port);
memcpy(&m_serverAddr.sin_addr.s_addr, server->h_addr, server->h_length);
if ( ::connect( m_socketfd,
(struct sockaddr *) &m_serverAddr,
sizeof(m_serverAddr)) == -1) {
std::cerr << errorToString("ERROR connecting to peer. ") << std::endl;
return false;
}
m_connected = true;
return true;
}

@ -0,0 +1,34 @@
#include "localSocketClient.hpp"
#include <string.h>
#include <iostream>
LocalSocketClient::LocalSocketClient(const std::string sockPath)
: SocketClient( AF_UNIX, SOCK_STREAM )
, m_sockPath(sockPath)
, m_remote()
{
}
LocalSocketClient::~LocalSocketClient()
{
}
bool LocalSocketClient::connectToPeer(void)
{
m_remote.sun_family = AF_UNIX;
strcpy(m_remote.sun_path, m_sockPath.c_str());
int len = strlen(m_remote.sun_path) + sizeof(m_remote.sun_family);
if ( ::connect(m_socketfd, (struct sockaddr *)&m_remote, len) == -1) {
std::cerr << errorToString("ERROR connecting to peer. ") << std::endl;
return false;
}
m_connected = true;
return true;
}

@ -0,0 +1,75 @@
#include "socketClient.hpp"
#include <errno.h> // errno
#include <string.h> // strerror
#include <iostream>
SocketClient::SocketClient( const int addrDomain,
const int socketType )
: m_connected(false)
, m_addrDomain(addrDomain)
, m_socketType(socketType)
, m_socketfd(0)
{
}
SocketClient::~SocketClient()
{
if ( m_connected && close(m_socketfd) == -1 )
std::cerr << errorToString("ERROR closing socket. ") << std::endl;
}
bool SocketClient::send(const std::string msg)
{
if ( !m_connected && !this->connect() )
return false;
ssize_t n = write(m_socketfd, msg.c_str(), msg.length());
if (n == -1) {
std::cerr << errorToString("ERROR writing to socket. ") << std::endl;
return false;
} else if ( n < (ssize_t)msg.length() ) {
std::cerr << "Only a part of msg has been written to socket. " << std::endl;
return false;
}
return true;
}
bool SocketClient::receive(std::string &reply)
{
if ( !m_connected && !this->connect() )
return false;
char buffer[256];
ssize_t n = read(m_socketfd, buffer, 255);
if (n == -1) {
std::cerr << errorToString("ERROR reading from socket. ") << std::endl;
return false;
}
reply = std::string(buffer, n);
return true;
}
bool SocketClient::connect(void)
{
m_socketfd = socket(m_addrDomain, m_socketType, 0);
if ( m_socketfd == -1 ) {
std::cerr << errorToString("ERROR opening socket. ") << std::endl;
return false;
}
return connectToPeer();
}
std::string SocketClient::errorToString(const char *s) const
{
return std::string(s).append(strerror(errno));
}
Loading…
Cancel
Save