From 5e386890b41fe043e2639b25b613831ef8362e7b Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Thu, 29 Jun 2006 02:50:56 +0000 Subject: Completely removed the old, crappy pproc and replaced it with the new, shiny ParamProc class...it's soooo much better it makes me wanna' throw things... --- src/paramproc.cpp | 398 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/paramproc.h | 139 ++++++++++++++++++ src/pproc.cpp | 169 ---------------------- src/pproc.h | 65 --------- src/test/param.cpp | 40 ++++++ src/test/param.h | 21 +++ src/test/params.cpp | 33 ----- 7 files changed, 598 insertions(+), 267 deletions(-) create mode 100644 src/paramproc.cpp create mode 100644 src/paramproc.h delete mode 100644 src/pproc.cpp delete mode 100644 src/pproc.h create mode 100644 src/test/param.cpp create mode 100644 src/test/param.h delete mode 100644 src/test/params.cpp diff --git a/src/paramproc.cpp b/src/paramproc.cpp new file mode 100644 index 0000000..10284c4 --- /dev/null +++ b/src/paramproc.cpp @@ -0,0 +1,398 @@ +#include "paramproc.h" +#include + +#define ptrtype( iitype, iiname ) \ + ParamProc::ParamPtr::ParamPtr( iitype *iiname ) : \ + type( vt ##iiname ) { val.iiname = iiname; } + +ParamProc::ParamPtr::ParamPtr() +{ + val.str = NULL; + type = vtunset; +} + +ptrtype( std::string, str ); +ptrtype( uint64_t, uint64 ); +ptrtype( uint32_t, uint32 ); +ptrtype( uint16_t, uint16 ); +ptrtype( uint8_t, uint8 ); +ptrtype( int64_t, int64 ); +ptrtype( int32_t, int32 ); +ptrtype( int16_t, int16 ); +ptrtype( int8_t, int8 ); +ptrtype( float, float32 ); +ptrtype( double, float64 ); +ptrtype( long double, float96 ); +ptrtype( bool, bln ); + +ParamProc::ParamPtr &ParamProc::ParamPtr::operator=( ParamProc::ParamPtr &ptr ) +{ + val = ptr.val; + type = ptr.type; + + return *this; +} + +bool ParamProc::ParamPtr::isSet() +{ + return type != vtunset; +} + +ParamProc::ParamPtr &ParamProc::ParamPtr::operator=( const char *str ) +{ + if( !isSet() ) return *this; + switch( type ) + { + case vtstr: + (*val.str) = str; + break; + + case vtuint64: + (*val.uint64) = strtoull( str, NULL, 10 ); + break; + + case vtuint32: + (*val.uint32) = strtoul( str, NULL, 10 ); + break; + + case vtuint16: + (*val.uint16) = (uint16_t)strtoul( str, NULL, 10 ); + break; + + case vtuint8: + (*val.uint8) = (uint8_t)strtoul( str, NULL, 10 ); + break; + + case vtint64: + (*val.int64) = strtoll( str, NULL, 10 ); + break; + + case vtint32: + (*val.int32) = strtol( str, NULL, 10 ); + break; + + case vtint16: + (*val.int16) = (int16_t)strtol( str, NULL, 10 ); + break; + + case vtint8: + (*val.int8) = (int8_t)strtol( str, NULL, 10 ); + break; + + case vtfloat32: + (*val.float32) = strtof( str, NULL ); + break; + + case vtfloat64: + (*val.float64) = strtod( str, NULL ); + break; + + case vtfloat96: + (*val.float96) = strtold( str, NULL ); + break; + + case vtbln: + if( strcasecmp("yes", str ) == 0 || + strcasecmp("true", str ) == 0 ) + { + (*val.bln) = true; + } + else + { + (*val.bln) = false; + } + break; + } + + return *this; +} + +ParamProc::ParamProc() +{ +} + +ParamProc::~ParamProc() +{ +} +/* +void ParamProc::addParam( const char *lpWord, char cChar, Proc proc, ParamPtr val ) +{ + printf("Calling callback...\n"); + val = "Hello there, this is set in the ParamProc"; + (this->*proc)(); +}*/ + +void ParamProc::addParam( const char *lpWord, char cChar, Proc proc, + ParamPtr val, const char *lpDesc, const char *lpExtra, + const char *lpValue ) +{ + ArgSpec *as = new ArgSpec; + if( lpWord ) + as->sWord = lpWord; + + as->cChar = cChar; + as->proc = proc; + as->val = val; + if( lpDesc ) + as->sDesc = lpDesc; + if( lpExtra ) + as->sExtra = lpExtra; + if( lpValue ) + as->sValue = lpValue; + + lArg.push_back( as ); +} + +void ParamProc::addParam( const char *lpWord, char cChar, Proc proc, + const char *lpDesc, const char *lpExtra, + const char *lpValue ) +{ + addParam( lpWord, cChar, proc, ParamPtr(), lpDesc, lpExtra, lpValue ); +} + +void ParamProc::addParam( const char *lpWord, char cChar, ParamPtr val, + const char *lpDesc, const char *lpExtra, + const char *lpValue ) +{ + addParam( lpWord, cChar, NULL, val, lpDesc, lpExtra, lpValue ); +} + +void ParamProc::addParam( const char *lpWord, Proc proc, ParamPtr val, + const char *lpDesc, const char *lpExtra, + const char *lpValue ) +{ + addParam( lpWord, '\0', proc, val, lpDesc, lpExtra, lpValue ); +} + +void ParamProc::addParam( const char *lpWord, Proc proc, + const char *lpDesc, const char *lpExtra, + const char *lpValue ) +{ + addParam( lpWord, '\0', proc, ParamPtr(), lpDesc, lpExtra, lpValue ); +} + +void ParamProc::addParam( const char *lpWord, ParamPtr val, + const char *lpDesc, const char *lpExtra, + const char *lpValue ) +{ + addParam( lpWord, '\0', NULL, val, lpDesc, lpExtra, lpValue ); +} + +void ParamProc::addParam( char cChar, Proc proc, ParamPtr val, + const char *lpDesc, const char *lpExtra, + const char *lpValue ) +{ + addParam( NULL, cChar, proc, val, lpDesc, lpExtra, lpValue ); +} + +void ParamProc::addParam( char cChar, Proc proc, + const char *lpDesc, const char *lpExtra, + const char *lpValue ) +{ + addParam( NULL, cChar, proc, ParamPtr(), lpDesc, lpExtra, lpValue ); +} + +void ParamProc::addParam( char cChar, ParamPtr val, + const char *lpDesc, const char *lpExtra, + const char *lpValue ) +{ + addParam( NULL, cChar, NULL, val, lpDesc, lpExtra, lpValue ); +} + +void ParamProc::process( int argc, char *argv[] ) +{ + for( int arg = 1; arg < argc; arg++ ) + { + printf(":::%d:::%s\n", arg, argv[arg] ); + if( argv[arg][0] == '-' ) + { + if( argv[arg][1] == '-' ) + { + ArgSpec *s = checkWord( argv[arg]+2 ); + if( s ) + { + if( argv[arg][s->sWord.getLength()+2] == '=' ) + { + if( s->val.isSet() ) + { + if( s->sValue.getString() == NULL ) + { + s->val = argv[arg]+s->sWord.getLength()+3; + } + else + { + s->val = s->sValue.getString(); + } + } + if( s->proc ) + { + char **tmp = new char*[argc-arg]; + tmp[0] = argv[arg]+s->sWord.getLength()+3; + for( int k = 1; k < argc-arg; k++ ) + tmp[k] = argv[arg+k]; + int ret = (this->*s->proc)( argc-arg, tmp ); + if( ret > 0 ) + { + arg += ret-1; + } + delete tmp; + } + } + else + { + int add = 0; + if( s->val.isSet() ) + { + if( s->sValue.getString() == NULL ) + { + if( arg+1 >= argc ) + { + return; + } + s->val = argv[arg+1]; + add++; + } + else + { + s->val = s->sValue.getString(); + } + } + if( s->proc ) + { + int ret = (this->*s->proc)( + argc-arg-1, argv+arg+1 ); + + if( ret > add ) + arg += ret; + else + arg += add; + } + } + continue; + } + } + else + { + for( int chr = 1; argv[arg][chr]; chr++ ) + { + ArgSpec *s = checkLetr( argv[arg][chr] ); + if( s ) + { + if( argv[arg][chr+1] != '\0' ) + { + bool bUsed = false; + if( s->val.isSet() ) + { + if( s->sValue.getString() == NULL ) + { + s->val = argv[arg]+chr+1; + bUsed = true; + } + else + { + s->val = s->sValue.getString(); + } + } + if( s->proc ) + { + char **tmp = new char*[argc-arg]; + tmp[0] = argv[arg]+chr+1; + for( int k = 1; k < argc-arg; k++ ) + tmp[k] = argv[arg+k]; + int ret = (this->*s->proc)( argc-arg, tmp ); + if( ret > 0 ) + { + arg += ret - 1; + delete tmp; + break; + } + if( bUsed ) + { + delete tmp; + break; + } + delete tmp; + } + } + else + { + bool bUsed = false; + if( s->val.isSet() ) + { + if( s->sValue.getString() == NULL ) + { + s->val = argv[arg+1]; + bUsed = true; + } + else + { + s->val = s->sValue.getString(); + } + } + if( s->proc ) + { + int ret = (this->*s->proc)( + argc-arg-1, argv+arg+1 + ); + if( ret > 0 ) + { + arg += ret; + break; + } + if( bUsed ) + { + arg++; + break; + } + } + } + } + } + } + } + } +} + +ParamProc::ArgSpec *ParamProc::checkWord( const char *arg ) +{ + printf("Checking \"%s\"...\n", arg ); + std::list::const_iterator i; + for( i = lArg.begin(); i != lArg.end(); i++ ) + { + if( (*i)->sWord.getString() == NULL ) + continue; + + if( !strcmp( (*i)->sWord, arg ) ) + return *i; + + if( (*i)->val.isSet() ) + { + if( !strncmp( (*i)->sWord, arg, (*i)->sWord.getLength() ) && + arg[(*i)->sWord.getLength()] == '=' ) + { + return *i; + } + } + } + + return NULL; +} + +ParamProc::ArgSpec *ParamProc::checkLetr( const char arg ) +{ + printf("Checking \'%c\'...\n", arg ); + std::list::const_iterator i; + for( i = lArg.begin(); i != lArg.end(); i++ ) + { + if( (*i)->cChar == '\0' ) + continue; + + if( (*i)->cChar == arg ) + { + return *i; + } + } + + return NULL; +} + diff --git a/src/paramproc.h b/src/paramproc.h new file mode 100644 index 0000000..b7450b7 --- /dev/null +++ b/src/paramproc.h @@ -0,0 +1,139 @@ +#ifndef PARAM_PROC_H +#define PARAM_PROC_H + +#include +#include +#include +#include "staticstring.h" + +class ParamProc +{ +public: + class ParamPtr + { + public: + ParamPtr(); + ParamPtr( std::string *str ); + ParamPtr( uint64_t *uint64 ); + ParamPtr( uint32_t *uint32 ); + ParamPtr( uint16_t *uint16 ); + ParamPtr( uint8_t *uint8 ); + ParamPtr( int64_t *int64 ); + ParamPtr( int32_t *int32 ); + ParamPtr( int16_t *int16 ); + ParamPtr( int8_t *int8 ); + ParamPtr( float *float32 ); + ParamPtr( double *float64 ); + ParamPtr( long double *float96 ); + ParamPtr( bool *bln ); + + enum + { + vtunset, + vtstr, + vtuint64, + vtuint32, + vtuint16, + vtuint8, + vtint64, + vtint32, + vtint16, + vtint8, + vtfloat32, + vtfloat64, + vtfloat96, + vtbln, + }; + ParamPtr &operator=( ParamPtr &ptr ); + ParamPtr &operator=( const char *str ); + + bool isSet(); + + private: + int type; + union + { + std::string *str; + uint64_t *uint64; + uint32_t *uint32; + uint16_t *uint16; + uint8_t *uint8; + int64_t *int64; + int32_t *int32; + int16_t *int16; + int8_t *int8; + float *float32; + double *float64; + long double *float96; + bool *bln; + } val; + }; + + typedef int (ParamProc::*Proc)( int, char *[] ); + + typedef struct ArgSpec + { + uint8_t nFlags; + StaticString sWord; + char cChar; + Proc proc; + ParamProc::ParamPtr val; + StaticString sExtra; + StaticString sDesc; + StaticString sValue; + } ArgSpec; + +public: + ParamProc(); + virtual ~ParamProc(); + + void addParam( const char *lpWord, char cChar, Proc proc, ParamPtr val, + const char *lpDesc=NULL, const char *lpExtra=NULL, + const char *lpValue=NULL + ); + void addParam( const char *lpWord, char cChar, Proc proc, + const char *lpDesc=NULL, const char *lpExtra=NULL, + const char *lpValue=NULL + ); + void addParam( const char *lpWord, char cChar, ParamPtr val, + const char *lpDesc=NULL, const char *lpExtra=NULL, + const char *lpValue=NULL + ); + + void addParam( const char *lpWord, Proc proc, ParamPtr val, + const char *lpDesc=NULL, const char *lpExtra=NULL, + const char *lpValue=NULL + ); + void addParam( const char *lpWord, Proc proc, + const char *lpDesc=NULL, const char *lpExtra=NULL, + const char *lpValue=NULL + ); + void addParam( const char *lpWord, ParamPtr val, + const char *lpDesc=NULL, const char *lpExtra=NULL, + const char *lpValue=NULL + ); + + void addParam( char cChar, Proc proc, ParamPtr val, + const char *lpDesc=NULL, const char *lpExtra=NULL, + const char *lpValue=NULL + ); + void addParam( char cChar, Proc proc, + const char *lpDesc=NULL, const char *lpExtra=NULL, + const char *lpValue=NULL + ); + void addParam( char cChar, ParamPtr val, + const char *lpDesc=NULL, const char *lpExtra=NULL, + const char *lpValue=NULL + ); + + void process( int argc, char *argv[] ); + ArgSpec *checkWord( const char *arg ); + ArgSpec *checkLetr( const char arg ); + +private: + std::list lArg; +}; + +#define mkproc( cls ) static_cast(&cls) + +#endif diff --git a/src/pproc.cpp b/src/pproc.cpp deleted file mode 100644 index eb52913..0000000 --- a/src/pproc.cpp +++ /dev/null @@ -1,169 +0,0 @@ -#include -#include -#include "pproc.h" - -void pprocHelp( PPROC *pproc ) -{ - int maxlen = 0; - for( int j = 0; pproc[j].proc || pproc[j].stateVar; j++ ) - { - int len = strlen( pproc[j].lpWord ); - if( len > maxlen ) maxlen = len; - } - - char fmt[100]; - sprintf( fmt, " -%%c, --%%-%ds %%s\n", maxlen ); - - for( int j = 0; pproc[j].proc || pproc[j].stateVar; j++ ) - { - printf( fmt, - pproc[j].cChar, - pproc[j].lpWord, - pproc[j].shortHelp ); - } -} - -void grabParamAsData( PPROC *pproc, char *str, int *aind, int *cind ) -{ - switch( pproc->cMode & PPROC_TYPE ) - { - case PPROC_BOOL_TRUE: - *((bool *)pproc->stateVar) = true; - break; - - case PPROC_BOOL_FALSE: - *((bool *)pproc->stateVar) = false; - break; - - case PPROC_BOOL_TOGGLE: - *((bool *)pproc->stateVar) = !(*((bool *)pproc->stateVar)); - break; - - case PPROC_CHAR: - (*cind)++; - *((char *)pproc->stateVar) = str[(*cind)]; - break; - - case PPROC_SHORT: - break; - - case PPROC_LONG: - break; - - case PPREC_LONG_LONG: - break; - - case PPROC_UCHAR: - break; - - case PPROC_USHORT: - break; - - case PPROC_ULONG: - break; - - case PPREC_ULONG_LONG: - break; - - case PPROC_FLOAT: - break; - - case PPROC_DOUBLE: - break; - - case PPROC_LONG_DOUBLE: - break; - - case PPROC_STRING: - strcpy( (char *)(pproc->stateVar), str ); - (*aind)++; - break; - } -} - -void processParams( int argc, char *argv[], PPROC *pproc ) -{ - bool bUsed; - // Loop over all the params except the first, no params, no looping! - for( int j = 1; j < argc; j++ ) - { - //printf("Param[%d]: \"%s\"\n", j, argv[j] ); - if( argv[j][0] == '-' ) - { - if( argv[j][1] == '-' ) - { - bUsed = false; - // Proccess a long-word param string - for( int k = 0; - pproc[k].proc != NULL || pproc[k].stateVar != NULL; - k++ ) - { - if( !strcmp( pproc[k].lpWord, &argv[j][2] ) ) - { - bUsed = true; - if( pproc[k].proc != NULL ) - { - j += pproc[k].proc( argc-j, &argv[j] ); - } - if( pproc[k].stateVar != NULL ) - { - grabParamAsData( &pproc[k], argv[j+1], &j, &k ); - } - break; - } - } - if( !bUsed ) - { - if( !strcmp( "help", &argv[j][2] ) ) - { - pprocHelp( pproc ); - } - } - } - else - { - bUsed = false; - // Process a one char param string - for( int k = 0; - pproc[k].proc != NULL || pproc[k].stateVar != NULL; - k++ ) - { - if( pproc[k].cChar == argv[j][1] ) - { - bUsed = true; - if( pproc[k].proc != NULL ) - { - j += pproc[k].proc( argc-j, &argv[j] ); - } - if( pproc[k].stateVar != NULL ) - { - int tmp = 1; - if( argv[j][2] == '\0' ) - { - grabParamAsData( &pproc[k], argv[j+1], &j, &tmp ); - } - else - { - j--; - grabParamAsData( &pproc[k], (&argv[j+1][2]), &j, &tmp ); - } - } - break; - } - } - if( !bUsed ) - { - if( argv[j][1] == 'h' ) - { - pprocHelp( pproc ); - } - } - } - } - else - { - // Handle generic params here. - } - } -} - diff --git a/src/pproc.h b/src/pproc.h deleted file mode 100644 index 31d7c02..0000000 --- a/src/pproc.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef PPROC_H_ -#define PPROC_H_ - -/** - * A mask to discover what the type is even if flags are set. - */ -#define PPROC_TYPE 0x0F - -#define PPROC_BOOL_TRUE 0x01 -#define PPROC_BOOL_FALSE 0x02 -#define PPROC_BOOL_TOGGLE 0x03 -#define PPROC_CHAR 0x04 -#define PPROC_SHORT 0x05 -#define PPROC_LONG 0x06 -#define PPREC_LONG_LONG 0x07 -#define PPROC_UCHAR 0x08 -#define PPROC_USHORT 0x09 -#define PPROC_ULONG 0x0A -#define PPREC_ULONG_LONG 0x0B -#define PPROC_FLOAT 0x0C -#define PPROC_DOUBLE 0x0D -#define PPROC_LONG_DOUBLE 0x0E -#define PPROC_STRING 0x0F - -#define PPROCF_CALLBACK 0x10 -#define PPROCF_ALLOW_EQUALS 0x20 -#define PPROCF_SHORT_TERMINAL 0x40 -#define PPROCF_TERMINATE 0x80 - - -/** - * Contains all required info to handle a single program parameter. - *@author Mike Buland - */ -typedef struct PPROC -{ - const char *lpWord; /**< The full text-word to use as a param. */ - const char cChar; /**< The short char version of the param. */ - - const char cMode; /**< One of the PPROC_* macros, these are not flags. */ - - /** - * Pointer to the function to call when this param is triggered. - *@param argc The number of params after and including the one that - * triggered this call. - *@param argv The array of commandline tokens to use as parameters. - *@returns 0 for everything is ok. A number greater than zero signals that - * this parameter function used n parameters and they should be skipped by - * the processParams function. - */ - int (*proc)( int argc, char *argv[] ); - void *stateVar; /**< A pointer to a variable to set */ - const char *shortHelp; -} PPROC; - -/** - * Process command line parameters based on a null-terminated array of PPROC - * structures. - *@param argc Should come straight from your main function's argc. - *@param argv Should come straight from your main function's argv. - *@param pproc The array of params that this function can respond to. - */ -void processParams( int argc, char *argv[], PPROC *pproc ); - -#endif /*PPROC_H_*/ diff --git a/src/test/param.cpp b/src/test/param.cpp new file mode 100644 index 0000000..0641f90 --- /dev/null +++ b/src/test/param.cpp @@ -0,0 +1,40 @@ +#include "param.h" +#include + +Param::Param() +{ + addParam( "name", 's', mkproc( Param::printStuff ), &str ); + //addParam( "name", &str ); + addParam( "job", 'U', mkproc( Param::printStuff ) ); + + // --name=Bobo + // --job hello +} + +Param::~Param() +{ +} + +int Param::printStuff( int argc, char *argv[] ) +{ + printf("------------%02d-------------\n", argc ); + for( int j = 0; j < argc; j++ ) + { + printf("%d: %s\n", j, argv[j] ); + } + printf("---------------------------\n" ); + printf("SETVAR===\"%s\"\n", str.c_str() ); + + return 1; +} + +int main( int argc, char *argv[] ) +{ + printf("Starting...\n"); + Param p; + p.process( argc, argv ); + + //printf("Calling by hand...\n"); + //p.printStuff(); +} + diff --git a/src/test/param.h b/src/test/param.h new file mode 100644 index 0000000..2756b69 --- /dev/null +++ b/src/test/param.h @@ -0,0 +1,21 @@ +#ifndef PARAM_H +#define PARAM_H + +#include + +#include "paramproc.h" + +class Param : public ParamProc +{ +public: + Param(); + virtual ~Param(); + +private: + int printStuff( int argc, char *argv[] ); + + std::string str; + uint32_t uint32; +}; + +#endif diff --git a/src/test/params.cpp b/src/test/params.cpp deleted file mode 100644 index bb62047..0000000 --- a/src/test/params.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include "pproc.h" - -int main( int argc, char *argv[] ) -{ - bool bOn = false; - bool bOff = true; - bool bTog = false; - char cChar = '?'; - PPROC table[] = { - { "boolon", 'n', PPROC_BOOL_TRUE, NULL, &bOn, - "Set the bool on." }, - { "booloff", 'f', PPROC_BOOL_FALSE, NULL, &bOff, - "Set the bool off." }, - { "booltog", 't', PPROC_BOOL_TOGGLE, NULL, &bTog, - "Set the bool off." }, - { "char", 'c', PPROC_CHAR, NULL, &cChar, - "Set the char." }, - { NULL, '\0',0, NULL, NULL, - NULL } - }; - - processParams( argc, argv, table ); - - printf("Final results:\n"); - printf("\tbOn = %s\n", (bOn ? "true" : "false") ); - printf("\tbOff = %s\n", (bOff ? "true" : "false") ); - printf("\tbTog = %s\n", (bTog ? "true" : "false") ); - printf("\tcChar = '%c'\n", cChar ); - - return 0; -} - -- cgit v1.2.3