/* $Id: GetOptClass.cxx 15828 2013-03-28 11:55:53Z sloot $ $URL: https://ilk.uvt.nl/svn/trunk/sources/Timbl6/src/GetOptClass.cxx $ Copyright (c) 1998 - 2013 ILK - Tilburg University CLiPS - University of Antwerp This file is part of timbl timbl 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 3 of the License, or (at your option) any later version. timbl 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, see . For questions and suggestions, see: http://ilk.uvt.nl/software.html or send mail to: timbl@uvt.nl */ #include #include #include #include #include #include #include #include #include "timbl/Common.h" #include "timbl/Types.h" #include "timbl/Options.h" #include "timbl/Instance.h" #include "timbl/Metrics.h" #include "timbl/CommandLine.h" #include "timbl/GetOptClass.h" #include "timbl/TimblExperiment.h" using namespace std; using namespace TiCC; namespace Timbl { void GetOptClass::set_default_options( int Max ){ local_algo = IB1_a; local_metric = UnknownMetric; local_order = UnknownOrdening; local_weight = Unknown_w; local_decay = Zero; local_decay_alfa = 1.0; local_decay_beta = 1.0; local_normalisation = unknownNorm; local_norm_factor = 1; no_neigh = 1; mvd_limit = 1; estimate = 0; maxbests = 500; BinSize = 0; BeamSize = 0; clip_freq = 10; clones = 1; bootstrap_lines = -1; local_progress = 100000; seed = -1; do_exact = false; do_hashed = true; min_present = false; keep_distributions = false; do_sample_weights = false; do_ignore_samples = false; do_ignore_samples_test = false; do_query = false; do_all_weights = false; do_sloppy_loo = false; do_silly = false; do_diversify = false; do_daemon = true; if ( MaxFeats == -1 ){ MaxFeats = Max; LocalInputFormat = UnknownInputFormat; // InputFormat and verbosity myVerbosity = NO_VERB; // are not reset! } target_pos = -1; metricsArray.resize(MaxFeats+1); for ( int i=0; i < MaxFeats+1; ++i ){ metricsArray[i] = UnknownMetric; } outPath = ""; logFile = ""; pidFile = ""; occIn = 0; } GetOptClass::GetOptClass( CL_Options& Opts ): LocalInputFormat( UnknownInputFormat ), MaxFeats(-1), target_pos(-1), f_length( 0 ), threshold( -1 ), igThreshold( -1 ), myVerbosity( NO_VERB ), opt_init( false ), opt_changed( false ), N_present( false ), parent_socket_os( 0 ) { int MaxF = DEFAULT_MAX_FEATS; bool the_mood; string optie; if ( Opts.Find( 'N', optie, the_mood ) ){ N_present = true; MaxF = stringTo( optie ); } set_default_options( MaxF ); } GetOptClass::~GetOptClass( ){ } GetOptClass::GetOptClass( const GetOptClass& in ): MsgClass(in), local_algo( in.local_algo ), local_metric( in.local_metric ), local_order( in.local_order ), local_weight( in.local_weight ), LocalInputFormat( in.LocalInputFormat ), local_decay( in.local_decay ), local_decay_alfa( in.local_decay_alfa ), local_decay_beta( in.local_decay_beta ), local_normalisation( in.local_normalisation ), local_norm_factor( in.local_norm_factor ), MaxFeats( in.MaxFeats ), no_neigh( in.no_neigh ), mvd_limit( in.mvd_limit ), estimate( in.estimate ), maxbests( in.maxbests ), clip_freq( in.clip_freq ), clones( in.clones ), BinSize( in.BinSize ), BeamSize( in.BeamSize ), bootstrap_lines( in.bootstrap_lines ), f_length( in.f_length ), local_progress( in.local_progress ), seed( in.seed ), threshold( in.threshold ), igThreshold( in.igThreshold ), myVerbosity( in.myVerbosity ), opt_init( in.opt_init ), opt_changed( in.opt_changed ), do_exact( in.do_exact ), do_hashed( in.do_hashed ), min_present( in.min_present ), N_present(false), keep_distributions( in.keep_distributions ), do_sample_weights( in.do_sample_weights ), do_ignore_samples( in.do_ignore_samples ), do_ignore_samples_test( in.do_ignore_samples_test ), do_query( in.do_query ), do_all_weights( false ), do_sloppy_loo( false ), do_silly( in.do_silly ), do_diversify( in.do_diversify ), do_daemon( in.do_daemon ), metricsArray( in.metricsArray ), parent_socket_os( in.parent_socket_os ), outPath( in.outPath ), logFile( in.logFile ), pidFile( in.pidFile ), occIn( in.occIn ) { } GetOptClass *GetOptClass::Clone( ostream *sock_os ) const{ GetOptClass *result = new GetOptClass(*this); result->parent_socket_os = sock_os; return result; } void GetOptClass::Error( const string& out_line ) const { if ( parent_socket_os ) *parent_socket_os << "ERROR { " << out_line << " }" << endl; else { cerr << "Error:" << out_line << endl; } } bool GetOptClass::definitive_options( TimblExperiment *Exp ){ if ( opt_changed || !opt_init ){ opt_changed = false; bool first = !opt_init; if ( !opt_init ) opt_init = true; string optline; if ( first ){ // the following options can only be set once! // If you try it anyway, you should get a MblClass warning... if ( LocalInputFormat == SparseBin ){ if ( !N_present ){ Error( "Missing -N option, mandatory for -F Binary" ); return false; } } if ( LocalInputFormat == Sparse ){ if ( !N_present ){ Error( "Missing -N option, mandatory for -F Sparse" ); return false; } } if ( LocalInputFormat != UnknownInputFormat ){ optline = "INPUTFORMAT: " + toString(LocalInputFormat); if (!Exp->SetOption( optline )) return false; } if ( target_pos != -1 ){ optline = "TARGET_POS: " + toString(target_pos-1); if (!Exp->SetOption( optline )) return false; } if ( keep_distributions ){ optline = "KEEP_DISTRIBUTIONS: true"; if (!Exp->SetOption( optline )) return false; } if ( do_sloppy_loo ){ if ( local_algo != LOO_a ){ Error( "sloppy only valid for LOO algorithm" ); return false; } else { optline = "DO_SLOPPY_LOO: true"; if (!Exp->SetOption( optline )) return false; } } if ( do_silly ){ optline = "DO_SILLY: true"; if (!Exp->SetOption( optline )) return false; } if ( do_diversify ){ optline = "DO_DIVERSIFY: true"; if (!Exp->SetOption( optline )) return false; } if ( f_length > 0 ){ optline = "FLENGTH: " + toString(f_length); if (!Exp->SetOption( optline )) return false; } if ( local_weight != Unknown_w ){ optline = "WEIGHTING: " + toString(local_weight); Exp->SetOption( optline ); } if ( do_all_weights ){ optline = "ALL_WEIGHTS: true"; Exp->SetOption( optline ); } optline = "MAXBESTS: " + toString(maxbests); Exp->SetOption( optline ); if ( BinSize > 0 ){ optline = "BIN_SIZE: " + toString(BinSize); Exp->SetOption( optline ); } if ( BeamSize > 0 ){ optline = "BEAM_SIZE: " + toString(BeamSize); Exp->SetOption( optline ); } if ( local_algo == TRIBL_a && threshold < 0 ){ Error( "-q is missing for TRIBL algorithm" ); return false; } if ( threshold >= 0 ){ if ( local_algo != TRIBL_a ){ Error( "-q option only valid for TRIBL algorithm" ); return false; } if ( threshold == 0 ){ Error( "invalid -q option. Must be > 0 " ); return false; } optline = "TRIBL_OFFSET: " + toString(threshold); Exp->SetOption( optline ); } if ( igThreshold > 0 ){ optline = "IG_THRESHOLD: " + toString(igThreshold); Exp->SetOption( optline ); } if ( local_order != UnknownOrdening ){ optline = "TREE_ORDER: " + toString(local_order); Exp->SetOption( optline ); } if ( !outPath.empty() ){ Exp->setOutPath( outPath ); } } if ( clones > 0 ) Exp->Clones( clones ); if ( estimate < 10 ) Exp->Estimate( 0 ); else Exp->Estimate( estimate ); if ( myVerbosity & CONFIDENCE ){ if ( local_normalisation == unknownNorm ){ Error( "Invalid option +vcf, while -G is missing!" ); return false; } } if ( myVerbosity & DISTRIB ){ if ( !keep_distributions && local_algo == IGTREE_a ){ myVerbosity &= ~DISTRIB; Error( "Invalid option +vdb, while +D is missing!" ); return false; } } if ( myVerbosity & ALL_K ){ if ( local_algo == IGTREE_a ){ Error( "Invalid option +vk, impossible with IGtree algorithm" ); return false; } else if ( !(myVerbosity & DISTRIB) ){ // silently add +vdb when +vk is set myVerbosity |= DISTRIB; } } if ( myVerbosity & NEAR_N ){ if ( local_algo == IGTREE_a ){ Error( "Invalid option +vn, impossible with IGtree algorithm" ); return false; } } if ( myVerbosity & CONF_MATRIX || myVerbosity & CLASS_STATS ) myVerbosity |= ADVANCED_STATS; if ( do_exact ) Exp->SetOption( "EXACT_MATCH: true" ); else Exp->SetOption( "EXACT_MATCH: false" ); if ( do_hashed ) Exp->SetOption( "HASHED_TREE: true" ); else Exp->SetOption( "HASHED_TREE: false" ); if ( occIn > 0 && do_sample_weights ){ Error( "--occurrences and -s cannot be combined!" ); return false; } if ( occIn > 0 ){ Exp->SetOption( "HANDLE_OCCURRENCES: " + toString(occIn) ); } else if ( do_sample_weights ){ Exp->SetOption( "EXEMPLAR_WEIGHTS: true" ); if ( do_ignore_samples ) Exp->SetOption( "IGNORE_EXEMPLAR_WEIGHTS: true" ); else Exp->SetOption( "IGNORE_EXEMPLAR_WEIGHTS: false" ); if ( do_ignore_samples_test ) Exp->SetOption( "NO_EXEMPLAR_WEIGHTS_TEST: true" ); else Exp->SetOption( "NO_EXEMPLAR_WEIGHTS_TEST: false" ); } else Exp->SetOption( "EXEMPLAR_WEIGHTS: false" ); if ( local_metric == UnknownMetric ){ // Ok, so NO defaults at all (API usage for instance) local_metric = Overlap; for ( size_t j=0; j < metricsArray.size(); ++j ){ metricsArray[j] = Overlap; } } optline = "GLOBAL_METRIC: " + toString(local_metric); Exp->SetOption( optline ); if ( bootstrap_lines > 0 ){ optline = "IB2_OFFSET: " + toString(bootstrap_lines); Exp->SetOption( optline ); } if ( local_normalisation != unknownNorm ){ optline = "NORMALISATION: " + toString( local_normalisation ); Exp->SetOption( optline ); if ( local_normalisation == addFactorNorm ){ optline = "NORM_FACTOR: " + toString( local_norm_factor ); Exp->SetOption( optline ); } } optline = "MVD_LIMIT: " + toString(mvd_limit); Exp->SetOption( optline ); optline = "NEIGHBORS: " + toString(no_neigh); if ( Exp->SetOption( optline ) ){ optline = "DECAY: " + toString(local_decay); if ( Exp->SetOption( optline ) ){ optline = "DECAYPARAM_A: " + toString(local_decay_alfa); if ( Exp->SetOption( optline ) ){ optline = "DECAYPARAM_B: " + toString(local_decay_beta); if ( Exp->SetOption( optline ) ){ optline = "CLIP_FACTOR: " + toString(clip_freq); if ( Exp->SetOption( optline ) ){ optline = "SEED: " + toString(seed); if ( Exp->SetOption( optline ) ){ optline = "PROGRESS: " + toString(local_progress); if ( Exp->SetOption( optline ) ){ optline = "VERBOSITY: " + toString(myVerbosity); if ( Exp->SetOption( optline ) ){ for ( size_t i=0; i < metricsArray.size(); ++i ){ if ( !first ){ if ( metricsArray[i] == Ignore ){ Error( "-m:I is not possible at this stage" ); return false; } } optline = "METRICS: " + toString( i ) + "=" + toString(metricsArray[i]); if (!Exp->SetOption( optline ) ) return false; } if ( do_query ){ Exp->ShowSettings( cerr ); do_query = false; } return true; } } } } } } } } return false; } return true; } inline bool GetOptClass::parse_range( string& line, string::iterator& it, MetricType Value ){ size_t m; string::iterator eit; while( it != line.end() && *it != ':' ){ eit = it; while( eit != line.end() && isdigit( *eit ) ) ++eit; string tmp = string( it, eit ); size_t k; if ( stringTo( tmp, k, 1, metricsArray.size() ) ){ if ( metricsArray[k] != UnknownMetric && metricsArray[k] != Value ){ Error( "metric of feature " + tmp + " is multiply changed!" ); return false; } metricsArray[k] = Value; } else { Error( "illegal value in metric description: -m " + line ); return false; } it = eit; if ( it == line.end() ){ return true; } else if ( *it == ',' ) ++it; else if ( *it == '-' ){ ++it; eit = it; while( eit != line.end() && isdigit( *eit ) ) ++eit; tmp = string( it, eit ); m = stringTo(tmp); if ( m <= 0 || m > metricsArray.size() ){ Error( "illegal value in metric description: -m " + line ); return false; } it = eit; if ( it != line.end() && (*it != ',' && *it != ':' ) ){ Error( "illegal value in metric description: -m " + line ); return false; } if ( m < k ){ Error( "illegal value in metric description: -m " + line ); return false; } else { for ( size_t j=k+1; j <= m && j <= metricsArray.size(); ++j ){ if ( metricsArray[j] != UnknownMetric && metricsArray[j] != Value ){ Error( "metric of feature " + toString(j) + " is multiply changed!" ); return false; } metricsArray[j] = Value; } } if ( it != line.end() && *it == ',' ) ++it; } } return true; } inline bool GetOptClass::parse_metrics( const string& Mline, MetricType& Def ){ string line = TiCC::trim( Mline ); TiCC::to_upper( line ); string::iterator p = line.begin(); if ( p != line.end() ){ switch ( *p++ ){ case 'O' : Def = Overlap; break; case 'J' : Def = JeffreyDiv; break; case 'S' : Def = JSDiv; break; case 'M' : Def = ValueDiff; break; case 'N' : Def = Numeric; break; case 'E' : Def = Euclidean; break; case 'D' : if ( p == line.end() || *p == ':' ) Def = DotProduct; else if ( *p == 'C' ){ Def = Dice; ++p; } break; case 'C' : Def = Cosine; break; case 'L' : Def = Levenshtein; break; case 'I' : Def = Ignore; break; default: Error( "illegal default value for metric: -m " + Mline ); return false; } if ( p == line.end() ){ // // only -m options, no further specifications // if ( Def == Ignore ){ Error( "Ignore without further specification for metric: -m " + Mline ); return false; } else { // set the defaults for ( vector::iterator it=metricsArray.begin(); it != metricsArray.end(); ++it ){ *it = Def; } return true; } } else if ( *p != ':' ){ Error( "missing ':' after default value in -m option" ); return false; } else { // deviating options expected. reset the array for ( vector::iterator it=metricsArray.begin(); it != metricsArray.end(); ++it ){ *it = UnknownMetric; } ++p; MetricType TmpMT; while( p != line.end() ){ switch ( *p ){ case 'O' : TmpMT = Overlap; break; case 'S' : TmpMT = JSDiv; break; case 'J' : TmpMT = JeffreyDiv; break; case 'D' : if ( *(p+1) && *(p+1) == 'C' ){ ++p; TmpMT = Dice; } else { Error( "illegal value in metric description: -m " + Mline ); return false; } break; case 'M' : TmpMT = ValueDiff; break; case 'E' : TmpMT = Euclidean; break; case 'N' : TmpMT = Numeric; break; case 'I' : TmpMT = Ignore; break; default: Error( "illegal value in metric description: -m " + Mline ); return false; } metricClass *tmpMC = getMetricClass(Def); if ( TmpMT != Ignore && tmpMC->isSimilarityMetric() ){ Error( "Similarity metric " + toString( Def ) + " only accepts -I specifications: -m " + Mline ); delete tmpMC; return false; } delete tmpMC; ++p; if ( !parse_range( line, p, TmpMT ) ) return false; if ( p == line.end() ){ break; } if ( *p != ':' ){ Error( "missing ':' in metric description" ); return false; } else ++p; } if ( p != line.end() ){ Error( "illegal value in metric description: -m " + Mline ); return false; } else { // // set defaults for those still unset // for ( vector::iterator it=metricsArray.begin(); it != metricsArray.end(); ++it ){ if ( *it == UnknownMetric ) *it = Def; } } } return true; } else return false; } inline bool isBoolOrEmpty( const string& in, bool& val ){ if ( in.empty() ){ val = true; return true; } else { string s = TiCC::uppercase( in ); if ( s == "TRUE" || s == "YES" || s == "FALSE" || s == "NO" ){ val = ( s == "TRUE" || s == "YES" ); return true; } } return false; } bool GetOptClass::parse_options( const CL_Options& opts, const int mode ){ opt_changed = true; // cerr << "options: " << opts << endl; // cerr << "mode: " << mode << endl; const char *q; list::const_iterator curr_opt; curr_opt = opts.Opts.begin(); if ( curr_opt == opts.Opts.end() ){ return true; } const char *ok_opt; switch ( mode ){ case 0: ok_opt = "a:b:B:c:C:d:De:F:G:Hk:l:L:m:M:n:N:o:O:p:q:QR:sS:t:T:v:w:Wx"; break; case 1: // limited usage, for @t ok_opt = "d:e:G:k:L:m:p:QR:v:x"; break; case 2: // limited usage, for Server ok_opt = "C:d:G:k:l:L:p:QS:v:x"; break; default: ok_opt = NULL; string msg = string("Invalid value '") + toString(mode) + "' in switch (" + __FILE__ + "," + toString(__LINE__) + ")\n" + "ABORTING now"; throw std::logic_error( msg ); } while ( curr_opt != opts.Opts.end() ) { bool mood = false; bool longOpt = false; string long_option; string myoptarg = curr_opt->Option(); char option = curr_opt->OptChar(); if ( curr_opt->isLong() ){ long_option = curr_opt->OptWord(); longOpt = true; } else { mood = curr_opt->getMood(); } // cerr << "long option:" << long_option << endl; // cerr << " myoptarg:" << myoptarg << endl; if ( !strchr( ok_opt, option ) ){ // invalid option switch ( mode ){ case 1: case 2:{ string LongLine; q = ok_opt; while ( *q ){ if ( *q != ':' ){ LongLine = LongLine + *q + ' '; } q++; } Error( string("Illegal option, -") + (char)option + ", only the following options are allowed: " + LongLine ); } break; default: break; } return false; }; try { // cerr << "try " << option << endl; switch (option) { case 'a': if ( !stringTo( myoptarg, local_algo ) ){ Error( "illegal -a value: " + myoptarg ); return false; } break; case 'b': bootstrap_lines = stringTo( myoptarg ); if ( bootstrap_lines < 1 ){ Error( "illegal value for -b option: " + myoptarg ); return false; } break; case 'B': if ( longOpt ){ if ( long_option == "Beam" ){ if ( !stringTo( myoptarg, BeamSize ) || BeamSize <= 0 ){ Error( "illegal value for -Beam option: " + myoptarg ); return false; } } else { Error( "invalid option: Did you mean '--Beam'?" ); return false; } } else if ( myoptarg.find("eam") != string::npos ){ Error( "invalid option: Did you mean '--B" + myoptarg + "'?" ); return false; } else { BinSize = stringTo( myoptarg ); if ( BinSize <= 1 ){ Error( "illegal value for -B option: " + myoptarg ); return false; } } break; case 'c': if ( longOpt ){ if ( long_option == "clones" ){ clones = stringTo( myoptarg ); if ( clones <= 0 ){ Error( "invalid value for " + long_option + ": '" + myoptarg + "'" ); return false; } } } else { clip_freq = stringTo( myoptarg ); if ( clip_freq < 0 ){ Error( "illegal value for -c option: " + myoptarg ); return false; } } break; case 'd': { if ( longOpt ){ if ( long_option == "daemonize" ){ bool val; if ( !isBoolOrEmpty(myoptarg,val) ){ Error( "invalid value for " + long_option + ": '" + myoptarg + "'" ); return false; } do_daemon = val; } else { Error( "invalid option: Did you mean '--daemonize'?" ); return false; } } else if ( myoptarg.find("aemonize") != string::npos ){ Error( "invalid option: Did you mean '--daemonize' ?" ); return false; } else { string::size_type pos1 = myoptarg.find( ":" ); if ( pos1 == string::npos ){ pos1 = myoptarg.find_first_of( "0123456789" ); if ( pos1 != string::npos ){ if ( ! ( stringTo( string( myoptarg, 0, pos1 ), local_decay ) && stringTo( string( myoptarg, pos1 ), local_decay_alfa ) ) ){ Error( "illegal value for -d option: " + myoptarg ); return false; } } else if ( !stringTo( myoptarg, local_decay ) ){ Error( "illegal value for -d option: " + myoptarg ); return false; } } else { string::size_type pos2 = myoptarg.find( ':', pos1+1 ); if ( pos2 == string::npos ){ pos2 = myoptarg.find_first_of( "0123456789", pos1+1 ); if ( pos2 != string::npos ){ if ( ! ( stringTo( string( myoptarg, 0, pos1 ), local_decay ) && stringTo( string( myoptarg, pos2 ), local_decay_alfa ) ) ){ Error( "illegal value for -d option: " + myoptarg ); return false; } } else { Error( "illegal value for -d option: " + myoptarg ); return false; } } else { if ( ! ( stringTo( string( myoptarg, 0, pos1 ), local_decay ) && stringTo( string( myoptarg, pos1+1, pos2-pos1-1 ), local_decay_alfa ) && stringTo( string( myoptarg, pos2+1 ), local_decay_beta ) ) ){ Error( "illegal value for -d option: " + myoptarg ); return false; } } } } break; } case 'D': if ( longOpt ){ if ( long_option == "Diversify" ) do_diversify = true; else { Error( "invalid option: Did you mean '--Diversify' ?" ); return false; } } else if ( myoptarg.size() > 1 ){ Error( "invalid option: Did you mean '--Diversify'?" ); return false; } else keep_distributions = mood; break; case 'e': estimate = stringTo( myoptarg ); if ( estimate < 0 ){ Error( "illegal value for -e option: " + myoptarg ); return false; } break; case 'F': if ( !stringTo( myoptarg, LocalInputFormat ) ){ Error( "illegal value for -F option: " + myoptarg ); return false; } break; case 'G': if ( myoptarg.empty() ) local_normalisation = probabilityNorm; else { string::size_type pos1 = myoptarg.find( ":" ); if ( pos1 == string::npos ){ local_normalisation = stringTo( myoptarg ); local_norm_factor = 1; } else { local_normalisation = stringTo( string( myoptarg, 0, pos1 ) ); if ( !stringTo( string( myoptarg, pos1+1 ), local_norm_factor ) || local_norm_factor < Epsilon ){ Error( "illegal value for -G option: " + myoptarg ); return false; } } if ( local_normalisation == unknownNorm ){ Error( "illegal value for -G option: " + myoptarg ); return false; } } break; case 'H': do_hashed = mood; break; case 'k': no_neigh = stringTo(myoptarg); if ( no_neigh <= 0 ){ Error( "illegal value for -k option: " + myoptarg ); return false; } break; case 'l': if ( longOpt ){ if ( long_option == "logfile" ){ if ( myoptarg.empty() ){ Error( "missing filename for '--logfile'" ); return false; } logFile = myoptarg; } else { Error( "invalid option: Did you mean '--logfile' ?" ); return false; } } else if ( myoptarg.find("ogfile") != string::npos ){ Error( "invalid option: Did you mean '--logfile' ?" ); return false; } else { f_length = stringTo( myoptarg ); if ( f_length <= 0 ){ Error( "illegal value for -l option: " + myoptarg ); return false; } } break; case 'L': { string::size_type pos1 = myoptarg.find( ":" ); if ( pos1 == string::npos ){ pos1 = myoptarg.find_first_of( "0123456789" ); if ( pos1 != string::npos ){ mvd_limit = stringTo( myoptarg ); if ( mvd_limit <= 0 ){ Error( "illegal value for -L option: " + myoptarg ); return false; } } } else { mvd_limit = stringTo( string( myoptarg, pos1+1 ) ); if ( mvd_limit <= 0 ){ Error( "illegal value for -L option: " + myoptarg ); return false; } } break; } case 'm': if ( !parse_metrics( myoptarg, local_metric ) ) return false; break; case 'M': maxbests = stringTo( myoptarg ); if ( maxbests <= 0 ){ Error( "illegal value for -M option: " + myoptarg ); return false; } break; case 'N': // skip previously parsed NumOfFeatures info. break; case 'O': outPath = myoptarg; break; case 'o': if ( longOpt ){ if ( long_option == "occurrences" ){ if ( myoptarg.empty() ){ Error( "missing value for '--occurrences'" ); return false; } if ( myoptarg == "train" ) occIn = 1; else if ( myoptarg == "test" ) occIn = 2; else if ( myoptarg == "both" ) occIn = 3; else { Error( "invalid --ocurrences value." ); return false; } } else { Error( "invalid option: Did you mean '--ocurrences' ?" ); return false; } } else if ( myoptarg.find("ccurences") != string::npos ){ Error( "invalid option: Did you mean '--occurrences' ?" ); return false; } break; case 'p': if ( longOpt ){ if ( long_option == "pidfile" ){ if ( myoptarg.empty() ){ Error( "missing filename for '--pidfile'" ); return false; } pidFile = myoptarg; } else { Error( "invalid option: Did you mean '--pidfile' ?" ); return false; } } else if ( myoptarg.find("idfile") != string::npos ){ Error( "invalid option: Did you mean '--pidfile' ?" ); return false; } else { local_progress = stringTo( myoptarg ); } break; case 'q': threshold = stringTo( myoptarg ); break; case 'Q': do_query = true; break; case 'R': if ( isdigit(myoptarg[0]) ) seed = stringTo( myoptarg ); else { Error( "Integer argument for Random Seed expected (-R option)" ); return false; } break; case 's': if ( longOpt ){ if ( long_option == "sloppy" ){ bool val; if ( !isBoolOrEmpty(myoptarg,val) ){ Error( "invalid value for sloppy: '" + myoptarg + "'" ); return false; } do_sloppy_loo = val; } else if ( long_option == "silly" ){ bool val; if ( !isBoolOrEmpty(myoptarg,val) ){ Error( "invalid value for silly: '" + myoptarg + "'" ); return false; } do_silly = val; } else { Error( "invalid option: Did you mean '--sloppy or --silly' ?" ); return false; } } else { if ( myoptarg.empty() ){ do_sample_weights = true; } else { if ( isdigit(myoptarg[0]) ){ int val = stringTo( myoptarg ); if ( val == 0 ){ do_ignore_samples = true; do_ignore_samples_test = false; do_sample_weights = true; } else if ( val == 1 ){ do_ignore_samples_test = true; do_sample_weights = true; } } if ( !do_sample_weights) { Error( "invalid value for -s: '" + myoptarg + "' (maybe you meant --s" + myoptarg + " ?)" ); return false; } } } break; case 't': if ( compare_nocase( myoptarg, "leave_one_out" ) ) local_algo = LOO_a; else if ( compare_nocase( myoptarg, "cross_validate" ) ) local_algo = CV_a; break; case 'T': { if ( longOpt ){ if ( long_option == "Threshold" ){ if ( !stringTo(myoptarg, igThreshold ) || igThreshold < 0 ){ Error( "invalid value for Threshold: " + myoptarg ); return false; } } else if ( long_option == "Treeorder" ){ if ( !stringTo( myoptarg, local_order ) ){ Error( "invalid value for Treeorder: " + myoptarg ); return false; } } else { Error( "invalid option: Did you mean '--Threshold' or --Treeorder ?" ); return false; } } else if ( myoptarg.find("hreshold") != string::npos || myoptarg.find("reeorder") != string::npos ){ Error( "invalid option: Did you mean '--T" + myoptarg + "' ?" ); return false; } else if ( ! stringTo( myoptarg, target_pos ) ){ Error( "invalid option: Did you mean '-T value ?" ); return false; } else if ( target_pos <= 0 ){ Error( "illegal value for -T option: " + myoptarg ); return false; } } break; case 'v':{ VerbosityFlags Flag = NO_VERB; if ( !stringTo( myoptarg, Flag ) ){ Error( "illegal value for +/- v option: " + myoptarg ); return false; } else { if ( mode == 2 && ( !(Flag & (SILENT|DISTANCE|DISTRIB|NEAR_N|CONF_MATRIX) ) ) ) return false; else if ( Flag > 0 ) if ( mood ){ myVerbosity |= Flag; } else { myVerbosity &= ~Flag; } else myVerbosity = NO_VERB; } } break; case 'w': { if ( !stringTo( myoptarg, local_weight ) ) return false; }; break; case 'W': { do_all_weights = true; }; break; case 'x': do_exact = mood; break; } } catch( std::runtime_error& err ) { cerr << "invalid value for option '" << option << "'" << endl; return false; } ++curr_opt; } return true; } }