1*11c03c6dSDamjan Jovanovic /************************************************************** 2*11c03c6dSDamjan Jovanovic * 3*11c03c6dSDamjan Jovanovic * Licensed to the Apache Software Foundation (ASF) under one 4*11c03c6dSDamjan Jovanovic * or more contributor license agreements. See the NOTICE file 5*11c03c6dSDamjan Jovanovic * distributed with this work for additional information 6*11c03c6dSDamjan Jovanovic * regarding copyright ownership. The ASF licenses this file 7*11c03c6dSDamjan Jovanovic * to you under the Apache License, Version 2.0 (the 8*11c03c6dSDamjan Jovanovic * "License"); you may not use this file except in compliance 9*11c03c6dSDamjan Jovanovic * with the License. You may obtain a copy of the License at 10*11c03c6dSDamjan Jovanovic * 11*11c03c6dSDamjan Jovanovic * http://www.apache.org/licenses/LICENSE-2.0 12*11c03c6dSDamjan Jovanovic * 13*11c03c6dSDamjan Jovanovic * Unless required by applicable law or agreed to in writing, 14*11c03c6dSDamjan Jovanovic * software distributed under the License is distributed on an 15*11c03c6dSDamjan Jovanovic * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*11c03c6dSDamjan Jovanovic * KIND, either express or implied. See the License for the 17*11c03c6dSDamjan Jovanovic * specific language governing permissions and limitations 18*11c03c6dSDamjan Jovanovic * under the License. 19*11c03c6dSDamjan Jovanovic * 20*11c03c6dSDamjan Jovanovic *************************************************************/ 21*11c03c6dSDamjan Jovanovic 22*11c03c6dSDamjan Jovanovic 23*11c03c6dSDamjan Jovanovic 24*11c03c6dSDamjan Jovanovic #include <precomp.h> 25*11c03c6dSDamjan Jovanovic #include <cosv/commandline.hxx> 26*11c03c6dSDamjan Jovanovic 27*11c03c6dSDamjan Jovanovic // NOT FULLY DECLARED SERVICES 28*11c03c6dSDamjan Jovanovic #include <cosv/file.hxx> 29*11c03c6dSDamjan Jovanovic 30*11c03c6dSDamjan Jovanovic 31*11c03c6dSDamjan Jovanovic namespace csv 32*11c03c6dSDamjan Jovanovic { 33*11c03c6dSDamjan Jovanovic 34*11c03c6dSDamjan Jovanovic namespace 35*11c03c6dSDamjan Jovanovic { 36*11c03c6dSDamjan Jovanovic 37*11c03c6dSDamjan Jovanovic const intt C_nNoOption = -1; 38*11c03c6dSDamjan Jovanovic 39*11c03c6dSDamjan Jovanovic const char * sIncludeOptionShort = "-A:"; 40*11c03c6dSDamjan Jovanovic const char * sIncludeOptionLong = "--Arguments:"; 41*11c03c6dSDamjan Jovanovic const uintt nIncludeOptionShort_Length = strlen(sIncludeOptionShort); 42*11c03c6dSDamjan Jovanovic const uintt nIncludeOptionLong_Length = strlen(sIncludeOptionLong); 43*11c03c6dSDamjan Jovanovic 44*11c03c6dSDamjan Jovanovic 45*11c03c6dSDamjan Jovanovic /** Analyses, if an option is the one to include a file with 46*11c03c6dSDamjan Jovanovic further command line arguments. 47*11c03c6dSDamjan Jovanovic */ 48*11c03c6dSDamjan Jovanovic bool IsIncludeOption( 49*11c03c6dSDamjan Jovanovic const String & i_option ); 50*11c03c6dSDamjan Jovanovic 51*11c03c6dSDamjan Jovanovic /** Gets the file name from an include-arguments-option. 52*11c03c6dSDamjan Jovanovic */ 53*11c03c6dSDamjan Jovanovic String IncludeFile_fromIncludeOption( 54*11c03c6dSDamjan Jovanovic const String & i_option ); 55*11c03c6dSDamjan Jovanovic 56*11c03c6dSDamjan Jovanovic 57*11c03c6dSDamjan Jovanovic bool 58*11c03c6dSDamjan Jovanovic IsIncludeOption(const String & i_option) 59*11c03c6dSDamjan Jovanovic { 60*11c03c6dSDamjan Jovanovic return strncmp(i_option, sIncludeOptionShort, nIncludeOptionShort_Length) == 0 61*11c03c6dSDamjan Jovanovic OR 62*11c03c6dSDamjan Jovanovic strncmp(i_option, sIncludeOptionLong, nIncludeOptionLong_Length) == 0; 63*11c03c6dSDamjan Jovanovic } 64*11c03c6dSDamjan Jovanovic 65*11c03c6dSDamjan Jovanovic String 66*11c03c6dSDamjan Jovanovic IncludeFile_fromIncludeOption(const String & i_option) 67*11c03c6dSDamjan Jovanovic { 68*11c03c6dSDamjan Jovanovic if ( strncmp(i_option, sIncludeOptionShort, nIncludeOptionShort_Length) 69*11c03c6dSDamjan Jovanovic == 0 ) 70*11c03c6dSDamjan Jovanovic { 71*11c03c6dSDamjan Jovanovic return String(i_option, nIncludeOptionShort_Length, str::maxsize); 72*11c03c6dSDamjan Jovanovic } 73*11c03c6dSDamjan Jovanovic else 74*11c03c6dSDamjan Jovanovic if ( strncmp(i_option, sIncludeOptionLong, nIncludeOptionLong_Length) 75*11c03c6dSDamjan Jovanovic == 0 ) 76*11c03c6dSDamjan Jovanovic { 77*11c03c6dSDamjan Jovanovic return String(i_option, nIncludeOptionLong_Length, str::maxsize); 78*11c03c6dSDamjan Jovanovic } 79*11c03c6dSDamjan Jovanovic return String::Null_(); 80*11c03c6dSDamjan Jovanovic } 81*11c03c6dSDamjan Jovanovic 82*11c03c6dSDamjan Jovanovic 83*11c03c6dSDamjan Jovanovic } // end anonymous namespace 84*11c03c6dSDamjan Jovanovic 85*11c03c6dSDamjan Jovanovic 86*11c03c6dSDamjan Jovanovic 87*11c03c6dSDamjan Jovanovic 88*11c03c6dSDamjan Jovanovic /** Local helper class for searching a possible option name in a vector of 89*11c03c6dSDamjan Jovanovic ->OptionDescription. 90*11c03c6dSDamjan Jovanovic */ 91*11c03c6dSDamjan Jovanovic struct CommandLine:: 92*11c03c6dSDamjan Jovanovic FindOptionByText 93*11c03c6dSDamjan Jovanovic { 94*11c03c6dSDamjan Jovanovic bool operator()( 95*11c03c6dSDamjan Jovanovic const CommandLine::OptionDescription & 96*11c03c6dSDamjan Jovanovic i_option ) 97*11c03c6dSDamjan Jovanovic { return i_option.sText == sOption; } 98*11c03c6dSDamjan Jovanovic 99*11c03c6dSDamjan Jovanovic /// @param i_searchText [i_searchText != ""] 100*11c03c6dSDamjan Jovanovic FindOptionByText( 101*11c03c6dSDamjan Jovanovic const String & i_option ) 102*11c03c6dSDamjan Jovanovic : sOption(i_option) { } 103*11c03c6dSDamjan Jovanovic private: 104*11c03c6dSDamjan Jovanovic const String sOption; 105*11c03c6dSDamjan Jovanovic }; 106*11c03c6dSDamjan Jovanovic 107*11c03c6dSDamjan Jovanovic 108*11c03c6dSDamjan Jovanovic typedef std::vector<StringVector::const_iterator> StringCIteratorList; 109*11c03c6dSDamjan Jovanovic typedef std::vector<intt> OptionIdList; 110*11c03c6dSDamjan Jovanovic 111*11c03c6dSDamjan Jovanovic bool 112*11c03c6dSDamjan Jovanovic CommandLine::Interpret( int argc, 113*11c03c6dSDamjan Jovanovic char * argv[] ) 114*11c03c6dSDamjan Jovanovic { 115*11c03c6dSDamjan Jovanovic Get_Arguments(argc,argv); 116*11c03c6dSDamjan Jovanovic csv_assert(aOptionPoints.size() == aOptionIds.size()); 117*11c03c6dSDamjan Jovanovic 118*11c03c6dSDamjan Jovanovic StringVector::const_iterator 119*11c03c6dSDamjan Jovanovic itNext = aCommandLine.begin(); 120*11c03c6dSDamjan Jovanovic ++itNext; // Move 1 forward from program name. 121*11c03c6dSDamjan Jovanovic StringVector::const_iterator 122*11c03c6dSDamjan Jovanovic itEnd = aCommandLine.end(); 123*11c03c6dSDamjan Jovanovic StringCIteratorList::const_iterator 124*11c03c6dSDamjan Jovanovic itOptPtsEnd = aOptionPoints.end(); 125*11c03c6dSDamjan Jovanovic 126*11c03c6dSDamjan Jovanovic OptionIdList::const_iterator 127*11c03c6dSDamjan Jovanovic itOptIds = aOptionIds.begin(); 128*11c03c6dSDamjan Jovanovic for ( StringCIteratorList::const_iterator itOptPts = aOptionPoints.begin(); 129*11c03c6dSDamjan Jovanovic itOptPts != itOptPtsEnd AND bIsOk; 130*11c03c6dSDamjan Jovanovic ++itOptPts, ++itOptIds ) 131*11c03c6dSDamjan Jovanovic { 132*11c03c6dSDamjan Jovanovic // May be, there are arguments which do not belong to the last option: 133*11c03c6dSDamjan Jovanovic // itNext != *is 134*11c03c6dSDamjan Jovanovic Handle_FreeArguments(itNext, *itOptPts); 135*11c03c6dSDamjan Jovanovic 136*11c03c6dSDamjan Jovanovic itNext = do_HandleOption( *itOptIds, 137*11c03c6dSDamjan Jovanovic *itOptPts + 1, 138*11c03c6dSDamjan Jovanovic itOptPts+1 == itOptPtsEnd ? itEnd : *(itOptPts+1) ); 139*11c03c6dSDamjan Jovanovic csv_assert(itNext <= itEnd); 140*11c03c6dSDamjan Jovanovic } // end for (is) 141*11c03c6dSDamjan Jovanovic Handle_FreeArguments(itNext, itEnd); 142*11c03c6dSDamjan Jovanovic 143*11c03c6dSDamjan Jovanovic return bIsOk; 144*11c03c6dSDamjan Jovanovic } 145*11c03c6dSDamjan Jovanovic 146*11c03c6dSDamjan Jovanovic CommandLine::CommandLine() 147*11c03c6dSDamjan Jovanovic : aOptions(), 148*11c03c6dSDamjan Jovanovic aCommandLine(), 149*11c03c6dSDamjan Jovanovic bIsOk(false) 150*11c03c6dSDamjan Jovanovic { 151*11c03c6dSDamjan Jovanovic } 152*11c03c6dSDamjan Jovanovic 153*11c03c6dSDamjan Jovanovic void 154*11c03c6dSDamjan Jovanovic CommandLine::Add_Option( intt i_id, 155*11c03c6dSDamjan Jovanovic String i_text ) 156*11c03c6dSDamjan Jovanovic { 157*11c03c6dSDamjan Jovanovic aOptions.push_back(OptionDescription( i_id, 158*11c03c6dSDamjan Jovanovic i_text )); 159*11c03c6dSDamjan Jovanovic } 160*11c03c6dSDamjan Jovanovic 161*11c03c6dSDamjan Jovanovic void 162*11c03c6dSDamjan Jovanovic CommandLine::Get_Arguments( int argc, 163*11c03c6dSDamjan Jovanovic char * argv[] ) 164*11c03c6dSDamjan Jovanovic { 165*11c03c6dSDamjan Jovanovic aCommandLine.erase(aCommandLine.begin(),aCommandLine.end()); 166*11c03c6dSDamjan Jovanovic aCommandLine.reserve(argc); 167*11c03c6dSDamjan Jovanovic 168*11c03c6dSDamjan Jovanovic char ** pArgEnd = argv + argc; 169*11c03c6dSDamjan Jovanovic for ( char ** pArg = &argv[0]; 170*11c03c6dSDamjan Jovanovic pArg != pArgEnd; 171*11c03c6dSDamjan Jovanovic ++pArg ) 172*11c03c6dSDamjan Jovanovic { 173*11c03c6dSDamjan Jovanovic Store_Argument(*pArg); 174*11c03c6dSDamjan Jovanovic } // end for 175*11c03c6dSDamjan Jovanovic Find_OptionPoints(); 176*11c03c6dSDamjan Jovanovic bIsOk = true; 177*11c03c6dSDamjan Jovanovic } 178*11c03c6dSDamjan Jovanovic 179*11c03c6dSDamjan Jovanovic intt 180*11c03c6dSDamjan Jovanovic CommandLine::Find_Option( const String & i_text ) const 181*11c03c6dSDamjan Jovanovic { 182*11c03c6dSDamjan Jovanovic if (i_text.empty()) 183*11c03c6dSDamjan Jovanovic return C_nNoOption; 184*11c03c6dSDamjan Jovanovic 185*11c03c6dSDamjan Jovanovic FindOptionByText aSearch(i_text); 186*11c03c6dSDamjan Jovanovic OptionList::const_iterator 187*11c03c6dSDamjan Jovanovic itFound = std::find_if( aOptions.begin(), 188*11c03c6dSDamjan Jovanovic aOptions.end(), 189*11c03c6dSDamjan Jovanovic aSearch ); 190*11c03c6dSDamjan Jovanovic if (itFound != aOptions.end()) 191*11c03c6dSDamjan Jovanovic { 192*11c03c6dSDamjan Jovanovic return (*itFound).nId; 193*11c03c6dSDamjan Jovanovic } 194*11c03c6dSDamjan Jovanovic return C_nNoOption; 195*11c03c6dSDamjan Jovanovic } 196*11c03c6dSDamjan Jovanovic 197*11c03c6dSDamjan Jovanovic bool 198*11c03c6dSDamjan Jovanovic CommandLine::Store_Argument( const String & i_arg ) 199*11c03c6dSDamjan Jovanovic { 200*11c03c6dSDamjan Jovanovic if ( NOT IsIncludeOption(i_arg) ) 201*11c03c6dSDamjan Jovanovic { 202*11c03c6dSDamjan Jovanovic aCommandLine.push_back(i_arg); 203*11c03c6dSDamjan Jovanovic return true; 204*11c03c6dSDamjan Jovanovic } 205*11c03c6dSDamjan Jovanovic 206*11c03c6dSDamjan Jovanovic return Try2Include_Options(i_arg); 207*11c03c6dSDamjan Jovanovic } 208*11c03c6dSDamjan Jovanovic 209*11c03c6dSDamjan Jovanovic void 210*11c03c6dSDamjan Jovanovic CommandLine::Find_OptionPoints() 211*11c03c6dSDamjan Jovanovic { 212*11c03c6dSDamjan Jovanovic StringVector::const_iterator itEnd = aCommandLine.end(); 213*11c03c6dSDamjan Jovanovic for ( StringVector::const_iterator it = aCommandLine.begin() + 1; 214*11c03c6dSDamjan Jovanovic it != itEnd; 215*11c03c6dSDamjan Jovanovic ++it ) 216*11c03c6dSDamjan Jovanovic { 217*11c03c6dSDamjan Jovanovic intt nOption = Find_Option(*it); 218*11c03c6dSDamjan Jovanovic if (nOption != C_nNoOption) 219*11c03c6dSDamjan Jovanovic { 220*11c03c6dSDamjan Jovanovic aOptionPoints.push_back(it); 221*11c03c6dSDamjan Jovanovic aOptionIds.push_back(nOption); 222*11c03c6dSDamjan Jovanovic } 223*11c03c6dSDamjan Jovanovic } // end for (i) 224*11c03c6dSDamjan Jovanovic } 225*11c03c6dSDamjan Jovanovic 226*11c03c6dSDamjan Jovanovic void 227*11c03c6dSDamjan Jovanovic CommandLine::Handle_FreeArguments( StringVector::const_iterator i_begin, 228*11c03c6dSDamjan Jovanovic StringVector::const_iterator i_end ) 229*11c03c6dSDamjan Jovanovic { 230*11c03c6dSDamjan Jovanovic for ( StringVector::const_iterator it = i_begin; 231*11c03c6dSDamjan Jovanovic it != i_end AND bIsOk; 232*11c03c6dSDamjan Jovanovic ++it ) 233*11c03c6dSDamjan Jovanovic { 234*11c03c6dSDamjan Jovanovic do_HandleFreeArgument(*it); 235*11c03c6dSDamjan Jovanovic } 236*11c03c6dSDamjan Jovanovic } 237*11c03c6dSDamjan Jovanovic 238*11c03c6dSDamjan Jovanovic bool 239*11c03c6dSDamjan Jovanovic CommandLine::Try2Include_Options(const String & i_includeOption) 240*11c03c6dSDamjan Jovanovic { 241*11c03c6dSDamjan Jovanovic static StringVector 242*11c03c6dSDamjan Jovanovic aIncludedOptionFiles_; 243*11c03c6dSDamjan Jovanovic 244*11c03c6dSDamjan Jovanovic const String 245*11c03c6dSDamjan Jovanovic aOptionFile(IncludeFile_fromIncludeOption(i_includeOption)); 246*11c03c6dSDamjan Jovanovic 247*11c03c6dSDamjan Jovanovic // Avoid recursion deadlock 1 248*11c03c6dSDamjan Jovanovic if ( std::find( aIncludedOptionFiles_.begin(), 249*11c03c6dSDamjan Jovanovic aIncludedOptionFiles_.end(), 250*11c03c6dSDamjan Jovanovic aOptionFile ) 251*11c03c6dSDamjan Jovanovic != aIncludedOptionFiles_.end() ) 252*11c03c6dSDamjan Jovanovic { 253*11c03c6dSDamjan Jovanovic Cerr() << "\nError: Self inclusion of option file " 254*11c03c6dSDamjan Jovanovic << aOptionFile 255*11c03c6dSDamjan Jovanovic << ".\n" 256*11c03c6dSDamjan Jovanovic << Endl(); 257*11c03c6dSDamjan Jovanovic return false; 258*11c03c6dSDamjan Jovanovic } 259*11c03c6dSDamjan Jovanovic 260*11c03c6dSDamjan Jovanovic // Avoid recursion deadlock 2 261*11c03c6dSDamjan Jovanovic aIncludedOptionFiles_.push_back(aOptionFile); 262*11c03c6dSDamjan Jovanovic 263*11c03c6dSDamjan Jovanovic bool ok = Include_Options(aOptionFile); 264*11c03c6dSDamjan Jovanovic 265*11c03c6dSDamjan Jovanovic // Avoid recursion deadlock 3 266*11c03c6dSDamjan Jovanovic aIncludedOptionFiles_.pop_back(); 267*11c03c6dSDamjan Jovanovic 268*11c03c6dSDamjan Jovanovic return ok; 269*11c03c6dSDamjan Jovanovic } 270*11c03c6dSDamjan Jovanovic 271*11c03c6dSDamjan Jovanovic bool 272*11c03c6dSDamjan Jovanovic CommandLine::Include_Options( const String & i_optionsFile ) 273*11c03c6dSDamjan Jovanovic { 274*11c03c6dSDamjan Jovanovic StreamStr 275*11c03c6dSDamjan Jovanovic aIncludedText(500); 276*11c03c6dSDamjan Jovanovic bool ok = Load_Options(aIncludedText, i_optionsFile); 277*11c03c6dSDamjan Jovanovic if (NOT ok) 278*11c03c6dSDamjan Jovanovic return false; 279*11c03c6dSDamjan Jovanovic 280*11c03c6dSDamjan Jovanovic StringVector 281*11c03c6dSDamjan Jovanovic aIncludedOptions; 282*11c03c6dSDamjan Jovanovic Split(aIncludedOptions, aIncludedText.c_str()); 283*11c03c6dSDamjan Jovanovic 284*11c03c6dSDamjan Jovanovic StringVector::const_iterator itEnd = aIncludedOptions.end(); 285*11c03c6dSDamjan Jovanovic for ( StringVector::const_iterator it = aIncludedOptions.begin(); 286*11c03c6dSDamjan Jovanovic it != itEnd; 287*11c03c6dSDamjan Jovanovic ++it ) 288*11c03c6dSDamjan Jovanovic { 289*11c03c6dSDamjan Jovanovic Store_Argument(*it); 290*11c03c6dSDamjan Jovanovic } // end for 291*11c03c6dSDamjan Jovanovic 292*11c03c6dSDamjan Jovanovic return true; 293*11c03c6dSDamjan Jovanovic } 294*11c03c6dSDamjan Jovanovic 295*11c03c6dSDamjan Jovanovic bool 296*11c03c6dSDamjan Jovanovic CommandLine::Load_Options( StreamStr & o_text, 297*11c03c6dSDamjan Jovanovic const String & i_optionsFile ) 298*11c03c6dSDamjan Jovanovic { 299*11c03c6dSDamjan Jovanovic if (i_optionsFile.empty()) 300*11c03c6dSDamjan Jovanovic return false; 301*11c03c6dSDamjan Jovanovic 302*11c03c6dSDamjan Jovanovic File 303*11c03c6dSDamjan Jovanovic aOptionsFile(i_optionsFile, CFM_READ); 304*11c03c6dSDamjan Jovanovic OpenCloseGuard 305*11c03c6dSDamjan Jovanovic aOFGuard(aOptionsFile); 306*11c03c6dSDamjan Jovanovic if (NOT aOFGuard) 307*11c03c6dSDamjan Jovanovic { 308*11c03c6dSDamjan Jovanovic Cerr() << "\nError: Options file " 309*11c03c6dSDamjan Jovanovic << i_optionsFile 310*11c03c6dSDamjan Jovanovic << " not found.\n" 311*11c03c6dSDamjan Jovanovic << Endl(); 312*11c03c6dSDamjan Jovanovic return false; 313*11c03c6dSDamjan Jovanovic } 314*11c03c6dSDamjan Jovanovic 315*11c03c6dSDamjan Jovanovic StreamStr 316*11c03c6dSDamjan Jovanovic aLoad(aOptionsFile); 317*11c03c6dSDamjan Jovanovic o_text.swap(aLoad); 318*11c03c6dSDamjan Jovanovic return true; 319*11c03c6dSDamjan Jovanovic } 320*11c03c6dSDamjan Jovanovic 321*11c03c6dSDamjan Jovanovic 322*11c03c6dSDamjan Jovanovic 323*11c03c6dSDamjan Jovanovic 324*11c03c6dSDamjan Jovanovic /****************** OptionDescription ***********************/ 325*11c03c6dSDamjan Jovanovic 326*11c03c6dSDamjan Jovanovic 327*11c03c6dSDamjan Jovanovic CommandLine:: 328*11c03c6dSDamjan Jovanovic OptionDescription::OptionDescription( intt i_id, 329*11c03c6dSDamjan Jovanovic String i_text ) 330*11c03c6dSDamjan Jovanovic : nId(i_id), 331*11c03c6dSDamjan Jovanovic sText(i_text) 332*11c03c6dSDamjan Jovanovic { 333*11c03c6dSDamjan Jovanovic } 334*11c03c6dSDamjan Jovanovic 335*11c03c6dSDamjan Jovanovic 336*11c03c6dSDamjan Jovanovic 337*11c03c6dSDamjan Jovanovic 338*11c03c6dSDamjan Jovanovic } // namespace csv 339