mirror of
https://github.com/aykhans/AzSuicideDataVisualization.git
synced 2025-07-04 23:32:37 +00:00
first commit
This commit is contained in:
361
.venv/Lib/site-packages/pythonwin/pywin/scintilla/config.py
Normal file
361
.venv/Lib/site-packages/pythonwin/pywin/scintilla/config.py
Normal file
@ -0,0 +1,361 @@
|
||||
# config.py - deals with loading configuration information.
|
||||
|
||||
# Loads config data from a .cfg file. Also caches the compiled
|
||||
# data back into a .cfc file.
|
||||
|
||||
# If you are wondering how to avoid needing .cfg files (eg,
|
||||
# if you are freezing Pythonwin etc) I suggest you create a
|
||||
# .py file, and put the config info in a docstring. Then
|
||||
# pass a CStringIO file (rather than a filename) to the
|
||||
# config manager.
|
||||
import sys
|
||||
import string
|
||||
from . import keycodes
|
||||
import marshal
|
||||
import stat
|
||||
import os
|
||||
import types
|
||||
import traceback
|
||||
import pywin
|
||||
import glob
|
||||
import importlib.util
|
||||
|
||||
import win32api
|
||||
|
||||
debugging = 0
|
||||
if debugging:
|
||||
import win32traceutil # Some trace statements fire before the interactive window is open.
|
||||
|
||||
def trace(*args):
|
||||
sys.stderr.write(" ".join(map(str, args)) + "\n")
|
||||
|
||||
else:
|
||||
trace = lambda *args: None
|
||||
|
||||
compiled_config_version = 3
|
||||
|
||||
|
||||
def split_line(line, lineno):
|
||||
comment_pos = line.find("#")
|
||||
if comment_pos >= 0:
|
||||
line = line[:comment_pos]
|
||||
sep_pos = line.rfind("=")
|
||||
if sep_pos == -1:
|
||||
if line.strip():
|
||||
print("Warning: Line %d: %s is an invalid entry" % (lineno, repr(line)))
|
||||
return None, None
|
||||
return "", ""
|
||||
return line[:sep_pos].strip(), line[sep_pos + 1 :].strip()
|
||||
|
||||
|
||||
def get_section_header(line):
|
||||
# Returns the section if the line is a section header, else None
|
||||
if line[0] == "[":
|
||||
end = line.find("]")
|
||||
if end == -1:
|
||||
end = len(line)
|
||||
rc = line[1:end].lower()
|
||||
try:
|
||||
i = rc.index(":")
|
||||
return rc[:i], rc[i + 1 :]
|
||||
except ValueError:
|
||||
return rc, ""
|
||||
return None, None
|
||||
|
||||
|
||||
def find_config_file(f):
|
||||
return os.path.join(pywin.__path__[0], f + ".cfg")
|
||||
|
||||
|
||||
def find_config_files():
|
||||
return [
|
||||
os.path.split(x)[1]
|
||||
for x in [
|
||||
os.path.splitext(x)[0]
|
||||
for x in glob.glob(os.path.join(pywin.__path__[0], "*.cfg"))
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
class ConfigManager:
|
||||
def __init__(self, f):
|
||||
self.filename = "unknown"
|
||||
self.last_error = None
|
||||
self.key_to_events = {}
|
||||
if hasattr(f, "readline"):
|
||||
fp = f
|
||||
self.filename = "<config string>"
|
||||
compiled_name = None
|
||||
else:
|
||||
try:
|
||||
f = find_config_file(f)
|
||||
src_stat = os.stat(f)
|
||||
except os.error:
|
||||
self.report_error("Config file '%s' not found" % f)
|
||||
return
|
||||
self.filename = f
|
||||
self.basename = os.path.basename(f)
|
||||
trace("Loading configuration", self.basename)
|
||||
compiled_name = os.path.splitext(f)[0] + ".cfc"
|
||||
try:
|
||||
cf = open(compiled_name, "rb")
|
||||
try:
|
||||
ver = marshal.load(cf)
|
||||
ok = compiled_config_version == ver
|
||||
if ok:
|
||||
kblayoutname = marshal.load(cf)
|
||||
magic = marshal.load(cf)
|
||||
size = marshal.load(cf)
|
||||
mtime = marshal.load(cf)
|
||||
if (
|
||||
magic == importlib.util.MAGIC_NUMBER
|
||||
and win32api.GetKeyboardLayoutName() == kblayoutname
|
||||
and src_stat[stat.ST_MTIME] == mtime
|
||||
and src_stat[stat.ST_SIZE] == size
|
||||
):
|
||||
self.cache = marshal.load(cf)
|
||||
trace("Configuration loaded cached", compiled_name)
|
||||
return # We are ready to roll!
|
||||
finally:
|
||||
cf.close()
|
||||
except (os.error, IOError, EOFError):
|
||||
pass
|
||||
fp = open(f)
|
||||
self.cache = {}
|
||||
lineno = 1
|
||||
line = fp.readline()
|
||||
while line:
|
||||
# Skip to the next section (maybe already there!)
|
||||
section, subsection = get_section_header(line)
|
||||
while line and section is None:
|
||||
line = fp.readline()
|
||||
if not line:
|
||||
break
|
||||
lineno = lineno + 1
|
||||
section, subsection = get_section_header(line)
|
||||
if not line:
|
||||
break
|
||||
|
||||
if section == "keys":
|
||||
line, lineno = self._load_keys(subsection, fp, lineno)
|
||||
elif section == "extensions":
|
||||
line, lineno = self._load_extensions(subsection, fp, lineno)
|
||||
elif section == "idle extensions":
|
||||
line, lineno = self._load_idle_extensions(subsection, fp, lineno)
|
||||
elif section == "general":
|
||||
line, lineno = self._load_general(subsection, fp, lineno)
|
||||
else:
|
||||
self.report_error(
|
||||
"Unrecognised section header '%s:%s'" % (section, subsection)
|
||||
)
|
||||
line = fp.readline()
|
||||
lineno = lineno + 1
|
||||
# Check critical data.
|
||||
if not self.cache.get("keys"):
|
||||
self.report_error("No keyboard definitions were loaded")
|
||||
if not self.last_error and compiled_name:
|
||||
try:
|
||||
cf = open(compiled_name, "wb")
|
||||
marshal.dump(compiled_config_version, cf)
|
||||
marshal.dump(win32api.GetKeyboardLayoutName(), cf)
|
||||
marshal.dump(importlib.util.MAGIC_NUMBER, cf)
|
||||
marshal.dump(src_stat[stat.ST_SIZE], cf)
|
||||
marshal.dump(src_stat[stat.ST_MTIME], cf)
|
||||
marshal.dump(self.cache, cf)
|
||||
cf.close()
|
||||
except (IOError, EOFError):
|
||||
pass # Ignore errors - may be read only.
|
||||
|
||||
def configure(self, editor, subsections=None):
|
||||
# Execute the extension code, and find any events.
|
||||
# First, we "recursively" connect any we are based on.
|
||||
if subsections is None:
|
||||
subsections = []
|
||||
subsections = [""] + subsections
|
||||
general = self.get_data("general")
|
||||
if general:
|
||||
parents = general.get("based on", [])
|
||||
for parent in parents:
|
||||
trace("Configuration based on", parent, "- loading.")
|
||||
parent = self.__class__(parent)
|
||||
parent.configure(editor, subsections)
|
||||
if parent.last_error:
|
||||
self.report_error(parent.last_error)
|
||||
|
||||
bindings = editor.bindings
|
||||
codeob = self.get_data("extension code")
|
||||
if codeob is not None:
|
||||
ns = {}
|
||||
try:
|
||||
exec(codeob, ns)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
self.report_error("Executing extension code failed")
|
||||
ns = None
|
||||
if ns:
|
||||
num = 0
|
||||
for name, func in list(ns.items()):
|
||||
if type(func) == types.FunctionType and name[:1] != "_":
|
||||
bindings.bind(name, func)
|
||||
num = num + 1
|
||||
trace("Configuration Extension code loaded", num, "events")
|
||||
# Load the idle extensions
|
||||
for subsection in subsections:
|
||||
for ext in self.get_data("idle extensions", {}).get(subsection, []):
|
||||
try:
|
||||
editor.idle.IDLEExtension(ext)
|
||||
trace("Loaded IDLE extension", ext)
|
||||
except:
|
||||
self.report_error("Can not load the IDLE extension '%s'" % ext)
|
||||
|
||||
# Now bind up the key-map (remembering a reverse map
|
||||
subsection_keymap = self.get_data("keys")
|
||||
num_bound = 0
|
||||
for subsection in subsections:
|
||||
keymap = subsection_keymap.get(subsection, {})
|
||||
bindings.update_keymap(keymap)
|
||||
num_bound = num_bound + len(keymap)
|
||||
trace("Configuration bound", num_bound, "keys")
|
||||
|
||||
def get_key_binding(self, event, subsections=None):
|
||||
if subsections is None:
|
||||
subsections = []
|
||||
subsections = [""] + subsections
|
||||
|
||||
subsection_keymap = self.get_data("keys")
|
||||
for subsection in subsections:
|
||||
map = self.key_to_events.get(subsection)
|
||||
if map is None: # Build it
|
||||
map = {}
|
||||
keymap = subsection_keymap.get(subsection, {})
|
||||
for key_info, map_event in list(keymap.items()):
|
||||
map[map_event] = key_info
|
||||
self.key_to_events[subsection] = map
|
||||
|
||||
info = map.get(event)
|
||||
if info is not None:
|
||||
return keycodes.make_key_name(info[0], info[1])
|
||||
return None
|
||||
|
||||
def report_error(self, msg):
|
||||
self.last_error = msg
|
||||
print("Error in %s: %s" % (self.filename, msg))
|
||||
|
||||
def report_warning(self, msg):
|
||||
print("Warning in %s: %s" % (self.filename, msg))
|
||||
|
||||
def _readline(self, fp, lineno, bStripComments=1):
|
||||
line = fp.readline()
|
||||
lineno = lineno + 1
|
||||
if line:
|
||||
bBreak = (
|
||||
get_section_header(line)[0] is not None
|
||||
) # A new section is starting
|
||||
if bStripComments and not bBreak:
|
||||
pos = line.find("#")
|
||||
if pos >= 0:
|
||||
line = line[:pos] + "\n"
|
||||
else:
|
||||
bBreak = 1
|
||||
return line, lineno, bBreak
|
||||
|
||||
def get_data(self, name, default=None):
|
||||
return self.cache.get(name, default)
|
||||
|
||||
def _save_data(self, name, data):
|
||||
self.cache[name] = data
|
||||
return data
|
||||
|
||||
def _load_general(self, sub_section, fp, lineno):
|
||||
map = {}
|
||||
while 1:
|
||||
line, lineno, bBreak = self._readline(fp, lineno)
|
||||
if bBreak:
|
||||
break
|
||||
|
||||
key, val = split_line(line, lineno)
|
||||
if not key:
|
||||
continue
|
||||
key = key.lower()
|
||||
l = map.get(key, [])
|
||||
l.append(val)
|
||||
map[key] = l
|
||||
self._save_data("general", map)
|
||||
return line, lineno
|
||||
|
||||
def _load_keys(self, sub_section, fp, lineno):
|
||||
# Builds a nested dictionary of
|
||||
# (scancode, flags) = event_name
|
||||
main_map = self.get_data("keys", {})
|
||||
map = main_map.get(sub_section, {})
|
||||
while 1:
|
||||
line, lineno, bBreak = self._readline(fp, lineno)
|
||||
if bBreak:
|
||||
break
|
||||
|
||||
key, event = split_line(line, lineno)
|
||||
if not event:
|
||||
continue
|
||||
sc, flag = keycodes.parse_key_name(key)
|
||||
if sc is None:
|
||||
self.report_warning("Line %d: Invalid key name '%s'" % (lineno, key))
|
||||
else:
|
||||
map[sc, flag] = event
|
||||
main_map[sub_section] = map
|
||||
self._save_data("keys", main_map)
|
||||
return line, lineno
|
||||
|
||||
def _load_extensions(self, sub_section, fp, lineno):
|
||||
start_lineno = lineno
|
||||
lines = []
|
||||
while 1:
|
||||
line, lineno, bBreak = self._readline(fp, lineno, 0)
|
||||
if bBreak:
|
||||
break
|
||||
lines.append(line)
|
||||
try:
|
||||
c = compile(
|
||||
"\n" * start_lineno + "".join(lines), # produces correct tracebacks
|
||||
self.filename,
|
||||
"exec",
|
||||
)
|
||||
self._save_data("extension code", c)
|
||||
except SyntaxError as details:
|
||||
errlineno = details.lineno + start_lineno
|
||||
# Should handle syntax errors better here, and offset the lineno.
|
||||
self.report_error(
|
||||
"Compiling extension code failed:\r\nFile: %s\r\nLine %d\r\n%s"
|
||||
% (details.filename, errlineno, details.msg)
|
||||
)
|
||||
return line, lineno
|
||||
|
||||
def _load_idle_extensions(self, sub_section, fp, lineno):
|
||||
extension_map = self.get_data("idle extensions")
|
||||
if extension_map is None:
|
||||
extension_map = {}
|
||||
extensions = []
|
||||
while 1:
|
||||
line, lineno, bBreak = self._readline(fp, lineno)
|
||||
if bBreak:
|
||||
break
|
||||
line = line.strip()
|
||||
if line:
|
||||
extensions.append(line)
|
||||
extension_map[sub_section] = extensions
|
||||
self._save_data("idle extensions", extension_map)
|
||||
return line, lineno
|
||||
|
||||
|
||||
def test():
|
||||
import time
|
||||
|
||||
start = time.clock()
|
||||
f = "default"
|
||||
cm = ConfigManager(f)
|
||||
map = cm.get_data("keys")
|
||||
took = time.clock() - start
|
||||
print("Loaded %s items in %.4f secs" % (len(map), took))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test()
|
Reference in New Issue
Block a user