ALib C++ Library
Library Version: 1912 R0
Documentation generated by doxygen
cliapp.cpp
1 // #################################################################################################
2 // ALib C++ Library
3 //
4 // Copyright 2013-2019 A-Worx GmbH, Germany
5 // Published under 'Boost Software License' (a free software license, see LICENSE.txt)
6 // #################################################################################################
8 
9 #if !defined(ALIB_DOX)
10 #if !defined (HPP_ALIB_CLI_CLIAPP)
11 # include "alib/cli/cliapp.hpp"
12 #endif
13 
14 #if !defined (HPP_ALIB_CLI_CLIUTIL)
15 # include "alib/cli/cliutil.hpp"
16 #endif
17 
18 #if !defined (HPP_ALIB_FS_MODULES_DISTRIBUTION)
20 #endif
21 #endif // !defined(ALIB_DOX)
22 
23 
24 namespace aworx { namespace lib { namespace cli {
25 
26 // #################################################################################################
27 // CLIApp Constructor
28 // #################################################################################################
29 
30 void CLIApp::Init( Module* resModule )
31 {
32  ResModule = resModule;
36 
37  ArgStrings.reserve( static_cast<size_t>(ArgcOriginal) );
38  ArgsLeft .reserve( static_cast<size_t>(ArgcOriginal) );
39 
40 #if !ALIB_CHARACTERS_WIDE
41  if( ArgNOriginal )
42  {
43  for ( int i= 1; i < ArgcOriginal ; ++i )
44  {
45  ArgStrings.emplace_back( ArgNOriginal[i] );
46  ArgsLeft .emplace_back( i -1 );
47  }
48  }
49  else
50  {
51  // convert wide to narrow strings
52  NString1K converter;
54 
55  for ( int i= 1; i < ArgcOriginal ; ++i )
56  {
57  converter.Reset() << ArgWOriginal[i];
58  ArgStrings.emplace_back( allocator.EmplaceString(converter) );
59  ArgsLeft .emplace_back( i - 1 );
60  }
61  }
62 #else
63  #if ALIB_CHARACTERS_NATIVE_WCHAR // use original strings only if aworx::wchar == wchar_t
64  if( ArgWOriginal )
65  {
66  for ( int i= 1; i < ArgcOriginal ; ++i )
67  {
68  ArgStrings.emplace_back( ArgWOriginal[i] );
69  ArgsLeft .emplace_back( i - 1 );
70  }
71  }
72  else
73  #endif
74  {
75  // convert narrow to wide strings (or "wrong" wide width to width)
76  String1K converter;
78 
79  for ( int i= 1; i < ArgcOriginal ; ++i )
80  {
81  converter.Reset() << ArgNOriginal[i];
82  ArgStrings.emplace_back( allocator.EmplaceString(converter) );
83  ArgsLeft .emplace_back( i -1 );
84  }
85  }
86 #endif
87 
88 
89 }
90 
91 // #################################################################################################
92 // Interface
93 // #################################################################################################
94 
96 {
97  // loop over all arg indices in ArgsLeft
98  integer argIdx= 0;
99  while( argIdx < static_cast<integer>(ArgsLeft.size()) )
100  {
101  // get arg number and string once
102  auto argNo= ArgsLeft[static_cast<size_t>(argIdx)];
103  String arg = Arg(argNo);
104 
105  SHORTCUT_JUMP:
106 
107  // ignore non-option args
108  if( arg.CharAtStart() != '-' )
109  {
110  ++argIdx;
111  continue;
112  }
113 
114  // create an option object and search decl with actual argument
115  {
116  Option option(this);
117 
118  auto optionDeclIt= OptionDecls.begin();
119  try
120  {
121  while( optionDeclIt != OptionDecls.end() )
122  {
123  if( option.Read( **optionDeclIt, arg, argNo ) )
124  break;
125  ++optionDeclIt;
126  }
127  }
128  catch ( Exception& e )
129  {
131  (*optionDeclIt)->HelpUsageLine() );
132  throw;
133  }
134 
135  // found a declaration?
136  if( option.QtyArgsConsumed > 0 )
137  {
138  // shortcut to another option?
139  OptionDecl& decl= *option.Declaration;
141  {
142  arg= decl.ShortcutReplacementString();
143  goto SHORTCUT_JUMP;
144  }
145 
146  // delete args and continue
147  ArgsLeft.erase( ArgsLeft.begin() + argIdx,
148  ArgsLeft.begin() + argIdx + option.QtyArgsConsumed );
149 
150  // move local option into the monotonic memory add to the list for this option type.
151  Options.PushBack( allocator.Emplace<Option>(std::move(option)) );
152  continue;
153  }
154 
155 
156  // erase args that start with '-' and put them into field OptionsIgnored.
157  if( ArgsLeft.size() > 0 )
158  {
159  OptionArgsIgnored.PushBack( Arg(argNo) );
160  ArgsLeft.erase( ArgsLeft.begin() + argIdx );
161  }
162  }
163  }
164 }
165 
167 {
168  for( auto optionIt= Options.rbegin() ; optionIt != Options.rend() ; optionIt ++ )
169  if( (*optionIt)->Declaration->Element() == element )
170  return *optionIt;
171  return nullptr;
172 }
173 
174 
176 {
177  // loop over all arg indices in ArgsLeft
178  bool lastCommandFullyParsed= true;
179  while( lastCommandFullyParsed && ArgsLeft.size() > 0 )
180  {
181  // create a command object and search decl with actual argument
182  Command command(this);
183  ALIB_ASSERT_ERROR( CommandDecls.Size() > 0, "No commands declared." )
184  for( auto* commandDecl : CommandDecls )
185  {
186  try
187  {
188  lastCommandFullyParsed= command.Read( *commandDecl );
189  }
190  catch ( Exception& e )
191  {
193  CLIUtil::GetCommandUsageFormat( *this, *commandDecl ),
194  commandDecl->HelpTextShort() );
195  throw;
196  }
197 
198  if( command.QtyArgsConsumed > 0 )
199  {
200  CommandsParsed.PushBack( std::move(command) );
201  if( NextCommandIt == CommandsParsed.end() )
202  --NextCommandIt;
203  break;
204  }
205  }
206  }
207 }
208 
210 {
211  if( NextCommandIt == CommandsParsed.end() )
213  if( NextCommandIt == CommandsParsed.end() )
214  {
215  // check for arguments left which got not recognized
216  if( ArgsLeft.size() > 0 )
218  ArgsLeft[0], PeekArg() );
219 
220  // check for no command
221  if ( CommandsParsed.IsEmpty() )
223 
224  return nullptr;
225  }
226 
227  auto* result= &*NextCommandIt;
228  ++NextCommandIt;
229  return result;
230 }
231 
232 
234 {
235  if( ArgsLeft.size() == 0)
236  return NullString();
237 
238  String result= Arg(ArgsLeft[0]);
239  ArgsLeft.erase( ArgsLeft.begin() );
240  return result;
241 }
242 
244 {
245  for( auto it= ArgsLeft.begin() ; it != ArgsLeft.end() ; ++it )
246  if( *it == argNo )
247  {
248  ArgsLeft.erase( it );
249  return;
250  }
251  ALIB_ERROR( "Argument number {} already removed.", argNo )
252 }
253 
254 
255 
256 }}}// namespace aworx::lib::system
257 
aworx::lib::monomem::MonoAllocator::Emplace
ALIB_FORCE_INLINE T * Emplace(TArgs &&... args)
Definition: monoallocator.hpp:485
aworx::lib::cli::Exceptions::UnknownCommand
Unknown command given.
aworx::lib::cli::Command
Definition: arguments.hpp:660
cliutil.hpp
aworx::lib::cli::CLIApp::GetOption
Option * GetOption(Enum element)
Definition: cliapp.cpp:166
aworx::lib::integer
platform_specific integer
Definition: integers.hpp:53
aworx::lib::cli::CLIApp::ArgStrings
std::vector< String, StdContMA< String > > ArgStrings
Definition: cliapp.hpp:119
aworx::lib::ALibDistribution::ArgC
int ArgC
Definition: lib/fs_modules/distribution.hpp:241
aworx::lib::cli::CLIApp::PeekArg
virtual String PeekArg()
Definition: cliapp.hpp:492
aworx::lib::cli::Command::Read
ALIB_API bool Read(CommandDecl &decl)
Definition: arguments.cpp:140
aworx::lib::cli::OptionDecl::ShortcutReplacementString
const String & ShortcutReplacementString()
Definition: arguments.hpp:451
aworx::lib::cli::CLIApp::Init
virtual ALIB_API void Init(Module *resModule)
Definition: cliapp.cpp:30
aworx::lib::strings::TAString::DbgDisableBufferReplacementWarning
void DbgDisableBufferReplacementWarning()
Definition: astring.hpp:361
aworx::lib::cli::OptionDecl
Definition: arguments.hpp:344
aworx::lib::cli::CLIApp::Arg
virtual String Arg(integer idx)
Definition: cliapp.hpp:476
aworx::lib::strings::TString
Definition: strings/fwds.hpp:42
aworx::lib::strings::TString::IsNotEmpty
constexpr bool IsNotEmpty() const
Definition: string.hpp:401
aworx::lib::strings::TAString::Reset
TAString & Reset()
Definition: astring.hpp:1282
aworx::lib::cli::CLIApp::RemoveArg
ALIB_API void RemoveArg(integer argNo)
Definition: cliapp.cpp:243
aworx::lib::cli::CLIUtil::GetCommandUsageFormat
static ALIB_API AString GetCommandUsageFormat(CLIApp &cliApp, CommandDecl &commandDecl)
Definition: cliutil.cpp:62
alib_precompile.hpp
aworx::lib::cli::CLIApp::ResModule
Module * ResModule
Definition: cliapp.hpp:173
aworx::lib::ALibDistribution::ArgVN
const char ** ArgVN
Definition: lib/fs_modules/distribution.hpp:248
cliapp.hpp
aworx::lib::strings::TString::CharAtStart
TChar CharAtStart() const
Definition: string.hpp:436
aworx::lib::cli::Option::Read
ALIB_API bool Read(OptionDecl &decl, String &arg, const integer argNo)
Definition: arguments.cpp:69
aworx::lib::ALibDistribution::ArgVW
const wchar_t ** ArgVW
Definition: lib/fs_modules/distribution.hpp:255
aworx::lib::cli::Parsed::QtyArgsConsumed
integer QtyArgsConsumed
Definition: arguments.hpp:50
aworx::NullString
constexpr String NullString()
Definition: string.hpp:2412
aworx::lib::cli::CLIApp::OptionArgsIgnored
List< String, Recycling::Shared > OptionArgsIgnored
Definition: cliapp.hpp:153
aworx::lib::cli::CLIApp::ArgWOriginal
const wchar_t ** ArgWOriginal
Definition: cliapp.hpp:110
aworx::lib::cli::Exceptions::ParsingCommand
General parameter parse error. Adds command help text.
aworx::lib::cli::CLIApp::ArgsLeft
std::vector< integer, StdContMA< integer > > ArgsLeft
Definition: cliapp.hpp:126
aworx::lib::cli::CLIApp::ReadNextCommands
virtual ALIB_API void ReadNextCommands()
Definition: cliapp.cpp:175
aworx
Definition: alox/alox.hpp:40
aworx::lib::results::Exception::Add
Exception & Add(const NCString &file, int line, const NCString &func, TEnum type, TArgs &&... args)
Definition: exception.hpp:299
aworx::ALIB
lib::ALibDistribution ALIB
Definition: distribution.cpp:112
aworx::lib::strings::TLocalString
Definition: strings/fwds.hpp:46
aworx::lib::cli::CLIApp::CommandsParsed
List< Command > CommandsParsed
Definition: cliapp.hpp:156
aworx::lib::cli::Option::Declaration
OptionDecl * Declaration
Definition: arguments.hpp:499
aworx::lib::cli::CLIApp::NextCommandIt
List< Command >::Iterator NextCommandIt
Definition: cliapp.hpp:159
aworx::lib::cli::CLIApp::Options
List< Option * > Options
Definition: cliapp.hpp:145
ALIB_ASSERT_ERROR
#define ALIB_ASSERT_ERROR(cond,...)
Definition: assert.hpp:119
aworx::lib::results::Exception
Definition: exception.hpp:129
aworx::lib::cli::CLIApp::CommandDecls
List< CommandDecl * > CommandDecls
Definition: cliapp.hpp:130
aworx::lib::cli::CLIApp::OptionDecls
List< OptionDecl * > OptionDecls
Definition: cliapp.hpp:133
aworx::lib::cli::CLIApp::NextCommand
virtual ALIB_API Command * NextCommand()
Definition: cliapp.cpp:209
distribution.hpp
aworx::lib::cli::CLIApp::allocator
MonoAllocator allocator
Definition: cliapp.hpp:75
ALIB_CALLER_NULLED
#define ALIB_CALLER_NULLED
Definition: tools.hpp:62
aworx::lib::cli::CLIApp::PopArg
virtual ALIB_API String PopArg()
Definition: cliapp.cpp:233
aworx::lib::cli::Exceptions::NoCommandGiven
Unknown command given.
aworx::lib::cli::Option
Definition: arguments.hpp:496
aworx::lib::cli::CLIApp::ReadOptions
virtual ALIB_API void ReadOptions()
Definition: cliapp.cpp:95
aworx::lib::Module
Definition: module.hpp:71
aworx::lib::cli::CLIApp::ArgcOriginal
int ArgcOriginal
Definition: cliapp.hpp:98
aworx::Exception
lib::results::Exception Exception
Type alias in namespace aworx.
Definition: exception.hpp:522
ALIB_ERROR
#define ALIB_ERROR(...)
Definition: assert.hpp:115
aworx::lib::cli::CLIApp::ArgNOriginal
const char ** ArgNOriginal
Definition: cliapp.hpp:104
aworx::lib::cli::Exceptions::ParsingOptions
General option parse error. Adds option help text.
aworx::lib::monomem::MonoAllocator::EmplaceString
strings::TString< TChar > EmplaceString(const strings::TString< TChar > &src)
Definition: monoallocator.hpp:566
aworx::lib::boxing::Enum
Definition: enum.hpp:57