/**
* @file hdstutilities.cc
* @author Simon Lang
* @date Fri May 5 15:58:45 2006
*
* @brief This Class provides Utility Functions for a DST Production
*
* $Id: hdstutilities.cc,v 1.2 2006/12/15 14:12:23 slang Exp $
*
*/
// STL headers
#include <cstdlib>
#include <cstdio>
#include <cstring>
// Hydra headers
#include "hdstutilities.h"
using namespace std;
///////////////////////////////////////////////////////////////////////////////
//
// Utility Functions for DST Productions
//
// Actually this class serves as a namespace for some functions which might
// be helpful for writting a program and/or marco which does a DST production
// from any kind of data.
//
//_____________________________________________________________________________
// this macro is used to implement Root's class features (e.g. the streamer)
ClassImp(HDstUtilities)
bool HDstUtilities::readCmdLineArgsFromFile(const char* filename,
int* argc, char*** argv)
{
// This function parses a text file and save the "key = value" pairs
// found on the lines of that file in a structure which looks exactly
// like the one filled with the command line arguments of a program.
// A file might look like that:
//
// ########################################
// #
// # Example config file
// #
// ########################################
//
// # a comment
// # another comment
//
// family-name = lang
// name=simon
// institute = GSI # in Darmstadt
//
// telephone = 06519 / 71-2914
// fax= "06159 / 71-2989"
// --email = 's.lang@gsi.de'
//
// The corresponding command line would look like this,
// filename --family-name=lang --name=simon --telephone="06159 / 71-2914"...
// which is what the getopt_long() function expects. Here, "filename"
// is the name of the test file being evaluated.
// The function fills argc and argv with the data and returns true on
// success. It is written in plain C (except the return type),
// because it's lazy author wants to use it in other C programs as well.
FILE* file = NULL;
int line_num = 0;
char line[MAX_LINE_LENGTH] = { '0' };
char argument[MAX_LINE_LENGTH + 2] = { '0' };
char* line_end = NULL;
char* option_begin = NULL;
char* option_end = NULL;
char* value_begin = NULL;
char* value_end = NULL;
// save the filename as the first argument - like the program name is
// saved as the first argument on command line
*argc = 1;
*argv = (char**)malloc( sizeof(char*) );
(*argv)[0] = strdup( filename );
if ((file = fopen( filename, "r" )) == NULL)
{
fprintf( stderr, "==> ERROR: Could not open input file %s!n", filename);
return kFALSE;
}
while (fgets( line, MAX_LINE_LENGTH, file ) != NULL)
{
line_num++;
// remove trailing newline
if ((line_end = strrchr( line, 'n' )) != NULL)
{
*line_end = '0';
}
// skip lines which contain just whitspaces and comments
if (line[strspn( line, " t" )] == '#' ||
line[strspn( line, " t" )] == '0' )
{
continue;
}
// find end of line, skipping trailing comments
if ((line_end = strchr( line, '#' )) == NULL)
{
line_end = line + strlen( line );
}
*line_end = '0';
// isolate option
option_begin = line + strspn( line, " t-" );
option_end = option_begin + strcspn( option_begin, " =" );
// isolate value
value_begin = option_end + strspn( option_end, " ="'" );
for (value_end = line_end - 1;
*value_end == ' ' || *value_end == 't' ||
*value_end == '"' || *value_end == ''';
value_end--);
value_end++;
// check consistency and cut line
if (option_begin >= line && option_begin < option_end &&
option_end < value_begin && value_begin < value_end &&
value_end <= line_end)
{
*option_end = '0';
*value_end = '0';
}
else
{
fprintf( stderr,
"==> ERROR: Wrong syntax in line %d of file %s!n",
line_num, filename );
fclose( file );
return kFALSE;
}
// compile pseudo command line argument
*argument = '0';
strcat( argument, "--" );
strcat( argument, option_begin );
strcat( argument, "=" );
strcat( argument, value_begin );
// save the result
(*argc)++;
*argv = (char**)realloc( *argv, *argc * sizeof(char*) );
(*argv)[*argc - 1] = strdup( argument );
}
if (feof( file ))
{
fclose( file );
return kTRUE;
}
else
{
fclose( file );
fprintf( stderr, "==> ERROR: Could not read from file %sn", filename );
return kFALSE;
}
}
void HDstUtilities::str2CmdLineArgs(const char* input, int* argc, char*** argv)
{
// This function converts a string which looks like a command line
// into the related array of arguments as it is usually passed to the
// main() function of a program. Results are stored in argc and argv.
// The first string (usually the name of the executable) is set to
// "from-string" here.
// Use (double-) quotes to protect arguments containing white spaces
// from being cut.
// This function is written in plain C because it's lazy author wants to
// use it in other C programs as well.
const char* source;
char* dest;
char* argument;
size_t length;
size_t size;
// set first argument to "from-string"
*argc = 1;
*argv = (char**)malloc( sizeof(char*) );
(*argv)[0] = strdup( "from-string" );
// create a buffer which has the size of the input string
length = 0;
size = strlen( input );
argument = (char*)calloc( size + 1, sizeof(char) );
source = input + strspn( input, " t" ); // skip leading white spaces
dest = argument;
while (source < input + size)
{
if (*source == ''')
{
// copy the whole quoted substring to destination
length = strcspn( source + 1, "'" );
strncpy( dest, source + 1, length );
source += length + 2;
dest += length;
}
else if (*source == '"')
{
// copy the whole double quoted substring to destination
length = strcspn( source + 1, """ );
strncpy( dest, source + 1, length );
source += length + 2;
dest += length;
}
else if (*source == ' ' || *source == 't')
{
*dest = '0';
dest = argument;
// skip embedded or trailing white spaces
source += strspn( source + 1, " t" ) + 1;
// save the current argument
(*argc)++;
*argv = (char**)realloc( *argv, *argc * sizeof(char*) );
(*argv)[*argc - 1] = strdup( argument );
}
else
{
*dest = *source;
source++;
dest++;
}
}
// save possibly the last argument
if (dest != argument)
{
*dest = '0';
(*argc)++;
*argv = (char**)realloc( *argv, *argc * sizeof(char*) );
(*argv)[*argc - 1] = strdup( argument );
}
free( argument );
}
void HDstUtilities::freeCmdLineArgs(int argc, char** argv)
{
// This functions frees the memory used by a command line argument structure
while (argc > 0)
{
free( argv[--argc] );
}
if (argv != NULL)
{
free( argv );
}
}
char* HDstUtilities::extractArg(int* argc, char*** argv, const char* arg)
{
// This function parses a list of command line arguments (saved in
// the structure referenced by 'argc' and 'argv'), and removes the argument
// specified by 'arg' from this list. If the argument describes an option
// with a value (in this case the next argument is treated as value), then
// one must append a ':' to its name. Finally, this returns the option name
// or the value.
// The memory of the returned string must be deleted by the caller of this
// function.
char* result = NULL;
char** new_argv = NULL;
int new_argc = 0;
size_t length = 0;
int found = 0;
int has_value = 0;
int i = 0;
// has the search argument a value? - then skip the trailing ':'
length = strlen( arg );
if (*(arg + length - 1) == ':')
{
has_value = 1;
length--;
}
// loop over the list and create a new argument list without the first
// appearance of the search argument
for (i = 0; i < *argc; i++)
{
if (strncmp( (*argv)[i], arg, length ) == 0 && !found)
{
if (has_value && i + 1 < *argc)
{
result = strdup( (*argv)[i + 1] );
found = 1;
i++;
}
else
{
result = strdup( arg );
found = 1;
}
}
else
{
new_argc++;
new_argv = (char**)realloc( new_argv, new_argc * sizeof(char*) );
new_argv[new_argc - 1] = strdup( (*argv)[i] );
}
}
freeCmdLineArgs( *argc, *argv );
*argc = new_argc;
*argv = new_argv;
return result;
}
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.