File: Synopsis/Trace.hh
  1//
  2// Copyright (C) 2004 Stefan Seefeld
  3// All rights reserved.
  4// Licensed to the public under the terms of the GNU LGPL (>= 2),
  5// see the file COPYING for details.
  6//
  7
  8#ifndef Synopsis_Trace_hh_
  9#define Synopsis_Trace_hh_
 10
 11#include <iostream>
 12#include <string>
 13
 14namespace Synopsis
 15{
 16
 17class Trace
 18{
 19public:
 20  // This category list is incomplete and needs to be filled in as
 21  // more code is being written.
 22  enum Category { NONE=0x0,
 23		  PTREE=0x01,
 24		  SYMBOLLOOKUP=0x02,
 25		  PARSING=0x04,
 26		  TRANSLATION=0x08,
 27		  ALL=0xff};
 28
 29  struct Entry
 30  {
 31    Entry(bool e);
 32    Entry(Entry const &e) : enabled(e.enabled) { e.enabled = false;}
 33    ~Entry();
 34
 35    template <typename T> Entry const &operator<<(T const &t) const;
 36
 37    mutable bool enabled;
 38  };
 39  friend struct Entry;
 40  Trace(std::string const &s, unsigned int c)
 41    : my_scope(s), my_visibility(my_mask & c)
 42  {
 43    if (!my_visibility) return;
 44    std::cout << indent() << "entering " << my_scope << std::endl;
 45    ++my_level;
 46  }
 47  template <typename T>
 48  Trace(std::string const &s, unsigned int c, T const &t)
 49    : my_scope(s), my_visibility(my_mask & c)
 50  {
 51    if (!my_visibility) return;
 52    std::cout << indent() << "entering " << my_scope << ' ' << t << std::endl;
 53    ++my_level;
 54  }
 55  ~Trace()
 56  {
 57    if (!my_visibility) return;
 58    --my_level;
 59    std::cout << indent() << "leaving " << my_scope << std::endl;
 60  }
 61
 62  template <typename T>
 63  Entry operator<<(T const &t) const;
 64
 65  static void enable(unsigned int mask = ALL) { my_mask = mask;}
 66
 67private:
 68  static std::string indent() { return std::string(my_level, ' ');}
 69
 70  static unsigned int my_mask;
 71  static size_t       my_level;
 72  std::string         my_scope;
 73  bool                my_visibility;
 74};
 75
 76inline Trace::Entry::Entry(bool e) 
 77  : enabled(e)
 78{
 79  if (enabled)
 80    std::cout << Trace::indent();
 81}
 82
 83inline Trace::Entry::~Entry() 
 84{
 85  if (enabled)
 86    std::cout << std::endl;
 87}
 88
 89template <typename T> 
 90inline Trace::Entry const &Trace::Entry::operator<<(T const &t) const
 91{
 92  if (enabled)
 93    std::cout << t;
 94  return *this;
 95}
 96
 97template <typename T>
 98inline Trace::Entry Trace::operator<<(T const &t) const
 99{
100  Entry entry(my_visibility);
101  return entry << t;
102}
103
104}
105
106#endif