Modules | Files | Inheritance Tree | Inheritance Graph | Name Index | Config
File: Synopsis/Parser/C++/syn/strace.hh
    1| // Synopsis C++ Parser: strace.hh header file
    2| // Defines the STrace class which can be used to provide detailed traces in
    3| // debug mode
    4| 
    5| // $Id: strace.hh,v 1.9 2002/11/17 12:11:44 chalky Exp $
    6| //
    7| // This file is a part of Synopsis.
    8| // Copyright (C) 2000, 2001 Stephen Davies
    9| // Copyright (C) 2000, 2001 Stefan Seefeld
   10| //
   11| // Synopsis is free software; you can redistribute it and/or modify it
   12| // under the terms of the GNU General Public License as published by
   13| // the Free Software Foundation; either version 2 of the License, or
   14| // (at your option) any later version.
   15| //
   16| // This program is distributed in the hope that it will be useful,
   17| // but WITHOUT ANY WARRANTY; without even the implied warranty of
   18| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   19| // General Public License for more details.
   20| //
   21| // You should have received a copy of the GNU General Public License
   22| // along with this program; if not, write to the Free Software
   23| // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   24| // 02111-1307, USA.
   25| 
   26| #ifndef H_SYNOPSIS_CPP_STRACE
   27| #define H_SYNOPSIS_CPP_STRACE
   28| 
   29| #include <string>
   30| #include <iostream>
   31| #include <sstream>
   32| #include <exception>
   33| #include <list>
   34| 
   35| class Ptree;
   36| 
   37| #if 1 && defined(DEBUG)
   38| #define DO_TRACE
   39| //. A tracer class that can be used as a Guard around sections of code. The
   40| //. instances are kept in a class-static stack, and enter/leave messages are
   41| //. only printed when output is made at a given level. To work this, two
   42| //. indices to the stack level are used: slevel and dlevel. The Stack Level
   43| //. indicates the current depth of the stack, including non-displayed levels.
   44| //. The Display Level indicates the level up to which enter statements have
   45| //. been printed. Leave statements are only printed if slevel falls below
   46| //. dlevel.
   47| class STrace
   48| {
   49|     //. A convenient typedef
   50|     typedef std::list<std::string> string_list;
   51| public:
   52|     //. Constructor
   53|     STrace(const std::string &s)
   54|             : m_scope(s)
   55|     {
   56|         m_list.push_back(indent() + "entering " + m_scope);
   57|         ++slevel;
   58|     }
   59|     //. Destructor, called when leaving a scope. Only print out leaving messages
   60|     //. if the enter was displayed.
   61|     ~STrace()
   62|     {
   63|         if (dlevel > --slevel)
   64|         {
   65|             // 'enter' message was displayed, so display leave message too
   66|             std::cout << indent() << "leaving  " << m_scope << std::endl;
   67|             --dlevel;
   68|         }
   69|         else
   70|             // 'enter' message wasn't displayed, so remove it from list
   71|             m_list.pop_back();
   72|     }
   73|     //. Insertion operator, used to start logging a line
   74|     std::ostream& operator <<(const std::string& s)
   75|     {
   76|         // Catch up on skipped enter messages
   77|         while (dlevel < slevel)
   78|         {
   79|             std::cout << m_list.front() << "\n";
   80|             m_list.pop_front();
   81|             ++dlevel;
   82|         }
   83|         // Start current log message at correct indent
   84|         std::cout << indent() << s;
   85|         return std::cout;
   86|     }
   87|     //. Insertion operator. Logs a Ptree
   88|     std::ostream& operator<<(Ptree* p); // defined in swalker.cc
   89|     //. Creates a new stringstream for use in buffering output
   90|     std::ostringstream& new_stream()
   91|     {
   92|         if (stream)
   93|             delete stream;
   94|         stream = new std::ostringstream;
   95|         *stream << m_scope << ": ";
   96|         return *stream;
   97|     }
   98|     //. Returns a string derived from the buffer for output
   99|     std::string get_stream_str()
  100|     {
  101|         if (stream)
  102|             return stream->str();
  103|         return "";
  104|     }
  105| 
  106| private:
  107|     //. Returns a string representing the indent
  108|     std::string indent()
  109|     {
  110|         return std::string(slevel, ' ');
  111|     }
  112|     //. The scope of this STrace object
  113|     std::string m_scope;
  114|     //. The Stack-Level and Display-Level indices
  115|     static int slevel, dlevel;
  116|     //. A StringStream used for buffering output
  117|     static std::ostringstream* stream;
  118|     //. The FIFO queue of skipped enter-messages
  119|     static string_list m_list;
  120| };
  121| 
  122| //. An exception object indicating errors in translating the Ptree to an AST.
  123| //. Upon invocation, will grab the error message stored by the ERROR macros in
  124| //. the STrace object
  125| class TranslateError : public std::exception
  126| {
  127| public:
  128|     //. The message
  129|     std::string message;
  130|     //. The node that was being translated
  131|     mutable Ptree* node;
  132| 
  133|     //. Constructor. Extracts the error message from the STracer (set by ERROR macros)
  134|     TranslateError(STrace& trace, Ptree* p = 0)
  135|             : node(p)
  136|     {
  137|         message = trace.get_stream_str();
  138|         trace << "Error: " << message << std::endl;
  139|     }
  140|     //. Copy constructor
  141|     TranslateError(const TranslateError& e)
  142|             : message(e.message), node(e.node)
  143|     { }
  144|     //. Destructor
  145|     ~TranslateError() throw()
  146|     {}
  147| 
  148|     //. overridden std::exception method (not that the original works too well)
  149|     virtual const char* what() const throw ()
  150|     {
  151|         return "TranslateError";
  152|     }
  153|     //. Returns the error message
  154|     std::string str() const
  155|     {
  156|         return message;
  157|     }
  158|     //. Sets a node for the error, if not already set.
  159|     void set_node(Ptree* p) const
  160|     {
  161|         if (!node)
  162|             node = p;
  163|     }
  164| };
  165| #define ERROR(message) (trace.new_stream() << message, TranslateError(trace))
  166| #define nodeERROR(node, message) (trace.new_stream() << message, TranslateError(trace, node))
  167| #define LOG(message) trace << message << std::endl
  168| #define nodeLOG(message) trace << message;
  169| 
  170| 
  171| #else // DEBUG
  172| 
  173| //. Dummy STrace guard for release code - should be optimized away
  174| class STrace
  175| {
  176| public:
  177|     STrace(const std::string &)
  178|     { }
  179|     ~STrace()
  180|     { }
  181| };
  182| 
  183| //. Exception thrown by errors when translating the Ptree into an AST
  184| class TranslateError : public std::exception
  185| {
  186| public:
  187|     charstr()
  188|     {
  189|         return "";
  190|     }
  191|     virtual const charwhat() const throw ()
  192|     {
  193|         return "TranslateError";
  194|     }
  195|     void set_node(Ptree*) const
  196|     { }
  197| };
  198| #define ERROR(message) TranslateError()
  199| #define nodeERROR(node, message) TranslateError()
  200| #define LOG(trash)
  201| #define nodeLOG(trash)
  202| 
  203| #endif
  204| 
  205| 
  206| #endif
  207| // vim: set ts=8 sts=4 sw=4 et: