30 bool G::Arg::m_first = true ;
31 std::string G::Arg::m_v0 ;
32 std::string G::Arg::m_cwd ;
36 G_ASSERT( argc > 0 ) ;
37 G_ASSERT( argv !=
nullptr ) ;
38 for(
int i = 0 ; i < argc ; i++ )
39 m_array.push_back( argv[i] ) ;
43 m_v0 = std::string( argv[0] ) ;
44 m_cwd = Process::cwd(
true) ;
55 m_array(other.m_array)
71 m_array.push_back( Process::exe() ) ;
72 parseCore( command_line_tail ) ;
77 G_ASSERT( !command_line.empty() ) ;
79 parseCore( command_line ) ;
84 while( m_array.size() > 1U ) m_array.pop_back() ;
85 parseCore( command_line_tail ) ;
96 m_array.swap( tmp.m_array ) ;
103 while( !result.empty() && shift-- )
104 result.erase( result.begin() ) ;
108 bool G::Arg::contains(
const std::string & option , size_type option_args ,
bool cs )
const
110 return find( cs , option , option_args ,
nullptr ) ;
113 bool G::Arg::find(
bool cs ,
const std::string & option , size_type option_args , size_type * index_p )
const
115 for( size_type i = 1 ; i < m_array.size() ; i++ )
117 if( match(cs,option,m_array[i]) && (i+option_args) < m_array.size() )
119 if( index_p !=
nullptr )
127 bool G::Arg::match(
bool cs ,
const std::string & s1 ,
const std::string & s2 )
135 const bool found = find(
true , option , option_args , &i ) ;
137 removeAt( i , option_args ) ;
143 G_ASSERT( option_index > 0U && option_index < m_array.size() ) ;
144 if( option_index > 0U && option_index < m_array.size() )
146 StringArray::iterator p = m_array.begin() ;
147 for( size_type i = 0U ; i < option_index ; i++ ) ++p ;
148 p = m_array.erase( p ) ;
149 for( size_type i = 0U ; i < option_args && p != m_array.end() ; i++ )
150 p = m_array.erase( p ) ;
154 G::Arg::size_type
G::Arg::index(
const std::string & option , size_type option_args )
const
157 const bool found = find(
true , option , option_args , &i ) ;
158 return found ? i : 0U ;
163 return m_array.size() ;
168 G_ASSERT( i < m_array.size() ) ;
169 return m_array.at(i) ;
174 G_ASSERT( m_array.size() > 0U ) ;
175 Path path( m_array.at(0U) ) ;
181 const char * exe = argv[0] ;
182 const char * p1 = std::strrchr( exe ,
'/' ) ;
183 const char * p2 = std::strrchr( exe ,
'\\' ) ;
184 p1 = p1 ? (p1+1U) : exe ;
185 p2 = p2 ? (p2+1U) : exe ;
186 return p1 > p2 ? p1 : p2 ;
189 void G::Arg::parseCore(
const std::string & command_line )
191 std::string s( command_line ) ;
194 unprotect( m_array ) ;
198 void G::Arg::protect( std::string & s )
203 bool in_quote = false ;
204 const char quote =
'"' ;
205 const char space =
' ' ;
206 const char replacement =
'\0' ;
207 for( std::string::size_type pos = 0U ; pos < s.length() ; pos++ )
209 if( s.at(pos) == quote ) in_quote = ! in_quote ;
210 if( in_quote && s.at(pos) == space ) s[pos] = replacement ;
218 const char space =
' ' ;
219 const char replacement =
'\0' ;
220 for( StringArray::iterator p = array.begin() ; p != array.end() ; ++p )
222 std::string & s = *p ;
231 for( StringArray::iterator p = array.begin() ; p != array.end() ; ++p )
233 std::string & s = *p ;
234 if( s.length() > 1U )
236 std::string::size_type start = s.at(0U) == qq ? 0U : s.find(
"=\"") ;
237 if( start != std::string::npos && s.at(start) != qq ) ++start ;
238 std::string::size_type end = s.at(s.length()-1U) == qq ? (s.length()-1U) : std::string::npos ;
239 if( start != std::string::npos && end != std::string::npos && start != end )
241 s.erase( end , 1U ) ;
242 s.erase( start , 1U ) ;
250 std::string procfs = Process::exe() ;
251 if( procfs.empty() && ( m_v0.empty() || ( m_cwd.empty() &&
Path(m_v0).
isRelative() ) ) )
254 throw std::runtime_error(
"cannot determine the absolute path of the current executable: try mounting procfs" ) ;
255 return std::string() ;
261 else if( procfs.empty() )
std::string str() const
Returns the path string.
std::string prefix() const
Returns the basename of v(0) without any extension.
Path withoutExtension() const
Returns a path without the basename extension, if any.
std::string basename() const
Returns the rightmost part of the path, ignoring "." parts.
std::vector< std::string > StringArray
A std::vector of std::strings.
Arg()
Default constructor. Initialise with parse().
static void splitIntoTokens(const std::string &in, StringArray &out, const std::string &ws)
Splits the string into 'ws'-delimited tokens.
static std::string exe(bool do_throw=true)
Returns Process::exe() or an absolute path constructed from v0().
Arg & operator=(const Arg &)
Assignment operator.
bool isRelative() const
Returns true if the path is a relative path.
StringArray array(unsigned int shift=0U) const
Returns the arguments a string array, including the program name in the first position.
std::string v(size_type i) const
Returns the i'th argument.
static unsigned int replaceAll(std::string &s, const std::string &from, const std::string &to)
Does a global replace on string 's', replacing all occurances of sub-string 'from' with 'to'...
void reparse(const std::string &command_line_tail)
Reinitialises the object with the given command-line tail.
size_type c() const
Returns the number of tokens in the command line, including the program name.
bool remove(const std::string &option, size_type option_args=0U)
Removes the given option and its arguments.
void parse(HINSTANCE hinstance, const std::string &command_line_tail)
Parses the given command-line tail, splitting it up into an array of tokens.
static std::string upper(const std::string &s)
Returns a copy of 's' in which all Latin-1 lowercase characters have been replaced by uppercase chara...
size_type index(const std::string &option, size_type option_args=0U) const
Returns the index of the given option. Returns zero if not present.
Path collapsed() const
Returns the path with "foo/.." and "." parts removed, so far as is possible without changing the mean...
A class which holds a represention of the argc/argv command line array, and supports simple command-l...
void removeAt(size_type option_index, size_type option_args=0U)
Removes the given argument and the following 'option_args' ones.
bool contains(const std::string &option, size_type option_args=0U, bool case_sensitive=true) const
Returns true if the command line contains the given option with enough command line arguments left to...
static std::string v0()
Returns a copy of argv[0] from the first call to the constructor that takes argc/argv.
A Path object represents a file system path.
static Path join(const StringArray &parts)
Builds a path from a set of parts.