~ubuntu-branches/ubuntu/jaunty/adacontrol/jaunty

« back to all changes in this revision

Viewing changes to GPS-old/adactl.py

  • Committer: Bazaar Package Importer
  • Author(s): Ludovic Brenta
  • Date: 2008-04-27 15:25:59 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20080427152559-qrlic533a1x02flu
Tags: 1.8r8-1

* New upstream version.
* debian/adacontrol.gpr: delete; use upstream's project file instead.
* patches/build.patch: patch upstream's project file to change Object_Dir
  and Exec_Dir.
* Build-depend on asis 2007 and gnat-4.3.
* Add support for mips, mipsel and ppc64.
* Build and provide ptree.
* ptree.1: new.
* adactl.1: update; new options and rules are available.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#  This file adds support for AdaControl
 
2
 
 
3
# If you are using GPS 3.x, change "true" to "false" in the next line:
 
4
GPS4_Bug=True
 
5
 
 
6
#######################################################################
 
7
import GPS, os, glob, re, sets
 
8
 
 
9
# Clean-up various windows before running AdaControl
 
10
def pre_clean ():
 
11
   GPS.MDI.save_all (GPS.Preference ("force-save").get())
 
12
   for C in adactl_cats:
 
13
      GPS.Locations.remove_category (C)
 
14
   GPS.MDI.get("Messages").raise_window()
 
15
 
 
16
# Clean-up after running AdaControl
 
17
def post_clean ():
 
18
   if GPS.Preference ("delete-trees").get():
 
19
      del_tree (confirm=False)
 
20
 
 
21
# Get the command name for AdaControl
 
22
def command_name ():
 
23
   result = GPS.Project.root().get_attribute_as_string("compiler_command", "Ide", "AdaControl")
 
24
   if result == "":
 
25
      return "adactl"
 
26
   else:
 
27
      return result
 
28
 
 
29
# Builds the options string
 
30
# Options -f and @ are defined as switches for the convenience of the user
 
31
# but they are actually passed as explicit parameters depending on the way
 
32
# Adacontrol is launched. We must therefore remove these options from the
 
33
# switches string provided by GPS.
 
34
# Similarly, the -o option depends on the setting of the (pseudo) switch
 
35
# -NOGPS
 
36
def options ():
 
37
   opt_list=GPS.Project.root().get_tool_switches_as_list("AdaControl")
 
38
   gps=True
 
39
   result="-v "
 
40
   skip_next=False
 
41
   outfile=""
 
42
   next_is_file=False
 
43
   for O in opt_list:
 
44
      if next_is_file:
 
45
         outfile=O
 
46
         result= result + ' ' + O
 
47
         next_is_file=False
 
48
      elif skip_next:
 
49
         skip_next=False
 
50
      elif O == "-NOGPS":
 
51
         gps=False
 
52
      elif O == "-F" and gps:
 
53
         skip_next=True
 
54
      elif O == "-o":
 
55
         if gps:
 
56
            skip_next=True
 
57
         else:
 
58
            next_is_file=True
 
59
            result= result + ' ' + O
 
60
      elif O[0] == "@":
 
61
         pass
 
62
      elif O == "-f":
 
63
         skip_next=True
 
64
      else:
 
65
         result= result + ' ' + O
 
66
 
 
67
   if not gps:
 
68
      if outfile == "":
 
69
         GPS.MDI.dialog ("Result file is not defined, please set it in Project properties/Switches/AdaControl")
 
70
         raise ValueError
 
71
      elif len (glob.glob(outfile)) != 0:
 
72
         if GPS.MDI.yes_no_dialog ("File " + outfile + " exists, override?"):
 
73
            result= result + " -w"
 
74
         else:
 
75
            raise ValueError
 
76
 
 
77
   result = result  + " --"
 
78
   for I in GPS.Project.dependencies (GPS.Project.root(), recursive=True) :
 
79
      for J in GPS.Project.source_dirs(I) :
 
80
         result=result +  '  -I' + J.replace("\\", "/")
 
81
 
 
82
   result = result + "   "
 
83
   return result
 
