Current Path: > > lib64 > python2.7 > idlelib
Operation : Linux premium107.web-hosting.com 4.18.0-553.44.1.lve.el8.x86_64 #1 SMP Thu Mar 13 14:29:12 UTC 2025 x86_64 Software : Apache Server IP : 198.54.126.246 | Your IP: 216.73.216.181 Domains : 1034 Domain(s) Permission : [ 0755 ]
| Name | Type | Size | Last Modified | Actions |
|---|---|---|---|---|
| Icons | Directory | - | - | |
| idle_test | Directory | - | - | |
| AutoComplete.py | File | 8964 bytes | April 10 2024 04:58:35. | |
| AutoComplete.pyc | File | 8012 bytes | April 10 2024 04:58:46. | |
| AutoComplete.pyo | File | 8012 bytes | April 10 2024 04:58:46. | |
| AutoCompleteWindow.py | File | 17318 bytes | April 10 2024 04:58:35. | |
| AutoCompleteWindow.pyc | File | 12480 bytes | April 10 2024 04:58:46. | |
| AutoCompleteWindow.pyo | File | 12421 bytes | April 10 2024 04:58:43. | |
| AutoExpand.py | File | 3395 bytes | April 10 2024 04:58:35. | |
| AutoExpand.pyc | File | 3502 bytes | April 10 2024 04:58:46. | |
| AutoExpand.pyo | File | 3502 bytes | April 10 2024 04:58:46. | |
| Bindings.py | File | 2976 bytes | April 10 2024 04:58:35. | |
| Bindings.pyc | File | 4695 bytes | April 10 2024 04:58:46. | |
| Bindings.pyo | File | 4695 bytes | April 10 2024 04:58:46. | |
| CREDITS.txt | File | 1866 bytes | April 10 2024 04:58:35. | |
| CallTipWindow.py | File | 6065 bytes | April 10 2024 04:58:35. | |
| CallTipWindow.pyc | File | 6136 bytes | April 10 2024 04:58:46. | |
| CallTipWindow.pyo | File | 6136 bytes | April 10 2024 04:58:46. | |
| CallTips.py | File | 7740 bytes | April 10 2024 04:58:35. | |
| CallTips.pyc | File | 8133 bytes | April 10 2024 04:58:46. | |
| CallTips.pyo | File | 8133 bytes | April 10 2024 04:58:46. | |
| ChangeLog | File | 56393 bytes | April 10 2024 04:58:35. | |
| ClassBrowser.py | File | 6999 bytes | April 10 2024 04:58:35. | |
| ClassBrowser.pyc | File | 9500 bytes | April 10 2024 04:58:46. | |
| ClassBrowser.pyo | File | 9500 bytes | April 10 2024 04:58:46. | |
| CodeContext.py | File | 8342 bytes | April 10 2024 04:58:35. | |
| CodeContext.pyc | File | 6658 bytes | April 10 2024 04:58:46. | |
| CodeContext.pyo | File | 6614 bytes | April 10 2024 04:58:43. | |
| ColorDelegator.py | File | 9762 bytes | April 10 2024 04:58:35. | |
| ColorDelegator.pyc | File | 8898 bytes | April 10 2024 04:58:46. | |
| ColorDelegator.pyo | File | 8898 bytes | April 10 2024 04:58:46. | |
| Debugger.py | File | 18236 bytes | April 10 2024 04:58:35. | |
| Debugger.pyc | File | 17546 bytes | April 10 2024 04:58:46. | |
| Debugger.pyo | File | 17546 bytes | April 10 2024 04:58:46. | |
| Delegator.py | File | 665 bytes | April 10 2024 04:58:35. | |
| Delegator.pyc | File | 1268 bytes | April 10 2024 04:58:46. | |
| Delegator.pyo | File | 1268 bytes | April 10 2024 04:58:46. | |
| EditorWindow.py | File | 65498 bytes | April 10 2024 04:58:35. | |
| EditorWindow.pyc | File | 56858 bytes | April 10 2024 04:58:46. | |
| EditorWindow.pyo | File | 56756 bytes | April 10 2024 04:58:43. | |
| FileList.py | File | 3718 bytes | April 10 2024 04:58:35. | |
| FileList.pyc | File | 4025 bytes | April 10 2024 04:58:46. | |
| FileList.pyo | File | 3992 bytes | April 10 2024 04:58:43. | |
| FormatParagraph.py | File | 7287 bytes | April 10 2024 04:58:35. | |
| FormatParagraph.pyc | File | 7142 bytes | April 10 2024 04:58:46. | |
| FormatParagraph.pyo | File | 7142 bytes | April 10 2024 04:58:46. | |
| GrepDialog.py | File | 5145 bytes | April 10 2024 04:58:35. | |
| GrepDialog.pyc | File | 6425 bytes | April 10 2024 04:58:46. | |
| GrepDialog.pyo | File | 6425 bytes | April 10 2024 04:58:46. | |
| HISTORY.txt | File | 10317 bytes | April 10 2024 04:58:35. | |
| HyperParser.py | File | 10497 bytes | April 10 2024 04:58:35. | |
| HyperParser.pyc | File | 6673 bytes | April 10 2024 04:58:46. | |
| HyperParser.pyo | File | 6673 bytes | April 10 2024 04:58:46. | |
| IOBinding.py | File | 21911 bytes | April 10 2024 04:58:35. | |
| IOBinding.pyc | File | 18535 bytes | April 10 2024 04:58:46. | |
| IOBinding.pyo | File | 18535 bytes | April 10 2024 04:58:46. | |
| IdleHistory.py | File | 4052 bytes | April 10 2024 04:58:35. | |
| IdleHistory.pyc | File | 4060 bytes | April 10 2024 04:58:46. | |
| IdleHistory.pyo | File | 4060 bytes | April 10 2024 04:58:46. | |
| MultiCall.py | File | 17701 bytes | April 10 2024 04:58:35. | |
| MultiCall.pyc | File | 16351 bytes | April 10 2024 04:58:46. | |
| MultiCall.pyo | File | 16277 bytes | April 10 2024 04:58:43. | |
| MultiStatusBar.py | File | 1348 bytes | April 10 2024 04:58:35. | |
| MultiStatusBar.pyc | File | 2279 bytes | April 10 2024 04:58:46. | |
| MultiStatusBar.pyo | File | 2279 bytes | April 10 2024 04:58:46. | |
| NEWS.txt | File | 47247 bytes | April 10 2024 04:58:35. | |
| ObjectBrowser.py | File | 4376 bytes | April 10 2024 04:58:35. | |
| ObjectBrowser.pyc | File | 7067 bytes | April 10 2024 04:58:46. | |
| ObjectBrowser.pyo | File | 7067 bytes | April 10 2024 04:58:46. | |
| OutputWindow.py | File | 4576 bytes | April 10 2024 04:58:35. | |
| OutputWindow.pyc | File | 5232 bytes | April 10 2024 04:58:46. | |
| OutputWindow.pyo | File | 5232 bytes | April 10 2024 04:58:46. | |
| ParenMatch.py | File | 6714 bytes | April 10 2024 04:58:35. | |
| ParenMatch.pyc | File | 7129 bytes | April 10 2024 04:58:46. | |
| ParenMatch.pyo | File | 7129 bytes | April 10 2024 04:58:46. | |
| PathBrowser.py | File | 3009 bytes | April 10 2024 04:58:35. | |
| PathBrowser.pyc | File | 4486 bytes | April 10 2024 04:58:46. | |
| PathBrowser.pyo | File | 4486 bytes | April 10 2024 04:58:46. | |
| Percolator.py | File | 3222 bytes | April 10 2024 04:58:35. | |
| Percolator.pyc | File | 4608 bytes | April 10 2024 04:58:46. | |
| Percolator.pyo | File | 4424 bytes | April 10 2024 04:58:43. | |
| PyParse.py | File | 19510 bytes | April 10 2024 04:58:35. | |
| PyParse.pyc | File | 10005 bytes | April 10 2024 04:58:46. | |
| PyParse.pyo | File | 9567 bytes | April 10 2024 04:58:43. | |
| PyShell.py | File | 58862 bytes | April 10 2024 04:58:35. | |
| PyShell.pyc | File | 52826 bytes | April 10 2024 04:58:46. | |
| PyShell.pyo | File | 52724 bytes | April 10 2024 04:58:43. | |
| README.txt | File | 7890 bytes | April 10 2024 04:58:35. | |
| RemoteDebugger.py | File | 11632 bytes | April 10 2024 04:58:35. | |
| RemoteDebugger.pyc | File | 16325 bytes | April 10 2024 04:58:46. | |
| RemoteDebugger.pyo | File | 16171 bytes | April 10 2024 04:58:43. | |
| RemoteObjectBrowser.py | File | 942 bytes | April 10 2024 04:58:35. | |
| RemoteObjectBrowser.pyc | File | 2150 bytes | April 10 2024 04:58:46. | |
| RemoteObjectBrowser.pyo | File | 2150 bytes | April 10 2024 04:58:46. | |
| ReplaceDialog.py | File | 6639 bytes | April 10 2024 04:58:35. | |
| ReplaceDialog.pyc | File | 7756 bytes | April 10 2024 04:58:46. | |
| ReplaceDialog.pyo | File | 7756 bytes | April 10 2024 04:58:46. | |
| RstripExtension.py | File | 1050 bytes | April 10 2024 04:58:35. | |
| RstripExtension.pyc | File | 1613 bytes | April 10 2024 04:58:46. | |
| RstripExtension.pyo | File | 1613 bytes | April 10 2024 04:58:46. | |
| ScriptBinding.py | File | 8459 bytes | April 10 2024 04:58:35. | |
| ScriptBinding.pyc | File | 8201 bytes | April 10 2024 04:58:46. | |
| ScriptBinding.pyo | File | 8201 bytes | April 10 2024 04:58:46. | |
| ScrolledList.py | File | 4373 bytes | April 10 2024 04:58:35. | |
| ScrolledList.pyc | File | 6482 bytes | April 10 2024 04:58:46. | |
| ScrolledList.pyo | File | 6482 bytes | April 10 2024 04:58:46. | |
| SearchDialog.py | File | 2630 bytes | April 10 2024 04:58:35. | |
| SearchDialog.pyc | File | 3983 bytes | April 10 2024 04:58:46. | |
| SearchDialog.pyo | File | 3983 bytes | April 10 2024 04:58:46. | |
| SearchDialogBase.py | File | 7094 bytes | April 10 2024 04:58:35. | |
| SearchDialogBase.pyc | File | 8462 bytes | April 10 2024 04:58:46. | |
| SearchDialogBase.pyo | File | 8462 bytes | April 10 2024 04:58:46. | |
| SearchEngine.py | File | 7463 bytes | April 10 2024 04:58:35. | |
| SearchEngine.pyc | File | 8302 bytes | April 10 2024 04:58:46. | |
| SearchEngine.pyo | File | 8302 bytes | April 10 2024 04:58:46. | |
| StackViewer.py | File | 4431 bytes | April 10 2024 04:58:35. | |
| StackViewer.pyc | File | 6404 bytes | April 10 2024 04:58:46. | |
| StackViewer.pyo | File | 6404 bytes | April 10 2024 04:58:46. | |
| TODO.txt | File | 8478 bytes | April 10 2024 04:58:35. | |
| ToolTip.py | File | 3173 bytes | April 10 2024 04:58:35. | |
| ToolTip.pyc | File | 4669 bytes | April 10 2024 04:58:46. | |
| ToolTip.pyo | File | 4669 bytes | April 10 2024 04:58:46. | |
| TreeWidget.py | File | 15037 bytes | April 10 2024 04:58:35. | |
| TreeWidget.pyc | File | 17694 bytes | April 10 2024 04:58:46. | |
| TreeWidget.pyo | File | 17694 bytes | April 10 2024 04:58:46. | |
| UndoDelegator.py | File | 10787 bytes | April 10 2024 04:58:35. | |
| UndoDelegator.pyc | File | 13555 bytes | April 10 2024 04:58:46. | |
| UndoDelegator.pyo | File | 13555 bytes | April 10 2024 04:58:46. | |
| WidgetRedirector.py | File | 6906 bytes | April 10 2024 04:58:35. | |
| WidgetRedirector.pyc | File | 7769 bytes | April 10 2024 04:58:46. | |
| WidgetRedirector.pyo | File | 7769 bytes | April 10 2024 04:58:46. | |
| WindowList.py | File | 2473 bytes | April 10 2024 04:58:35. | |
| WindowList.pyc | File | 3636 bytes | April 10 2024 04:58:46. | |
| WindowList.pyo | File | 3636 bytes | April 10 2024 04:58:46. | |
| ZoomHeight.py | File | 1300 bytes | April 10 2024 04:58:35. | |
| ZoomHeight.pyc | File | 1646 bytes | April 10 2024 04:58:46. | |
| ZoomHeight.pyo | File | 1646 bytes | April 10 2024 04:58:46. | |
| __init__.py | File | 288 bytes | April 10 2024 04:58:35. | |
| __init__.pyc | File | 431 bytes | April 10 2024 04:58:46. | |
| __init__.pyo | File | 431 bytes | April 10 2024 04:58:46. | |
| aboutDialog.py | File | 7014 bytes | April 10 2024 04:58:35. | |
| aboutDialog.pyc | File | 6848 bytes | April 10 2024 04:58:46. | |
| aboutDialog.pyo | File | 6848 bytes | April 10 2024 04:58:46. | |
| config-extensions.def | File | 2965 bytes | April 10 2024 04:58:35. | |
| config-highlight.def | File | 2515 bytes | April 10 2024 04:58:35. | |
| config-keys.def | File | 7777 bytes | April 10 2024 04:58:35. | |
| config-main.def | File | 2561 bytes | April 10 2024 04:58:35. | |
| configDialog.py | File | 65958 bytes | April 10 2024 04:58:35. | |
| configDialog.pyc | File | 53291 bytes | April 10 2024 04:58:46. | |
| configDialog.pyo | File | 53291 bytes | April 10 2024 04:58:46. | |
| configHandler.py | File | 32485 bytes | April 10 2024 04:58:35. | |
| configHandler.pyc | File | 29361 bytes | April 10 2024 04:58:46. | |
| configHandler.pyo | File | 29361 bytes | April 10 2024 04:58:46. | |
| configHelpSourceEdit.py | File | 6686 bytes | April 10 2024 04:58:35. | |
| configHelpSourceEdit.pyc | File | 6595 bytes | April 10 2024 04:58:46. | |
| configHelpSourceEdit.pyo | File | 6595 bytes | April 10 2024 04:58:46. | |
| configSectionNameDialog.py | File | 4040 bytes | April 10 2024 04:58:35. | |
| configSectionNameDialog.pyc | File | 4419 bytes | April 10 2024 04:58:46. | |
| configSectionNameDialog.pyo | File | 4419 bytes | April 10 2024 04:58:46. | |
| dynOptionMenuWidget.py | File | 1984 bytes | April 10 2024 04:58:35. | |
| dynOptionMenuWidget.pyc | File | 2790 bytes | April 10 2024 04:58:46. | |
| dynOptionMenuWidget.pyo | File | 2790 bytes | April 10 2024 04:58:46. | |
| extend.txt | File | 3642 bytes | April 10 2024 04:58:35. | |
| help.html | File | 42414 bytes | April 10 2024 04:58:35. | |
| help.py | File | 11035 bytes | April 10 2024 04:58:35. | |
| help.pyc | File | 12270 bytes | April 10 2024 04:58:46. | |
| help.pyo | File | 12270 bytes | April 10 2024 04:58:46. | |
| help.txt | File | 12144 bytes | April 10 2024 04:58:35. | |
| idle.py | File | 453 bytes | April 10 2024 04:58:35. | |
| idle.pyc | File | 410 bytes | April 10 2024 04:58:46. | |
| idle.pyo | File | 410 bytes | April 10 2024 04:58:46. | |
| idle.pyw | File | 563 bytes | April 10 2024 04:58:35. | |
| idlever.py | File | 415 bytes | April 10 2024 04:58:35. | |
| idlever.pyc | File | 578 bytes | April 10 2024 04:58:46. | |
| idlever.pyo | File | 578 bytes | April 10 2024 04:58:46. | |
| keybindingDialog.py | File | 12468 bytes | April 10 2024 04:58:35. | |
| keybindingDialog.pyc | File | 12173 bytes | April 10 2024 04:58:46. | |
| keybindingDialog.pyo | File | 12173 bytes | April 10 2024 04:58:46. | |
| macosxSupport.py | File | 8435 bytes | April 10 2024 04:58:35. | |
| macosxSupport.pyc | File | 8351 bytes | April 10 2024 04:58:46. | |
| macosxSupport.pyo | File | 8213 bytes | April 10 2024 04:58:43. | |
| rpc.py | File | 20150 bytes | April 10 2024 04:58:35. | |
| rpc.pyc | File | 21728 bytes | April 10 2024 04:58:46. | |
| rpc.pyo | File | 21622 bytes | April 10 2024 04:58:43. | |
| run.py | File | 12917 bytes | April 10 2024 04:58:35. | |
| run.pyc | File | 13419 bytes | April 10 2024 04:58:46. | |
| run.pyo | File | 13361 bytes | April 10 2024 04:58:43. | |
| tabbedpages.py | File | 18439 bytes | April 10 2024 04:58:35. | |
| tabbedpages.pyc | File | 18561 bytes | April 10 2024 04:58:46. | |
| tabbedpages.pyo | File | 18561 bytes | April 10 2024 04:58:46. | |
| textView.py | File | 3520 bytes | April 10 2024 04:58:35. | |
| textView.pyc | File | 4025 bytes | April 10 2024 04:58:46. | |
| textView.pyo | File | 4025 bytes | April 10 2024 04:58:46. |
import re
import sys
# Reason last stmt is continued (or C_NONE if it's not).
(C_NONE, C_BACKSLASH, C_STRING_FIRST_LINE,
C_STRING_NEXT_LINES, C_BRACKET) = range(5)
if 0: # for throwaway debugging output
def dump(*stuff):
sys.__stdout__.write(" ".join(map(str, stuff)) + "\n")
# Find what looks like the start of a popular stmt.
_synchre = re.compile(r"""
^
[ \t]*
(?: while
| else
| def
| return
| assert
| break
| class
| continue
| elif
| try
| except
| raise
| import
| yield
)
\b
""", re.VERBOSE | re.MULTILINE).search
# Match blank line or non-indenting comment line.
_junkre = re.compile(r"""
[ \t]*
(?: \# \S .* )?
\n
""", re.VERBOSE).match
# Match any flavor of string; the terminating quote is optional
# so that we're robust in the face of incomplete program text.
_match_stringre = re.compile(r"""
\""" [^"\\]* (?:
(?: \\. | "(?!"") )
[^"\\]*
)*
(?: \""" )?
| " [^"\\\n]* (?: \\. [^"\\\n]* )* "?
| ''' [^'\\]* (?:
(?: \\. | '(?!'') )
[^'\\]*
)*
(?: ''' )?
| ' [^'\\\n]* (?: \\. [^'\\\n]* )* '?
""", re.VERBOSE | re.DOTALL).match
# Match a line that starts with something interesting;
# used to find the first item of a bracket structure.
_itemre = re.compile(r"""
[ \t]*
[^\s#\\] # if we match, m.end()-1 is the interesting char
""", re.VERBOSE).match
# Match start of stmts that should be followed by a dedent.
_closere = re.compile(r"""
\s*
(?: return
| break
| continue
| raise
| pass
)
\b
""", re.VERBOSE).match
# Chew up non-special chars as quickly as possible. If match is
# successful, m.end() less 1 is the index of the last boring char
# matched. If match is unsuccessful, the string starts with an
# interesting char.
_chew_ordinaryre = re.compile(r"""
[^[\](){}#'"\\]+
""", re.VERBOSE).match
# Build translation table to map uninteresting chars to "x", open
# brackets to "(", and close brackets to ")".
_tran = ['x'] * 256
for ch in "({[":
_tran[ord(ch)] = '('
for ch in ")}]":
_tran[ord(ch)] = ')'
for ch in "\"'\\\n#":
_tran[ord(ch)] = ch
_tran = ''.join(_tran)
del ch
try:
UnicodeType = type(unicode(""))
except NameError:
UnicodeType = None
class Parser:
def __init__(self, indentwidth, tabwidth):
self.indentwidth = indentwidth
self.tabwidth = tabwidth
def set_str(self, str):
assert len(str) == 0 or str[-1] == '\n'
if type(str) is UnicodeType:
# The parse functions have no idea what to do with Unicode, so
# replace all Unicode characters with "x". This is "safe"
# so long as the only characters germane to parsing the structure
# of Python are 7-bit ASCII. It's *necessary* because Unicode
# strings don't have a .translate() method that supports
# deletechars.
uniphooey = str
str = []
push = str.append
for raw in map(ord, uniphooey):
push(raw < 127 and chr(raw) or "x")
str = "".join(str)
self.str = str
self.study_level = 0
# Return index of a good place to begin parsing, as close to the
# end of the string as possible. This will be the start of some
# popular stmt like "if" or "def". Return None if none found:
# the caller should pass more prior context then, if possible, or
# if not (the entire program text up until the point of interest
# has already been tried) pass 0 to set_lo.
#
# This will be reliable iff given a reliable is_char_in_string
# function, meaning that when it says "no", it's absolutely
# guaranteed that the char is not in a string.
def find_good_parse_start(self, is_char_in_string=None,
_synchre=_synchre):
str, pos = self.str, None
if not is_char_in_string:
# no clue -- make the caller pass everything
return None
# Peek back from the end for a good place to start,
# but don't try too often; pos will be left None, or
# bumped to a legitimate synch point.
limit = len(str)
for tries in range(5):
i = str.rfind(":\n", 0, limit)
if i < 0:
break
i = str.rfind('\n', 0, i) + 1 # start of colon line
m = _synchre(str, i, limit)
if m and not is_char_in_string(m.start()):
pos = m.start()
break
limit = i
if pos is None:
# Nothing looks like a block-opener, or stuff does
# but is_char_in_string keeps returning true; most likely
# we're in or near a giant string, the colorizer hasn't
# caught up enough to be helpful, or there simply *aren't*
# any interesting stmts. In any of these cases we're
# going to have to parse the whole thing to be sure, so
# give it one last try from the start, but stop wasting
# time here regardless of the outcome.
m = _synchre(str)
if m and not is_char_in_string(m.start()):
pos = m.start()
return pos
# Peeking back worked; look forward until _synchre no longer
# matches.
i = pos + 1
while 1:
m = _synchre(str, i)
if m:
s, i = m.span()
if not is_char_in_string(s):
pos = s
else:
break
return pos
# Throw away the start of the string. Intended to be called with
# find_good_parse_start's result.
def set_lo(self, lo):
assert lo == 0 or self.str[lo-1] == '\n'
if lo > 0:
self.str = self.str[lo:]
# As quickly as humanly possible <wink>, find the line numbers (0-
# based) of the non-continuation lines.
# Creates self.{goodlines, continuation}.
def _study1(self):
if self.study_level >= 1:
return
self.study_level = 1
# Map all uninteresting characters to "x", all open brackets
# to "(", all close brackets to ")", then collapse runs of
# uninteresting characters. This can cut the number of chars
# by a factor of 10-40, and so greatly speed the following loop.
str = self.str
str = str.translate(_tran)
str = str.replace('xxxxxxxx', 'x')
str = str.replace('xxxx', 'x')
str = str.replace('xx', 'x')
str = str.replace('xx', 'x')
str = str.replace('\nx', '\n')
# note that replacing x\n with \n would be incorrect, because
# x may be preceded by a backslash
# March over the squashed version of the program, accumulating
# the line numbers of non-continued stmts, and determining
# whether & why the last stmt is a continuation.
continuation = C_NONE
level = lno = 0 # level is nesting level; lno is line number
self.goodlines = goodlines = [0]
push_good = goodlines.append
i, n = 0, len(str)
while i < n:
ch = str[i]
i = i+1
# cases are checked in decreasing order of frequency
if ch == 'x':
continue
if ch == '\n':
lno = lno + 1
if level == 0:
push_good(lno)
# else we're in an unclosed bracket structure
continue
if ch == '(':
level = level + 1
continue
if ch == ')':
if level:
level = level - 1
# else the program is invalid, but we can't complain
continue
if ch == '"' or ch == "'":
# consume the string
quote = ch
if str[i-1:i+2] == quote * 3:
quote = quote * 3
firstlno = lno
w = len(quote) - 1
i = i+w
while i < n:
ch = str[i]
i = i+1
if ch == 'x':
continue
if str[i-1:i+w] == quote:
i = i+w
break
if ch == '\n':
lno = lno + 1
if w == 0:
# unterminated single-quoted string
if level == 0:
push_good(lno)
break
continue
if ch == '\\':
assert i < n
if str[i] == '\n':
lno = lno + 1
i = i+1
continue
# else comment char or paren inside string
else:
# didn't break out of the loop, so we're still
# inside a string
if (lno - 1) == firstlno:
# before the previous \n in str, we were in the first
# line of the string
continuation = C_STRING_FIRST_LINE
else:
continuation = C_STRING_NEXT_LINES
continue # with outer loop
if ch == '#':
# consume the comment
i = str.find('\n', i)
assert i >= 0
continue
assert ch == '\\'
assert i < n
if str[i] == '\n':
lno = lno + 1
if i+1 == n:
continuation = C_BACKSLASH
i = i+1
# The last stmt may be continued for all 3 reasons.
# String continuation takes precedence over bracket
# continuation, which beats backslash continuation.
if (continuation != C_STRING_FIRST_LINE
and continuation != C_STRING_NEXT_LINES and level > 0):
continuation = C_BRACKET
self.continuation = continuation
# Push the final line number as a sentinel value, regardless of
# whether it's continued.
assert (continuation == C_NONE) == (goodlines[-1] == lno)
if goodlines[-1] != lno:
push_good(lno)
def get_continuation_type(self):
self._study1()
return self.continuation
# study1 was sufficient to determine the continuation status,
# but doing more requires looking at every character. study2
# does this for the last interesting statement in the block.
# Creates:
# self.stmt_start, stmt_end
# slice indices of last interesting stmt
# self.stmt_bracketing
# the bracketing structure of the last interesting stmt;
# for example, for the statement "say(boo) or die", stmt_bracketing
# will be [(0, 0), (3, 1), (8, 0)]. Strings and comments are
# treated as brackets, for the matter.
# self.lastch
# last non-whitespace character before optional trailing
# comment
# self.lastopenbracketpos
# if continuation is C_BRACKET, index of last open bracket
def _study2(self):
if self.study_level >= 2:
return
self._study1()
self.study_level = 2
# Set p and q to slice indices of last interesting stmt.
str, goodlines = self.str, self.goodlines
i = len(goodlines) - 1
p = len(str) # index of newest line
while i:
assert p
# p is the index of the stmt at line number goodlines[i].
# Move p back to the stmt at line number goodlines[i-1].
q = p
for nothing in range(goodlines[i-1], goodlines[i]):
# tricky: sets p to 0 if no preceding newline
p = str.rfind('\n', 0, p-1) + 1
# The stmt str[p:q] isn't a continuation, but may be blank
# or a non-indenting comment line.
if _junkre(str, p):
i = i-1
else:
break
if i == 0:
# nothing but junk!
assert p == 0
q = p
self.stmt_start, self.stmt_end = p, q
# Analyze this stmt, to find the last open bracket (if any)
# and last interesting character (if any).
lastch = ""
stack = [] # stack of open bracket indices
push_stack = stack.append
bracketing = [(p, 0)]
while p < q:
# suck up all except ()[]{}'"#\\
m = _chew_ordinaryre(str, p, q)
if m:
# we skipped at least one boring char
newp = m.end()
# back up over totally boring whitespace
i = newp - 1 # index of last boring char
while i >= p and str[i] in " \t\n":
i = i-1
if i >= p:
lastch = str[i]
p = newp
if p >= q:
break
ch = str[p]
if ch in "([{":
push_stack(p)
bracketing.append((p, len(stack)))
lastch = ch
p = p+1
continue
if ch in ")]}":
if stack:
del stack[-1]
lastch = ch
p = p+1
bracketing.append((p, len(stack)))
continue
if ch == '"' or ch == "'":
# consume string
# Note that study1 did this with a Python loop, but
# we use a regexp here; the reason is speed in both
# cases; the string may be huge, but study1 pre-squashed
# strings to a couple of characters per line. study1
# also needed to keep track of newlines, and we don't
# have to.
bracketing.append((p, len(stack)+1))
lastch = ch
p = _match_stringre(str, p, q).end()
bracketing.append((p, len(stack)))
continue
if ch == '#':
# consume comment and trailing newline
bracketing.append((p, len(stack)+1))
p = str.find('\n', p, q) + 1
assert p > 0
bracketing.append((p, len(stack)))
continue
assert ch == '\\'
p = p+1 # beyond backslash
assert p < q
if str[p] != '\n':
# the program is invalid, but can't complain
lastch = ch + str[p]
p = p+1 # beyond escaped char
# end while p < q:
self.lastch = lastch
if stack:
self.lastopenbracketpos = stack[-1]
self.stmt_bracketing = tuple(bracketing)
# Assuming continuation is C_BRACKET, return the number
# of spaces the next line should be indented.
def compute_bracket_indent(self):
self._study2()
assert self.continuation == C_BRACKET
j = self.lastopenbracketpos
str = self.str
n = len(str)
origi = i = str.rfind('\n', 0, j) + 1
j = j+1 # one beyond open bracket
# find first list item; set i to start of its line
while j < n:
m = _itemre(str, j)
if m:
j = m.end() - 1 # index of first interesting char
extra = 0
break
else:
# this line is junk; advance to next line
i = j = str.find('\n', j) + 1
else:
# nothing interesting follows the bracket;
# reproduce the bracket line's indentation + a level
j = i = origi
while str[j] in " \t":
j = j+1
extra = self.indentwidth
return len(str[i:j].expandtabs(self.tabwidth)) + extra
# Return number of physical lines in last stmt (whether or not
# it's an interesting stmt! this is intended to be called when
# continuation is C_BACKSLASH).
def get_num_lines_in_stmt(self):
self._study1()
goodlines = self.goodlines
return goodlines[-1] - goodlines[-2]
# Assuming continuation is C_BACKSLASH, return the number of spaces
# the next line should be indented. Also assuming the new line is
# the first one following the initial line of the stmt.
def compute_backslash_indent(self):
self._study2()
assert self.continuation == C_BACKSLASH
str = self.str
i = self.stmt_start
while str[i] in " \t":
i = i+1
startpos = i
# See whether the initial line starts an assignment stmt; i.e.,
# look for an = operator
endpos = str.find('\n', startpos) + 1
found = level = 0
while i < endpos:
ch = str[i]
if ch in "([{":
level = level + 1
i = i+1
elif ch in ")]}":
if level:
level = level - 1
i = i+1
elif ch == '"' or ch == "'":
i = _match_stringre(str, i, endpos).end()
elif ch == '#':
break
elif level == 0 and ch == '=' and \
(i == 0 or str[i-1] not in "=<>!") and \
str[i+1] != '=':
found = 1
break
else:
i = i+1
if found:
# found a legit =, but it may be the last interesting
# thing on the line
i = i+1 # move beyond the =
found = re.match(r"\s*\\", str[i:endpos]) is None
if not found:
# oh well ... settle for moving beyond the first chunk
# of non-whitespace chars
i = startpos
while str[i] not in " \t\n":
i = i+1
return len(str[self.stmt_start:i].expandtabs(\
self.tabwidth)) + 1
# Return the leading whitespace on the initial line of the last
# interesting stmt.
def get_base_indent_string(self):
self._study2()
i, n = self.stmt_start, self.stmt_end
j = i
str = self.str
while j < n and str[j] in " \t":
j = j + 1
return str[i:j]
# Did the last interesting stmt open a block?
def is_block_opener(self):
self._study2()
return self.lastch == ':'
# Did the last interesting stmt close a block?
def is_block_closer(self):
self._study2()
return _closere(self.str, self.stmt_start) is not None
# index of last open bracket ({[, or None if none
lastopenbracketpos = None
def get_last_open_bracket_pos(self):
self._study2()
return self.lastopenbracketpos
# the structure of the bracketing of the last interesting statement,
# in the format defined in _study2, or None if the text didn't contain
# anything
stmt_bracketing = None
def get_last_stmt_bracketing(self):
self._study2()
return self.stmt_bracketing
SILENT KILLER Tool