12 #ifndef ZYPP_BASE_STRING_H
13 #define ZYPP_BASE_STRING_H
21 #include <boost/format.hpp>
22 #include <boost/utility/string_ref.hpp>
29 namespace boost {
namespace logic {
class tribool; } }
30 namespace zypp {
typedef boost::logic::tribool
TriBool; }
41 {
return val_r.asUserString(); }
98 C_Str(
const char * c_str_r ) :
_val( c_str_r ),
_sze( std::string::npos ) {}
107 if (
_sze == std::string::npos )
112 operator const char *()
const {
return c_str(); }
122 {
return str << obj.
c_str(); }
136 inline const std::string &
asString(
const std::string & t )
139 #ifndef SWIG // Swig treats it as syntax error
141 {
return std::move(t); }
145 {
return t ==
nullptr ? std::string() : t; }
148 {
return t ==
nullptr ? std::string() : t; }
152 {
return t.asString(); }
155 inline std::string
asString(
const intrusive_ptr<Tp> &p )
156 {
return p->asString(); }
159 inline std::string
asString(
const weak_ptr<Tp> &p )
160 {
return p->asString(); }
164 {
return t ?
"true" :
"false"; }
168 std::string
form(
const char * format, ... )
169 __attribute__ ((format (printf, 1, 2)));
176 std::
string strerror(
int errno_r );
195 {
return _buf ? std::string(_buf) : std::string(); }
214 { _str << std::forward<Tp>(val);
return *
this; }
217 {
_str << iomanip;
return *
this; }
219 operator std::string()
const {
return _str.str(); }
221 std::string
str()
const {
return _str.str(); }
234 {
return str << obj.
str(); }
258 {
_fmter % std::forward<Tp>(arg);
return *
this; }
260 operator std::string()
const {
return _fmter.str(); }
273 {
return str << obj.
fmter(); }
288 inline std::string
numstring(
char n,
int w = 0 ) {
return form(
"%*hhd", w, n ); }
289 inline std::string
numstring(
unsigned char n,
int w = 0 ) {
return form(
"%*hhu", w, n ); }
290 inline std::string
numstring(
short n,
int w = 0 ) {
return form(
"%*hd", w, n ); }
291 inline std::string
numstring(
unsigned short n,
int w = 0 ) {
return form(
"%*hu", w, n ); }
292 inline std::string
numstring(
int n,
int w = 0 ) {
return form(
"%*d", w, n ); }
293 inline std::string
numstring(
unsigned n,
int w = 0 ) {
return form(
"%*u", w, n ); }
294 inline std::string
numstring(
long n,
int w = 0 ) {
return form(
"%*ld", w, n ); }
295 inline std::string
numstring(
unsigned long n,
int w = 0 ) {
return form(
"%*lu", w, n ); }
296 inline std::string
numstring(
long long n,
int w = 0 ) {
return form(
"%*lld", w, n ); }
297 inline std::string
numstring(
unsigned long long n,
int w = 0 ) {
return form(
"%*llu", w, n ); }
308 template<>
inline std::string
asString(
const unsigned long long & t ) {
return numstring( t ); }
323 inline std::string
hexstring(
char n,
int w = 4 ) {
return form(
"%#0*hhx", w, n ); }
324 inline std::string
hexstring(
unsigned char n,
int w = 4 ) {
return form(
"%#0*hhx", w, n ); }
325 inline std::string
hexstring(
short n,
int w = 10 ){
return form(
"%#0*hx", w, n ); }
326 inline std::string
hexstring(
unsigned short n,
int w = 10 ){
return form(
"%#0*hx", w, n ); }
327 inline std::string
hexstring(
int n,
int w = 10 ){
return form(
"%#0*x", w, n ); }
328 inline std::string
hexstring(
unsigned n,
int w = 10 ){
return form(
"%#0*x", w, n ); }
329 inline std::string
hexstring(
long n,
int w = 10 ){
return form(
"%#0*lx", w, n ); }
330 inline std::string
hexstring(
unsigned long n,
int w = 10 ){
return form(
"%#0*lx", w, n ); }
331 inline std::string
hexstring(
long long n,
int w = 0 ) {
return form(
"%#0*llx", w, n ); }
332 inline std::string
hexstring(
unsigned long long n,
int w = 0 ) {
return form(
"%#0*llx", w, n ); }
347 inline std::string
octstring(
char n,
int w = 4 ) {
return form(
"%#0*hho", w, n ); }
348 inline std::string
octstring(
unsigned char n,
int w = 4 ) {
return form(
"%#0*hho", w, n ); }
349 inline std::string
octstring(
short n,
int w = 5 ) {
return form(
"%#0*ho", w, n ); }
350 inline std::string
octstring(
unsigned short n,
int w = 5 ) {
return form(
"%#0*ho", w, n ); }
351 inline std::string
octstring(
int n,
int w = 5 ) {
return form(
"%#0*o", w, n ); }
352 inline std::string
octstring(
unsigned n,
int w = 5 ) {
return form(
"%#0*o", w, n ); }
353 inline std::string
octstring(
long n,
int w = 5 ) {
return form(
"%#0*lo", w, n ); }
354 inline std::string
octstring(
unsigned long n,
int w = 5 ) {
return form(
"%#0*lo", w, n ); }
355 inline std::string
octstring(
long long n,
int w = 0 ) {
return form(
"%#0*llo", w, n ); }
356 inline std::string
octstring(
unsigned long long n,
int w = 0 ) {
return form(
"%#0*llo", w, n ); }
362 template <
typename TInt>
365 constexpr
unsigned bits =
sizeof(TInt)*8;
366 std::string ret( bits,
' ' );
368 for (
unsigned pos = bits; pos > 0; )
369 { --pos; ret[pos] = ((val_r & bit)?
'1':
'0'); bit = bit<<1; }
383 template<
typename TInt>
387 inline short strtonum(
const C_Str & str ) { return ::strtol ( str, NULL, 0 ); }
389 inline int strtonum(
const C_Str & str ) { return ::strtol ( str, NULL, 0 ); }
391 inline long strtonum(
const C_Str & str ) { return ::strtol ( str, NULL, 0 ); }
393 inline long long strtonum(
const C_Str & str ) { return ::strtoll ( str, NULL, 0 ); }
396 inline unsigned short strtonum(
const C_Str & str ) { return ::strtoul ( str, NULL, 0 ); }
398 inline unsigned strtonum(
const C_Str & str ) { return ::strtoul ( str, NULL, 0 ); }
400 inline unsigned long strtonum(
const C_Str & str ) { return ::strtoul ( str, NULL, 0 ); }
402 inline unsigned long long strtonum(
const C_Str & str ) { return ::strtoull( str, NULL, 0 ); }
409 template<
typename TInt>
411 {
return i = strtonum<TInt>( str ); }
437 if (
strToTrue( str ) )
return (return_r =
true);
438 if ( !
strToFalse( str ) )
return (return_r =
false);
450 std::string
gsub(
const std::string & str_r,
const std::string & from_r,
const std::string & to_r );
454 std::string
gsubFun(
const std::string & str_r,
const std::string & from_r,
function<std::string()> to_r );
460 std::string &
replaceAll( std::string & str_r,
const std::string & from_r,
const std::string & to_r );
464 std::string &
replaceAllFun( std::string & str_r,
const std::string & from_r,
function<std::string()> to_r );
480 if ( gap_r && inp_r.size() > gap_r )
482 inp_r.reserve( inp_r.size() + (inp_r.size()-1)/gap_r );
484 inp_r.insert( pos, 1, gapchar );
501 template<
class TOutputIterator>
502 unsigned split(
const C_Str & line_r, TOutputIterator result_r,
const C_Str & sepchars_r =
" \t" )
504 const char * beg = line_r;
505 const char * cur = beg;
507 while ( *cur && ::strchr( sepchars_r, *cur ) )
510 for ( beg = cur; *beg; beg = cur, ++result_r, ++ret )
513 while( *cur && !::strchr( sepchars_r, *cur ) )
516 *result_r = std::string( beg, cur-beg );
518 while ( *cur && ::strchr( sepchars_r, *cur ) )
560 template<
class TOutputIterator>
561 unsigned splitEscaped(
const C_Str & line_r, TOutputIterator result_r,
const C_Str & sepchars_r =
" \t",
bool withEmpty =
false)
563 const char * beg = line_r;
564 const char * cur = beg;
568 while ( *cur && ::strchr( sepchars_r, *cur ) )
579 if (!*cur && withEmpty)
586 enum class Quote { None, Slash, Single, Double, DoubleSlash };
587 std::vector<char> buf;
588 Quote quoting = Quote::None;
589 for ( beg = cur; *beg; beg = cur, ++result_r, ++ret )
593 quoting = Quote::None;
600 case '\\': quoting = Quote::Slash;
break;
601 case '\'': quoting = Quote::Single;
break;
602 case '"': quoting = Quote::Double;
break;
603 default: buf.push_back( *cur );
break;
608 buf.push_back( *cur );
609 quoting = Quote::None;
615 case '\'': quoting = Quote::None;
break;
616 default: buf.push_back( *cur );
break;
623 case '\"': quoting = Quote::None;
break;
624 case '\\': quoting = Quote::DoubleSlash;
break;
625 default: buf.push_back( *cur );
break;
629 case Quote::DoubleSlash:
633 case '\\': buf.push_back( *cur );
break;
635 buf.push_back(
'\\' );
636 buf.push_back( *cur );
639 quoting = Quote::Double;
643 }
while ( *cur && ( quoting != Quote::None || !::strchr( sepchars_r, *cur ) ) );
644 *result_r = std::string( buf.begin(), buf.end() );
648 if ( *cur && ::strchr( sepchars_r, *cur ) )
650 while ( *cur && ::strchr( sepchars_r, *cur ) )
660 if ( !*cur && withEmpty && ::strchr( sepchars_r, *(cur-1) ) )
690 template<
class TOutputIterator>
693 const char * beg = line_r;
694 const char * cur = beg;
696 for ( beg = cur; *beg; beg = cur, ++result_r )
699 while( *cur && !::strchr( sepchars_r, *cur ) )
701 if ( *cur ==
'\\' && *(cur+1) )
706 *result_r = std::string( beg, cur-beg );
714 *result_r = std::string();
729 template<
class TOutputIterator>
732 return splitEscaped( line_r, result_r, sepchars_r,
true );
741 template <
class TIterator>
742 std::string
join( TIterator begin, TIterator end,
const C_Str & sep_r =
" " )
745 for ( TIterator iter = begin; iter != end; ++ iter )
755 template <
class TContainer>
756 std::string
join(
const TContainer & cont_r,
const C_Str & sep_r =
" " )
757 {
return join( cont_r.begin(), cont_r.end(), sep_r ); }
763 template <
class TIterator>
764 std::string
joinEscaped( TIterator begin, TIterator end,
const char sep_r =
' ' )
766 std::vector<char> buf;
767 for ( TIterator iter = begin; iter != end; ++ iter )
770 buf.push_back( sep_r );
775 buf.push_back(
'"' );
776 buf.push_back(
'"' );
780 std::string toadd(
asString(*iter) );
781 for_( ch, toadd.begin(), toadd.end() )
788 buf.push_back(
'\\' );
789 buf.push_back( *ch );
793 buf.push_back(
'\\' );
794 buf.push_back( *ch );
799 return std::string( buf.begin(), buf.end() );
811 inline std::ostream &
printIndented( std::ostream & str,
const std::string & text_r,
const std::string & indent_r =
" ",
unsigned maxWitdh_r = 0 )
815 if ( indent_r.size() >= maxWitdh_r )
818 maxWitdh_r -= indent_r.size();
821 for (
const char * e = text_r.c_str(), * s = e; *e; s = ++e )
823 for ( ; *e && *e !=
'\n'; ++e ) ;
825 if ( maxWitdh_r && width > maxWitdh_r )
829 for ( e = s+width; e > s && *e !=
' '; --e ) ;
836 str.write( s, width );
844 inline std::ostream &
printIndented( std::ostream & str,
const std::string & text_r,
unsigned indent_r,
char indentch_r =
' ',
unsigned maxWitdh_r = 0 )
845 {
return printIndented( str, text_r, std::string( indent_r, indentch_r ), maxWitdh_r ); }
847 inline std::ostream &
printIndented( std::ostream & str,
const std::string & text_r,
unsigned indent_r,
unsigned maxWitdh_r,
char indentch_r =
' ' )
848 {
return printIndented( str, text_r, std::string( indent_r, indentch_r ), maxWitdh_r ); }
853 inline std::ostream &
autoPrefix( std::ostream & str,
const std::string & text_r,
function<std::string(
const char*,
const char*)> fnc_r )
855 for (
const char * e = text_r.c_str(); *e; ++e )
858 for ( ; *e && *e !=
'\n'; ++e ) ;
859 str << fnc_r( s, e );
868 inline std::ostream &
autoPrefix0( std::ostream & str,
const std::string & text_r,
function<std::string()> fnc_r )
870 auto wrap = [&fnc_r](
const char*,
const char* )-> std::string {
885 std::string
escape(
const C_Str & str_r,
const char c =
' ' );
890 if ( ! str_r.empty() )
892 if ( next_r.
empty() )
895 str_r +=
escape( next_r, sep_r );
899 std::string
bEscape( std::string str_r,
const C_Str & special_r );
931 std::string
toLower(
const std::string & s );
932 std::string
toLower( std::string && s );
935 {
return( s ?
toLower( std::string(s) ) : std::string() ); }
940 std::string
toUpper(
const std::string & s );
941 std::string
toUpper( std::string && s );
944 {
return( s ?
toUpper( std::string(s) ) : std::string() ); }
951 { return ::strcasecmp( lhs, rhs ); }
958 { return ::strstr( str_r, val_r ); }
961 { return ::strcasestr( str_r, val_r ); }
977 std::string
trim(
const std::string & s,
const Trim trim_r =
TRIM );
978 std::string
trim( std::string && s,
const Trim trim_r =
TRIM );
980 inline std::string
ltrim(
const std::string & s )
982 inline std::string
ltrim( std::string && s )
985 inline std::string
rtrim(
const std::string & s )
987 inline std::string
rtrim( std::string && s )
991 std::string
stripFirstWord( std::string & line,
const bool ltrim_first =
true );
993 std::string
stripLastWord( std::string & line,
const bool rtrim_first =
true );
998 std::string
getline( std::istream & str,
bool trim =
false );
1003 std::string
getline( std::istream & str,
const Trim trim_r );
1012 std::string
receiveUpTo( std::istream & str,
const char delim_r,
bool returnDelim_r =
false );
1021 {
return( ::strncmp( str_r, prefix_r, prefix_r.
size() ) == 0 ); }
1024 {
return( ::strncasecmp( str_r, prefix_r, prefix_r.
size() ) == 0 ); }
1028 {
return(
hasPrefix( str_r, prefix_r ) ? str_r + prefix_r.
size() : str_r.
c_str() ); }
1035 {
return( str_r.
size() >= suffix_r.
size() && ::strncmp( str_r + str_r.
size() - suffix_r.
size() , suffix_r, suffix_r.
size() ) == 0 ); }
1038 {
return( str_r.
size() >= suffix_r.
size() && ::strncasecmp( str_r + str_r.
size() - suffix_r.
size() , suffix_r, suffix_r.
size() ) == 0 ); }
1044 return std::string( str_r, str_r.
size() - suffix_r.
size() );
1045 return str_r.
c_str();
1051 return std::string( str_r, str_r.
size() - suffix_r.
size() );
1052 return str_r.
c_str();
1058 const char * lp = lhs.
c_str();
1059 const char * rp = rhs.
c_str();
1061 while ( *lp == *rp && *lp !=
'\0' )
1062 { ++lp, ++rp, ++ret; }
1068 const char * lp = lhs.
c_str();
1069 const char * rp = rhs.
c_str();
1071 while ( tolower(*lp) == tolower(*rp) && *lp !=
'\0' )
1072 { ++lp, ++rp, ++ret; }
1079 {
return hasPrefix( str_r, prefix_r ); }
1086 {
return hasSuffix( str_r, prefix_r ); }
1099 #endif // ZYPP_BASE_STRING_H