84
 
 
85
# Make a '+'-separated list of all units in the project
 
86
def Project_units ():
 
87
   files=GPS.Project.root().sources()
 
88
   result= ""
 
89
   prev_name=""
 
90
   for f in files:
 
91
      if GPS.File.language (f) == "ada":
 
92
         name= os.path.splitext(os.path.basename (f.name()))[0]
 
93
         name= re.sub("-", ".", name)
 
94
         if name != prev_name:
 
95
            result= result + '+' + name
 
96
            prev_name=name
 
97
   return result
 
98
 
 
99
# Compare two source references
 
100
# If the references are the same, keep the original order
 
101
# (for the case of error messages that span several lines)
 
102
def sloc_cmp (l,r):
 
103
   "Compare SLOC references (file:line:col)"
 
104
   ls=l.split(':');
 
105
   rs=r.split(':');
 
106
   if len(ls[0]) == 1:
 
107
      # Presumably, we have a "C:"...
 
108
      Offset=1
 
109
   else:
 
110
      Offset=0
 
111
 
 
112
   if len(ls) < 5+Offset and len(rs) < 3+Offset:
 
113
      # No reference =>Keep order
 
114
      return -1
 
115
   if len(ls) < 5+Offset:
 
116
      # Reference only in r: put references ahead
 
117
      return 1
 
118
   if len(rs) < 5+Offset:
 
119
      # Reference only in l: put references ahead
 
120
      return -1
 
121
 
 
122
   if ls[0+Offset] != rs [0+Offset]:
 
123
      return cmp (ls[0+Offset], rs[0+Offset])
 
124
   if ls[1+Offset] != rs[1+Offset]:
 
125
      return cmp (int(ls[1+Offset]), int(rs[1+Offset]))
 
126
   return cmp (int(ls[2+Offset]), int(rs[2+Offset]))
 
127
 
 
128
# Sort and parse the result of running Adacontrol
 
129
def parse (output):
 
130
   global adactl_cats
 
131
   list=output.splitlines()
 
132
   list.sort(sloc_cmp)
 
133
   pos=0
 
134
   category = "Adacontrol"
 
135
   adactl_cats = sets.Set()
 
136
   for Mess in list:
 
137
     pos+=1
 
138
     if re.match ("^(.+):(\\d+):(\\d+): (Found:|Error:|Parameter:|Syntax:).*$", Mess):
 
139
       # Regular AdaCtl message
 
140
       if GPS.Preference ("separate-rules").get():
 
141
          category = re.sub (r"^.+:\d+:\d+: \w+: (.*?):.*$", r"\1", Mess)
 
142
       adactl_cats.add (category)
 
143
       GPS.Locations.parse (Mess,
 
144
         category,
 
145
         "^(.+):(\\d+):(\\d+): (((Found:)|(Error:|Parameter:|Syntax:)).*)$",
 
146
         1, 2, 3, 4, 7, 6,
 
147
         "",
 
148
         "Adactl_check",
 
149
         "Adactl_found")
 
150
     elif re.match ("^(\\d+: )?(Found:|Error:|Parameter:|Syntax:).*$", Mess):
 
151
       # AdaCtl message without location, or just a column location (syntax error in interactive command)
 
152
       if GPS.Preference ("separate-rules").get():
 
153
          category = re.sub (r"^(\\d+: )?\w+: (.*?):.*$", r"\2", Mess)
 
154
       adactl_cats.add (category)
 
155
       message  = re.sub (r"^(\\d+: )?(\w+: ).*?:(.*)$", r"\2", Mess) + re.sub (r"^(\\d+: )?\w+: .*?:(.*)$", r"\2", Mess)
 
156
       try:
 
157
          GPS.Locations.add (category, GPS.File("none"), 1, 1, message)
 
158
       except:
 
159
          # Always an exception, since file "none" does not exist (presumably)
 
160
          pass
 
161
     elif re.match (r"^.*: ((Check: \d+, Search: \d+, Count: \d+)|(not triggered))$", Mess):
 
162
       # Count summary
 
163
       adactl_cats.add ("Counts summary")
 
164
       try:
 
