ROSE  0.10.5.0
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 <boost/regex.hpp>
21 #include <cassert>
22 #include <cstring>
23 #include <list>
24 #include <ostream>
25 #include <set>
26 #include <streambuf>
27 #include <string>
28 #include <vector>
29 
30 namespace Sawyer {
31 
276 namespace Message {
277 
285 SAWYER_EXPORT bool initializeLibrary();
286 
287 // Any header that #defines words that are this common is just plain stupid!
288 #if defined(DEBUG) || defined(TRACE) || defined(WHERE) || defined(MARCH) || \
289  defined(INFO) || defined(WARN) || defined(ERROR) || defined(FATAL)
290 # ifdef _MSC_VER
291 # pragma message("Undefining common words from the global namespace: DEBUG, TRACE, WHERE, MARCH, INFO, WARN, ERROR, FATAL")
292 # else
293 # warning "Undefining common words from the global namespace: DEBUG, TRACE, WHERE, MARCH, INFO, WARN, ERROR, FATAL"
294 # endif
295 # undef DEBUG
296 # undef TRACE
297 # undef WHERE
298 # undef MARCH
299 # undef INFO
300 # undef WARN
301 # undef ERROR
302 # undef FATAL
303 #endif
304 
339 };
340 
343 enum AnsiColor { // the values are important: they are the ANSI foreground and background color offsets
345  COLOR_RED = 1,
353 };
354 
355 
356 
358 // Functions
360 
361 SAWYER_EXPORT std::string stringifyImportance(Importance);
362 SAWYER_EXPORT std::string stringifyColor(AnsiColor);
363 SAWYER_EXPORT double now();
364 SAWYER_EXPORT std::string escape(const std::string&);
368 // Colors
371 
375 struct SAWYER_EXPORT ColorSpec {
378 #include <Sawyer/WarningsOff.h>
379  boost::tribool bold;
380 #include <Sawyer/WarningsRestore.h>
381 
383  ColorSpec(): foreground(COLOR_DEFAULT), background(COLOR_DEFAULT), bold(false) {}
384 
386  explicit ColorSpec(AnsiColor fg): foreground(fg), background(COLOR_DEFAULT), bold(false) {}
387 
389  ColorSpec(AnsiColor fg, AnsiColor bg, bool bold): foreground(fg), background(bg), bold(bold) {}
390 
392  bool isDefault() const { return COLOR_DEFAULT==foreground && COLOR_DEFAULT==background && !bold ? true : false; }
393 };
394 
398 class SAWYER_EXPORT ColorSet {
399  ColorSpec spec_[N_IMPORTANCE];
400 public:
403  static ColorSet blackAndWhite();
404 
406  static ColorSet fullColor();
407 
410  const ColorSpec& operator[](Importance imp) const { return spec_[imp]; }
411  ColorSpec& operator[](Importance imp) { return spec_[imp]; }
413 };
414 
415 
416 
418 // Message Properties
420 
427 struct SAWYER_EXPORT MesgProps {
428 #include <Sawyer/WarningsOff.h>
431  boost::tribool isBuffered;
436  boost::tribool useColor;
437 #include <Sawyer/WarningsRestore.h>
438 
439  MesgProps(): isBuffered(boost::indeterminate), useColor(boost::indeterminate) {}
440 
444  MesgProps merge(const MesgProps&) const;
445 
447  void print(std::ostream&) const;
448 };
449 
451 SAWYER_EXPORT std::ostream& operator<<(std::ostream &o, const MesgProps &props);
452 
453 
454 
456 // Type defintions
458 
495 typedef std::pair<DestinationPtr, MesgProps> BakedDestination;
496 
498 typedef std::vector<BakedDestination> BakedDestinations;
499 
500 
501 
503 // Messages
505 
514 class SAWYER_EXPORT Mesg {
515  static unsigned nextId_; // class-wide unique ID numbers
516  unsigned id_; // unique message ID
517 #include <Sawyer/WarningsOff.h>
518  std::string text_; // text of the message
519 #include <Sawyer/WarningsRestore.h>
520  bool isComplete_; // true when the message is complete
521  bool isCanceled_; // true when message is being canceled without completing
522  MesgProps props_; // message properties
523 public:
524 
527  : id_(nextId_++), isComplete_(false), isCanceled_(false) {}
528 
530  Mesg(const std::string &facilityName, Importance imp)
531  : id_(nextId_++), isComplete_(false), isCanceled_(false) {
532  props_.facilityName = facilityName;
533  props_.importance = imp;
534  }
535 
537  explicit Mesg(const MesgProps &props)
538  : id_(nextId_++), isComplete_(false), isCanceled_(false), props_(props) {}
539 
541  explicit Mesg(const std::string &mesg)
542  : id_(nextId_++), text_(mesg), isComplete_(true), isCanceled_(false) {}
543 
546  Mesg(const std::string &facilityName, Importance imp, const std::string &mesg)
547  : id_(nextId_++), text_(mesg), isComplete_(true), isCanceled_(false) {
548  props_.facilityName = facilityName;
549  props_.importance = imp;
550  }
551 
553  Mesg(const MesgProps &props, const std::string &mesg)
554  : id_(nextId_++), text_(mesg), isComplete_(true), isCanceled_(false), props_(props) {}
555 
557  unsigned id() const { return id_; }
558 
560  const std::string& text() const { return text_; }
561 
563  bool isComplete() const { return isComplete_; }
564 
567  bool isCanceled() const { return isCanceled_; }
568 
571  bool isEmpty() const { return text_.empty(); }
572 
575  bool hasText() const;
576 
581  const MesgProps& properties() const { return props_; }
582  MesgProps& properties() { return props_; }
586  void complete() { isComplete_ = true; }
587 
590  void cancel() { isCanceled_ = true; }
591 
595  void insert(const std::string&);
596  void insert(char);
600  void post(const BakedDestinations&) const;
601 };
602 
604 // Plumbing lattice nodes
606 
610 class SAWYER_EXPORT Destination: public SharedObject, public SharedFromThis<Destination> {
611 protected:
612  mutable SAWYER_THREAD_TRAITS::RecursiveMutex mutex_;
615 protected:
616  Destination() {}
617 public:
618  virtual ~Destination() {}
619 
628  const MesgProps& defaultPropertiesNS() const { return dflts_; }
629  MesgProps& defaultPropertiesNS() { return dflts_; }
640  const MesgProps& overridePropertiesNS() const { return overrides_; }
641  MesgProps& overridePropertiesNS() { return overrides_; }
651  virtual void bakeDestinations(const MesgProps&, BakedDestinations &baked);
652 
655  virtual void post(const Mesg&, const MesgProps &bakedProperties) = 0;
656 
664  MesgProps mergePropertiesNS(const MesgProps &props);
665 };
666 
670 class SAWYER_EXPORT Multiplexer: public Destination {
671  typedef std::list<DestinationPtr> Destinations;
672 #include <Sawyer/WarningsOff.h>
673  Destinations destinations_;
674 #include <Sawyer/WarningsRestore.h>
675 protected:
678 public:
680  static MultiplexerPtr instance() { return MultiplexerPtr(new Multiplexer); }
681 
682  virtual void bakeDestinations(const MesgProps&, BakedDestinations&) /*override*/;
683  virtual void post(const Mesg&, const MesgProps&) /*override*/;
684 
693  MultiplexerPtr addDestination(const DestinationPtr&);
694 
700  MultiplexerPtr removeDestination(const DestinationPtr&);
701 
709  MultiplexerPtr to(const DestinationPtr&); // more convenient form of addDestination()
710  MultiplexerPtr to(const DestinationPtr&, const DestinationPtr&);
711  MultiplexerPtr to(const DestinationPtr&, const DestinationPtr&, const DestinationPtr&);
712  MultiplexerPtr to(const DestinationPtr&, const DestinationPtr&, const DestinationPtr&, const DestinationPtr&);
714 };
715 
717 // Filters
719 
724 class SAWYER_EXPORT Filter: public Multiplexer {
725 protected:
727  Filter() {}
728 public:
729  virtual void bakeDestinations(const MesgProps&, BakedDestinations&) /*override*/;
730 
739  virtual bool shouldForward(const MesgProps&) = 0; // return true if message should be forwarded to children when baking
740 
744  virtual void forwarded(const MesgProps&) = 0; // message was forwarded to children
745 };
746 
751 class SAWYER_EXPORT SequenceFilter: public Filter {
752  size_t nSkip_; // skip initial messages posted to this sequencer
753  size_t rate_; // emit only 1/Nth of the messages (0 and 1 both mean every message)
754  size_t limit_; // emit at most this many messages (0 means infinite)
755  size_t nPosted_; // number of messages posted (including those suppressed)
756 protected:
758  SequenceFilter(size_t nskip, size_t rate, size_t limit)
759  : nSkip_(nskip), rate_(rate), limit_(limit), nPosted_(0) {}
760 public:
766  static SequenceFilterPtr instance(size_t nskip, size_t rate, size_t limit) {
767  return SequenceFilterPtr(new SequenceFilter(nskip, rate, limit));
768  }
769 
777  size_t nSkip() const;
778  SequenceFilterPtr nSkip(size_t n);
789  size_t rate() const;
790  SequenceFilterPtr rate(size_t n);
801  size_t limit() const;
802  SequenceFilterPtr limit(size_t n);
810  size_t nPosted() const;
811 
812  virtual bool shouldForward(const MesgProps&) /*override*/;
813  virtual void forwarded(const MesgProps&) /*override*/ {}
814 };
815 
820 class SAWYER_EXPORT TimeFilter: public Filter {
821  double initialDelay_; // amount to delay before emitting the first message
822  double minInterval_; // minimum time between messages
823  double prevMessageTime_; // time previous message was emitted
824  double lastBakeTime_; // time cached by shouldForward, used by forwarded
825  size_t nPosted_; // number of messages posted (including those suppressed)
826 protected:
830  explicit TimeFilter(double minInterval)
831  : initialDelay_(0.0), minInterval_(minInterval), prevMessageTime_(0.0), lastBakeTime_(0.0) {}
832 public:
836  static TimeFilterPtr instance(double minInterval) {
837  return TimeFilterPtr(new TimeFilter(minInterval));
838  }
839 
848  double minInterval() const;
849  TimeFilterPtr minInterval(double d);
859  double initialDelay() const;
860  TimeFilterPtr initialDelay(double d);
868  size_t nPosted() const;
869 
870  virtual bool shouldForward(const MesgProps&) /*override*/;
871  virtual void forwarded(const MesgProps&) /*override*/;
872 };
873 
881 class SAWYER_EXPORT ImportanceFilter: public Filter {
882  bool enabled_[N_IMPORTANCE];
883 protected:
887  explicit ImportanceFilter(bool dflt) {
888  memset(enabled_, dflt?0xff:0, sizeof enabled_);
889  }
890 public:
895  static ImportanceFilterPtr instance(bool dflt) {
896  return ImportanceFilterPtr(new ImportanceFilter(dflt));
897  }
898 
906  bool enabled(Importance imp) const;
907  ImportanceFilterPtr enabled(Importance imp, bool b);
913  ImportanceFilterPtr enable(Importance);
914 
918  ImportanceFilterPtr disable(Importance);
919 
920  virtual bool shouldForward(const MesgProps&) /*override*/;
921  virtual void forwarded(const MesgProps&) /*override*/ {}
922 };
923 
925 // Support for final destinations
927 
932 class HighWater {
933  Optional<unsigned> id_;
934  MesgProps props_;
935  size_t ntext_;
936 protected:
937  mutable SAWYER_THREAD_TRAITS::RecursiveMutex mutex_;
938  HighWater(const HighWater&) { abort(); } // not copyable
939  HighWater& operator=(const HighWater&) { abort(); } // not copyable
940 public:
941  HighWater(): ntext_(0) {}
942  explicit HighWater(const Mesg &m, const MesgProps &p) { emitted(m, p); }
943  SAWYER_THREAD_TRAITS::RecursiveMutex& mutex() const { return mutex_; }
944  void emitted(const Mesg&, const MesgProps&);
945  void clear();
946  bool isValid() const;
947  unsigned id() const;
948  MesgProps properties() const;
949  size_t ntext() const;
950 };
951 
960 class Gang: public HighWater, public SharedObject {
961  // Gangs are intentionally leaked. I played with an implementation that removed them from the gangs_ map when they were
962  // destroyed (which also required a GangMap that didn't use shared pointers), but it turned out to not work. The problem
963  // is that some streams are static objects and there's no portable way to control the order that those objects are
964  // destroyed. What was happening was that boost::thread support was destroyed before the static Sawyer::Message::Stream
965  // objects, so when it came time to destroy their Gang objects we could no longer reliably lock classMutex_.
967  static GangMap *gangs_;
968  static const int TTY_GANG = -1;
969  static const int NO_GANG_ID = -2;
970  static SAWYER_THREAD_TRAITS::Mutex classMutex_;
971 protected:
972  Gang() {}
973 public:
974  static GangPtr instance();
975  static GangPtr instanceForId(int id);
976  static GangPtr instanceForTty();
977  static void shutdownNS();
978 private:
979  static GangPtr createNS(int id); // non-synchronized implementation for instance methods
980 };
981 
983 // Messages prefixes
985 
987 class SAWYER_EXPORT Prefix: public SharedObject, public SharedFromThis<Prefix> {
988 #include <Sawyer/WarningsOff.h>
989 public:
991  enum When {
992  NEVER=0,
993  SOMETIMES=1,
994  ALWAYS=2
995  };
996 private:
997  mutable SAWYER_THREAD_TRAITS::RecursiveMutex mutex_;
998  ColorSet colorSet_;
999  Optional<std::string> programName_;
1000  bool showProgramName_;
1001  bool showThreadId_;
1002  Optional<double> startTime_;
1003  bool showElapsedTime_;
1004  When showFacilityName_;
1005  bool showImportance_;
1006  void initFromSystem();
1007 #include <Sawyer/WarningsRestore.h>
1008 protected:
1013  : showProgramName_(true), showThreadId_(true), showElapsedTime_(true), showFacilityName_(SOMETIMES),
1014  showImportance_(true) {
1015  initFromSystem();
1016  colorSet_ = ColorSet::fullColor();
1017  }
1018 public:
1019  virtual ~Prefix() {}
1020 
1025  static PrefixPtr instance() { return PrefixPtr(new Prefix); }
1026 
1030  static PrefixPtr silentInstance();
1031 
1039  const ColorSet& colorSet() const { return colorSet_; }
1040  ColorSet& colorSet() { return colorSet_; }
1053  const Optional<std::string>& programName() const { return programName_; }
1054  PrefixPtr programName(const std::string &s) { programName_ = s; return sharedFromThis(); }
1062  void setProgramName();
1063 
1072  bool showProgramName() const { return showProgramName_; }
1073  PrefixPtr showProgramName(bool b) { showProgramName_ = b; return sharedFromThis(); }
1083  bool showThreadId() const { return showThreadId_; }
1084  PrefixPtr showThreadId(bool b) { showThreadId_ = b; return sharedFromThis(); }
1096  const Optional<double> startTime() const;
1097  PrefixPtr startTime(double t);
1108  void setStartTime();
1109 
1118  bool showElapsedTime() const { return showElapsedTime_; }
1119  PrefixPtr showElapsedTime(bool b) { showElapsedTime_ = b; return sharedFromThis(); }
1130  When showFacilityName() const { return showFacilityName_; }
1131  PrefixPtr showFacilityName(When w) { showFacilityName_ = w; return sharedFromThis(); }
1141  bool showImportance() const { return showImportance_; }
1142  PrefixPtr showImportance(bool b) { showImportance_ = b; return sharedFromThis(); }
1150  virtual std::string toString(const Mesg&, const MesgProps&) const;
1151 };
1152 
1154 // Final destinations (sinks)
1156 
1160 class SAWYER_EXPORT UnformattedSink: public Destination {
1161 #include <Sawyer/WarningsOff.h>
1162  GangPtr gang_;
1163  PrefixPtr prefix_;
1164 #include <Sawyer/WarningsRestore.h>
1165 
1166 protected:
1167  bool partialMessagesAllowed_;
1168 
1169 protected:
1171  explicit UnformattedSink(const PrefixPtr &prefix): partialMessagesAllowed_(true) {
1172  gang_ = Gang::instance();
1173  prefix_ = prefix ? prefix : Prefix::instance();
1174  init();
1175  }
1176 public:
1189  GangPtr gang() const;
1190  UnformattedSinkPtr gang(const GangPtr &g);
1219  bool partialMessagesAllowed() const;
1220  UnformattedSinkPtr partialMessagesAllowed(bool);
1231  PrefixPtr prefix() const;
1232  UnformattedSinkPtr prefix(const PrefixPtr &p);
1242  virtual std::string maybeTerminatePrior(const Mesg&, const MesgProps&);
1243 
1251  virtual std::string maybePrefix(const Mesg&, const MesgProps&);
1252 
1261  virtual std::string maybeBody(const Mesg&, const MesgProps&);
1262 
1271  virtual std::string maybeFinal(const Mesg&, const MesgProps&);
1272 
1280  virtual std::string render(const Mesg&, const MesgProps&);
1281 protected:
1285  void gangInternal(const GangPtr &g);
1286 private:
1287  void init();
1288 };
1289 
1291 class SAWYER_EXPORT FdSink: public UnformattedSink {
1292  int fd_; // file descriptor or -1
1293 protected:
1295  FdSink(int fd, const PrefixPtr &prefix): UnformattedSink(prefix), fd_(fd) { init(); }
1296 public:
1298  static FdSinkPtr instance(int fd, const PrefixPtr &prefix=PrefixPtr()) {
1299  return FdSinkPtr(new FdSink(fd, prefix));
1300  }
1301 
1302  virtual void post(const Mesg&, const MesgProps&) /*override*/;
1303 private:
1304  void init();
1305 };
1306 
1308 class SAWYER_EXPORT FileSink: public UnformattedSink {
1309  FILE *file_;
1310 protected:
1312  FileSink(FILE *f, const PrefixPtr &prefix): UnformattedSink(prefix), file_(f) { init(); }
1313 public:
1315  static FileSinkPtr instance(FILE *f, const PrefixPtr &prefix=PrefixPtr()) {
1316  return FileSinkPtr(new FileSink(f, prefix));
1317  }
1318 
1319  virtual void post(const Mesg&, const MesgProps&) /*override*/;
1320 private:
1321  void init();
1322 };
1323 
1325 class SAWYER_EXPORT StreamSink: public UnformattedSink {
1326  std::ostream &stream_;
1327 protected:
1329  StreamSink(std::ostream &stream, const PrefixPtr &prefix): UnformattedSink(prefix), stream_(stream) {}
1330 public:
1332  static StreamSinkPtr instance(std::ostream &stream, const PrefixPtr &prefix=PrefixPtr()) {
1333  return StreamSinkPtr(new StreamSink(stream, prefix));
1334  }
1335 
1336  virtual void post(const Mesg&, const MesgProps&) /*override*/;
1337 };
1338 
1339 #ifndef BOOST_WINDOWS
1340 
1343 class SAWYER_EXPORT SyslogSink: public Destination {
1344 protected:
1346  SyslogSink(const char *ident, int option, int facility);
1347 public:
1351  static SyslogSinkPtr instance(const char *ident, int option, int facility) {
1352  return SyslogSinkPtr(new SyslogSink(ident, option, facility));
1353  }
1354  virtual void post(const Mesg&, const MesgProps&) /*override*/;
1355 private:
1356  void init();
1357 };
1358 #endif
1359 
1361 // Message streams
1363 
1364 class Stream;
1365 class StreamBuf;
1366 
1375 class SAWYER_EXPORT SProxy {
1376  Stream *stream_;
1377 public:
1378  SProxy(): stream_(NULL) {}
1379  SProxy(std::ostream*); /*implicit*/
1380  SProxy(std::ostream&); /*implicit*/
1381  SProxy(const SProxy&);
1382  SProxy& operator=(const SProxy&);
1383  ~SProxy() { reset(); }
1384  Stream& operator*() { return *stream_; }
1385  Stream* operator->() { return stream_; }
1386  Stream* get() const { return stream_; }
1387  operator bool() const;
1388  void reset();
1389 };
1390 
1397 class SAWYER_EXPORT Stream: public std::ostream {
1398  friend class StreamBuf;
1399  mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
1400  size_t nrefs_; // used when we don't have std::move semantics
1401  StreamBuf *streambuf_; // each stream has its own, protected by our mutex
1402 public:
1403 
1405  Stream(const std::string facilityName, Importance imp, const DestinationPtr &destination);
1406 
1408  Stream(const MesgProps &props, const DestinationPtr &destination);
1409 
1415  Stream(const Stream &other);
1416 
1422  Stream& operator=(const Stream &other);
1423 
1434  Stream(const std::ostream &other_);
1435 
1446  Stream& operator=(const std::ostream &other_);
1447 
1448  ~Stream();
1449 
1450  // used internally by SProxy; thread-safe
1451  void incrementRefCount();
1452  size_t decrementRefCount(); // returns new ref count
1453 
1457  SProxy dup() const;
1458 
1459 protected:
1466  void initFromNS(const Stream &other);
1467 
1468 public:
1472  bool enabled() const;
1473 
1474  // We'd like bool context to return a value that can't be used in arithmetic or comparison operators, but unfortunately
1475  // we need to also work with the super class (std::basic_ios) that has an implicit "void*" conversion which conflicts with
1476  // the way Sawyer normally handles this (see SharedPointer for an example). We therefore override the super-class'
1477  // void* conversion and "!" operator instead. We also need to override operator bool if there is one.
1478 
1507  operator void*() const {
1508  return enabled() ? const_cast<Stream*>(this) : NULL;
1509  }
1510 #if __cplusplus >= 201103L
1511  explicit operator bool() const {
1512  return enabled();
1513  }
1514 #else
1515  // Needed on macOS
1516  operator bool() const {
1517  return enabled();
1518  }
1519 #endif
1520 
1523  bool operator!() const { return !enabled(); }
1524 
1525  // See Stream::bool()
1526  #define SAWYER_MESG(message_stream) (message_stream) && (message_stream)
1527  #define SAWYER_MSG(message_stream) (message_stream) && (message_stream)
1528  #define SAWYER_MESG_OR(s1, s2) ((s1) || (s2)) && ((s1) ? (s1) : (s2))
1529  #define SAWYER_MSG_OR(s1, s2) ((s1) || (s2)) && ((s1) ? (s1) : (s2))
1530 
1531 
1540  void enable(bool b=true);
1541  void disable() { enable(false); }
1553  void completionString(const std::string &s, bool asDefault=true);
1554  void interruptionString(const std::string &s, bool asDefault=true);
1555  void cancelationString(const std::string &s, bool asDefault=true);
1556  void facilityName(const std::string &s, bool asDefault=true);
1566  DestinationPtr destination() const;
1567  Stream& destination(const DestinationPtr &d);
1576  MesgProps properties() const;
1577 };
1578 
1600 class SAWYER_EXPORT Facility {
1601  static const unsigned CONSTRUCTED_MAGIC = 0x73617779;
1602  unsigned constructed_;
1603  mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
1604 #include <Sawyer/WarningsOff.h>
1605  std::string name_, comment_;
1606  std::vector<SProxy> streams_;
1607 #include <Sawyer/WarningsRestore.h>
1608 
1609 public:
1615  Facility(): constructed_(CONSTRUCTED_MAGIC) {}
1616 
1620  Facility(const Facility &other);
1621 
1625  Facility& operator=(const Facility &src);
1626 
1627  Facility(const std::string &name, const DestinationPtr &destination): constructed_(CONSTRUCTED_MAGIC), name_(name) {
1628  initStreams(destination);
1629  }
1630 
1631  ~Facility() {
1632  constructed_ = 0;
1633  }
1634 
1638  Facility& initialize(const std::string &name);
1639 
1641  Facility& initialize(const std::string &name, const DestinationPtr &destination);
1642 
1650  bool isConstructed() const { return constructed_ == CONSTRUCTED_MAGIC; }
1651 
1666  Stream& get(Importance imp);
1668  return get(imp);
1669  }
1675  static bool isValidName(const std::string&);
1676 
1682  std::string name() const;
1683 
1692  std::string comment() const;
1693  Facility& comment(const std::string&);
1702  Facility& renameStreams(const std::string &name = "");
1703 
1710  Facility& initStreams(const DestinationPtr&);
1711 
1712 protected:
1713  // Parse a name into a vector of components. Returns an empty vector if the name is not valid.
1714  static std::vector<std::string> parseName(const std::string&);
1715 
1716 };
1717 
1730 class SAWYER_EXPORT Facilities {
1731 public:
1732  typedef std::set<Importance> ImportanceSet;
1733 private:
1735  mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
1736 #include <Sawyer/WarningsOff.h>
1737  FacilityMap facilities_;
1738  ImportanceSet impset_;
1739  bool impsetInitialized_;
1740 #include <Sawyer/WarningsRestore.h>
1741 public:
1742 
1745  //initializeLibrary(); -- delay until later for sake of static initialization of Message::mfacilities
1746  // Initialize impset_ for the sake of insertAndAdjust(), but do not consider it to be truly initialized until after
1747  // a MessageFacility is inserted.
1748  impset_.insert(WARN);
1749  impset_.insert(ERROR);
1750  impset_.insert(FATAL);
1751  impsetInitialized_ = false;
1752  }
1753 
1755  Facilities(const Facilities&);
1756 
1758  Facilities& operator=(const Facilities&);
1759 
1765  ImportanceSet impset() const;
1766 
1776  Facilities& impset(Importance, bool enabled);
1777 
1796  Facilities& insert(Facility &facility, const std::string &name="");
1797  Facilities& insertAndAdjust(Facility &facility, std::string name="");
1803  Facilities& erase(const std::string &name);
1804 
1808  Facilities& erase(Facility &facility);
1809 
1818  Facility& facility(const std::string &name) const;
1819 
1823  std::vector<std::string> facilityNames() const;
1824 
1862  std::string control(const std::string &s);
1863 
1867  std::string configuration() const;
1868 
1880  Facilities& reenable();
1881  Facilities& reenableFrom(const Facilities &other);
1893  Facilities& enable(Importance, bool b=true);
1894  Facilities& disable(Importance imp) { return enable(imp, false); }
1905  Facilities& disable(const std::string &switch_name) { return enable(switch_name, false); }
1906  Facilities& enable(const std::string &switch_name, bool b=true);
1917  Facilities& enable(bool b=true);
1918  Facilities& disable() { return enable(false); }
1925  void shutdown();
1926 
1932  void print(std::ostream&) const;
1933 
1934 private:
1936  struct ControlTerm {
1937  ControlTerm(const boost::regex &facilityNamePattern, bool enable)
1938  : facilityNamePattern(facilityNamePattern), lo(DEBUG), hi(DEBUG), enable(enable) {}
1939  std::string toString() const;
1940  boost::regex facilityNamePattern;
1941  Importance lo, hi;
1942  bool enable;
1943  };
1944 
1945  Facilities& insertNS(Facility&, std::string); // non-synchronized version
1946  Facilities& enableNS(Importance, bool); // non-synchronized version
1947 
1948  // Error information thrown internally.
1949  struct ControlError {
1950  ControlError(const std::string &mesg, const char *position): mesg(mesg), inputPosition(position) {}
1951  std::string mesg;
1952  const char *inputPosition;
1953  };
1954 
1955  // Functions used by the control() method
1956  static boost::regex parseFacilityNamePattern(const char* &input);
1957  static std::string parseEnablement(const char* &input);
1958  static std::string parseRelation(const char* &input);
1959  static std::string parseImportanceName(const char* &input);
1960  static Importance importanceFromString(const std::string&);
1961  static std::list<ControlTerm> parseImportanceList(const boost::regex &facilityNamePattern, const char* &input, bool isGlobal);
1962 
1963  // Remove Facility objects that have apparently been destroyed
1964  void eraseDestroyedNS();
1965 
1966  // Return the list of facilities whose name matches the pattern.
1967  std::vector<Facility*> matchingFacilitiesNS(const boost::regex &namePattern) const;
1968 };
1969 
1970 
1972 
1975 SAWYER_EXPORT extern DestinationPtr merr;
1976 
1978 SAWYER_EXPORT extern Facility mlog;
1979 
1983 SAWYER_EXPORT extern Facilities mfacilities;
1984 
1993 SAWYER_EXPORT extern SProxy assertionStream;
1994 
2001 SAWYER_EXPORT void shutdown();
2002 
2003 
2005 // Facilities guard
2007 
2012 class SAWYER_EXPORT FacilitiesGuard {
2013  Facilities &facilities_;
2015  State state_;
2016 public:
2021  : facilities_(mfacilities) {
2022  save();
2023  }
2024 
2026  explicit FacilitiesGuard(Facilities &facilities)
2027  : facilities_(facilities) {
2028  save();
2029  }
2030 
2033  restore();
2034  }
2035 
2036 private:
2037  void save();
2038  void restore();
2039 };
2040 
2042 // The most commonly used stuff
2044 
2057 namespace Common {
2058 
2059 using Message::DEBUG;
2060 using Message::TRACE;
2061 using Message::WHERE;
2062 using Message::MARCH;
2063 using Message::INFO;
2064 using Message::WARN;
2065 using Message::ERROR;
2066 using Message::FATAL;
2067 
2068 using Message::Stream;
2069 using Message::Facility;
2070 using Message::Facilities;
2071 
2072 } // namespace
2073 
2074 
2075 } // namespace
2076 } // namespace
2077 
2078 #endif
PrefixPtr showImportance(bool b)
Property: whether to show the importance property.
Definition: Message.h:1142
static TimeFilterPtr instance(double minInterval)
Allocating constructor.
Definition: Message.h:836
Facilities()
Constructs an empty container of Facility objects.
Definition: Message.h:1744
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:314
ANSI "red" color.
Definition: Message.h:345
ImportanceFilter(bool dflt)
Constructor for derived classes.
Definition: Message.h:887
static MultiplexerPtr instance()
Allocating constructor.
Definition: Message.h:680
ANSI Color specification for text written to a terminal.
Definition: Message.h:375
ANSI "magenta" color.
Definition: Message.h:349
ColorSpec(AnsiColor fg)
Constructs an object that specifies only a foreground color.
Definition: Message.h:386
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:1332
FacilitiesGuard(Facilities &facilities)
Saves and restores specified message facilities.
Definition: Message.h:2026
ANSI "cyan" color.
Definition: Message.h:350
MesgProps & properties()
Returns a reference to message properties.
Definition: Message.h:582
boost::tribool bold
Use ANSI "bold" attribute?
Definition: Message.h:379
FdSink(int fd, const PrefixPtr &prefix)
Constructor for derived classes.
Definition: Message.h:1295
bool showImportance() const
Property: whether to show the importance property.
Definition: Message.h:1141
Send free-format messages to a Unix file descriptor.
Definition: Message.h:1291
const MesgProps & defaultPropertiesNS() const
Default values for message properties.
Definition: Message.h:628
bool isCanceled() const
Returns true if the message has entered the canceled state.
Definition: Message.h:567
boost::tribool isBuffered
Whether the output buffered and emitted on a per-message basis.
Definition: Message.h:431
Optional< Importance > importance
The message importance level.
Definition: Message.h:430
Collection of streams.
Definition: Message.h:1600
~FacilitiesGuard()
Restores previously saved facility settings.
Definition: Message.h:2032
Facility()
Construct an empty facility.
Definition: Message.h:1615
bool isDefault() const
Returns true if this object is in its default-constructed state.
Definition: Message.h:392
std::vector< BakedDestination > BakedDestinations
Baked properties for multiple destinations.
Definition: Message.h:498
Mesg(const MesgProps &props)
Creates a new, partial message that is empty.
Definition: Message.h:537
Optional< std::string > interruptionStr
String to append when a partial message is interrupted.
Definition: Message.h:433
MesgProps overrides_
Override properties applied to incoming message.
Definition: Message.h:614
bool isValid() const
Returns true if high water is defined.
Collection of facilities.
Definition: Message.h:1730
SharedPointer< class Filter > FilterPtr
Smart pointer.
Definition: Message.h:478
Mesg(const std::string &mesg)
Creates a new, completed message with the specified text.
Definition: Message.h:541
Error messages that indicate an abnormal situation from which the program was able to at least partia...
Definition: Message.h:330
SharedPointer< class FileSink > FileSinkPtr
Smart pointer.
Definition: Message.h:486
PrefixPtr showThreadId(bool b)
Property: whether to show the thread ID in the message prefix area.
Definition: Message.h:1084
Mesg(const std::string &facilityName, Importance imp)
Creates a new, partial message that is empty.
Definition: Message.h:530
std::set< Importance > ImportanceSet
A set of importance levels.
Definition: Message.h:1732
FacilitiesGuard()
Saves and restores the global message facilities.
Definition: Message.h:2020
std::pair< DestinationPtr, MesgProps > BakedDestination
Baked properties for a destination.
Definition: Message.h:495
bool isComplete() const
Returns true if the message has entered the completed state.
Definition: Message.h:563
void clear()
Reset to initial state.
Base class for internal nodes that filter messages.
Definition: Message.h:724
Facility mlog
Facility used by Sawyer components.
Information printed at the beginning of each free-format message.
Definition: Message.h:987
TimeFilter(double minInterval)
Constructor for derived classes.
Definition: Message.h:830
unsigned id() const
Exception unless isValid().
const ColorSpec & operator[](Importance imp) const
Colors for a message.
Definition: Message.h:410
ColorSet & colorSet()
Property: colors to use for the prefix if coloring is enabled.
Definition: Message.h:1040
ColorSpec & operator[](Importance imp)
Colors for a message.
Definition: Message.h:411
Messages that indicate an abnormal situation from which the program was unable to recover...
Definition: Message.h:332
ColorSpec()
Constructs an object with default foreground and background colors.
Definition: Message.h:383
ANSI "black" color.
Definition: Message.h:344
bool isEmpty() const
Returns true if the message has no text.
Definition: Message.h:571
Filters messages based on importance level.
Definition: Message.h:881
ANSI default color.
Definition: Message.h:352
const std::string & text() const
Return the message text.
Definition: Message.h:560
Mesg()
Creates a new, partial message that is empty.
Definition: Message.h:526
Stream & operator[](Importance imp)
Returns a stream for the specified importance level.
Definition: Message.h:1667
SharedPointer< class ImportanceFilter > ImportanceFilterPtr
Smart pointer.
Definition: Message.h:481
Reference-counting smart pointer.
Definition: SharedPointer.h:67
When showFacilityName() const
Property: whether to show the facilityName property.
Definition: Message.h:1130
Name space for the entire library.
boost::tribool useColor
Whether to use ANSI escape sequences to colorize output.
Definition: Message.h:436
SharedPointer< class Prefix > PrefixPtr
Smart pointer.
Definition: Message.h:483
static ImportanceFilterPtr instance(bool dflt)
Allocating constructor.
Definition: Message.h:895
Filter()
Constructor for derived classes.
Definition: Message.h:727
ANSI "white" color.
Definition: Message.h:351
SharedPointer< class SyslogSink > SyslogSinkPtr
Smart pointer.
Definition: Message.h:488
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:2012
AnsiColor
Colors used by sinks that write to terminals.
Definition: Message.h:343
Sawyer::SynchronizationTraits< Sawyer::SingleThreadedTag >::RecursiveMutex mutex_
Mutex protecting data members here and in subclasses.
Definition: Message.h:612
PrefixPtr programName(const std::string &s)
Property: program name.
Definition: Message.h:1054
When
When to show something.
Definition: Message.h:991
SharedPointer< class Destination > DestinationPtr
Smart pointer.
Definition: Message.h:476
virtual void forwarded(const MesgProps &)
Called once by bakeDestinations if shouldForward() returned true.
Definition: Message.h:813
static SyslogSinkPtr instance(const char *ident, int option, int facility)
Allocating constructor.
Definition: Message.h:1351
bool isConstructed() const
Returns true if called on an object that has been constructed.
Definition: Message.h:1650
Progress reports and other similar rapidly updating partial messages.
Definition: Message.h:325
Sends messages to the syslog daemon.
Definition: Message.h:1343
unsigned id() const
Return unique message ID.
Definition: Message.h:557
PrefixPtr showElapsedTime(bool b)
Property: whether to show time deltas.
Definition: Message.h:1119
Sends incoming messages to multiple destinations.
Definition: Message.h:670
Optional< std::string > lineTermination
Line termination for completion, interruption, and cancelation.
Definition: Message.h:435
Facilities mfacilities
Library-provided facility group.
Properties for messages.
Definition: Message.h:427
Multiplexer()
Constructor for derived classes.
Definition: Message.h:677
void cancel()
Cause the message to enter the canceled state.
Definition: Message.h:590
SharedPointer< class SequenceFilter > SequenceFilterPtr
Smart pointer.
Definition: Message.h:479
MesgProps & defaultPropertiesNS()
Default values for message properties.
Definition: Message.h:629
Colors to use for each message importance.
Definition: Message.h:398
bool showElapsedTime() const
Property: whether to show time deltas.
Definition: Message.h:1118
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:546
const Optional< std::string > & programName() const
Property: program name.
Definition: Message.h:1053
Send free-format messages to a C FILE pointer.
Definition: Message.h:1308
void disable()
Enable or disable a stream.
Definition: Message.h:1541
ANSI "blue" color.
Definition: Message.h:348
SharedPointer< class Gang > GangPtr
Smart pointer.
Definition: Message.h:482
const ColorSet & colorSet() const
Property: colors to use for the prefix if coloring is enabled.
Definition: Message.h:1039
SharedPointer< class TimeFilter > TimeFilterPtr
Smart pointer.
Definition: Message.h:480
Facilities & disable(const std::string &switch_name)
Enable/disable a facility by name.
Definition: Message.h:1905
bool showProgramName() const
Property: whether to show the program name in the message prefix area.
Definition: Message.h:1072
static FileSinkPtr instance(FILE *f, const PrefixPtr &prefix=PrefixPtr())
Allocating constructor.
Definition: Message.h:1315
A single message.
Definition: Message.h:514
static SequenceFilterPtr instance(size_t nskip, size_t rate, size_t limit)
Construct an instance.
Definition: Message.h:766
Facilities & disable(Importance imp)
Enable/disable specific importance level across all facilities.
Definition: Message.h:1894
Importance
Level of importance for a message.
Definition: Message.h:313
void shutdown()
Reset global variables to initial states.
Filters messages based on time.
Definition: Message.h:820
SharedPointer< class FdSink > FdSinkPtr
Smart pointer.
Definition: Message.h:485
std::string stringifyImportance(Importance)
Convert an Importance enum to a string.
MesgProps dflts_
Default properties merged into each incoming message.
Definition: Message.h:613
const MesgProps & overridePropertiesNS() const
Overrides message properties.
Definition: Message.h:640
SProxy assertionStream
The stream to be used for assertions.
FileSink(FILE *f, const PrefixPtr &prefix)
Constructor for derived classes.
Definition: Message.h:1312
Base class for all types of message destinations.
Definition: Message.h:610
Base class for reference counted objects.
Definition: SharedObject.h:64
DestinationPtr merr
Library-provided message destination.
void complete()
Cause the message to enter the completed state.
Definition: Message.h:586
Number of distinct importance levels.
Definition: Message.h:338
static FdSinkPtr instance(int fd, const PrefixPtr &prefix=PrefixPtr())
Allocating constructor.
Definition: Message.h:1298
SharedPointer< class StreamSink > StreamSinkPtr
Smart pointer.
Definition: Message.h:487
UnformattedSink(const PrefixPtr &prefix)
Constructor for derived classes.
Definition: Message.h:1171
Send free-format messages to a C++ I/O stream.
Definition: Message.h:1325
PrefixPtr showFacilityName(When w)
Property: whether to show the facilityName property.
Definition: Message.h:1131
virtual void forwarded(const MesgProps &)
Called once by bakeDestinations if shouldForward() returned true.
Definition: Message.h:921
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:328
MesgProps & overridePropertiesNS()
Overrides message properties.
Definition: Message.h:641
static PrefixPtr instance()
Allocating constructor.
Definition: Message.h:1025
Detailed tracing information useful to end-users that are trying to understand program internals...
Definition: Message.h:317
Prefix()
Constructor for derived classes.
Definition: Message.h:1012
ANSI "yellow" color.
Definition: Message.h:347
StreamSink(std::ostream &stream, const PrefixPtr &prefix)
Constructor for derived classes.
Definition: Message.h:1329
static GangPtr instanceForTty()
Returns the gang for streams that are emitting to a tty.
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:581
Optional< std::string > completionStr
String to append to the end of each complete message.
Definition: Message.h:432
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:434
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:553
Converts text to messages.
Definition: Message.h:1397
SequenceFilter(size_t nskip, size_t rate, size_t limit)
Constructor for derived classes.
Definition: Message.h:758
ColorSpec(AnsiColor fg, AnsiColor bg, bool bold)
Constructs an object with fully-specified colors.
Definition: Message.h:389
SharedPointer< class UnformattedSink > UnformattedSinkPtr
Smart pointer.
Definition: Message.h:484
Optional< std::string > facilityName
The name of the logging facility that produced this message.
Definition: Message.h:429
Base class for final destinations that are free-format.
Definition: Message.h:1160
AnsiColor background
Background color, or COLOR_DEFAULT.
Definition: Message.h:377
PrefixPtr showProgramName(bool b)
Property: whether to show the program name in the message prefix area.
Definition: Message.h:1073
bool showThreadId() const
Property: whether to show the thread ID in the message prefix area.
Definition: Message.h:1083
ANSI "green" color.
Definition: Message.h:346
bool initializeLibrary()
Explicitly initialize the library.
Facilities & disable()
Enable/disable all facilities.
Definition: Message.h:1918
Container associating values with keys.
Definition: Sawyer/Map.h:66
Informative messages.
Definition: Message.h:326
SharedPointer< class Multiplexer > MultiplexerPtr
Smart pointer.
Definition: Message.h:477
bool operator!() const
Returns false if this stream is enabled.
Definition: Message.h:1523
AnsiColor foreground
Foreground color, or COLOR_DEFAULT.
Definition: Message.h:376
Granular tracing information useful to end-users that are trying to understand program internals...
Definition: Message.h:322
Filters messages based on how many messages have been seen.
Definition: Message.h:751