+++ /dev/null
-CC= g++
-CXXFLAGS= -c -O2 -Wall -pedantic
-LDFLAGS= -lgd -lsndfile -ljpeg
-EXEC=wav2png
-
-all: anyoption.o main.o
- $(CC) anyoption.o main.o $(LDFLAGS) -o $(EXEC)
-
-static: anyoption.o main.o
- $(CC) -static anyoption.o main.o $(LDFLAGS) -lpng12 -lz -o $(EXEC)-static
-
-main.o: main.cpp
- $(CC) $(CXXFLAGS) main.cpp
-
-anyoption.o: anyoption.cpp
- $(CC) $(CXXFLAGS) anyoption.cpp
-
-clean:
- rm ./*.o
- rm $(EXEC)
+++ /dev/null
-Telemeta notes:
-
-This is the (slighly modified) GPL'ed wav2png program that generates waveform
-at freesound, downloaded from:
-http://freesound.iua.upf.edu/files/wav2png.tar.gz
-
-It is used by the initial Telemeta WaveformVisualizer.
-
-You need the libgd and libsndfile libraries to compile it.
-
-You also need anyoption.h and anyoption.cpp from:
-http://www.hackorama.com/anyoption/
-
-Then simply type:
-
-$ make
-
-
+++ /dev/null
-/*
- * AnyOption 1.3
- *
- * kishan at hackorama dot com www.hackorama.com JULY 2001
- *
- * + Acts as a common facade class for reading
- * commandline options as well as options from
- * an optionfile with delimited type value pairs
- *
- * + Handles the POSIX style single character options ( -w )
- * as well as the newer GNU long options ( --width )
- *
- * + The option file assumes the traditional format of
- * first character based comment lines and type value
- * pairs with a delimiter , and flags which are not pairs
- *
- * # this is a coment
- * # next line is an option value pair
- * width : 100
- * # next line is a flag
- * noimages
- *
- * + Supports printing out Help and Usage
- *
- * + Why not just use getopt() ?
- *
- * getopt() Its a POSIX standard not part of ANSI-C.
- * So it may not be available on platforms like Windows.
- *
- * + Why it is so long ?
- *
- * The actual code which does command line parsing
- * and option file parsing are done in few methods.
- * Most of the extra code are for providing a flexible
- * common public interface to both a resourcefile and
- * and command line supporting POSIX style and
- * GNU long option as well as mixing of both.
- *
- * + Please see "anyoption.h" for public method descriptions
- *
- */
-
-/* Updated Auguest 2004
- * Fix from Michael D Peters (mpeters at sandia.gov)
- * to remove static local variables, allowing multiple instantiations
- * of the reader (for using multiple configuration files). There is
- * an error in the destructor when using multiple instances, so you
- * cannot delete your objects (it will crash), but not calling the
- * destructor only introduces a small memory leak, so I
- * have not bothered tracking it down.
- *
- * Also updated to use modern C++ style headers, rather than
- * depricated iostream.h (it was causing my compiler problems)
-*/
-
-/*
- * Updated September 2006
- * Fix from Boyan Asenov for a bug in mixing up option indexes
- * leading to exception when mixing different options types
- */
-
-#include "anyoption.h"
-
-AnyOption::AnyOption()
-{
- init();
-}
-
-AnyOption::AnyOption(int maxopt)
-{
- init( maxopt , maxopt );
-}
-
-AnyOption::AnyOption(int maxopt, int maxcharopt)
-{
- init( maxopt , maxcharopt );
-}
-
-AnyOption::~AnyOption()
-{
- if( mem_allocated )
- cleanup();
-}
-
-void
-AnyOption::init()
-{
- init( DEFAULT_MAXOPTS , DEFAULT_MAXOPTS );
-}
-
-void
-AnyOption::init(int maxopt, int maxcharopt )
-{
-
- max_options = maxopt;
- max_char_options = maxcharopt;
- max_usage_lines = DEFAULT_MAXUSAGE;
- usage_lines = 0 ;
- argc = 0;
- argv = NULL;
- posix_style = true;
- verbose = false;
- filename = NULL;
- appname = NULL;
- option_counter = 0;
- optchar_counter = 0;
- new_argv = NULL;
- new_argc = 0 ;
- max_legal_args = 0 ;
- command_set = false;
- file_set = false;
- values = NULL;
- g_value_counter = 0;
- mem_allocated = false;
- command_set = false;
- file_set = false;
- opt_prefix_char = '-';
- file_delimiter_char = ':';
- file_comment_char = '#';
- equalsign = '=';
- comment = '#' ;
- delimiter = ':' ;
- endofline = '\n';
- whitespace = ' ' ;
- nullterminate = '\0';
- set = false;
- once = true;
- hasoptions = false;
- autousage = false;
-
- strcpy( long_opt_prefix , "--" );
-
- if( alloc() == false ){
- cout << endl << "OPTIONS ERROR : Failed allocating memory" ;
- cout << endl ;
- cout << "Exiting." << endl ;
- exit (0);
- }
-}
-
-bool
-AnyOption::alloc()
-{
- int i = 0 ;
- int size = 0 ;
-
- if( mem_allocated )
- return true;
-
- size = (max_options+1) * sizeof(const char*);
- options = (const char**)malloc( size );
- optiontype = (int*) malloc( (max_options+1)*sizeof(int) );
- optionindex = (int*) malloc( (max_options+1)*sizeof(int) );
- if( options == NULL || optiontype == NULL || optionindex == NULL )
- return false;
- else
- mem_allocated = true;
- for( i = 0 ; i < max_options ; i++ ){
- options[i] = NULL;
- optiontype[i] = 0 ;
- optionindex[i] = -1 ;
- }
- optionchars = (char*) malloc( (max_char_options+1)*sizeof(char) );
- optchartype = (int*) malloc( (max_char_options+1)*sizeof(int) );
- optcharindex = (int*) malloc( (max_char_options+1)*sizeof(int) );
- if( optionchars == NULL ||
- optchartype == NULL ||
- optcharindex == NULL )
- {
- mem_allocated = false;
- return false;
- }
- for( i = 0 ; i < max_char_options ; i++ ){
- optionchars[i] = '0';
- optchartype[i] = 0 ;
- optcharindex[i] = -1 ;
- }
-
- size = (max_usage_lines+1) * sizeof(const char*) ;
- usage = (const char**) malloc( size );
-
- if( usage == NULL ){
- mem_allocated = false;
- return false;
- }
- for( i = 0 ; i < max_usage_lines ; i++ )
- usage[i] = NULL;
-
- return true;
-}
-
-bool
-AnyOption::doubleOptStorage()
-{
- options = (const char**)realloc( options,
- ((2*max_options)+1) * sizeof( const char*) );
- optiontype = (int*) realloc( optiontype ,
- ((2 * max_options)+1)* sizeof(int) );
- optionindex = (int*) realloc( optionindex,
- ((2 * max_options)+1) * sizeof(int) );
- if( options == NULL || optiontype == NULL || optionindex == NULL )
- return false;
- /* init new storage */
- for( int i = max_options ; i < 2*max_options ; i++ ){
- options[i] = NULL;
- optiontype[i] = 0 ;
- optionindex[i] = -1 ;
- }
- max_options = 2 * max_options ;
- return true;
-}
-
-bool
-AnyOption::doubleCharStorage()
-{
- optionchars = (char*) realloc( optionchars,
- ((2*max_char_options)+1)*sizeof(char) );
- optchartype = (int*) realloc( optchartype,
- ((2*max_char_options)+1)*sizeof(int) );
- optcharindex = (int*) realloc( optcharindex,
- ((2*max_char_options)+1)*sizeof(int) );
- if( optionchars == NULL ||
- optchartype == NULL ||
- optcharindex == NULL )
- return false;
- /* init new storage */
- for( int i = max_char_options ; i < 2*max_char_options ; i++ ){
- optionchars[i] = '0';
- optchartype[i] = 0 ;
- optcharindex[i] = -1 ;
- }
- max_char_options = 2 * max_char_options;
- return true;
-}
-
-bool
-AnyOption::doubleUsageStorage()
-{
- usage = (const char**)realloc( usage,
- ((2*max_usage_lines)+1) * sizeof( const char*) );
- if ( usage == NULL )
- return false;
- for( int i = max_usage_lines ; i < 2*max_usage_lines ; i++ )
- usage[i] = NULL;
- max_usage_lines = 2 * max_usage_lines ;
- return true;
-
-}
-
-
-void
-AnyOption::cleanup()
-{
- free (options);
- free (optiontype);
- free (optionindex);
- free (optionchars);
- free (optchartype);
- free (optcharindex);
- free (usage);
- if( values != NULL )
- free (values);
- if( new_argv != NULL )
- free (new_argv);
-}
-
-void
-AnyOption::setCommandPrefixChar( char _prefix )
-{
- opt_prefix_char = _prefix;
-}
-
-void
-AnyOption::setCommandLongPrefix( char *_prefix )
-{
- if( strlen( _prefix ) > MAX_LONG_PREFIX_LENGTH ){
- *( _prefix + MAX_LONG_PREFIX_LENGTH ) = '\0';
- }
-
- strcpy (long_opt_prefix, _prefix);
-}
-
-void
-AnyOption::setFileCommentChar( char _comment )
-{
- file_delimiter_char = _comment;
-}
-
-
-void
-AnyOption::setFileDelimiterChar( char _delimiter )
-{
- file_comment_char = _delimiter ;
-}
-
-bool
-AnyOption::CommandSet()
-{
- return( command_set );
-}
-
-bool
-AnyOption::FileSet()
-{
- return( file_set );
-}
-
-void
-AnyOption::noPOSIX()
-{
- posix_style = false;
-}
-
-bool
-AnyOption::POSIX()
-{
- return posix_style;
-}
-
-
-void
-AnyOption::setVerbose()
-{
- verbose = true ;
-}
-
-void
-AnyOption::printVerbose()
-{
- if( verbose )
- cout << endl ;
-}
-void
-AnyOption::printVerbose( const char *msg )
-{
- if( verbose )
- cout << msg ;
-}
-
-void
-AnyOption::printVerbose( char *msg )
-{
- if( verbose )
- cout << msg ;
-}
-
-void
-AnyOption::printVerbose( char ch )
-{
- if( verbose )
- cout << ch ;
-}
-
-bool
-AnyOption::hasOptions()
-{
- return hasoptions;
-}
-
-void
-AnyOption::autoUsagePrint(bool _autousage)
-{
- autousage = _autousage;
-}
-
-void
-AnyOption::useCommandArgs( int _argc, char **_argv )
-{
- argc = _argc;
- argv = _argv;
- command_set = true;
- appname = argv[0];
- if(argc > 1) hasoptions = true;
-}
-
-void
-AnyOption::useFiileName( const char *_filename )
-{
- filename = _filename;
- file_set = true;
-}
-
-/*
- * set methods for options
- */
-
-void
-AnyOption::setCommandOption( const char *opt )
-{
- addOption( opt , COMMAND_OPT );
- g_value_counter++;
-}
-
-void
-AnyOption::setCommandOption( char opt )
-{
- addOption( opt , COMMAND_OPT );
- g_value_counter++;
-}
-
-void
-AnyOption::setCommandOption( const char *opt , char optchar )
-{
- addOption( opt , COMMAND_OPT );
- addOption( optchar , COMMAND_OPT );
- g_value_counter++;
-}
-
-void
-AnyOption::setCommandFlag( const char *opt )
-{
- addOption( opt , COMMAND_FLAG );
- g_value_counter++;
-}
-
-void
-AnyOption::setCommandFlag( char opt )
-{
- addOption( opt , COMMAND_FLAG );
- g_value_counter++;
-}
-
-void
-AnyOption::setCommandFlag( const char *opt , char optchar )
-{
- addOption( opt , COMMAND_FLAG );
- addOption( optchar , COMMAND_FLAG );
- g_value_counter++;
-}
-
-void
-AnyOption::setFileOption( const char *opt )
-{
- addOption( opt , FILE_OPT );
- g_value_counter++;
-}
-
-void
-AnyOption::setFileOption( char opt )
-{
- addOption( opt , FILE_OPT );
- g_value_counter++;
-}
-
-void
-AnyOption::setFileOption( const char *opt , char optchar )
-{
- addOption( opt , FILE_OPT );
- addOption( optchar, FILE_OPT );
- g_value_counter++;
-}
-
-void
-AnyOption::setFileFlag( const char *opt )
-{
- addOption( opt , FILE_FLAG );
- g_value_counter++;
-}
-
-void
-AnyOption::setFileFlag( char opt )
-{
- addOption( opt , FILE_FLAG );
- g_value_counter++;
-}
-
-void
-AnyOption::setFileFlag( const char *opt , char optchar )
-{
- addOption( opt , FILE_FLAG );
- addOption( optchar , FILE_FLAG );
- g_value_counter++;
-}
-
-void
-AnyOption::setOption( const char *opt )
-{
- addOption( opt , COMMON_OPT );
- g_value_counter++;
-}
-
-void
-AnyOption::setOption( char opt )
-{
- addOption( opt , COMMON_OPT );
- g_value_counter++;
-}
-
-void
-AnyOption::setOption( const char *opt , char optchar )
-{
- addOption( opt , COMMON_OPT );
- addOption( optchar , COMMON_OPT );
- g_value_counter++;
-}
-
-void
-AnyOption::setFlag( const char *opt )
-{
- addOption( opt , COMMON_FLAG );
- g_value_counter++;
-}
-
-void
-AnyOption::setFlag( const char opt )
-{
- addOption( opt , COMMON_FLAG );
- g_value_counter++;
-}
-
-void
-AnyOption::setFlag( const char *opt , char optchar )
-{
- addOption( opt , COMMON_FLAG );
- addOption( optchar , COMMON_FLAG );
- g_value_counter++;
-}
-
-void
-AnyOption::addOption( const char *opt, int type )
-{
- if( option_counter >= max_options ){
- if( doubleOptStorage() == false ){
- addOptionError( opt );
- return;
- }
- }
- options[ option_counter ] = opt ;
- optiontype[ option_counter ] = type ;
- optionindex[ option_counter ] = g_value_counter;
- option_counter++;
-}
-
-void
-AnyOption::addOption( char opt, int type )
-{
- if( !POSIX() ){
- printVerbose("Ignoring the option character \"");
- printVerbose( opt );
- printVerbose( "\" ( POSIX options are turned off )" );
- printVerbose();
- return;
- }
-
-
- if( optchar_counter >= max_char_options ){
- if( doubleCharStorage() == false ){
- addOptionError( opt );
- return;
- }
- }
- optionchars[ optchar_counter ] = opt ;
- optchartype[ optchar_counter ] = type ;
- optcharindex[ optchar_counter ] = g_value_counter;
- optchar_counter++;
-}
-
-void
-AnyOption::addOptionError( const char *opt )
-{
- cout << endl ;
- cout << "OPTIONS ERROR : Failed allocating extra memory " << endl ;
- cout << "While adding the option : \""<< opt << "\"" << endl;
- cout << "Exiting." << endl ;
- cout << endl ;
- exit(0);
-}
-
-void
-AnyOption::addOptionError( char opt )
-{
- cout << endl ;
- cout << "OPTIONS ERROR : Failed allocating extra memory " << endl ;
- cout << "While adding the option: \""<< opt << "\"" << endl;
- cout << "Exiting." << endl ;
- cout << endl ;
- exit(0);
-}
-
-void
-AnyOption::processOptions()
-{
- if( ! valueStoreOK() )
- return;
-}
-
-void
-AnyOption::processCommandArgs(int max_args)
-{
- max_legal_args = max_args;
- processCommandArgs();
-}
-
-void
-AnyOption::processCommandArgs( int _argc, char **_argv, int max_args )
-{
- max_legal_args = max_args;
- processCommandArgs( _argc, _argv );
-}
-
-void
-AnyOption::processCommandArgs( int _argc, char **_argv )
-{
- useCommandArgs( _argc, _argv );
- processCommandArgs();
-}
-
-void
-AnyOption::processCommandArgs()
-{
- if( ! ( valueStoreOK() && CommandSet() ) )
- return;
-
- if( max_legal_args == 0 )
- max_legal_args = argc;
- new_argv = (int*) malloc( (max_legal_args+1) * sizeof(int) );
- for( int i = 1 ; i < argc ; i++ ){/* ignore first argv */
- if( argv[i][0] == long_opt_prefix[0] &&
- argv[i][1] == long_opt_prefix[1] ) { /* long GNU option */
- int match_at = parseGNU( argv[i]+2 ); /* skip -- */
- if( match_at >= 0 && i < argc-1 ) /* found match */
- setValue( options[match_at] , argv[++i] );
- }else if( argv[i][0] == opt_prefix_char ) { /* POSIX char */
- if( POSIX() ){
- char ch = parsePOSIX( argv[i]+1 );/* skip - */
- if( ch != '0' && i < argc-1 ) /* matching char */
- setValue( ch , argv[++i] );
- } else { /* treat it as GNU option with a - */
- int match_at = parseGNU( argv[i]+1 ); /* skip - */
- if( match_at >= 0 && i < argc-1 ) /* found match */
- setValue( options[match_at] , argv[++i] );
- }
- }else { /* not option but an argument keep index */
- if( new_argc < max_legal_args ){
- new_argv[ new_argc ] = i ;
- new_argc++;
- }else{ /* ignore extra arguments */
- printVerbose( "Ignoring extra argument: " );
- printVerbose( argv[i] );
- printVerbose( );
- printAutoUsage();
- }
- printVerbose( "Unknown command argument option : " );
- printVerbose( argv[i] );
- printVerbose( );
- printAutoUsage();
- }
- }
-}
-
-char
-AnyOption::parsePOSIX( char* arg )
-{
-
- for( unsigned int i = 0 ; i < strlen(arg) ; i++ ){
- char ch = arg[i] ;
- if( matchChar(ch) ) { /* keep matching flags till an option */
- /*if last char argv[++i] is the value */
- if( i == strlen(arg)-1 ){
- return ch;
- }else{/* else the rest of arg is the value */
- i++; /* skip any '=' and ' ' */
- while( arg[i] == whitespace
- || arg[i] == equalsign )
- i++;
- setValue( ch , arg+i );
- return '0';
- }
- }
- }
- printVerbose( "Unknown command argument option : " );
- printVerbose( arg );
- printVerbose( );
- printAutoUsage();
- return '0';
-}
-
-int
-AnyOption::parseGNU( char *arg )
-{
- int split_at = 0;
- /* if has a '=' sign get value */
- for( unsigned int i = 0 ; i < strlen(arg) ; i++ ){
- if(arg[i] == equalsign ){
- split_at = i ; /* store index */
- i = strlen(arg); /* get out of loop */
- }
- }
- if( split_at > 0 ){ /* it is an option value pair */
- char* tmp = (char*) malloc( (split_at+1)*sizeof(char) );
- for( int i = 0 ; i < split_at ; i++ )
- tmp[i] = arg[i];
- tmp[split_at] = '\0';
-
- if ( matchOpt( tmp ) >= 0 ){
- setValue( options[matchOpt(tmp)] , arg+split_at+1 );
- free (tmp);
- }else{
- printVerbose( "Unknown command argument option : " );
- printVerbose( arg );
- printVerbose( );
- printAutoUsage();
- free (tmp);
- return -1;
- }
- }else{ /* regular options with no '=' sign */
- return matchOpt(arg);
- }
- return -1;
-}
-
-
-int
-AnyOption::matchOpt( char *opt )
-{
- for( int i = 0 ; i < option_counter ; i++ ){
- if( strcmp( options[i], opt ) == 0 ){
- if( optiontype[i] == COMMON_OPT ||
- optiontype[i] == COMMAND_OPT )
- { /* found option return index */
- return i;
- }else if( optiontype[i] == COMMON_FLAG ||
- optiontype[i] == COMMAND_FLAG )
- { /* found flag, set it */
- setFlagOn( opt );
- return -1;
- }
- }
- }
- printVerbose( "Unknown command argument option : " );
- printVerbose( opt ) ;
- printVerbose( );
- printAutoUsage();
- return -1;
-}
-bool
-AnyOption::matchChar( char c )
-{
- for( int i = 0 ; i < optchar_counter ; i++ ){
- if( optionchars[i] == c ) { /* found match */
- if(optchartype[i] == COMMON_OPT ||
- optchartype[i] == COMMAND_OPT )
- { /* an option store and stop scanning */
- return true;
- }else if( optchartype[i] == COMMON_FLAG ||
- optchartype[i] == COMMAND_FLAG ) { /* a flag store and keep scanning */
- setFlagOn( c );
- return false;
- }
- }
- }
- printVerbose( "Unknown command argument option : " );
- printVerbose( c ) ;
- printVerbose( );
- printAutoUsage();
- return false;
-}
-
-bool
-AnyOption::valueStoreOK( )
-{
- int size= 0;
- if( !set ){
- if( g_value_counter > 0 ){
- size = g_value_counter * sizeof(char*);
- values = (char**)malloc( size );
- for( int i = 0 ; i < g_value_counter ; i++)
- values[i] = NULL;
- set = true;
- }
- }
- return set;
-}
-
-/*
- * public get methods
- */
-char*
-AnyOption::getValue( const char *option )
-{
- if( !valueStoreOK() )
- return NULL;
-
- for( int i = 0 ; i < option_counter ; i++ ){
- if( strcmp( options[i], option ) == 0 )
- return values[ optionindex[i] ];
- }
- return NULL;
-}
-
-bool
-AnyOption::getFlag( const char *option )
-{
- if( !valueStoreOK() )
- return false;
- for( int i = 0 ; i < option_counter ; i++ ){
- if( strcmp( options[i], option ) == 0 )
- return findFlag( values[ optionindex[i] ] );
- }
- return false;
-}
-
-char*
-AnyOption::getValue( char option )
-{
- if( !valueStoreOK() )
- return NULL;
- for( int i = 0 ; i < optchar_counter ; i++ ){
- if( optionchars[i] == option )
- return values[ optcharindex[i] ];
- }
- return NULL;
-}
-
-bool
-AnyOption::getFlag( char option )
-{
- if( !valueStoreOK() )
- return false;
- for( int i = 0 ; i < optchar_counter ; i++ ){
- if( optionchars[i] == option )
- return findFlag( values[ optcharindex[i] ] ) ;
- }
- return false;
-}
-
-bool
-AnyOption::findFlag( char* val )
-{
- if( val == NULL )
- return false;
-
- if( strcmp( TRUE_FLAG , val ) == 0 )
- return true;
-
- return false;
-}
-
-/*
- * private set methods
- */
-bool
-AnyOption::setValue( const char *option , char *value )
-{
- if( !valueStoreOK() )
- return false;
- for( int i = 0 ; i < option_counter ; i++ ){
- if( strcmp( options[i], option ) == 0 ){
- values[ optionindex[i] ] = (char*) malloc((strlen(value)+1)*sizeof(char));
- strcpy( values[ optionindex[i] ], value );
- return true;
- }
- }
- return false;
-}
-
-bool
-AnyOption::setFlagOn( const char *option )
-{
- if( !valueStoreOK() )
- return false;
- for( int i = 0 ; i < option_counter ; i++ ){
- if( strcmp( options[i], option ) == 0 ){
- values[ optionindex[i] ] = (char*) malloc((strlen(TRUE_FLAG)+1)*sizeof(char));
- strcpy( values[ optionindex[i] ] , TRUE_FLAG );
- return true;
- }
- }
- return false;
-}
-
-bool
-AnyOption::setValue( char option , char *value )
-{
- if( !valueStoreOK() )
- return false;
- for( int i = 0 ; i < optchar_counter ; i++ ){
- if( optionchars[i] == option ){
- values[ optcharindex[i] ] = (char*) malloc((strlen(value)+1)*sizeof(char));
- strcpy( values[ optcharindex[i] ], value );
- return true;
- }
- }
- return false;
-}
-
-bool
-AnyOption::setFlagOn( char option )
-{
- if( !valueStoreOK() )
- return false;
- for( int i = 0 ; i < optchar_counter ; i++ ){
- if( optionchars[i] == option ){
- values[ optcharindex[i] ] = (char*) malloc((strlen(TRUE_FLAG)+1)*sizeof(char));
- strcpy( values[ optcharindex[i] ] , TRUE_FLAG );
- return true;
- }
- }
- return false;
-}
-
-
-int
-AnyOption::getArgc( )
-{
- return new_argc;
-}
-
-char*
-AnyOption::getArgv( int index )
-{
- if( index < new_argc ){
- return ( argv[ new_argv[ index ] ] );
- }
- return NULL;
-}
-
-/* dotfile sub routines */
-
-bool
-AnyOption::processFile()
-{
- if( ! (valueStoreOK() && FileSet()) )
- return false;
- return ( consumeFile(readFile()) );
-}
-
-bool
-AnyOption::processFile( const char *filename )
-{
- useFiileName(filename );
- return ( processFile() );
-}
-
-char*
-AnyOption::readFile()
-{
- return ( readFile(filename) );
-}
-
-/*
- * read the file contents to a character buffer
- */
-
-char*
-AnyOption::readFile( const char* fname )
-{
- int length;
- char *buffer;
- ifstream is;
- is.open ( fname , ifstream::in );
- if( ! is.good() ){
- is.close();
- return NULL;
- }
- is.seekg (0, ios::end);
- length = is.tellg();
- is.seekg (0, ios::beg);
- buffer = (char*) malloc(length*sizeof(char));
- is.read (buffer,length);
- is.close();
- return buffer;
-}
-
-/*
- * scans a char* buffer for lines that does not
- * start with the specified comment character.
- */
-bool
-AnyOption::consumeFile( char *buffer )
-{
-
- if( buffer == NULL )
- return false;
-
- char *cursor = buffer;/* preserve the ptr */
- char *pline = NULL ;
- int linelength = 0;
- bool newline = true;
- for( unsigned int i = 0 ; i < strlen( buffer ) ; i++ ){
- if( *cursor == endofline ) { /* end of line */
- if( pline != NULL ) /* valid line */
- processLine( pline, linelength );
- pline = NULL;
- newline = true;
- }else if( newline ){ /* start of line */
- newline = false;
- if( (*cursor != comment ) ){ /* not a comment */
- pline = cursor ;
- linelength = 0 ;
- }
- }
- cursor++; /* keep moving */
- linelength++;
- }
- free (buffer);
- return true;
-}
-
-
-/*
- * find a valid type value pair separated by a delimiter
- * character and pass it to valuePairs()
- * any line which is not valid will be considered a value
- * and will get passed on to justValue()
- *
- * assuming delimiter is ':' the behaviour will be,
- *
- * width:10 - valid pair valuePairs( width, 10 );
- * width : 10 - valid pair valuepairs( width, 10 );
- *
- * :::: - not valid
- * width - not valid
- * :10 - not valid
- * width: - not valid
- * :: - not valid
- * : - not valid
- *
- */
-
-void
-AnyOption::processLine( char *theline, int length )
-{
- bool found = false;
- char *pline = (char*) malloc( (length+1)*sizeof(char) );
- for( int i = 0 ; i < length ; i ++ )
- pline[i]= *(theline++);
- pline[length] = nullterminate;
- char *cursor = pline ; /* preserve the ptr */
- if( *cursor == delimiter || *(cursor+length-1) == delimiter ){
- justValue( pline );/* line with start/end delimiter */
- }else{
- for( int i = 1 ; i < length-1 && !found ; i++){/* delimiter */
- if( *cursor == delimiter ){
- *(cursor-1) = nullterminate; /* two strings */
- found = true;
- valuePairs( pline , cursor+1 );
- }
- cursor++;
- }
- cursor++;
- if( !found ) /* not a pair */
- justValue( pline );
- }
- free (pline);
-}
-
-/*
- * removes trailing and preceeding whitespaces from a string
- */
-char*
-AnyOption::chomp( char *str )
-{
- while( *str == whitespace )
- str++;
- char *end = str+strlen(str)-1;
- while( *end == whitespace )
- end--;
- *(end+1) = nullterminate;
- return str;
-}
-
-void
-AnyOption::valuePairs( char *type, char *value )
-{
- if ( strlen(chomp(type)) == 1 ){ /* this is a char option */
- for( int i = 0 ; i < optchar_counter ; i++ ){
- if( optionchars[i] == type[0] ){ /* match */
- if( optchartype[i] == COMMON_OPT ||
- optchartype[i] == FILE_OPT )
- {
- setValue( type[0] , chomp(value) );
- return;
- }
- }
- }
- }
- /* if no char options matched */
- for( int i = 0 ; i < option_counter ; i++ ){
- if( strcmp( options[i], type ) == 0 ){ /* match */
- if( optiontype[i] == COMMON_OPT ||
- optiontype[i] == FILE_OPT )
- {
- setValue( type , chomp(value) );
- return;
- }
- }
- }
- printVerbose( "Unknown option in resourcefile : " );
- printVerbose( type );
- printVerbose( );
-}
-
-void
-AnyOption::justValue( char *type )
-{
-
- if ( strlen(chomp(type)) == 1 ){ /* this is a char option */
- for( int i = 0 ; i < optchar_counter ; i++ ){
- if( optionchars[i] == type[0] ){ /* match */
- if( optchartype[i] == COMMON_FLAG ||
- optchartype[i] == FILE_FLAG )
- {
- setFlagOn( type[0] );
- return;
- }
- }
- }
- }
- /* if no char options matched */
- for( int i = 0 ; i < option_counter ; i++ ){
- if( strcmp( options[i], type ) == 0 ){ /* match */
- if( optiontype[i] == COMMON_FLAG ||
- optiontype[i] == FILE_FLAG )
- {
- setFlagOn( type );
- return;
- }
- }
- }
- printVerbose( "Unknown option in resourcefile : " );
- printVerbose( type );
- printVerbose( );
-}
-
-/*
- * usage and help
- */
-
-
-void
-AnyOption::printAutoUsage()
-{
- if( autousage ) printUsage();
-}
-
-void
-AnyOption::printUsage()
-{
-
- if( once ) {
- once = false ;
- cout << endl ;
- for( int i = 0 ; i < usage_lines ; i++ )
- cout << usage[i] << endl ;
- cout << endl ;
- }
-}
-
-
-void
-AnyOption::addUsage( const char *line )
-{
- if( usage_lines >= max_usage_lines ){
- if( doubleUsageStorage() == false ){
- addUsageError( line );
- exit(1);
- }
- }
- usage[ usage_lines ] = line ;
- usage_lines++;
-}
-
-void
-AnyOption::addUsageError( const char *line )
-{
- cout << endl ;
- cout << "OPTIONS ERROR : Failed allocating extra memory " << endl ;
- cout << "While adding the usage/help : \""<< line << "\"" << endl;
- cout << "Exiting." << endl ;
- cout << endl ;
- exit(0);
-
-}
+++ /dev/null
-#ifndef _ANYOPTION_H
-#define _ANYOPTION_H
-
-#include <iostream>
-#include <fstream>
-#include <stdlib.h>
-#include <string>
-
-#define COMMON_OPT 1
-#define COMMAND_OPT 2
-#define FILE_OPT 3
-#define COMMON_FLAG 4
-#define COMMAND_FLAG 5
-#define FILE_FLAG 6
-
-#define COMMAND_OPTION_TYPE 1
-#define COMMAND_FLAG_TYPE 2
-#define FILE_OPTION_TYPE 3
-#define FILE_FLAG_TYPE 4
-#define UNKNOWN_TYPE 5
-
-#define DEFAULT_MAXOPTS 10
-#define MAX_LONG_PREFIX_LENGTH 2
-
-#define DEFAULT_MAXUSAGE 3
-#define DEFAULT_MAXHELP 10
-
-#define TRUE_FLAG "true"
-
-using namespace std;
-
-class AnyOption
-{
-
-public: /* the public interface */
- AnyOption();
- AnyOption(int maxoptions );
- AnyOption(int maxoptions , int maxcharoptions);
- ~AnyOption();
-
- /*
- * following set methods specifies the
- * special characters and delimiters
- * if not set traditional defaults will be used
- */
-
- void setCommandPrefixChar( char _prefix ); /* '-' in "-w" */
- void setCommandLongPrefix( char *_prefix ); /* '--' in "--width" */
- void setFileCommentChar( char _comment ); /* '#' in shellscripts */
- void setFileDelimiterChar( char _delimiter );/* ':' in "width : 100" */
-
- /*
- * provide the input for the options
- * like argv[] for commndline and the
- * option file name to use;
- */
-
- void useCommandArgs( int _argc, char **_argv );
- void useFiileName( const char *_filename );
-
- /*
- * turn off the POSIX style options
- * this means anything starting with a '-' or "--"
- * will be considered a valid option
- * which alo means you cannot add a bunch of
- * POIX options chars together like "-lr" for "-l -r"
- *
- */
-
- void noPOSIX();
-
- /*
- * prints warning verbose if you set anything wrong
- */
- void setVerbose();
-
-
- /*
- * there are two types of options
- *
- * Option - has an associated value ( -w 100 )
- * Flag - no value, just a boolean flag ( -nogui )
- *
- * the options can be either a string ( GNU style )
- * or a character ( traditional POSIX style )
- * or both ( --width, -w )
- *
- * the options can be common to the commandline and
- * the optionfile, or can belong only to either of
- * commandline and optionfile
- *
- * following set methods, handle all the aboove
- * cases of options.
- */
-
- /* options comman to command line and option file */
- void setOption( const char *opt_string );
- void setOption( char opt_char );
- void setOption( const char *opt_string , char opt_char );
- void setFlag( const char *opt_string );
- void setFlag( char opt_char );
- void setFlag( const char *opt_string , char opt_char );
-
- /* options read from commandline only */
- void setCommandOption( const char *opt_string );
- void setCommandOption( char opt_char );
- void setCommandOption( const char *opt_string , char opt_char );
- void setCommandFlag( const char *opt_string );
- void setCommandFlag( char opt_char );
- void setCommandFlag( const char *opt_string , char opt_char );
-
- /* options read from an option file only */
- void setFileOption( const char *opt_string );
- void setFileOption( char opt_char );
- void setFileOption( const char *opt_string , char opt_char );
- void setFileFlag( const char *opt_string );
- void setFileFlag( char opt_char );
- void setFileFlag( const char *opt_string , char opt_char );
-
- /*
- * process the options, registerd using
- * useCommandArgs() and useFileName();
- */
- void processOptions();
- void processCommandArgs();
- void processCommandArgs( int max_args );
- bool processFile();
-
- /*
- * process the specified options
- */
- void processCommandArgs( int _argc, char **_argv );
- void processCommandArgs( int _argc, char **_argv, int max_args );
- bool processFile( const char *_filename );
-
- /*
- * get the value of the options
- * will return NULL if no value is set
- */
- char *getValue( const char *_option );
- bool getFlag( const char *_option );
- char *getValue( char _optchar );
- bool getFlag( char _optchar );
-
- /*
- * Print Usage
- */
- void printUsage();
- void printAutoUsage();
- void addUsage( const char *line );
- void printHelp();
- /* print auto usage printing for unknown options or flag */
- void autoUsagePrint(bool flag);
-
- /*
- * get the argument count and arguments sans the options
- */
- int getArgc();
- char* getArgv( int index );
- bool hasOptions();
-
-private: /* the hidden data structure */
- int argc; /* commandline arg count */
- char **argv; /* commndline args */
- const char* filename; /* the option file */
- char* appname; /* the application name from argv[0] */
-
- int *new_argv; /* arguments sans options (index to argv) */
- int new_argc; /* argument count sans the options */
- int max_legal_args; /* ignore extra arguments */
-
-
- /* option strings storage + indexing */
- int max_options; /* maximum number of options */
- const char **options; /* storage */
- int *optiontype; /* type - common, command, file */
- int *optionindex; /* index into value storage */
- int option_counter; /* counter for added options */
-
- /* option chars storage + indexing */
- int max_char_options; /* maximum number options */
- char *optionchars; /* storage */
- int *optchartype; /* type - common, command, file */
- int *optcharindex; /* index into value storage */
- int optchar_counter; /* counter for added options */
-
- /* values */
- char **values; /* common value storage */
- int g_value_counter; /* globally updated value index LAME! */
-
- /* help and usage */
- const char **usage; /* usage */
- int max_usage_lines; /* max usage lines reseverd */
- int usage_lines; /* number of usage lines */
-
- bool command_set; /* if argc/argv were provided */
- bool file_set; /* if a filename was provided */
- bool mem_allocated; /* if memory allocated in init() */
- bool posix_style; /* enables to turn off POSIX style options */
- bool verbose; /* silent|verbose */
- bool print_usage; /* usage verbose */
- bool print_help; /* help verbose */
-
- char opt_prefix_char; /* '-' in "-w" */
- char long_opt_prefix[MAX_LONG_PREFIX_LENGTH]; /* '--' in "--width" */
- char file_delimiter_char; /* ':' in width : 100 */
- char file_comment_char; /* '#' in "#this is a comment" */
- char equalsign;
- char comment;
- char delimiter;
- char endofline;
- char whitespace;
- char nullterminate;
-
- bool set; //was static member
- bool once; //was static member
-
- bool hasoptions;
- bool autousage;
-
-private: /* the hidden utils */
- void init();
- void init(int maxopt, int maxcharopt );
- bool alloc();
- void cleanup();
- bool valueStoreOK();
-
- /* grow storage arrays as required */
- bool doubleOptStorage();
- bool doubleCharStorage();
- bool doubleUsageStorage();
-
- bool setValue( const char *option , char *value );
- bool setFlagOn( const char *option );
- bool setValue( char optchar , char *value);
- bool setFlagOn( char optchar );
-
- void addOption( const char* option , int type );
- void addOption( char optchar , int type );
- void addOptionError( const char *opt);
- void addOptionError( char opt);
- bool findFlag( char* value );
- void addUsageError( const char *line );
- bool CommandSet();
- bool FileSet();
- bool POSIX();
-
- char parsePOSIX( char* arg );
- int parseGNU( char *arg );
- bool matchChar( char c );
- int matchOpt( char *opt );
-
- /* dot file methods */
- char *readFile();
- char *readFile( const char* fname );
- bool consumeFile( char *buffer );
- void processLine( char *theline, int length );
- char *chomp( char *str );
- void valuePairs( char *type, char *value );
- void justValue( char *value );
-
- void printVerbose( const char *msg );
- void printVerbose( char *msg );
- void printVerbose( char ch );
- void printVerbose( );
-
-
-};
-
-#endif /* ! _ANYOPTION_H */
+++ /dev/null
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
+++ /dev/null
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
-*/
-
-/* Created by Bram de Jong <bram.dejong@gmail.com> for MTG http://www.mtg.upf.edu/
- *
- * You will need anyoption ( http://www.hackorama.com/anyoption/ ) and libsndfile
- * ( http://www.mega-nerd.com/libsndfile/ ) and GD2 (http://www.boutell.com/gd/)
- * to build this program.
-*/
-
-#include <math.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdio.h>
-#include <cctype>
-#include <string>
-#include <iostream>
-#include <fstream>
-#include <vector>
-#include <algorithm>
-
-#include "sndfile.h"
-
-#ifdef WIN32
-#include "gdwin32/gd.h"
-#else
-#include "gd.h"
-#endif
-
-#include "anyoption.h"
-
-typedef std::vector<long> ColorVector;
-
-long hex2dec(char h)
-{
- switch(h)
- {
- case 'a': return 10;
- case 'b': return 11;
- case 'c': return 12;
- case 'd': return 13;
- case 'e': return 14;
- case 'f': return 15;
- default:
- {
- char tmp = h - '0';
- if(tmp >= 0 && tmp <= 9)
- return tmp;
- else
- return 0;
- }
- }
-}
-
-// string as a HEX HTML value 000000 (black) FF0000 (red) etc...
-long string2color(std::string s, gdImagePtr image)
-{
- long r,g,b;
- if(s.length() == 6)
- {
- std::transform(s.begin(), s.end(), s.begin(), (int (*)(int)) tolower);
- r = (hex2dec(s.at(0))<<4) + hex2dec(s.at(1));
- g = (hex2dec(s.at(2))<<4) + hex2dec(s.at(3));
- b = (hex2dec(s.at(4))<<4) + hex2dec(s.at(5));
- }
- else
- {
- r = g = b = 0;
- }
-
- return gdImageColorAllocate(image, r, g, b);
-}
-
-void HSVtoRGB( float &r, float &g, float &b, float h, float s, float v )
-{
- int i;
- float f, p, q, t;
-
- if( s == 0 ) {
- // achromatic (grey)
- r = g = b = v;
- return;
- }
-
- h /= 60; // sector 0 to 5
- i = (int)floor( h );
- f = h - i; // factorial part of h
- p = v * ( 1 - s );
- q = v * ( 1 - s * f );
- t = v * ( 1 - s * ( 1 - f ) );
-
- switch( i ) {
- case 0:
- r = v;
- g = t;
- b = p;
- break;
- case 1:
- r = q;
- g = v;
- b = p;
- break;
- case 2:
- r = p;
- g = v;
- b = t;
- break;
- case 3:
- r = p;
- g = q;
- b = v;
- break;
- case 4:
- r = t;
- g = p;
- b = v;
- break;
- default: // case 5:
- r = v;
- g = p;
- b = q;
- break;
- }
-
-}
-
-/* The hue value H runs from 0 to 360º. The saturation S is the degree of strength
-or purity and is from 0 to 1. Purity is how much white is added to the color, so S=1
-makes the purest color (no white). Brightness V also ranges from 0 to 1, where 0 is the black.*/
-// x in [0..1]
-long float2color(float value, gdImagePtr image)
-{
- if(value > 1.f) value = 1.f;
- else if(value < 0.f) value = 0.f;
-
- float h;
- float s;
- float v;
-
- h = (1.f-value)*360.0;
- s = 0.8f;
- v = 1.f;
-
- float r,g,b;
-
- HSVtoRGB(r,g,b,h,s,v);
-
- return gdImageColorAllocate(image, (int)(r*255), (int)(g*255), (int)(b*255));
-}
-
-
-void getPeakSamplesInBlock(float *samples, long count, long channels, float &first, float &second, bool verbose)
-{
- if (verbose)
- std::cout << "\tprocessing " << count << " samples, " << channels << " channels" << std::endl;
-
- if(count < 1)
- {
- first = second = 0.f;
- if (verbose)
- std::cout << "\texiting as there's no samples" << std::endl;
- return;
- }
- else if(count < 2)
- {
- first = second = samples[0];
- if (verbose)
- std::cout << "\texiting as there's less than two samples" << std::endl;
- return;
- return;
- }
-
- float tlow = samples[0];
- float thigh = samples[0];
- long high_i = 0;
- long low_i = 0;
-
- for(long i=channels;i<count;i+=channels)
- {
- float val = samples[i];
-
- if(val > thigh)
- {
- thigh = val;
- high_i = i;
- }
-
- if(val < tlow)
- {
- tlow = val;
- low_i = i;
- }
- }
-
- if (high_i > low_i)
- {
- first = tlow;
- second = thigh;
- }
- else
- {
- first = thigh;
- second = tlow;
- }
-
- if (verbose)
- std::cout << "\tprocessing: done" << std::endl;
-}
-
-bool getPositionAndValue(std::string line, long &position, float &value, long positionIncrement = 0)
-{
- long pos;
- float val;
- int good;
-
- good = sscanf(line.c_str(),"%ld,%f",&pos,&val);
-
- if(good == 2 && pos >= 0)
- {
- position = pos;
- value = val;
- return true;
- }
-
- good = sscanf(line.c_str(),"%f",&val);
-
- if(good == 1 && good != EOF)
- {
- position += positionIncrement;
- value = val;
- return true;
- }
-
- return false;
-}
-
-bool getPositionAndColor(std::string line, long &position, long &color, gdImagePtr image, long positionIncrement = 0)
-{
- long pos;
- char colorString[6];
- int good;
-
- good = sscanf(line.c_str(),"%ld,#%6s",&pos,colorString);
-
- if(good == 2 && pos >= 0)
- {
- position = pos;
- color = string2color(colorString,image);
- return true;
- }
-
- good = sscanf(line.c_str(),"#%6s",colorString);
-
- if(good == 1)
- {
- position += positionIncrement;
- color = string2color(colorString,image);
- return true;
- }
-
- return false;
-}
-
-ColorVector getColorValues(std::string filename, float samplesPerPixel, long width, gdImagePtr image)
-{
- ColorVector colors;
-
- char buffer[256];
- std::string line;
- std::ifstream infile;
- infile.open(filename.c_str(), std::ifstream::in);
-
- float value = 0.f;
- long color = 0;
- long position = 0;
- bool inputGood = true;
- bool colorFileUsesColors = false;
- long stepsize = 0;
- std::vector<float> values;
-
- if(infile.good())
- {
- infile.getline(buffer,256);
- line = buffer;
-
- int success = sscanf(line.c_str(),"[%ld]",&stepsize);
- if(success == 1)
- {
- if(infile.good())
- {
- infile.getline(buffer,256);
- line = buffer;
- }
- else
- {
- return colors;
- }
- }
- else
- {
- stepsize = 0;
- }
-
- long hasHasChar = std::string(line).find("#");
-
- if(hasHasChar > 0)
- {
- colorFileUsesColors = true;
- }
- }
- else
- {
- return colors;
- }
-
- if(colorFileUsesColors)
- inputGood = getPositionAndColor(line,position,color,image,stepsize);
- else
- inputGood = getPositionAndValue(line,position,value,stepsize);
-
- float nextValue = value;
- long nextColor = color;
-
- for(long i=0;i<width;i++)
- {
- long sampleLocation = (long)ceilf((double)i * (double)samplesPerPixel);
-
- while(sampleLocation >= position && inputGood)
- {
- color = nextColor;
- value = nextValue;
-
- if(infile.good())
- {
- infile.getline(buffer,256);
- line = buffer;
-
- if(colorFileUsesColors)
- {
- inputGood = getPositionAndColor(line,position,nextColor,image,stepsize);
- }
- else
- {
- inputGood = getPositionAndValue(line,position,nextValue,stepsize);
- }
- }
- else
- {
- inputGood = false;
- }
- }
-
- if(colorFileUsesColors)
- colors.push_back(color);
- else
- values.push_back(value);
-
- }
-
- infile.close();
-
- if(colorFileUsesColors)
- return colors;
-
- if(values.size())
- {
- int type = 1;
-
- switch(type)
- {
- case 0:
- {
- for(unsigned long k=0;k<values.size();k++)
- {
- if(values[k] < 0.f)
- values[k] = 0.f;
-
- float scaledValue = sqrt(values[k]) / sqrt((double)11025);
-
- colors.push_back(float2color(scaledValue,image));
- }
-
- break;
- }
- case 1:
- {
- for(unsigned long k=0;k<values.size();k++)
- {
- if(values[k] < 0.f)
- values[k] = 0.f;
-
- float scaledValue = log(values[k]+1) / log((double)(512+1));
-
- colors.push_back(float2color(scaledValue,image));
- }
-
- break;
- }
- case 2:
- default:
- {
- float maxValue = values[0];
- float minValue = values[0];
-
- for(unsigned long j=1;j<values.size();j++)
- {
- if(values[j] > maxValue)
- maxValue = values[j];
-
- if(values[j] < minValue)
- minValue = values[j];
- }
-
- if(minValue != maxValue)
- {
- for(unsigned long k=0;k<values.size();k++)
- {
- colors.push_back(float2color((values[k] - minValue) / (maxValue - minValue),image));
- }
- }
- else
- {
- for(unsigned long k=0;k<colors.size();k++)
- {
- colors.push_back(float2color(1.0,image));
- }
- }
-
- break;
- }
- }
- }
-
- return colors;
-}
-
-inline long round(float x)
-{
- return (long)floorf(x + 0.5f);
-}
-
-// this is pretty ugly and should be removed :-)
-float oldX, oldY;
-
-void moveTo(float x, float y)
-{
- oldX = x;
- oldY = y;
-}
-
-void lineTo(gdImagePtr image, float x, float y, long color, long padding, long width, long height, bool verbose)
-{
- long x1 = (long)round(oldX)+padding;
- long y1 = (long)round(oldY)+padding;
- long x2 = (long)round(x)+padding;
- long y2 = (long)round(y)+padding;
-
- // GD seems to segfault when we try to draw anti-aliased lines to the teges :-(
- y1 = std::max((long)0,std::min(height-2, y1));
- y2 = std::max((long)0,std::min(height-2, y2));
-
- if (verbose)
- std::cout << "\tdrawing line: (" << x1 << "," << y1 << ") -> (" << x2 << "," << y2 << "), color = " << std::hex << color << " image : " << image << std::dec << std::endl;
-
- gdImageLine(image,x1,y1,x2,y2,color);
- oldX = x;
- oldY = y;
-
- if (verbose)
- std::cout << "\tdrawing line: done" << std::endl;
-}
-
-int main(int argc, char* argv[])
-{
- AnyOption *opt = new AnyOption();
-
- opt->setOption("input",'i');
- opt->setOption("width",'w');
- opt->setOption("height",'h');
- opt->setOption("output",'o');
- opt->setOption("colorfile",'c');
- opt->setOption("linecolor",'l');
- opt->setOption("backgroundcolor",'b');
- opt->setOption("zerocolor",'z');
- opt->setOption("padding",'p');
- opt->setOption("verbose",'v');
-
- opt->setOption("type",'t');
- opt->setOption("quality",'q');
-
- opt->addUsage( "Usage: wav2png --input wavefile.wav" );
- opt->addUsage( "\t" );
- opt->addUsage( "\tAdditional options: --width 300 --height 151 --output image.jpg --linecolor ff00aa --backgroundcolor 002222 --zerocolor ff0000 --colorfile filename --padding 2 --verbose true --type jpeg --quality 85" );
- opt->addUsage( "\tShort command line switches: -i -w -h -o -l -b -z -c -o");
- opt->addUsage( "\t" );
- opt->addUsage( "\twidth: width of PNG (default: 300)");
- opt->addUsage( "\theight: height of PNG (default: 151)");
- opt->addUsage( "\toutput: output filename (default: input filename with '.png' appended)");
- opt->addUsage( "\tlinecolor: color of waveform lines (default: 323232)");
- opt->addUsage( "\tbackgroundcolor: color of background (default: FFFFFF)");
- opt->addUsage( "\tzerocolor: color of line through zero (default: 960000)");
- opt->addUsage( "\t\tcolors are defined like HTML colors in hex");
- opt->addUsage( "\tcolorfile: file with (samplePosition,value) pairs for coloring");
- opt->addUsage( "\tpadding: padding around the edge");
- opt->addUsage( "\tverbose: true or false");
- opt->addUsage( "\ttype: png or jpeg");
- opt->addUsage( "\tquality: jpeg quality between 0 and 100");
-
- opt->processCommandArgs( argc, argv );
-
- std::string inputFilename;
- std::string outputFilename;
-
- bool verbose = false;
- if( opt->getValue("verbose") != NULL && strcmp(opt->getValue("verbose"), "true") == 0)
- verbose = true;
-
- if (verbose)
- std::cout << "verbose true" << std::endl;
-
- if (verbose) std::cout << "parsing options" << std::endl;
-
- long quality = -1;
- if ( opt->getValue("quality") != NULL )
- quality = atoi(opt->getValue("quality"));
-
- if (verbose)
- std::cout << "quality " << quality << std::endl;
-
- bool isPng = true;
- if ( opt->getValue("type") != NULL && strcmp(opt->getValue("type"), "jpeg") == 0)
- isPng = false;
-
- if (verbose)
- std::cout << "isPng " << (isPng?"true":"false") << std::endl;
-
- if( opt->getValue("input") != NULL )
- {
- inputFilename = opt->getValue("input");
- }
- else
- {
- opt->printUsage();
- return 1;
- }
-
- if (verbose)
- std::cout << "input filename " << inputFilename << std::endl;
-
- if( opt->getValue("output") != NULL )
- {
- outputFilename = opt->getValue("output");
- }
- else
- {
- outputFilename = inputFilename + std::string(".png");
- }
-
- if (verbose)
- std::cout << "output filename " << outputFilename << std::endl;
-
- long width = 354;
- if( opt->getValue("width") != NULL )
- {
- width = atoi(opt->getValue("width"));
-
- if(width <= 0)
- return 1;
- }
-
-
- if (verbose)
- std::cout << "width " << width << std::endl;
-
- long height = 165;
- if( opt->getValue("height") != NULL )
- {
- height = atoi(opt->getValue("height"));
-
- if(height <= 0)
- return 1;
- }
-
- if (verbose)
- std::cout << "height " << height << std::endl;
-
- long padding = 2;
- if( opt->getValue("padding") != NULL )
- {
- padding = atoi(opt->getValue("padding"));
-
- if(padding<0)
- return 1;
- }
-
- if (verbose)
- std::cout << "padding " << padding << std::endl;
-
- std::string colorFilename("");
- if( opt->getValue("colorfile") != NULL )
- {
- colorFilename = std::string(opt->getValue("colorfile"));
- }
-
- if (verbose)
- std::cout << "color filename " << colorFilename << std::endl;
-
- if (verbose) std::cout << "opening wave file" << std::endl;
-
- SNDFILE *infile;
- SF_INFO sfinfo ;
-
- // open the soundfile
- if(!(infile = sf_open (inputFilename.c_str(), SFM_READ, &sfinfo)))
- {
- return 1;
- };
-
- if(sfinfo.frames == 0 || sfinfo.channels == 0)
- {
- sf_close(infile);
- return 1;
- }
-
- float samplesPerPixel = (float) sfinfo.frames / (float) width;
- long maxReadSize = (long)ceilf(samplesPerPixel);
-
- if (verbose) std::cout << "samps/pixel "<< samplesPerPixel << std::endl;
-
- if (verbose) std::cout << "allocating image..." << std::endl;
- gdImagePtr image = gdImageCreateTrueColor(width+padding*2, height+padding*2);
- if (verbose) std::cout << "done..." << std::endl;
-
- ColorVector colors;
- if(colorFilename != "")
- {
- if (verbose) std::cout << "getting color values" << std::endl;
- colors = getColorValues(colorFilename,samplesPerPixel,width,image);
- }
-
-
- long backgroundColor;
- long lineColor;
- long zeroColor;
-
- if (verbose) std::cout << "parsing more options" << std::endl;
-
- if( opt->getValue("linecolor") != NULL )
- lineColor = string2color(opt->getValue("linecolor"),image);
- else
- lineColor = string2color("FFFFFF",image);
-
- if (verbose)
- std::cout << "line color " << std::hex << lineColor << std::dec << std::endl;
-
- if( opt->getValue("backgroundcolor") != NULL )
- backgroundColor = string2color(opt->getValue("backgroundcolor"),image);
- else
- backgroundColor = string2color("000000",image);
-
- if (verbose)
- std::cout << "background color " << std::hex << backgroundColor << std::dec << std::endl;
-
- if( opt->getValue("zerocolor") != NULL )
- zeroColor = string2color(opt->getValue("zerocolor"),image);
- else
- zeroColor = string2color("960000",image);
-
- if (verbose)
- std::cout << "zero color " << std::hex << zeroColor << std::dec << std::endl;
-
- gdImageFilledRectangle(image,0,0,width+padding*2-1,height+padding*2-1, backgroundColor);
- gdImageSetAntiAliased(image,lineColor);
- moveTo(0,height*0.5f);
-
-
- // sampling data
- long dataSize = sfinfo.channels * maxReadSize;
- if (verbose) std::cout << "allocating " << dataSize << " bytes" << std::endl;
- float *data = new float[dataSize];
- if (verbose) std::cout << "allocated..." << std::endl;
-
- float first = 0, second = 0;
-
- // we need at least width samples to do something usefull...
- for(long i=0;i<width;i++)
- {
- if (verbose && !(i % std::max(width/20,(long)1)))
- std::cout << "looping over sound " << i+1 << " of " << width << std::endl;
-
- if (colors.size() && (unsigned) i < colors.size())
- {
- if (verbose)
- std::cout << "\tsetting antialiased line color..." << std::endl;
- gdImageSetAntiAliased(image,colors[i]);
- }
-
- float start = i * samplesPerPixel;
- float end = (i + 1) * samplesPerPixel;
-
- long blockSize = (long) floorf(end + 0.5f) - (long) floorf(start + 0.5f);
-
- if(blockSize > maxReadSize)
- {
- blockSize = maxReadSize;
- }
- else if(blockSize < 1)
- {
- lineTo(image, (float)i, height * 0.5f * (1.f - first), gdAntiAliased, padding, width, height, verbose);
- lineTo(image, (float)i, height * 0.5f * (1.f - second), gdAntiAliased, padding, width, height, verbose);
- continue;
- }
-
- if (verbose && !(i % std::max(width/20,(long)1)))
- std::cout << "\treading wave file" << std::endl;
-
- long readcount = sf_readf_float(infile, data, blockSize);
-
- if(readcount == 0)
- {
- if (verbose)
- std::cout << "\tthis is probably a broken wave file... It reported more samples than it has!" << std::endl;
- break;
- }
- if(readcount < blockSize)
- {
- if (verbose)
- std::cout << "\twe just read a non-complete block..." << std::endl;
- }
-
- if (verbose && !(i % std::max(width/20,(long)1)))
- std::cout << "\tread OK" << std::endl;
-
- if (verbose && !(i % std::max(width/20,(long)1)))
- std::cout << "\tgetting sample peaks" << std::endl;
-
- getPeakSamplesInBlock(data, readcount, sfinfo.channels, first, second, verbose);
-
- if (verbose && !(i % std::max(width/20,(long)1)))
- std::cout << "\tpeak OK" << std::endl;
-
- if(first != second)
- {
- lineTo(image, (float)i, height * 0.5f * (1.f - first), gdAntiAliased, padding, width, height, verbose);
- lineTo(image, (float)i, height * 0.5f * (1.f - second), gdAntiAliased, padding, width, height, verbose);
- }
- else
- {
- lineTo(image, (float)i, height * 0.5f * (1.f - first), gdAntiAliased, padding, width, height, verbose);
- }
- }
-
- if (verbose)
- std::cout << "closing sound file" << std::endl;
-
- sf_close (infile) ;
-
- if (verbose)
- std::cout << "closed" << std::endl;
-
-
- if (verbose)
- std::cout << "generating GD image" << std::endl;
-
- if (verbose)
- std::cout << "\topening output file" << std::endl;
-
- FILE *outputFile = fopen(outputFilename.c_str(),"wb");
-
- if (verbose)
- std::cout << "\tgdImageCreate" << std::endl;
-
- if (isPng)
- gdImagePng(image,outputFile);
- else
- gdImageJpeg(image,outputFile,quality);
-
- if (verbose)
- std::cout << "\tclose output file" << std::endl;
-
- fclose(outputFile);
-
- if (verbose)
- std::cout << "\tgdImageDestroy" << std::endl;
-
- gdImageDestroy(image);
-
- if (verbose)
- std::cout << "deleting data" << std::endl;
-
- delete data;
-
- if (verbose)
- std::cout << "all fine and dandy, exiting" << std::endl;
-
- return 0;
-}