STATUS: stable Implementing optional argument lists. More...
#include "definitions.h"
#include "slist.h"
#include <stdarg.h>
Go to the source code of this file.
Data Structures | |
struct | OptArg |
An optional Argument. More... | |
struct | OptArgList |
A list of optional Arguments. More... | |
Defines | |
#define | NO_OPTARGS NULL |
#define | optarg_PARSE_PTR(opts, label, var, type, tmp) |
Check and assign a void-ptr from OptArgList. Suppose you got optargs in a function and want to check for variable "distfct" of type "DistFct",. | |
#define | optarg_PARSE_SCALAR(opts, label, var, type, tmp) |
Check and assign a scalar from OptArgList. Suppose you got optargs in a function and want to check for variable "seed" of type "unsigned long",. | |
Functions | |
OptArg * | optarg_ptr (const char *key, void *ptr) |
create a new OptArg* containing a pointer. | |
OptArg * | optarg_scalar (const char *key, double scalar) |
create a new OptArg* containing a scalar value. | |
OptArgList * | optarglist (char *format,...) |
Creates an OptArgList out of one or many arguments. | |
OptArgList * | optarglist_append_arg (OptArgList *list, OptArg *arg) |
create a new optarglist that is the former optarglist with the new arg appended. | |
OptArgList * | optarglist_delete_arg (OptArgList *list, OptArg *arg) |
delete an argument from the argument list. | |
void | optarglist_free (OptArgList *list) |
free an optarglist. | |
bool | optarglist_has_key (OptArgList *list, const char *key) |
return TRUE if key is found in list, else FALSE. | |
OptArg * | optarglist_optarg_by_key (OptArgList *list, const char *key) |
Return a pointer to an OptArg struct with the key from the list. | |
void | optarglist_print (OptArgList *list, FILE *out) |
print an optarglist. | |
void * | optarglist_ptr_by_key (OptArgList *list, const char *key) |
Return a pointer to the data_ptr field of the OptArg struct. | |
OptArgList * | optarglist_remove_freeflag (OptArgList *list, bool *removedflag) |
remove the optarglist_free-flag from the list. | |
double | optarglist_scalar_by_key (OptArgList *list, const char *key) |
Return the value of the scalar argument. | |
OptArgList * | optarglisttmp (char *format,...) |
Creates an OptArgList including a optarglist_free arg. |
STATUS: stable Implementing optional argument lists.
This feature can be used to conveniently pass arguments to functions. This makes sense for generic functions that take one or more function pointers requiring different arguements each.
The syntax is as follows:
double *mydata = read_data(); OptArgList *args = optarglist( "bottom_frequency=double,num_trials=int,data=double*", 0.5, 10, mydata ); function_taking_optargs( args ); free_optarglist( args ) // does not free any mydata
Every function that receives an optarglist is required to check for the existence of "optarglist_free" within the parameterlist. If this parameter exists, the function is required to free the memory pointed to the argument. Also, the parameter is removed from the list and possibly passed to other functions.
This enables the use of optarglists like this:
function_taking_optargs( optarglist( "bottom_frequency=double, num_trials=int, data=double*, optarglist_free=int", 0.5, 10, mydata, 1) );
or even shorter like
function_taking_optargs( optarglisttmp( "bottom_frequency=double, num_trials=int, data=double*", 0.5, 10, mydata) );
where the memory deallocation is handled by the called function.
The function optarlist_remove_freeflag() removes the optarglist_free-flag from the list and returns a new list without the flag. The old list is free'd in case that the optarglist_free argument is found.
The removedflag-flag is set to FALSE if it is the same list, to TRUE if it is a new (truncated) list.
Usage is as follows:
void testfct( OptArgList *opts ){ // overwrite the pointer bool freeflag_removed=FALSE; opts=optarglist_remove_freeflag( opts, &freeflag_removed ); // do some stuff including passing the argument to some other function call_other_function( opts ); // clean up in case the flag was indeed removed if( freeflag_removed ) optarglist_free( opts ); }
Definition in file optarg.h.
#define optarg_PARSE_PTR | ( | opts, | ||
label, | ||||
var, | ||||
type, | ||||
tmp | ||||
) |
if( optarglist_has_key( (opts), (label) ) ){ \ (tmp) = optarglist_ptr_by_key( (opts), (label) ); \ if( (tmp) ) (var)=(type)(tmp); \ }
Check and assign a void-ptr from OptArgList. Suppose you got optargs in a function and want to check for variable "distfct" of type "DistFct",.
void *ptr; // tmp DistFct distf; optarg_PARSE_PTR( optargs, "distfct", distf, DistFct, ptr );
#define optarg_PARSE_SCALAR | ( | opts, | ||
label, | ||||
var, | ||||
type, | ||||
tmp | ||||
) |
if( optarglist_has_key( (opts), (label) ) ){ \ (tmp) = optarglist_scalar_by_key( (opts), (label) ); \ if( !isnan( (tmp) ) ) (var)=(type)(tmp); \ }
Check and assign a scalar from OptArgList. Suppose you got optargs in a function and want to check for variable "seed" of type "unsigned long",.
double x; // tmp unsigned long seed; optarg_PARSE_SCALAR( optargs, "seed", seed, unsigned long, x );
OptArg* optarg_ptr | ( | const char * | key, | |
void * | ptr | |||
) |
OptArg* optarg_scalar | ( | const char * | key, | |
double | scalar | |||
) |
OptArgList* optarglist | ( | char * | format, | |
... | ||||
) |
Creates an OptArgList out of one or many arguments.
The Format string has the following convention:
key1=double*,key2=void*,key3=int,key=double,...
If you have at least one asterisk (*) in the specification, then the corresponding argument needs to be a pointer. Internally, all pointer types are void*
and stored along with the given specification.
Be VERY careful to typecast all variables to match the type you indicated. For example, if you have a float-variable and pass it as double, you need to typecast to (double).
Only "basic" scalar values (without asterisk) are supported:
Blanks/Newlines etc are stripped from key and type, so
key = double , key2=void*
are ok.
OptArgList* optarglist_append_arg | ( | OptArgList * | list, | |
OptArg * | arg | |||
) |
OptArgList* optarglist_delete_arg | ( | OptArgList * | list, | |
OptArg * | arg | |||
) |
delete an argument from the argument list.
The function returns a new OptArgList containing which is the old list minus the argument. The arguments copied!
The caller is responsible for freeing the old list.
list | the list | |
arg | the argument to delete |
void optarglist_free | ( | OptArgList * | list | ) |
bool optarglist_has_key | ( | OptArgList * | list, | |
const char * | key | |||
) |
OptArg* optarglist_optarg_by_key | ( | OptArgList * | list, | |
const char * | key | |||
) |
void optarglist_print | ( | OptArgList * | list, | |
FILE * | out | |||
) |
void* optarglist_ptr_by_key | ( | OptArgList * | list, | |
const char * | key | |||
) |
OptArgList* optarglist_remove_freeflag | ( | OptArgList * | list, | |
bool * | removedflag | |||
) |
remove the optarglist_free-flag from the list.
This function is only interesting for you, if you want to write an own function that takes an OptArgList* as an argument.
The function removes the optarglist_free-flag from the list and returns a new list without the flag. The old list is free'd in case that the optarglist_free argument is found.
The removedflag-flag is set to FALSE if it is the same list, to TRUE if it is a new (truncated) list.
Usage is as follows:
void testfct( OptArgList *opts ){ // overwrite the pointer bool freeflag_removed=FALSE; opts=optarglist_remove_freeflag( opts, &freeflag_removed ); // do some stuff including passing the argument to some other function call_other_function( opts ); // clean up in case the flag was indeed removed if( freeflag_removed ) optarglist_free( opts );
list | the list | |
removedflag | is set to FALSE if it is the same list, to TRUE if it is a new (truncated) list. |
double optarglist_scalar_by_key | ( | OptArgList * | list, | |
const char * | key | |||
) |
OptArgList* optarglisttmp | ( | char * | format, | |
... | ||||
) |
Creates an OptArgList including a optarglist_free arg.
The Format string has the following convention:
key1=double*,key2=void*,key3=int,key=double,...
If you have at least one asterisk (*) in the specification, then the corresponding argument needs to be a pointer. Internally, all pointer types are void*
and stored along with the given specification.
Be VERY careful to typecast all variables to match the type you indicated. For example, if you have a float-variable and pass it as double, you need to typecast to (double).
Only "basic" scalar values (without asterisk) are supported:
Blanks/Newlines etc are stripped from key and type, so
key = double , key2=void*
are ok.