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|
174| class STrace
175| {
176| public:
177| STrace(const std::string &)
178| { }
179| ~STrace()
180| { }
181| };
182|
183|
184| class TranslateError : public std::exception
185| {
186| public:
187| char* str()
188| {
189| return "";
190| }
191| virtual const char* what() 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|