ROSE  0.9.9.139
Message.h
1 // See also Rose::Diagnostics in $ROSE/src/roseSupport/Diagnostics.h
2 // WARNING: Changes to this file must be contributed back to Sawyer or else they will
3 // be clobbered by the next update from Sawyer. The Sawyer repository is at
4 // https://github.com/matzke1/sawyer.
5 
6 
7 
8 
9 #ifndef Sawyer_Message_H
10 #define Sawyer_Message_H
11 
12 #include <Sawyer/Map.h>
13 #include <Sawyer/Optional.h>
14 #include <Sawyer/Sawyer.h>
15 #include <Sawyer/SharedPointer.h>
16 #include <Sawyer/Synchronization.h>
17 
18 #include <boost/config.hpp>
19 #include <boost/logic/tribool.hpp>
20 #include <cassert>
21 #include <cstring>
22 #include <list>
23 #include <ostream>
24 #include <set>
25 #include <streambuf>
26 #include <string>
27 #include <vector>
28 
29 namespace Sawyer {
30 
273 namespace Message {
274 
282 SAWYER_EXPORT bool initializeLibrary();
283 
284 // Any header that #defines words that are this common is just plain stupid!
285 #if defined(DEBUG) || defined(TRACE) || defined(WHERE) || defined(MARCH) || \
286  defined(INFO) || defined(WARN) || defined(ERROR) || defined(FATAL)
287 # ifdef _MSC_VER
288 # pragma message("Undefining common words from the global namespace: DEBUG, TRACE, WHERE, MARCH, INFO, WARN, ERROR, FATAL")
289 # else
290 # warning "Undefining common words from the global namespace: DEBUG, TRACE, WHERE, MARCH, INFO, WARN, ERROR, FATAL"
291 # endif
292 # undef DEBUG
293 # undef TRACE
294 # undef WHERE
295 # undef MARCH
296 # undef INFO
297 # undef WARN
298 # undef ERROR
299 # undef FATAL
300 #endif
301 
336 };
337 
340 enum AnsiColor { // the values are important: they are the ANSI foreground and background color offsets
342  COLOR_RED = 1,
350 };
351 
352 
353 
355 // Functions
357 
358 SAWYER_EXPORT std::string stringifyImportance(Importance);
359 SAWYER_EXPORT std::string stringifyColor(AnsiColor);
360 SAWYER_EXPORT double now();
361 SAWYER_EXPORT std::string escape(const std::string&);
365 // Colors
368 
372 struct SAWYER_EXPORT ColorSpec {
375 #include <Sawyer/WarningsOff.h>
376  boost::tribool bold;
377 #include <Sawyer/WarningsRestore.h>
378 
380  ColorSpec(): foreground(COLOR_DEFAULT), background(COLOR_DEFAULT), bold(false) {}
381 
383  explicit ColorSpec(AnsiColor fg): foreground(fg), background(COLOR_DEFAULT), bold(false) {}
384 
386  ColorSpec(AnsiColor fg, AnsiColor bg, bool bold): foreground(fg), background(bg), bold(bold) {}
387 
389  bool isDefault() const { return COLOR_DEFAULT==foreground && COLOR_DEFAULT==background && !bold; }
390 };
391 
395 class SAWYER_EXPORT ColorSet {
396  ColorSpec spec_[N_IMPORTANCE];
397 public:
400  static ColorSet blackAndWhite();
401 
403  static ColorSet fullColor();
404 
407  const ColorSpec& operator[](Importance imp) const { return spec_[imp]; }
408  ColorSpec& operator[](Importance imp) { return spec_[imp]; }
410 };
411 
412 
413 
415 // Message Properties
417 
424 struct SAWYER_EXPORT MesgProps {
425 #include <Sawyer/WarningsOff.h>
428  boost::tribool isBuffered;
433  boost::tribool useColor;
434 #include <Sawyer/WarningsRestore.h>
435 
436  MesgProps(): isBuffered(boost::indeterminate), useColor(boost::indeterminate) {}
437 
441  MesgProps merge(const MesgProps&) const;
442 
444  void print(std::ostream&) const;
445 };
446 
448 SAWYER_EXPORT std::ostream& operator<<(std::ostream &o, const MesgProps &props);
449 
450 
451 
453 // Type defintions
455 
492 typedef std::pair<DestinationPtr, MesgProps> BakedDestination;
493 
495 typedef std::vector<BakedDestination> BakedDestinations;
496 
497 
498 
500 // Messages
502 
511 class SAWYER_EXPORT Mesg {
512  static unsigned nextId_; // class-wide unique ID numbers
513  unsigned id_; // unique message ID
514 #include <Sawyer/WarningsOff.h>
515  std::string text_; // text of the message
516 #include <Sawyer/WarningsRestore.h>
517  bool isComplete_; // true when the message is complete
518  bool isCanceled_; // true when message is being canceled without completing
519  MesgProps props_; // message properties
520 public:
521 
524  : id_(nextId_++), isComplete_(false), isCanceled_(false) {}
525 
527  Mesg(const std::string &facilityName, Importance imp)
528  : id_(nextId_++), isComplete_(false), isCanceled_(false) {
529  props_.facilityName = facilityName;
530  props_.importance = imp;
531  }
532 
534  explicit Mesg(const MesgProps &props)
535  : id_(nextId_++), isComplete_(false), isCanceled_(false), props_(props) {}
536 
538  explicit Mesg(const std::string &mesg)
539  : id_(nextId_++), text_(mesg), isComplete_(true), isCanceled_(false) {}
540 
543  Mesg(const std::string &facilityName, Importance imp, const std::string &mesg)
544  : id_(nextId_++), text_(mesg), isComplete_(true), isCanceled_(false) {
545  props_.facilityName = facilityName;
546  props_.importance = imp;
547  }
548 
550  Mesg(const MesgProps &props, const std::string &mesg)
551  : id_(nextId_++), text_(mesg), isComplete_(true), isCanceled_(false), props_(props) {}
552 
554  unsigned id() const { return id_; }
555 
557  const std::string& text() const { return text_; }
558 
560  bool isComplete() const { return isComplete_; }
561 
564  bool isCanceled() const { return isCanceled_; }
565 
568  bool isEmpty() const { return text_.empty(); }
569 
572  bool hasText() const;
573 
578  const MesgProps& properties() const { return props_; }
579  MesgProps& properties() { return props_; }
583  void complete() { isComplete_ = true; }
584 
587  void cancel() { isCanceled_ = true; }
588 
592  void insert(const std::string&);
593  void insert(char);
597  void post(const BakedDestinations&) const;
598 };
599 
601 // Plumbing lattice nodes
603 
607 class SAWYER_EXPORT Destination: public SharedObject, public SharedFromThis<Destination> {
608 protected:
609  mutable SAWYER_THREAD_TRAITS::RecursiveMutex mutex_;
612 protected:
613  Destination() {}
614 public:
615  virtual ~Destination() {}
616 
625  const MesgProps& defaultPropertiesNS() const { return dflts_; }
626  MesgProps& defaultPropertiesNS() { return dflts_; }
637  const MesgProps& overridePropertiesNS() const { return overrides_; }
638  MesgProps& overridePropertiesNS() { return overrides_; }
648  virtual void bakeDestinations(const MesgProps&, BakedDestinations &baked);
649 
652  virtual void post(const Mesg&, const MesgProps &bakedProperties) = 0;
653 
661  MesgProps mergePropertiesNS(const MesgProps &props);
662 };
663 
667 class SAWYER_EXPORT Multiplexer: public Destination {
668  typedef std::list<DestinationPtr> Destinations;
669 #include <Sawyer/WarningsOff.h>
670  Destinations destinations_;
671 #include <Sawyer/WarningsRestore.h>
672 protected:
675 public:
677  static MultiplexerPtr instance() { return MultiplexerPtr(new Multiplexer); }
678 
679  virtual void bakeDestinations(const MesgProps&, BakedDestinations&) /*override*/;
680  virtual void post(const Mesg&, const MesgProps&) /*override*/;
681 
690  MultiplexerPtr addDestination(const DestinationPtr&);
691 
697  MultiplexerPtr removeDestination(const DestinationPtr&);
698 
706  MultiplexerPtr to(const DestinationPtr&); // more convenient form of addDestination()
707  MultiplexerPtr to(const DestinationPtr&, const DestinationPtr&);
708  MultiplexerPtr to(const DestinationPtr&, const DestinationPtr&, const DestinationPtr&);
709  MultiplexerPtr to(const DestinationPtr&, const DestinationPtr&, const DestinationPtr&, const DestinationPtr&);
711 };
712 
714 // Filters
716 
721 class SAWYER_EXPORT Filter: public Multiplexer {
722 protected:
724  Filter() {}
725 public:
726  virtual void bakeDestinations(const MesgProps&, BakedDestinations&) /*override*/;
727 
736  virtual bool shouldForward(const MesgProps&) = 0; // return true if message should be forwarded to children when baking
737 
741  virtual void forwarded(const MesgProps&) = 0; // message was forwarded to children
742 };
743 
748 class SAWYER_EXPORT SequenceFilter: public Filter {
749  size_t nSkip_; // skip initial messages posted to this sequencer
750  size_t rate_; // emit only 1/Nth of the messages (0 and 1 both mean every message)
751  size_t limit_; // emit at most this many messages (0 means infinite)
752  size_t nPosted_; // number of messages posted (including those suppressed)
753 protected:
755  SequenceFilter(size_t nskip, size_t rate, size_t limit)
756  : nSkip_(nskip), rate_(rate), limit_(limit), nPosted_(0) {}
757 public:
763  static SequenceFilterPtr instance(size_t nskip, size_t rate, size_t limit) {
764  return SequenceFilterPtr(new SequenceFilter(nskip, rate, limit));
765  }
766 
774  size_t nSkip() const;
775  SequenceFilterPtr nSkip(size_t n);
786  size_t rate() const;
787  SequenceFilterPtr rate(size_t n);
798  size_t limit() const;
799  SequenceFilterPtr limit(size_t n);
807  size_t nPosted() const;
808 
809  virtual bool shouldForward(const MesgProps&) /*override*/;
810  virtual void forwarded(const MesgProps&) /*override*/ {}
811 };
812 
817 class SAWYER_EXPORT TimeFilter: public Filter {
818  double initialDelay_; // amount to delay before emitting the first message
819  double minInterval_; // minimum time between messages
820  double prevMessageTime_; // time previous message was emitted
821  double lastBakeTime_; // time cached by shouldForward, used by forwarded
822  size_t nPosted_; // number of messages posted (including those suppressed)
823 protected:
827  explicit TimeFilter(double minInterval)
828  : initialDelay_(0.0), minInterval_(minInterval), prevMessageTime_(0.0), lastBakeTime_(0.0) {}
829 public:
833  static TimeFilterPtr instance(double minInterval) {
834  return TimeFilterPtr(new TimeFilter(minInterval));
835  }
836 
845  double minInterval() const;
846  TimeFilterPtr minInterval(double d);
856  double initialDelay() const;
857  TimeFilterPtr initialDelay(double d);
865  size_t nPosted() const;
866 
867  virtual bool shouldForward(const MesgProps&) /*override*/;
868  virtual void forwarded(const MesgProps&) /*override*/;
869 };
870 
878 class SAWYER_EXPORT ImportanceFilter: public Filter {
879  bool enabled_[N_IMPORTANCE];
880 protected:
884  explicit ImportanceFilter(bool dflt) {
885  memset(enabled_, dflt?0xff:0, sizeof enabled_);
886  }
887 public:
892  static ImportanceFilterPtr instance(bool dflt) {
893  return ImportanceFilterPtr(new ImportanceFilter(dflt));
894  }
895 
903  bool enabled(Importance imp) const;
904  ImportanceFilterPtr enabled(Importance imp, bool b);
910  ImportanceFilterPtr enable(Importance);
911 
915  ImportanceFilterPtr disable(Importance);
916 
917  virtual bool shouldForward(const MesgProps&) /*override*/;
918  virtual void forwarded(const MesgProps&) /*override*/ {}
919 };
920 
922 // Support for final destinations
924 
929 class HighWater {
930  Optional<unsigned> id_;
931  MesgProps props_;
932  size_t ntext_;
933 protected:
934  mutable SAWYER_THREAD_TRAITS::RecursiveMutex mutex_;
935  HighWater(const HighWater&) { abort(); } // not copyable
936  HighWater& operator=(const HighWater&) { abort(); } // not copyable
937 public:
938  HighWater(): ntext_(0) {}
939  explicit HighWater(const Mesg &m, const MesgProps &p) { emitted(m, p); }
940  SAWYER_THREAD_TRAITS::RecursiveMutex& mutex() const { return mutex_; }
941  void emitted(const Mesg&, const MesgProps&);
942  void clear();
943  bool isValid() const;
944  unsigned id() const;
945  MesgProps properties() const;
946  size_t ntext() const;
947 };
948 
957 class Gang: public HighWater, public SharedObject {
958  // Gangs are intentionally leaked. I played with an implementation that removed them from the gangs_ map when they were
959  // destroyed (which also required a GangMap that didn't use shared pointers), but it turned out to not work. The problem
960  // is that some streams are static objects and there's no portable way to control the order that those objects are
961  // destroyed. What was happening was that boost::thread support was destroyed before the static Sawyer::Message::Stream
962  // objects, so when it came time to destroy their Gang objects we could no longer reliably lock classMutex_.
964  static GangMap *gangs_;
965  static const int TTY_GANG = -1;
966  static const int NO_GANG_ID = -2;
967  static SAWYER_THREAD_TRAITS::Mutex classMutex_;
968 protected:
969  Gang() {}
970 public:
971  static GangPtr instance();
972  static GangPtr instanceForId(int id);
973  static GangPtr instanceForTty();
974  static void shutdownNS();
975 private:
976  static GangPtr createNS(int id); // non-synchronized implementation for instance methods
977 };
978 
980 // Messages prefixes
982 
984 class SAWYER_EXPORT Prefix: public SharedObject, public SharedFromThis<Prefix> {
985 #include <Sawyer/WarningsOff.h>
986 public:
988  enum When {
989  NEVER=0,
990  SOMETIMES=1,
991  ALWAYS=2
992  };
993 private:
994  mutable SAWYER_THREAD_TRAITS::RecursiveMutex mutex_;
995  ColorSet colorSet_;
996  Optional<std::string> programName_;
997  bool showProgramName_;
998  bool showThreadId_;
999  Optional<double> startTime_;
1000  bool showElapsedTime_;
1001  When showFacilityName_;
1002  bool showImportance_;
1003  void initFromSystem();
1004 #include <Sawyer/WarningsRestore.h>
1005 protected:
1010  : showProgramName_(true), showThreadId_(true), showElapsedTime_(true), showFacilityName_(SOMETIMES),
1011  showImportance_(true) {
1012  initFromSystem();
1013  colorSet_ = ColorSet::fullColor();
1014  }
1015 public:
1016  virtual ~Prefix() {}
1017 
1022  static PrefixPtr instance() { return PrefixPtr(new Prefix); }
1023 
1027  static PrefixPtr silentInstance();
1028 
1036  const ColorSet& colorSet() const { return colorSet_; }
1037  ColorSet& colorSet() { return colorSet_; }
1050  const Optional<std::string>& programName() const { return programName_; }
1051  PrefixPtr programName(const std::string &s) { programName_ = s; return sharedFromThis(); }
1059  void setProgramName();
1060 
1069  bool showProgramName() const { return showProgramName_; }
1070  PrefixPtr showProgramName(bool b) { showProgramName_ = b; return sharedFromThis(); }
1080  bool showThreadId() const { return showThreadId_; }
1081  PrefixPtr showThreadId(bool b) { showThreadId_ = b; return sharedFromThis(); }
1093  const Optional<double> startTime() const;
1094  PrefixPtr startTime(double t);
1105  void setStartTime();
1106 
1115  bool showElapsedTime() const { return showElapsedTime_; }
1116  PrefixPtr showElapsedTime(bool b) { showElapsedTime_ = b; return sharedFromThis(); }
1127  When showFacilityName() const { return showFacilityName_; }
1128  PrefixPtr showFacilityName(When w) { showFacilityName_ = w; return sharedFromThis(); }
1138  bool showImportance() const { return showImportance_; }
1139  PrefixPtr showImportance(bool b) { showImportance_ = b; return sharedFromThis(); }
1147  virtual std::string toString(const Mesg&, const MesgProps&) const;
1148 };
1149 
1151 // Final destinations (sinks)
1153 
1157 class SAWYER_EXPORT UnformattedSink: public Destination {
1158 #include <Sawyer/WarningsOff.h>
1159  GangPtr gang_;
1160  PrefixPtr prefix_;
1161 #include <Sawyer/WarningsRestore.h>
1162 
1163 protected:
1164  bool partialMessagesAllowed_;
1165 
1166 protected:
1168  explicit UnformattedSink(const PrefixPtr &prefix): partialMessagesAllowed_(true) {
1169  gang_ = Gang::instance();
1170  prefix_ = prefix ? prefix : Prefix::instance();
1171  init();
1172  }
1173 public:
1186  GangPtr gang() const;
1187  UnformattedSinkPtr gang(const GangPtr &g);
1216  bool partialMessagesAllowed() const;
1217  UnformattedSinkPtr partialMessagesAllowed(bool);
1228  PrefixPtr prefix() const;
1229  UnformattedSinkPtr prefix(const PrefixPtr &p);
1239  virtual std::string maybeTerminatePrior(const Mesg&, const MesgProps&);
1240 
1248  virtual std::string maybePrefix(const Mesg&, const MesgProps&);
1249 
1258  virtual std::string maybeBody(const Mesg&, const MesgProps&);
1259 
1268  virtual std::string maybeFinal(const Mesg&, const MesgProps&);
1269 
1277  virtual std::string render(const Mesg&, const MesgProps&);
1278 protected:
1282  void gangInternal(const GangPtr &g);
1283 private:
1284  void init();
1285 };
1286 
1288 class SAWYER_EXPORT FdSink: public UnformattedSink {
1289  int fd_; // file descriptor or -1
1290 protected:
1292  FdSink(int fd, const PrefixPtr &prefix): UnformattedSink(prefix), fd_(fd) { init(); }
1293 public:
1295  static FdSinkPtr instance(int fd, const PrefixPtr &prefix=PrefixPtr()) {
1296  return FdSinkPtr(new FdSink(fd, prefix));
1297  }
1298 
1299  virtual void post(const Mesg&, const MesgProps&) /*override*/;
1300 private:
1301  void init();
1302 };
1303 
1305 class SAWYER_EXPORT FileSink: public UnformattedSink {
1306  FILE *file_;
1307 protected:
1309  FileSink(FILE *f, const PrefixPtr &prefix): UnformattedSink(prefix), file_(f) { init(); }
1310 public:
1312  static FileSinkPtr instance(FILE *f, const PrefixPtr &prefix=PrefixPtr()) {
1313  return FileSinkPtr(new FileSink(f, prefix));
1314  }
1315 
1316  virtual void post(const Mesg&, const MesgProps&) /*override*/;
1317 private:
1318  void init();
1319 };
1320 
1322 class SAWYER_EXPORT StreamSink: public UnformattedSink {
1323  std::ostream &stream_;
1324 protected:
1326  StreamSink(std::ostream &stream, const PrefixPtr &prefix): UnformattedSink(prefix), stream_(stream) {}
1327 public:
1329  static StreamSinkPtr instance(std::ostream &stream, const PrefixPtr &prefix=PrefixPtr()) {
1330  return StreamSinkPtr(new StreamSink(stream, prefix));
1331  }
1332 
1333  virtual void post(const Mesg&, const MesgProps&) /*override*/;
1334 };
1335 
1336 #ifndef BOOST_WINDOWS
1337 
1340 class SAWYER_EXPORT SyslogSink: public Destination {
1341 protected:
1343  SyslogSink(const char *ident, int option, int facility);
1344 public:
1348  static SyslogSinkPtr instance(const char *ident, int option, int facility) {
1349  return SyslogSinkPtr(new SyslogSink(ident, option, facility));
1350  }
1351  virtual void post(const Mesg&, const MesgProps&) /*override*/;
1352 private:
1353  void init();
1354 };
1355 #endif
1356 
1358 // Message streams
1360 
1361 class Stream;
1362 class StreamBuf;
1363 
1372 class SAWYER_EXPORT SProxy {
1373  Stream *stream_;
1374 public:
1375  SProxy(): stream_(NULL) {}
1376  SProxy(std::ostream*); /*implicit*/
1377  SProxy(std::ostream&); /*implicit*/
1378  SProxy(const SProxy&);
1379  SProxy& operator=(const SProxy&);
1380  ~SProxy() { reset(); }
1381  Stream& operator*() { return *stream_; }
1382  Stream* operator->() { return stream_; }
1383  Stream* get() const { return stream_; }
1384  operator bool() const;
1385  void reset();
1386 };
1387 
1394 class SAWYER_EXPORT Stream: public std::ostream {
1395  friend class StreamBuf;
1396  mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
1397  size_t nrefs_; // used when we don't have std::move semantics
1398  StreamBuf *streambuf_; // each stream has its own, protected by our mutex
1399 public:
1400 
1402  Stream(const std::string facilityName, Importance imp, const DestinationPtr &destination);
1403 
1405  Stream(const MesgProps &props, const DestinationPtr &destination);
1406 
1412  Stream(const Stream &other);
1413 
1419  Stream& operator=(const Stream &other);
1420 
1431  Stream(const std::ostream &other_);
1432 
1443  Stream& operator=(const std::ostream &other_);
1444 
1445  ~Stream();
1446 
1447  // used internally by SProxy; thread-safe
1448  void incrementRefCount();
1449  size_t decrementRefCount(); // returns new ref count
1450 
1454  SProxy dup() const;
1455 
1456 protected:
1463  void initFromNS(const Stream &other);
1464 
1465 public:
1469  bool enabled() const;
1470 
1471  // We'd like bool context to return a value that can't be used in arithmetic or comparison operators, but unfortunately
1472  // we need to also work with the super class (std::basic_ios) that has an implicit "void*" conversion which conflicts with
1473  // the way Sawyer normally handles this (see SharedPointer for an example). We therefore override the super-class'
1474  // void* conversion and "!" operator instead. We also need to override operator bool if there is one.
1475 
1494  operator void*() const {
1495  return enabled() ? const_cast<Stream*>(this) : NULL;
1496  }
1497 #if __cplusplus >= 201103L
1498  explicit operator bool() const {
1499  return enabled();
1500  }
1501 #else
1502  // Needed on macOS
1503  operator bool() const {
1504  return enabled();
1505  }
1506 #endif
1507 
1510  bool operator!() const { return !enabled(); }
1511 
1512  // See Stream::bool()
1513  #define SAWYER_MESG(message_stream) message_stream && message_stream
1514 
1523  void enable(bool b=true);
1524  void disable() { enable(false); }
1536  void completionString(const std::string &s, bool asDefault=true);
1537  void interruptionString(const std::string &s, bool asDefault=true);
1538  void cancelationString(const std::string &s, bool asDefault=true);
1539  void facilityName(const std::string &s, bool asDefault=true);
1549  DestinationPtr destination() const;
1550  Stream& destination(const DestinationPtr &d);
1559  MesgProps properties() const;
1560 };
1561 
1579 class SAWYER_EXPORT Facility {
1580  static const unsigned CONSTRUCTED_MAGIC = 0x73617779;
1581  unsigned constructed_;
1582  mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
1583 #include <Sawyer/WarningsOff.h>
1584  std::string name_;
1585  std::vector<SProxy> streams_;
1586 #include <Sawyer/WarningsRestore.h>
1587 
1588 public:
1594  Facility(): constructed_(CONSTRUCTED_MAGIC) {}
1595 
1599  Facility(const Facility &other);
1600 
1604  Facility& operator=(const Facility &src);
1605 
1609  explicit Facility(const std::string &name): constructed_(CONSTRUCTED_MAGIC), name_(name) {
1610  //initializeLibrary() //delay until later
1611  initStreams(FdSink::instance(2));
1612  }
1613 
1615  Facility(const std::string &name, const DestinationPtr &destination): constructed_(CONSTRUCTED_MAGIC), name_(name) {
1616  initStreams(destination);
1617  }
1618 
1619  ~Facility() {
1620  constructed_ = 0;
1621  }
1622 
1630  bool isConstructed() const { return constructed_ == CONSTRUCTED_MAGIC; }
1631 
1646  Stream& get(Importance imp);
1648  return get(imp);
1649  }
1657  std::string name() const;
1658 
1665  Facility& renameStreams(const std::string &name = "");
1666 
1673  Facility& initStreams(const DestinationPtr&);
1674 };
1675 
1688 class SAWYER_EXPORT Facilities {
1689 public:
1690  typedef std::set<Importance> ImportanceSet;
1691 private:
1693  mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
1694 #include <Sawyer/WarningsOff.h>
1695  FacilityMap facilities_;
1696  ImportanceSet impset_;
1697  bool impsetInitialized_;
1698 #include <Sawyer/WarningsRestore.h>
1699 public:
1700 
1703  //initializeLibrary(); -- delay until later for sake of static initialization of Message::mfacilities
1704  // Initialize impset_ for the sake of insertAndAdjust(), but do not consider it to be truly initialized until after
1705  // a MessageFacility is inserted.
1706  impset_.insert(WARN);
1707  impset_.insert(ERROR);
1708  impset_.insert(FATAL);
1709  impsetInitialized_ = false;
1710  }
1711 
1713  Facilities(const Facilities&);
1714 
1716  Facilities& operator=(const Facilities&);
1717 
1723  ImportanceSet impset() const;
1724 
1734  Facilities& impset(Importance, bool enabled);
1735 
1754  Facilities& insert(Facility &facility, const std::string &name="");
1755  Facilities& insertAndAdjust(Facility &facility, std::string name="");
1761  Facilities& erase(const std::string &name);
1762 
1766  Facilities& erase(Facility &facility);
1767 
1776  Facility& facility(const std::string &name) const;
1777 
1781  std::vector<std::string> facilityNames() const;
1782 
1820  std::string control(const std::string &s);
1821 
1825  std::string configuration() const;
1826 
1838  Facilities& reenable();
1839  Facilities& reenableFrom(const Facilities &other);
1851  Facilities& enable(Importance, bool b=true);
1852  Facilities& disable(Importance imp) { return enable(imp, false); }
1863  Facilities& disable(const std::string &switch_name) { return enable(switch_name, false); }
1864  Facilities& enable(const std::string &switch_name, bool b=true);
1875  Facilities& enable(bool b=true);
1876  Facilities& disable() { return enable(false); }
1883  void shutdown();
1884 
1890  void print(std::ostream&) const;
1891 
1892 private:
1894  struct ControlTerm {
1895  ControlTerm(const std::string &facilityName, bool enable)
1896  : facilityName(facilityName), lo(DEBUG), hi(DEBUG), enable(enable) {}
1897  std::string toString() const;
1898  std::string facilityName;
1899  Importance lo, hi;
1900  bool enable;
1901  };
1902 
1903  Facilities& insertNS(Facility&, std::string); // non-synchronized version
1904  Facilities& enableNS(Importance, bool); // non-synchronized version
1905 
1906  // Error information thrown internally.
1907  struct ControlError {
1908  ControlError(const std::string &mesg, const char *position): mesg(mesg), inputPosition(position) {}
1909  std::string mesg;
1910  const char *inputPosition;
1911  };
1912 
1913  // Functions used by the control() method
1914  static std::string parseFacilityName(const char* &input);
1915  static std::string parseEnablement(const char* &input);
1916  static std::string parseRelation(const char* &input);
1917  static std::string parseImportanceName(const char* &input);
1918  static Importance importanceFromString(const std::string&);
1919  static std::list<ControlTerm> parseImportanceList(const std::string &facilityName, const char* &input, bool isGlobal);
1920 
1921  // Remove Facility objects that have apparently been destroyed
1922  void eraseDestroyedNS();
1923 
1924 };
1925 
1926 
1928 
1931 SAWYER_EXPORT extern DestinationPtr merr;
1932 
1934 SAWYER_EXPORT extern Facility mlog;
1935 
1939 SAWYER_EXPORT extern Facilities mfacilities;
1940 
1949 SAWYER_EXPORT extern SProxy assertionStream;
1950 
1957 SAWYER_EXPORT void shutdown();
1958 
1959 
1961 // Facilities guard
1963 
1968 class SAWYER_EXPORT FacilitiesGuard {
1969  Facilities &facilities_;
1971  State state_;
1972 public:
1977  : facilities_(mfacilities) {
1978  save();
1979  }
1980 
1982  explicit FacilitiesGuard(Facilities &facilities)
1983  : facilities_(facilities) {
1984  save();
1985  }
1986 
1989  restore();
1990  }
1991 
1992 private:
1993  void save();
1994  void restore();
1995 };
1996 
1998 // The most commonly used stuff
2000 
2013 namespace Common {
2014 
2015 using Message::DEBUG;
2016 using Message::TRACE;
2017 using Message::WHERE;
2018 using Message::MARCH;
2019 using Message::INFO;
2020 using Message::WARN;
2021 using Message::ERROR;
2022 using Message::FATAL;
2023 
2024 using Message::Stream;
2025 using Message::Facility;
2026 using Message::Facilities;
2027 
2028 } // namespace
2029 
2030 
2031 } // namespace
2032 } // namespace
2033 
2034 #endif
PrefixPtr showImportance(bool b)
Property: whether to show the importance property.
Definition: Message.h:1139
static TimeFilterPtr instance(double minInterval)
Allocating constructor.
Definition: Message.h:833
Facilities()
Constructs an empty container of Facility objects.
Definition: Message.h:1702
std::string stringifyColor(AnsiColor)
Convert an AnsiColor enum to a string.
size_t ntext() const
Zero if !isValid().
static GangPtr instanceForId(int id)
The gang for the specified ID, creating a new one if necessary.
Messages intended to be useful primarily to the author of the code.
Definition: Message.h:311
ANSI "red" color.
Definition: Message.h:342
ImportanceFilter(bool dflt)
Constructor for derived classes.
Definition: Message.h:884
static MultiplexerPtr instance()
Allocating constructor.
Definition: Message.h:677
ANSI Color specification for text written to a terminal.
Definition: Message.h:372
ANSI "magenta" color.
Definition: Message.h:346
ColorSpec(AnsiColor fg)
Constructs an object that specifies only a foreground color.
Definition: Message.h:383
void emitted(const Mesg &, const MesgProps &)
Make specified message the high water mark.
static StreamSinkPtr instance(std::ostream &stream, const PrefixPtr &prefix=PrefixPtr())
Allocating constructor.
Definition: Message.h:1329
FacilitiesGuard(Facilities &facilities)
Saves and restores specified message facilities.
Definition: Message.h:1982
ANSI "cyan" color.
Definition: Message.h:347
MesgProps & properties()
Returns a reference to message properties.
Definition: Message.h:579
boost::tribool bold
Use ANSI "bold" attribute?
Definition: Message.h:376
FdSink(int fd, const PrefixPtr &prefix)
Constructor for derived classes.
Definition: Message.h:1292
bool showImportance() const
Property: whether to show the importance property.
Definition: Message.h:1138
Send free-format messages to a Unix file descriptor.
Definition: Message.h:1288
const MesgProps & defaultPropertiesNS() const
Default values for message properties.
Definition: Message.h:625
bool isCanceled() const
Returns true if the message has entered the canceled state.
Definition: Message.h:564
boost::tribool isBuffered
Whether the output buffered and emitted on a per-message basis.
Definition: Message.h:428
Optional< Importance > importance
The message importance level.
Definition: Message.h:427
Collection of streams.
Definition: Message.h:1579
~FacilitiesGuard()
Restores previously saved facility settings.
Definition: Message.h:1988
Facility()
Construct an empty facility.
Definition: Message.h:1594
bool isDefault() const
Returns true if this object is in its default-constructed state.
Definition: Message.h:389
std::vector< BakedDestination > BakedDestinations
Baked properties for multiple destinations.
Definition: Message.h:495
Mesg(const MesgProps &props)
Creates a new, partial message that is empty.
Definition: Message.h:534
Optional< std::string > interruptionStr
String to append when a partial message is interrupted.
Definition: Message.h:430
MesgProps overrides_
Override properties applied to incoming message.
Definition: Message.h:611
bool isValid() const
Returns true if high water is defined.
Collection of facilities.
Definition: Message.h:1688
SharedPointer< class Filter > FilterPtr
Smart pointer.
Definition: Message.h:475
Mesg(const std::string &mesg)
Creates a new, completed message with the specified text.
Definition: Message.h:538
Error messages that indicate an abnormal situation from which the program was able to at least partia...
Definition: Message.h:327
SharedPointer< class FileSink > FileSinkPtr
Smart pointer.
Definition: Message.h:483
PrefixPtr showThreadId(bool b)
Property: whether to show the thread ID in the message prefix area.
Definition: Message.h:1081
Mesg(const std::string &facilityName, Importance imp)
Creates a new, partial message that is empty.
Definition: Message.h:527
std::set< Importance > ImportanceSet
A set of importance levels.
Definition: Message.h:1690
FacilitiesGuard()
Saves and restores the global message facilities.
Definition: Message.h:1976
std::pair< DestinationPtr, MesgProps > BakedDestination
Baked properties for a destination.
Definition: Message.h:492
bool isComplete() const
Returns true if the message has entered the completed state.
Definition: Message.h:560
void clear()
Reset to initial state.
Base class for internal nodes that filter messages.
Definition: Message.h:721
Facility mlog
Facility used by Sawyer components.
Information printed at the beginning of each free-format message.
Definition: Message.h:984
TimeFilter(double minInterval)
Constructor for derived classes.
Definition: Message.h:827
unsigned id() const
Exception unless isValid().
const ColorSpec & operator[](Importance imp) const
Colors for a message.
Definition: Message.h:407
ColorSet & colorSet()
Property: colors to use for the prefix if coloring is enabled.
Definition: Message.h:1037
ColorSpec & operator[](Importance imp)
Colors for a message.
Definition: Message.h:408
Messages that indicate an abnormal situation from which the program was unable to recover...
Definition: Message.h:329
ColorSpec()
Constructs an object with default foreground and background colors.
Definition: Message.h:380
ANSI "black" color.
Definition: Message.h:341
bool isEmpty() const
Returns true if the message has no text.
Definition: Message.h:568
Filters messages based on importance level.
Definition: Message.h:878
ANSI default color.
Definition: Message.h:349
const std::string & text() const
Return the message text.
Definition: Message.h:557
Mesg()
Creates a new, partial message that is empty.
Definition: Message.h:523
Stream & operator[](Importance imp)
Returns a stream for the specified importance level.
Definition: Message.h:1647
SharedPointer< class ImportanceFilter > ImportanceFilterPtr
Smart pointer.
Definition: Message.h:478
Reference-counting smart pointer.
Definition: SharedPointer.h:34
When showFacilityName() const
Property: whether to show the facilityName property.
Definition: Message.h:1127
Name space for the entire library.
Definition: Access.h:11
boost::tribool useColor
Whether to use ANSI escape sequences to colorize output.
Definition: Message.h:433
SharedPointer< class Prefix > PrefixPtr
Smart pointer.
Definition: Message.h:480
static ImportanceFilterPtr instance(bool dflt)
Allocating constructor.
Definition: Message.h:892
Filter()
Constructor for derived classes.
Definition: Message.h:724
ANSI "white" color.
Definition: Message.h:348
SharedPointer< class SyslogSink > SyslogSinkPtr
Smart pointer.
Definition: Message.h:485
static ColorSet fullColor()
Returns a color set that uses various foreground colors for the different message importance levels...
Saves and restores facilities.
Definition: Message.h:1968
AnsiColor
Colors used by sinks that write to terminals.
Definition: Message.h:340
Sawyer::SynchronizationTraits< Sawyer::SingleThreadedTag >::RecursiveMutex mutex_
Mutex protecting data members here and in subclasses.
Definition: Message.h:609
PrefixPtr programName(const std::string &s)
Property: program name.
Definition: Message.h:1051
When
When to show something.
Definition: Message.h:988
SharedPointer< class Destination > DestinationPtr
Smart pointer.
Definition: Message.h:473
virtual void forwarded(const MesgProps &)
Called once by bakeDestinations if shouldForward() returned true.
Definition: Message.h:810
static SyslogSinkPtr instance(const char *ident, int option, int facility)
Allocating constructor.
Definition: Message.h:1348
bool isConstructed() const
Returns true if called on an object that has been constructed.
Definition: Message.h:1630
Progress reports and other similar rapidly updating partial messages.
Definition: Message.h:322
Sends messages to the syslog daemon.
Definition: Message.h:1340
unsigned id() const
Return unique message ID.
Definition: Message.h:554
PrefixPtr showElapsedTime(bool b)
Property: whether to show time deltas.
Definition: Message.h:1116
Sends incoming messages to multiple destinations.
Definition: Message.h:667
Optional< std::string > lineTermination
Line termination for completion, interruption, and cancelation.
Definition: Message.h:432
Facilities mfacilities
Library-provided facility group.
Properties for messages.
Definition: Message.h:424
Multiplexer()
Constructor for derived classes.
Definition: Message.h:674
void cancel()
Cause the message to enter the canceled state.
Definition: Message.h:587
SharedPointer< class SequenceFilter > SequenceFilterPtr
Smart pointer.
Definition: Message.h:476
MesgProps & defaultPropertiesNS()
Default values for message properties.
Definition: Message.h:626
Colors to use for each message importance.
Definition: Message.h:395
bool showElapsedTime() const
Property: whether to show time deltas.
Definition: Message.h:1115
Creates SharedPointer from this.
static void shutdownNS()
Reset to initial state to free memory.
Mesg(const std::string &facilityName, Importance imp, const std::string &mesg)
Creates a new, completed message with the specified text.
Definition: Message.h:543
const Optional< std::string > & programName() const
Property: program name.
Definition: Message.h:1050
Send free-format messages to a C FILE pointer.
Definition: Message.h:1305
void disable()
Enable or disable a stream.
Definition: Message.h:1524
ANSI "blue" color.
Definition: Message.h:345
SharedPointer< class Gang > GangPtr
Smart pointer.
Definition: Message.h:479
const ColorSet & colorSet() const
Property: colors to use for the prefix if coloring is enabled.
Definition: Message.h:1036
SharedPointer< class TimeFilter > TimeFilterPtr
Smart pointer.
Definition: Message.h:477
Facilities & disable(const std::string &switch_name)
Enable/disable a facility by name.
Definition: Message.h:1863
bool showProgramName() const
Property: whether to show the program name in the message prefix area.
Definition: Message.h:1069
static FileSinkPtr instance(FILE *f, const PrefixPtr &prefix=PrefixPtr())
Allocating constructor.
Definition: Message.h:1312
A single message.
Definition: Message.h:511
static SequenceFilterPtr instance(size_t nskip, size_t rate, size_t limit)
Construct an instance.
Definition: Message.h:763
Facilities & disable(Importance imp)
Enable/disable specific importance level across all facilities.
Definition: Message.h:1852
Importance
Level of importance for a message.
Definition: Message.h:310
void shutdown()
Reset global variables to initial states.
Filters messages based on time.
Definition: Message.h:817
SharedPointer< class FdSink > FdSinkPtr
Smart pointer.
Definition: Message.h:482
std::string stringifyImportance(Importance)
Convert an Importance enum to a string.
MesgProps dflts_
Default properties merged into each incoming message.
Definition: Message.h:610
Facility(const std::string &name, const DestinationPtr &destination)
Creates streams of all importance levels.
Definition: Message.h:1615
const MesgProps & overridePropertiesNS() const
Overrides message properties.
Definition: Message.h:637
SProxy assertionStream
The stream to be used for assertions.
FileSink(FILE *f, const PrefixPtr &prefix)
Constructor for derived classes.
Definition: Message.h:1309
Base class for all types of message destinations.
Definition: Message.h:607
Base class for reference counted objects.
Definition: SharedObject.h:22
DestinationPtr merr
Library-provided message destination.
void complete()
Cause the message to enter the completed state.
Definition: Message.h:583
Number of distinct importance levels.
Definition: Message.h:335
static FdSinkPtr instance(int fd, const PrefixPtr &prefix=PrefixPtr())
Allocating constructor.
Definition: Message.h:1295
SharedPointer< class StreamSink > StreamSinkPtr
Smart pointer.
Definition: Message.h:484
UnformattedSink(const PrefixPtr &prefix)
Constructor for derived classes.
Definition: Message.h:1168
Send free-format messages to a C++ I/O stream.
Definition: Message.h:1322
PrefixPtr showFacilityName(When w)
Property: whether to show the facilityName property.
Definition: Message.h:1128
virtual void forwarded(const MesgProps &)
Called once by bakeDestinations if shouldForward() returned true.
Definition: Message.h:918
std::string escape(const std::string &)
Convert a string to its C representation.
Warning messages that indicate an unusual situation from which the program was able to fully recover...
Definition: Message.h:325
MesgProps & overridePropertiesNS()
Overrides message properties.
Definition: Message.h:638
static PrefixPtr instance()
Allocating constructor.
Definition: Message.h:1022
Detailed tracing information useful to end-users that are trying to understand program internals...
Definition: Message.h:314
Prefix()
Constructor for derived classes.
Definition: Message.h:1009
ANSI "yellow" color.
Definition: Message.h:344
StreamSink(std::ostream &stream, const PrefixPtr &prefix)
Constructor for derived classes.
Definition: Message.h:1326
static GangPtr instanceForTty()
Returns the gang for streams that are emitting to a tty.
Facility(const std::string &name)
Create a named facility with default destinations.
Definition: Message.h:1609
std::ostream & operator<<(std::ostream &o, const MesgProps &props)
Print the values for all message properties.
const MesgProps & properties() const
Returns a reference to message properties.
Definition: Message.h:578
Optional< std::string > completionStr
String to append to the end of each complete message.
Definition: Message.h:429
double now()
Current system time in seconds.
Optional< std::string > cancelationStr
String to append to a partial message when it is destroyed.
Definition: Message.h:431
static GangPtr instance()
New non-shared gang with NO_GANG_ID.
Mesg(const MesgProps &props, const std::string &mesg)
Creates a new, completed message with the specified text.
Definition: Message.h:550
Converts text to messages.
Definition: Message.h:1394
SequenceFilter(size_t nskip, size_t rate, size_t limit)
Constructor for derived classes.
Definition: Message.h:755
ColorSpec(AnsiColor fg, AnsiColor bg, bool bold)
Constructs an object with fully-specified colors.
Definition: Message.h:386
SharedPointer< class UnformattedSink > UnformattedSinkPtr
Smart pointer.
Definition: Message.h:481
Optional< std::string > facilityName
The name of the logging facility that produced this message.
Definition: Message.h:426
Base class for final destinations that are free-format.
Definition: Message.h:1157
AnsiColor background
Background color, or COLOR_DEFAULT.
Definition: Message.h:374
PrefixPtr showProgramName(bool b)
Property: whether to show the program name in the message prefix area.
Definition: Message.h:1070
bool showThreadId() const
Property: whether to show the thread ID in the message prefix area.
Definition: Message.h:1080
ANSI "green" color.
Definition: Message.h:343
bool initializeLibrary()
Explicitly initialize the library.
Facilities & disable()
Enable/disable all facilities.
Definition: Message.h:1876
Container associating values with keys.
Definition: Sawyer/Map.h:64
Informative messages.
Definition: Message.h:323
SharedPointer< class Multiplexer > MultiplexerPtr
Smart pointer.
Definition: Message.h:474
bool operator!() const
Returns false if this stream is enabled.
Definition: Message.h:1510
AnsiColor foreground
Foreground color, or COLOR_DEFAULT.
Definition: Message.h:373
Granular tracing information useful to end-users that are trying to understand program internals...
Definition: Message.h:319
Filters messages based on how many messages have been seen.
Definition: Message.h:748