165
          GPS.Locations.add ("Counts summary", GPS.File(re.sub(r"^(.*): ((Check: \d+, Search: \d+, Count: \d+)|(not triggered))$", r"\1", Mess)), 1, 1, Mess)
 
166
       except:
 
167
          # Always an exception, since file does not exist
 
168
          pass
 
169
     else:
 
170
       # Assume it is a compilation message
 
171
       redundant=False
 
172
       for Other in list[max (0,pos-5):pos-1]:
 
173
         if Mess == Other:
 
174
           redundant=True
 
175
           break
 
176
       if not redundant:
 
177
         GPS.Locations.parse (Mess, "Compilation")
 
178
         adactl_cats.add ("Compilation")
 
179
 
 
180
# Ask for confirmation, then delete tree files (and possibly .ali files)
 
181
def del_tree (confirm):
 
182
   dir      = os.getcwd()
 
183
   ali_also = GPS.Preference ("delete-ali").get()
 
184
   if ali_also:
 
185
      supp = "and .ali "
 
186
   else:
 
187
      supp = ""
 
188
   if not confirm or GPS.MDI.yes_no_dialog ("Remove all tree "
 
189
                                            + supp
 
190
                                            + "files from " + dir + "?"):
 
191
      for I in glob.glob (os.path.join (dir, "*.adt")):
 
192
         os.remove (I)
 
193
      if ali_also:
 
194
         for I in glob.glob (os.path.join (dir, "*.ali")):
 
195
            os.remove (I)
 
196
 
 
197
# Create adp file from project
 
198
def create_adp ():
 
199
   name= GPS.Project.file(GPS.Project.root()).name()[:-4]+".adp"
 
200
   if GPS.MDI.yes_no_dialog ("Create " + name + "?"):
 
201
      f=open (name, 'w')
 
202
      for I in [GPS.Project.root()] + GPS.Project.dependencies (GPS.Project.root()) :
 
203
         for J in GPS.Project.source_dirs(I) :
 
204
            f.write ("src_dir=" + J + "\n")
 
205
         for J in GPS.Project.object_dirs(I) :
 
206
            f.write ("obj_dir=" + J + "\n")
 
207
      f.close
 
208
      print ("Project file " + name + " created")
 
209
 
 
210
# Return the units file
 
211
def get_units_file ():
 
212
   opt_list=GPS.Project.root().get_tool_switches_as_list("AdaControl")
 
213
   for O in opt_list:
 
214
      if O[0] == "@":
 
215
         return O[1:]
 
216
   return ""
 
217
 
 
218
# Is the units file defined?
 
219
def units_file_defined ():
 
220
   if get_units_file() == "":
 
221
      return "false"
 
222
   else:
 
223
      return "true"
 
224
 
 
225
# Get the rules file
 
226
def get_rules_file ():
 
227
   opt_list=GPS.Project.root().get_tool_switches_as_list("AdaControl")
 
228
   next_is_result=False
 
229
   for O in opt_list:
 
230
      if next_is_result:
 
231
         return O
 
232
      elif O == "-f":
 
233
         next_is_result=True
 
234
   return ""
 
235
 
 
236
# Is the rules file defined?
 
237
def rules_file_defined ():
 
238
   if get_rules_file() == "":
 
239
      return "false"
 
240
   else:
 
241
      return "true"
 
242
 
 
243
# Run Adacontrol
 
244
# rules = "ask" | "file"
 
245
# files = "current" | "list" | "project" | "" (means: depending on button definition)
 
246
def run (rules, files):
 
247
   global previous_command
 
248
 
 
249
   if files == "":
 
250
      tmp = GPS.Preference ("button-target").get();
 
251
      if tmp == "Current File":
 
252
         files = "current"
 
253
      elif tmp == "Root Project":
 
254
         files = "project"
 
255
      else: # Units from list
 
256
         files = "list"
 
257
 
 
258
   if files == "current":
 
259
      try:
 
260
         win = GPS.current_context().file()
 
261
      except:
 
262
         GPS.MDI.dialog ("no active window")
 
263
         return
 
264
      if win.language() != "ada" :
 
