########################################################################
# $Header: /var/local/cvsroot/4Suite/Ft/Xml/Xslt/Debugger/TerminalOutput.py,v 1.5 2004/04/16 06:27:48 mbrown Exp $
"""
Output handler to route debugger messages to a terminal
Copyright 2004 Fourthought, Inc. (USA).
Detailed license and copyright information: http://4suite.org/COPYRIGHT
Project home, documentation, distributions: http://4suite.org/
"""
import cStringIO, string, sys, traceback
from Ft.Xml.Xslt import Processor
from xml.dom import Node
import DebugCommands
from Ft.Xml.XPath import NAMESPACE_NODE
from Ft.Lib import boolean
import types,urllib
try:
g_stringTypes= [types.StringType, types.UnicodeType]
except:
g_stringTypes= [types.StringType]
g_commandPrint = {DebugCommands.RUN:'Run',
DebugCommands.QUIT:'Quit',
DebugCommands.PRINT:'Print',
DebugCommands.TEMPLATE:'Run to Template',
DebugCommands.LIST_SHEET:'List Sheet',
DebugCommands.BACK_TRACE:'Back Trace',
DebugCommands.STEP:'Step',
DebugCommands.NEXT:'Next',
DebugCommands.EVAL:'Evaluate Expression',
DebugCommands.TEST:'Test XPath',
DebugCommands.MATCH:'Match Pattern',
DebugCommands.AVT:'Attribute Value Template',
DebugCommands.LIST_TEMPLATE:'List current Template',
DebugCommands.SET_BREAK:'Set a break point in stylesheet',
DebugCommands.DELETE_BREAK:'Delete a break point in stylesheet',
DebugCommands.LIST_BREAK:'List break points',
DebugCommands.HELP:'help',
}
g_help = {'run':"Run till the next break point",
'quit':"Exit the program",
'print':"Print information about the context",
'template':"Run till the next template is instantiated",
'ls':"List the current stylesheet",
'bt':"Print the call stack",
'step':"Step to next element",
'next':"Step to next element at same level",
'eval':"Evaluate a XPath expression at the current context",
'test':"Evaluate a XPath expression at the current context and return the boolean results",
'match':"Evaluate a XPattern expression at the current context",
'avt':"Evaluate a attribute value template at the current context",
'lt':"Print the current template",
'b':'Set a break point in stylesheet',
'db':'Delete a break point in stylesheet',
'lb':'List break points',
'help':'help',
}
g_detailedHelp = g_help.copy()
g_detailedHelp['print'] = """Print arg
Possible values for arg:
con
The current context
con.position
The position of the current context
con.size
The size of the current context
con.node
The node of the current context
con.mode
The mode of the current context
con.currentNode
The current node of the current context
$
The last XPath results evaluated
$$
The last results from a XSLT element instantiation
"""
g_detailedHelp['ls'] = """List Sheet
ls [fileName:][start[-end]]
fileName: Name of stylesheet to list, default to the current sheet
start: Line number to start listing at.T
The default is one line before the current line
end: The last line to print.
The default is nine lines after the current line
"""
class TerminalOutputHandler:
def display_error(self,err):
sys.stderr.write(err+'\n')
def display(self,msg):
print msg
def display_exception(self,etype,value,tb):
traceback.print_exception(etype, value, None)
def display_expressionResults(self,expr,rt):
print expr + " --> " + str(rt)
def display_backTrace(self,tb):
indent = ""
for t in tb[1:]:
n = self._getPrettyNodeName(t)
if hasattr(t,'nodeType'):
fileName = t.baseUri
lineNum = str(t._ft_lineNumber)
n = n + ' (%s line %d)' % (t.baseUri,t._ft_lineNumber)
print indent + n
indent = indent + " "
def display_breakpoints(self,bps):
for bNum,lineNum,fileName in bps:
print "Break Point %d: File: %s Line Number: %d" % (bNum,fileName,lineNum)
def display_selectResults(self,expr,rt):
print expr + " -->",
object_type = type(rt)
if hasattr(rt, 'nodeType'):
self._printNode(rt)
elif object_type in g_stringTypes:
print rt
elif object_type in [types.IntType, types.LongType]:
print rt
elif isinstance(rt, types.FloatType):
if str(rt) == 'nan':
print 'NaN'
else:
print "%g"%(rt)
elif isinstance(rt, boolean.BooleanType):
print str(rt)
elif isinstance(rt, types.ListType):
print
for r in rt:
print self._getPrettyNodeName(r)
print "-" * 15
def display_context(self,context):
print "Current Context"
print "-"*15
print "Node: %s" % str(context.node)
print "Position: %d" % context.position
print "Size: %d" % context.size
print "Current Node: %s" % str(context.currentNode)
print "Var Bindings: %s" % str(context.varBindings)
print "Processor Nss: %s" % str(context.processorNss)
print "Mode: %s" % str(context.mode)
def display_contextPosition(self,position):
print "Context Position: %d" % position
def display_contextSize(self,size):
print "Context Size: %d" % size
def display_contextMode(self,mode):
print "Context Mode: %s" % mode
def display_contextNode(self,node):
print "Context.Node: "
self._printNode(node)
def display_contextCurrentNode(self,cn):
print "Context.CurrentNode: "
self._printNode(cn)
def display_lastResult(self,lr):
print "Last Results"
print "-"*10
print lr
print "-"*10
def display_lastOutputs(self,lo):
print "Outputs"
print "-"*10
indent = ""
for name,args in lo:
if name == 'Start: element':
print indent,
print "<%s>" % args['name']
indent = indent + " "
elif name == 'Start: document':
print indent,
print "<?xsml version='1.0'?>"
indent = indent + " "
elif name == "End: element":
indent = indent[:-2]
print indent,
print "</>"
elif name == 'text':
print indent,
print string.strip(args['text'])
elif name == 'attribute':
print indent,
print "%s='%s'" % (args['name'],args['value'])
else:
print name,args
print "-"*10
def display_currentPosition(self,node):
print
if isinstance(node,Processor.Processor):
print "-"*40
print "Processor.ApplyTemplates"
elif hasattr(node,'nodeType'):
#Print the line number +/- 3
marker = 6 + node._ft_columnNumber + 1
print '-'*marker + "|" + '-' * (40-marker)
print ' '*marker + "V"
self._printFromFile(node.baseUri,node._ft_lineNumber,2,2)
else:
return str(node)
print "-"*40
def display_currentCommand(self,cmd):
print g_commandPrint[cmd]
def _printNode(self,node):
if hasattr(node,'baseUri'):
self._printFromFile(node.baseUri,node._ft_lineNumber,1,9)
elif hasattr(node,'nodeType'):
st = cStringIO.StringIO()
PrettyPrint(node,stream=st)
print st.getvalue()
elif isinstance(node,Processor.Processor):
print "Processor"
else:
print str(node)
display_node = _printNode
def display_sheet(self,node,start=None,end=None,fileName=None):
if isinstance(node,Processor.Processor) and fileName is None:
print "Processor"
return
if fileName is None:
if hasattr(node,'baseUri'):
fileName = node.baseUri
else:
raise Exception("You need to specify a fileName")
if start is None:
if hasattr(node,'_ft_lineNumber'):
start = node._ft_lineNumber
else:
start = 1
if end is None:
end = 9
else:
end = end - start
self._printFromFile(fileName,start,1,end)
def _getPrettyNodeName(self,node):
if isinstance(node,Processor.Processor):
return "Processor.ApplyTemplates"
elif hasattr(node,'nodeType'):
if node.nodeType == Node.ELEMENT_NODE:
st = "<%s " % node.nodeName
for attr in node.attributes:
st = st + "%s ='%s' " % (attr.name,attr.value)
return st[:-1] + '>'
else:
return str(node)
else:
return str(node)
g_fileLineCache = {}
def _printFromFile(self,fileName,lineNo,previousLines,extraLines,addMarker = 1):
if not self.g_fileLineCache.has_key(fileName):
lines = Uri.UrlOpen(fileName).readlines()
self.g_fileLineCache[fileName] = lines
else:
lines = self.g_fileLineCache[fileName]
start = lineNo-previousLines-1
if start < 0:
start = 0
ctr = start
for line in lines[start:lineNo+extraLines]:
if addMarker and ctr == lineNo-1:
marker = "->"
else:
marker = " "
print "%03d%s: %s" % (ctr+1,marker,line[:-1])
ctr = ctr + 1
def display_help(self,args):
if not args:
commands = g_help.keys()
commands.sort()
print "4XDebug Commands"
for cmd in commands:
print "%s: %s" % (cmd,g_help[cmd])
else:
print g_detailedHelp.get(args[0],"Unknown Command %s" % args[0])
|