/usr/share/gps/plug-ins/expanded_code.py is in gnat-gps-common 6.1.2016-1ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | """
This file provides support for displaying Ada expanded code as generated by
GNAT (-gnatGL switch).
"""
import os
import os.path
import distutils.dep_util
import GPS
from gps_utils import *
def create_dg(f, str):
res = file(f, 'wb')
first = str.find(
"\n", str.find("\n", str.find("Source recreated from tree")) + 1) + 2
if first > 2:
last = str.find("Source recreated from tree", first)
res.write(str[first:last - 1])
res.close()
expanded_code_marks = {}
# A dictionary that associates a source filename with a list of marks
highlighting = ""
bg_pref = GPS.Preference("Editor/Ada/expanded_code_style")
bg_pref.create(
"Expanded code color", "color", "Background color of expanded code",
"#dddddd"
)
def subprogram_bounds(cursor):
"""Return the first and last line of the current subprogram, and (0,0) if
the current subprogram could not be determined."""
blocks = {"CAT_PROCEDURE": 1, "CAT_FUNCTION": 1, "CAT_ENTRY": 1,
"CAT_PROTECTED": 1, "CAT_TASK": 1, "CAT_PACKAGE": 1}
if cursor.block_type() == "CAT_UNKNOWN":
return 0, 0
min = cursor.buffer().beginning_of_buffer()
while not (cursor.block_type() in blocks) and cursor > min:
cursor = cursor.block_start() - 1
if cursor > min:
return cursor.block_start_line(), cursor.block_end_line()
else:
return 0, 0
def clear_dg(source_filename):
""" Clear dg information for filename """
global expanded_code_marks
if source_filename in expanded_code_marks:
# Remove special lines
srcbuf = GPS.EditorBuffer.get(GPS.File(source_filename))
for (mark, lines) in expanded_code_marks[source_filename]:
srcbuf.remove_special_lines(mark, lines)
# Empty entry in the dictionary
expanded_code_marks[source_filename] = []
def edit_dg(dg, source_filename, line, for_subprogram, in_external_editor):
global highlighting, expanded_code_marks
# If we are showing the dg in an external editor, simply open this editor
# and jump to the line
if in_external_editor:
buf = GPS.EditorBuffer.get(GPS.File(dg))
loc = buf.at(1, 1)
try:
(frm, to) = loc.search("^-- " + repr(line) + ":", regexp=True)
if frm:
buf.current_view().goto(frm.forward_line(1))
except Exception:
pass
return
# If the highlighting category does not exist, register it now
if highlighting == "":
highlighting = "expanded"
Editor.register_highlighting(highlighting, bg_pref.get(), False)
clear_dg(source_filename)
srcbuf = GPS.EditorBuffer.get(GPS.File(source_filename))
if for_subprogram:
(block_first, block_last) = subprogram_bounds(
srcbuf.current_view().cursor())
else:
(block_first, block_last) = (0, 0)
# Read the text of the dg file
f = open(dg)
txt = f.read()
f.close()
current_code = []
current_line = 1
lines = 0
for line in txt.split("\n"):
if line.startswith("-- "):
if current_code:
if (block_first == 0
or (block_first < current_line < block_last)):
mark = srcbuf.add_special_line(current_line + 1,
"\n".join(current_code),
highlighting)
# Add mark to the list of marks
mark_num = (mark, len(current_code))
if source_filename in expanded_code_marks:
expanded_code_marks[source_filename] += [mark_num]
else:
expanded_code_marks[source_filename] = [mark_num]
current_line = int(line[3:line.find(":")])
current_code = []
else:
if line != "":
lines += 1
current_code.append(line)
# noinspection PyUnusedLocal
def on_exit(process, status, full_output):
create_dg(process.dg, full_output)
edit_dg(process.dg, process.source_filename,
process.line, process.for_subprogram, process.in_external_editor)
def show_gnatdg(for_subprogram=False, in_external_editor=False):
"""Show the .dg file of the current file"""
GPS.MDI.save_all(False)
context = GPS.current_context()
local_file = context.file().name()
file = context.file().name("Build_Server")
line = context.location().line()
try:
if context.project():
l = context.project().object_dirs(False)
prj = ' -P """' + \
GPS.Project.root().file().name("Build_Server") + '"""'
else:
l = GPS.Project.root().object_dirs(False)
prj = " -a"
except Exception:
GPS.Console("Messages").write(
"Could not obtain project information for this file")
return
if l:
objdir = l[0]
else:
objdir = GPS.get_tmp_dir()
GPS.Console("Messages").write(
"Could not find an object directory for %s, reverting to %s" %
(file, objdir))
dg = os.path.join(objdir, os.path.basename(local_file)) + '.dg'
if distutils.dep_util.newer(local_file, dg):
cmd = 'gprbuild -q %s -f -c -u -gnatcdx -gnatws -gnatGL """%s"""' % (
prj, file)
GPS.Console("Messages").write("Generating " + dg + "...\n")
proc = GPS.Process(cmd, on_exit=on_exit, remote_server="Build_Server")
proc.source_filename = local_file
proc.dg = dg
proc.line = line
proc.for_subprogram = for_subprogram
proc.in_external_editor = in_external_editor
else:
edit_dg(dg, local_file, line, for_subprogram, in_external_editor)
#################################
# Register the contextual menus #
#################################
@interactive("Ada", in_ada_file, contextual="Expanded code/Show subprogram",
name="show expanded code for subprogram", before="Align")
def show_gnatdg_subprogram():
"""Show the expanded code of the current subprogram"""
show_gnatdg(True)
@interactive("Ada", in_ada_file, contextual="Expanded code/Show entire file",
name="show expanded code for file", before="Align")
def show_gnatdg_file():
"""Show the .dg file of the current file"""
show_gnatdg(False)
@interactive(
"Ada", in_ada_file, contextual="Expanded code/Show in separate editor",
name="show expanded code in separate editor", before="Align")
def show_gnatdg_separate_editor():
"""Show the expanded code of the current subprogram"""
show_gnatdg(False, True)
@interactive("Ada", in_ada_file, contextual="Expanded code/Clear",
name="clear expanded code", before="Align")
def clear_expanded_code():
"""Show the expanded code of the current subprogram"""
context = GPS.current_context()
clear_dg(context.file().name())
|