265
         GPS.MDI.dialog ("active window is not Ada")
 
266
         return
 
267
      files_param = win.name()
 
268
   elif files == "list":
 
269
      files_param = "@" + get_units_file()
 
270
   else:   # "project"
 
271
      files_param = Project_units()
 
272
 
 
273
   if rules == "ask":
 
274
      value=GPS.MDI.input_dialog ("Interactive run", "Command(s)=" + previous_command)
 
275
      if value != [] and value [0] != "":
 
276
         previous_command= value[0]
 
277
         rules_param = "-l \"" + re.sub('"', '~', previous_command) + "\""
 
278
      else:
 
279
         return
 
280
   else:
 
281
      if rules_file_defined () == "false" :
 
282
         GPS.MDI.dialog ("no rules file defined")
 
283
         return
 
284
      rules_param = "-f " + get_rules_file()
 
285
 
 
286
   pre_clean()
 
287
   if GPS4_Bug:
 
288
      GPS.execute_asynchronous_action ("AdaControl", command_name(), rules_param + ' ' + files_param + ' ' + options() )
 
289
   else:
 
290
      GPS.execute_action ("AdaControl", command_name(), rules_param + ' ' + files_param + ' ' + options() )
 
291
 
 
292
# Displays help for a given rule, and launcher
 
293
def display_help (proc, status, mess):
 
294
   GPS.MDI.dialog (mess)
 
295
 
 
296
def Help_On_Rule (self):
 
297
   if GPS.Preference ("help-format").get() == "Pop-up":
 
298
     GPS.Process ("adactl -h " + self.name, on_exit = display_help)
 
299
   else:
 
300
     GPS.HTML.browse ("adacontrol_ug.html", self.name, navigation = False)
 
301
 
 
302
# Add a new entry to the "help on rule" menu
 
303
def Add_Rule_Menu (self, matched, unmatched):
 
304
   entry=GPS.Menu.create ("Help/AdaControl/Help on rule/" + matched, Help_On_Rule);
 
305
   entry.name=matched
 
306
 
 
307
# Hook on preference changes
 
308
def on_pref_changed (H):
 
309
   if GPS.Preference ("delete-ali").get():
 
310
      DelTree_Menu.rename("Delete Tree and .ali Files")
 
311
   else:
 
312
      DelTree_Menu.rename("Delete Tree Files")
 
313
 
 
314
################################################################
 
315
# Initialization actions
 
316
 
 
317
# Global variables
 
318
adactl_cats= sets.Set()
 
319
previous_command= ""
 
320
 
 
321
# Colors used in highliting the results
 
322
GPS.Editor.register_highlighting ("Adactl_check", "red", "True")
 
323
GPS.Editor.register_highlighting ("Adactl_found", "orange", "True")
 
324
 
 
325
# We must define the buttons here in order to compute the place of the icons from
 
326
# the GPS directory, but we cannot call GPS.Button(), because it does not allow
 
327
# the declaration of an icon (hence we use parse_xml).
 
328
GPS.parse_xml("""
 
329
<button action='Check_Unknown_File'>
 
330
   <title>Launch AdaControl (rules file)</title>
 
331
   <pixmap>"""
 
332
           + GPS.get_system_dir()
 
333
           + """share/gps/plug-ins/adactl.gif</pixmap>
 
334
</button>
 
335
<button action='Check_Unknown_Ask'>
 
336
   <title>Launch AdaControl (interactive)</title>
 
337
   <pixmap>"""
 
338
           + GPS.get_system_dir()
 
339
           + """share/gps/plug-ins/adactl_ask.gif</pixmap>
 
340
</button>
 
341
""")
 
342
 
 
343
# Create the Help/Adacontrol/Help rule menu
 
344
GPS.Process ("adactl -h list", ".+", Add_Rule_Menu)
 
345
 
 
346
# Create hook on preference changes, and keep the "Delete Tree" menu in it
 
347
GPS.Hook("preferences_changed").add (on_pref_changed)
 
348
DelTree_Menu = GPS.Menu.get ("AdaControl/Delete Tree Files")
 
349
on_pref_changed (GPS.Hook("preferences_changed"))