1 |
|
# Orca |
2 |
|
# |
3 |
|
# Copyright 2005-2007 Sun Microsystems Inc. |
4 |
|
# |
5 |
|
# This library is free software; you can redistribute it and/or |
6 |
|
# modify it under the terms of the GNU Library General Public |
7 |
|
# License as published by the Free Software Foundation; either |
8 |
|
# version 2 of the License, or (at your option) any later version. |
9 |
|
# |
10 |
|
# This library is distributed in the hope that it will be useful, |
11 |
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 |
|
# Library General Public License for more details. |
14 |
|
# |
15 |
|
# You should have received a copy of the GNU Library General Public |
16 |
|
# License along with this library; if not, write to the |
17 |
|
# Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 |
|
# Boston, MA 02111-1307, USA. |
19 |
|
|
20 |
|
"""Provides debug utilities for Orca. Debugging is managed by a debug |
21 |
|
level, which is held in the debugLevel field. All other methods take |
22 |
|
a debug level, which is compared to the current debug level to |
23 |
1 |
determine if the content should be output.""" |
24 |
|
|
25 |
1 |
__id__ = "$Id: debug.py 2535 2007-07-09 21:43:14Z wwalker $" |
26 |
1 |
__version__ = "$Revision: 2535 $" |
27 |
1 |
__date__ = "$Date: 2007-07-09 17:43:14 -0400 (Mon, 09 Jul 2007) $" |
28 |
1 |
__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc." |
29 |
1 |
__license__ = "LGPL" |
30 |
|
|
31 |
1 |
import sys |
32 |
1 |
import traceback |
33 |
|
|
34 |
|
# Used to turn off all debugging. |
35 |
|
# |
36 |
1 |
LEVEL_OFF = 10000 |
37 |
|
|
38 |
|
# Used to describe events of considerable importance and which will prevent |
39 |
|
# normal program execution. |
40 |
|
# |
41 |
1 |
LEVEL_SEVERE = 1000 |
42 |
|
|
43 |
|
# Used to decribe events of interest to end users or system managers or which |
44 |
|
# indicate potential problems, but which Orca can deal with without crashing. |
45 |
|
# |
46 |
1 |
LEVEL_WARNING = 900 |
47 |
|
|
48 |
|
# Used to indicate reasonably significant messages that make sense to end users |
49 |
|
# and system managers. |
50 |
|
# |
51 |
|
# For the purposes of Orca, LEVEL_INFO means display the text being sent to |
52 |
|
# speech and braille. |
53 |
|
# |
54 |
1 |
LEVEL_INFO = 800 |
55 |
|
|
56 |
|
# Used to indicate static configuration information to assist in debugging |
57 |
|
# problems that may be associated with a particular configuration. |
58 |
|
# |
59 |
|
# For the purposes of Orca, LEVEL_CONFIGURATION means display the various |
60 |
|
# apsects of whether a particular feature (e.g., speech, braille, etc.) |
61 |
|
# is enabled or not as well as details about that feature. |
62 |
|
# |
63 |
1 |
LEVEL_CONFIGURATION = 700 |
64 |
|
|
65 |
|
# Used for lowest volume of detailed tracing information. |
66 |
|
# |
67 |
|
# For the purposes of Orca, this is braille and keyboard input, script |
68 |
|
# activation and deletion, locus of focus changes, and visual changes |
69 |
|
# to the locus of focus. |
70 |
|
# |
71 |
1 |
LEVEL_FINE = 600 |
72 |
|
|
73 |
|
# Used for medium volume of detailed tracing information. |
74 |
|
# |
75 |
|
# For the purposes of Orca, this is for debugging speech and braille |
76 |
|
# generators and tracking the synthesis of device events. |
77 |
|
# |
78 |
1 |
LEVEL_FINER = 500 |
79 |
|
|
80 |
|
# Used for maximum volume of detailed tracing information. |
81 |
|
# |
82 |
|
# For the purposes of Orca, this is for tracking all AT-SPI object |
83 |
|
# events. NOTE that one can up the debug level of AT-SPI object |
84 |
|
# events by setting the eventDebugLevel. In addition, one can filter |
85 |
|
# events by setting eventDebugFilter to a regular expression that |
86 |
|
# matches event type names. |
87 |
|
# |
88 |
1 |
LEVEL_FINEST = 400 |
89 |
|
|
90 |
|
# Used for all detailed tracing information, even finer than LEVEL_FINEST |
91 |
|
# |
92 |
1 |
LEVEL_ALL = 0 |
93 |
|
|
94 |
1 |
debugLevel = LEVEL_SEVERE |
95 |
|
|
96 |
|
# The debug file. If this is not set, then all debug output is done |
97 |
|
# via stdout. If this is set, then all debug output is sent to the |
98 |
|
# file. This can be useful for debugging because one can pass in a |
99 |
|
# non-buffered file to better track down hangs. |
100 |
|
# |
101 |
1 |
debugFile = None |
102 |
|
|
103 |
|
# The debug filter should be either None (which means to match all |
104 |
|
# events) or a compiled regular expression from the 're' module (see |
105 |
|
# http://www.amk.ca/python/howto/regex/). The regular expression will |
106 |
|
# be used as a matching function - if the event type creates a match |
107 |
|
# in the regular expression, then it will be considered for output. A |
108 |
|
# typical call to this method might look like: |
109 |
|
# |
110 |
|
# debug.eventDebugFilter = rc.compile('focus:|window:activate') |
111 |
|
# |
112 |
1 |
eventDebugLevel = LEVEL_FINEST |
113 |
1 |
eventDebugFilter = None |
114 |
|
|
115 |
1 |
def printException(level): |
116 |
|
"""Prints out information regarding the current exception. |
117 |
|
|
118 |
|
Arguments: |
119 |
|
- level: the accepted debug level |
120 |
|
""" |
121 |
|
|
122 |
446 |
if level >= debugLevel: |
123 |
0 |
println(level) |
124 |
0 |
traceback.print_exc(100, debugFile) |
125 |
0 |
println(level) |
126 |
|
|
127 |
1 |
def printStack(level): |
128 |
|
"""Prints out the current stack. |
129 |
|
|
130 |
|
Arguments: |
131 |
|
- level: the accepted debug level |
132 |
|
""" |
133 |
|
|
134 |
0 |
if level >= debugLevel: |
135 |
0 |
println(level) |
136 |
0 |
traceback.print_stack(None, 100, debugFile) |
137 |
0 |
println(level) |
138 |
|
|
139 |
1 |
def println(level, text = ""): |
140 |
|
"""Prints the text to stdout if debug is enabled. |
141 |
|
|
142 |
|
Arguments: |
143 |
|
- level: the accepted debug level |
144 |
|
- text: the text to print (default is a blank line) |
145 |
|
""" |
146 |
|
|
147 |
|
# Check to see if debugging is not enabled for the calling module. |
148 |
|
# |
149 |
140625 |
frame = sys._getframe(1) |
150 |
140625 |
name = frame.f_globals["__name__"] |
151 |
140625 |
module = sys.modules[name] |
152 |
140625 |
if module.__dict__.has_key("_enableDebug") and not module._enableDebug: |
153 |
0 |
return |
154 |
|
|
155 |
140625 |
if level >= debugLevel: |
156 |
0 |
if debugFile: |
157 |
0 |
debugFile.writelines([text,"\n"]) |
158 |
|
else: |
159 |
0 |
print text |
160 |
|
|
161 |
1 |
def printObjectEvent(level, event, sourceInfo=None): |
162 |
|
"""Prints out an Python Event object. The given level may be |
163 |
|
overridden if the eventDebugLevel is greater. Furthermore, only |
164 |
|
events with event types matching the eventDebugFilter regular |
165 |
|
expression will be printed. |
166 |
|
|
167 |
|
Arguments: |
168 |
|
- level: the accepted debug level |
169 |
|
- event: the Python Event to print |
170 |
|
- sourceInfo: additional string to print out |
171 |
|
""" |
172 |
|
|
173 |
13852 |
if eventDebugFilter and not eventDebugFilter.match(event.type): |
174 |
0 |
return |
175 |
|
|
176 |
13852 |
level = max(level, eventDebugLevel) |
177 |
|
|
178 |
13852 |
text = "OBJECT EVENT: %-40s detail=(%d,%d)" \ |
179 |
13852 |
% (event.type, event.detail1, event.detail2) |
180 |
13852 |
println(level, text) |
181 |
|
|
182 |
13852 |
if sourceInfo: |
183 |
0 |
println(level, " " + sourceInfo) |
184 |
|
|
185 |
1 |
def printInputEvent(level, string): |
186 |
|
"""Prints out an input event. The given level may be overridden |
187 |
|
if the eventDebugLevel (see setEventDebugLevel) is greater. |
188 |
|
|
189 |
|
Arguments: |
190 |
|
- level: the accepted debug level |
191 |
|
- string: the string representing the input event |
192 |
|
""" |
193 |
|
|
194 |
3579 |
println(max(level, eventDebugLevel), string) |
195 |
|
|
196 |
1 |
def printDetails(level, indent, accessible, includeApp=True): |
197 |
|
"""Lists the details of the given accessible with the given |
198 |
|
indentation. |
199 |
|
|
200 |
|
Arguments: |
201 |
|
- level: the accepted debug level |
202 |
|
- indent: a string containing spaces for indentation |
203 |
|
- accessible: the accessible whose details are to be listed |
204 |
|
- includeApp: if True, include information about the app |
205 |
|
""" |
206 |
|
|
207 |
12885 |
if level >= debugLevel and accessible: |
208 |
0 |
println(level, accessible.toString(indent, includeApp)) |
209 |
|
|
210 |
|
# The following code has been borrowed from the following URL: |
211 |
|
# |
212 |
|
# http://www.dalkescientific.com/writings/diary/archive/2005/04/20/tracing_python_code.html |
213 |
|
# |
214 |
1 |
import linecache |
215 |
|
|
216 |
1 |
def traceit(frame, event, arg): |
217 |
|
"""Line tracing utility to output all lines as they are executed by |
218 |
|
the interpreter. This is to be used by sys.settrace and is for |
219 |
|
debugging purposes. |
220 |
|
|
221 |
|
Arguments: |
222 |
|
- frame: is the current stack frame |
223 |
|
- event: 'call', 'line', 'return', 'exception', 'c_call', 'c_return', |
224 |
|
or 'c_exception' |
225 |
|
- arg: depends on the event type (see docs for sys.settrace) |
226 |
|
""" |
227 |
|
|
228 |
0 |
if event == "line": |
229 |
0 |
lineno = frame.f_lineno |
230 |
0 |
filename = frame.f_globals["__file__"] |
231 |
0 |
if (filename.endswith(".pyc") or |
232 |
0 |
filename.endswith(".pyo")): |
233 |
0 |
filename = filename[:-1] |
234 |
0 |
name = frame.f_globals["__name__"] |
235 |
0 |
if name == "gettext" \ |
236 |
0 |
or name == "locale" \ |
237 |
0 |
or name == "posixpath" \ |
238 |
0 |
or name == "UserDict": |
239 |
0 |
return traceit |
240 |
0 |
line = linecache.getline(filename, lineno) |
241 |
0 |
println(LEVEL_ALL, "TRACE %s:%s: %s" % (name, lineno, line.rstrip())) |
242 |
0 |
return traceit |