libzypp  17.35.15
LogTools.h
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #ifndef ZYPP_BASE_LOGTOOLS_H
13 #define ZYPP_BASE_LOGTOOLS_H
14 
15 #include <iostream>
16 #include <optional>
17 #include <string>
18 #include <vector>
19 #include <list>
20 #include <set>
21 #include <map>
22 
23 #include <zypp-core/base/Hash.h>
24 #include <zypp-core/base/Logger.h>
25 #include <zypp-core/base/String.h>
27 #include <zypp-core/Globals.h>
28 
29 #ifdef __GNUG__
30 #include <cstdlib>
31 #include <memory>
32 #include <cxxabi.h>
33 #endif
34 
36 namespace zypp
37 {
38 
39  using std::endl;
40 
52  struct MLSep
53  {
54  MLSep() {}
55  MLSep( char sep_r ) : _sep { sep_r } {}
56  bool _first = true;
57  char _sep = '\n';
58  };
59  inline std::ostream & operator<<( std::ostream & str, MLSep & obj )
60  { if ( obj._first ) obj._first = false; else str << obj._sep; return str; }
61 
119  template<class TIterator>
120  std::ostream & dumpRange( std::ostream & str,
121  TIterator begin, TIterator end,
122  const std::string & intro = "{",
123  const std::string & pfx = "\n ",
124  const std::string & sep = "\n ",
125  const std::string & sfx = "\n",
126  const std::string & extro = "}" )
127  {
128  str << intro;
129  if ( begin != end )
130  {
131  str << pfx << *begin;
132  for ( ++begin; begin != end; ++begin )
133  str << sep << *begin;
134  str << sfx;
135  }
136  return str << extro;
137  }
138 
142  template<class TIterator>
143  std::ostream & dumpRangeLine( std::ostream & str,
144  TIterator begin, TIterator end )
145  { return dumpRange( str, begin, end, "(", "", ", ", "", ")" ); }
147  template<class TContainer>
148  std::ostream & dumpRangeLine( std::ostream & str, const TContainer & cont )
149  { return dumpRangeLine( str, cont.begin(), cont.end() ); }
150 
151 
153  namespace iomanip
154  {
159  template<class TIterator>
160  struct RangeLine
161  {
162  RangeLine( TIterator begin, TIterator end )
163  : _begin( begin )
164  , _end( end )
165  {}
166  TIterator _begin;
167  TIterator _end;
168  };
169 
171  template<class TIterator>
172  std::ostream & operator<<( std::ostream & str, const RangeLine<TIterator> & obj )
173  { return dumpRangeLine( str, obj._begin, obj._end ); }
174 
175  } // namespce iomanip
177 
185  template<class TIterator>
186  iomanip::RangeLine<TIterator> rangeLine( TIterator begin, TIterator end )
187  { return iomanip::RangeLine<TIterator>( begin, end ); }
189  template<class TContainer>
190  auto rangeLine( const TContainer & cont ) -> decltype( rangeLine( cont.begin(), cont.end() ) )
191  { return rangeLine( cont.begin(), cont.end() ); }
192 
193  template<class Tp>
194  std::ostream & operator<<( std::ostream & str, const std::vector<Tp> & obj )
195  { return dumpRange( str, obj.begin(), obj.end() ); }
196 
197  template<class Tp, class TCmp, class TAlloc>
198  std::ostream & operator<<( std::ostream & str, const std::set<Tp,TCmp,TAlloc> & obj )
199  { return dumpRange( str, obj.begin(), obj.end() ); }
200 
201  template<class Tp>
202  std::ostream & operator<<( std::ostream & str, const std::unordered_set<Tp> & obj )
203  { return dumpRange( str, obj.begin(), obj.end() ); }
204 
205  template<class Tp>
206  std::ostream & operator<<( std::ostream & str, const std::multiset<Tp> & obj )
207  { return dumpRange( str, obj.begin(), obj.end() ); }
208 
209  template<class Tp>
210  std::ostream & operator<<( std::ostream & str, const std::list<Tp> & obj )
211  { return dumpRange( str, obj.begin(), obj.end() ); }
212 
213  template<class Tp>
214  std::ostream & operator<<( std::ostream & str, const Iterable<Tp> & obj )
215  { return dumpRange( str, obj.begin(), obj.end() ); }
216 
218  namespace _logtoolsdetail
219  {
220 
222  // mapEntry
224 
230  template<class TPair>
231  class MapEntry
232  {
233  public:
234  MapEntry( const TPair & pair_r )
235  : _pair( &pair_r )
236  {}
237 
238  const TPair & pair() const
239  { return *_pair; }
240 
241  private:
242  const TPair *const _pair;
243  };
244 
246  template<class TPair>
247  std::ostream & operator<<( std::ostream & str, const MapEntry<TPair> & obj )
248  {
249  return str << '[' << obj.pair().first << "] = " << obj.pair().second;
250  }
251 
253  template<class TPair>
254  MapEntry<TPair> mapEntry( const TPair & pair_r )
255  { return MapEntry<TPair>( pair_r ); }
256 
258  // dumpMap
260 
265  template<class TMap>
266  class DumpMap
267  {
268  public:
269  using MapType = TMap;
270  using PairType = typename TMap::value_type;
272 
273  struct Transformer
274  {
275  MapEntryType operator()( const PairType & pair_r ) const
276  { return mapEntry( pair_r ); }
277  };
278 
279  using MapEntry_const_iterator = transform_iterator<Transformer, typename MapType::const_iterator>;
280 
281  public:
282  DumpMap( const TMap & map_r )
283  : _map( &map_r )
284  {}
285 
286  const TMap & map() const
287  { return *_map; }
288 
290  { return make_transform_iterator( map().begin(), Transformer() ); }
291 
293  { return make_transform_iterator( map().end(), Transformer() );}
294 
295  private:
296  const TMap *const _map;
297  };
298 
300  template<class TMap>
301  std::ostream & operator<<( std::ostream & str, const DumpMap<TMap> & obj )
302  { return dumpRange( str, obj.begin(), obj.end() ); }
303 
305  template<class TMap>
306  DumpMap<TMap> dumpMap( const TMap & map_r )
307  { return DumpMap<TMap>( map_r ); }
308 
310  // dumpKeys
312 
320  template<class TMap>
321  class DumpKeys
322  {
323  public:
325 
326  public:
327  DumpKeys( const TMap & map_r )
328  : _map( &map_r )
329  {}
330 
331  const TMap & map() const
332  { return *_map; }
333 
335  { return make_map_key_begin( map() ); }
336 
338  { return make_map_key_end( map() ); }
339 
340  private:
341  const TMap *const _map;
342  };
343 
345  template<class TMap>
346  std::ostream & operator<<( std::ostream & str, const DumpKeys<TMap> & obj )
347  { return dumpRange( str, obj.begin(), obj.end() ); }
348 
350  template<class TMap>
351  DumpKeys<TMap> dumpKeys( const TMap & map_r )
352  { return DumpKeys<TMap>( map_r ); }
353 
355  // dumpValues
357 
365  template<class TMap>
367  {
368  public:
370 
371  public:
372  DumpValues( const TMap & map_r )
373  : _map( &map_r )
374  {}
375 
376  const TMap & map() const
377  { return *_map; }
378 
380  { return make_map_value_begin( map() ); }
381 
383  { return make_map_value_end( map() ); }
384 
385  private:
386  const TMap *const _map;
387  };
388 
390  template<class TMap>
391  std::ostream & operator<<( std::ostream & str, const DumpValues<TMap> & obj )
392  { return dumpRange( str, obj.begin(), obj.end() ); }
393 
395  template<class TMap>
396  DumpValues<TMap> dumpValues( const TMap & map_r )
397  { return DumpValues<TMap>( map_r ); }
398 
400  } // namespace _logtoolsdetail
402 
403  // iomanipulator
404  using _logtoolsdetail::mapEntry; // std::pair as '[key] = value'
405  using _logtoolsdetail::dumpMap; // dumpRange '[key] = value'
406  using _logtoolsdetail::dumpKeys; // dumpRange keys
407  using _logtoolsdetail::dumpValues; // dumpRange values
408 
409  template<class TKey, class Tp>
410  std::ostream & operator<<( std::ostream & str, const std::map<TKey, Tp> & obj )
411  { return str << dumpMap( obj ); }
412 
413  template<class TKey, class Tp>
414  std::ostream & operator<<( std::ostream & str, const std::unordered_map<TKey, Tp> & obj )
415  { return str << dumpMap( obj ); }
416 
417  template<class TKey, class Tp>
418  std::ostream & operator<<( std::ostream & str, const std::multimap<TKey, Tp> & obj )
419  { return str << dumpMap( obj ); }
420 
430  inline std::ostream & operator<<( std::ostream & str, const std::basic_ios<char> & obj )
431  {
432  std::string ret( "[" );
433  ret += ( obj.good() ? 'g' : '_' );
434  ret += ( obj.eof() ? 'e' : '_' );
435  ret += ( obj.fail() ? 'F' : '_' );
436  ret += ( obj.bad() ? 'B' : '_' );
437  ret += "]";
438  return str << ret;
439  }
440 
442  // iomanipulator: str << dump(val) << ...
443  // calls: std::ostream & dumpOn( std::ostream & str, const Type & obj )
445 
446  namespace detail
447  {
448  template<class Tp>
449  struct Dump
450  {
451  Dump( const Tp & obj_r ) : _obj( obj_r ) {}
452  const Tp & _obj;
453  };
454 
455  template<class Tp>
456  std::ostream & operator<<( std::ostream & str, const Dump<Tp> & obj )
457  { return dumpOn( str, obj._obj ); }
458  }
459 
460  template<class Tp>
461  detail::Dump<Tp> dump( const Tp & obj_r )
462  { return detail::Dump<Tp>(obj_r); }
463 
472  inline std::ostream & hexdumpOn( std::ostream & outs, const unsigned char *ptr, size_t size )
473  {
474  size_t i = 0,c = 0;
475  unsigned width = 0x10;
476  outs << str::form( "hexdump %10.10ld bytes (0x%8.8lx):\n", (long)size, (long)size );
477 
478  for ( i = 0; i < size; i += width ) {
479  outs << str::form( "%4.4lx: ", (long)i );
480  /* show hex to the left */
481  for ( c = 0; c < width; ++c ) {
482  if ( i+c < size )
483  outs << str::form( "%02x ", ptr[i+c] );
484  else
485  outs << (" ");
486  }
487  /* show data on the right */
488  for ( c = 0; (c < width) && (i+c < size); ++c ) {
489  char x = (ptr[i+c] >= 0x20 && ptr[i+c] < 0x7f) ? ptr[i+c] : '.';
490  outs << x;
491  }
492  outs << std::endl;
493  }
494  return outs;
495  }
497  inline std::ostream & hexdumpOn( std::ostream & outs, const char *ptr, size_t size )
498  { return hexdumpOn( outs, reinterpret_cast<const unsigned char*>(ptr), size ); }
499 
504  inline std::ostream & operator<<( std::ostream & str, const std::type_info &info )
505  {
506 #ifdef __GNUG__
507  int status = -4; // some arbitrary value to eliminate the compiler warning
508 
509  // enable c++11 by passing the flag -std=c++11 to g++
510  std::unique_ptr<char, void(*)(void*)> res {
511  abi::__cxa_demangle(info.name(), NULL, NULL, &status),
512  std::free
513  };
514  return str << std::string((status==0) ? res.get() : info.name());
515 #else
516  return str << info.name();
517 #endif
518  }
519 
520 #ifdef __cpp_lib_optional // YAST/PK explicitly use c++11 until 15-SP3
521  template<class Tp>
522  inline std::ostream & operator<<( std::ostream & str, const std::optional<Tp> & obj )
523  {
524  if ( obj )
525  str << "opt(" << *obj << ")";
526  else
527  str << "nullopt";
528  return str;
529  }
530 #endif
531 
532 
534 } // namespace zypp
536 #endif // ZYPP_BASE_LOGTOOLS_H
DumpKeys< TMap > dumpKeys(const TMap &map_r)
Definition: LogTools.h:351
std::ostream & dumpOn(std::ostream &str, const PoolQueryIterator &obj)
Definition: PoolQuery.cc:1838
const TMap & map() const
Definition: LogTools.h:376
const Tp & _obj
Definition: LogTools.h:452
Dump(const Tp &obj_r)
Definition: LogTools.h:451
MapKey_const_iterator end() const
Definition: LogTools.h:337
std::ostream & dumpRange(std::ostream &str, TIterator begin, TIterator end, const std::string &intro="{", const std::string &pfx="\ ", const std::string &sep="\ ", const std::string &sfx="\, const std::string &extro="}")
Print range defined by iterators (multiline style).
Definition: LogTools.h:120
MapValue_const_iterator end() const
Definition: LogTools.h:382
String related utilities and Regular expression matching.
MapKVIteratorTraits< TMap >::Value_const_iterator make_map_value_begin(const TMap &map_r)
Convenience to create the value iterator from container::begin()
Definition: Iterator.h:236
std::ostream & operator<<(std::ostream &str, const SerialNumber &obj)
Definition: SerialNumber.cc:52
std::map wrapper for stream output.
Definition: LogTools.h:266
Provides API related macros.
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition: String.cc:37
MapKVIteratorTraits< TMap >::Key_const_iterator make_map_key_begin(const TMap &map_r)
Convenience to create the key iterator from container::begin()
Definition: Iterator.h:226
MapEntry(const TPair &pair_r)
Definition: LogTools.h:234
typename TMap::value_type PairType
Definition: LogTools.h:270
MapEntry< TPair > mapEntry(const TPair &pair_r)
Definition: LogTools.h:254
std::pair wrapper for std::map output.
Definition: LogTools.h:231
transform_iterator< Transformer, typename MapType::const_iterator > MapEntry_const_iterator
Definition: LogTools.h:279
DumpValues(const TMap &map_r)
Definition: LogTools.h:372
const TMap *const _map
Definition: LogTools.h:296
iomanip::RangeLine< TIterator > rangeLine(TIterator begin, TIterator end)
Iomanip printing dumpRangeLine style.
Definition: LogTools.h:186
const TPair *const _pair
Definition: LogTools.h:242
MapKVIteratorTraits< TMap >::Key_const_iterator make_map_key_end(const TMap &map_r)
Convenience to create the key iterator from container::end()
Definition: Iterator.h:231
std::map wrapper for stream output of keys.
Definition: LogTools.h:321
MapValue_const_iterator begin() const
Definition: LogTools.h:379
transform_iterator< GetPairFirst< typename MapType::value_type >, typename MapType::const_iterator > Key_const_iterator
The key iterator type.
Definition: Iterator.h:217
DumpMap< TMap > dumpMap(const TMap &map_r)
Definition: LogTools.h:306
MapEntryType operator()(const PairType &pair_r) const
Definition: LogTools.h:275
std::ostream & hexdumpOn(std::ostream &outs, const unsigned char *ptr, size_t size)
hexdump data on stream
Definition: LogTools.h:472
MapKey_const_iterator begin() const
Definition: LogTools.h:334
bool _first
Definition: LogTools.h:56
MapEntry_const_iterator end() const
Definition: LogTools.h:292
MapKVIteratorTraits< TMap >::Value_const_iterator make_map_value_end(const TMap &map_r)
Convenience to create the value iterator from container::end()
Definition: Iterator.h:241
Helper to produce not-NL-terminated multi line output.
Definition: LogTools.h:52
typename MapKVIteratorTraits< TMap >::Key_const_iterator MapKey_const_iterator
Definition: LogTools.h:324
DumpValues< TMap > dumpValues(const TMap &map_r)
Definition: LogTools.h:396
transform_iterator< GetPairSecond< typename MapType::value_type >, typename MapType::const_iterator > Value_const_iterator
The value iterator type.
Definition: Iterator.h:221
MLSep(char sep_r)
Definition: LogTools.h:55
DumpKeys(const TMap &map_r)
Definition: LogTools.h:327
const TMap & map() const
Definition: LogTools.h:286
const TPair & pair() const
Definition: LogTools.h:238
const TMap & map() const
Definition: LogTools.h:331
const TMap *const _map
Definition: LogTools.h:341
std::ostream & dumpRangeLine(std::ostream &str, TIterator begin, TIterator end)
Print range defined by iterators (single line style).
Definition: LogTools.h:143
RangeLine(TIterator begin, TIterator end)
Definition: LogTools.h:162
std::map wrapper for stream output of values.
Definition: LogTools.h:366
Easy-to use interface to the ZYPP dependency resolver.
Definition: Application.cc:19
DumpMap(const TMap &map_r)
Definition: LogTools.h:282
detail::Dump< Tp > dump(const Tp &obj_r)
Definition: LogTools.h:461
char _sep
Definition: LogTools.h:57
MapEntry_const_iterator begin() const
Definition: LogTools.h:289
typename MapKVIteratorTraits< TMap >::Value_const_iterator MapValue_const_iterator
Definition: LogTools.h:369