/[eiffelstudio]/branches/eth/eve/Src/Eiffel/interface/graphical/tools/code_analysis/es_code_analysis_command.e
ViewVC logotype

Contents of /branches/eth/eve/Src/Eiffel/interface/graphical/tools/code_analysis/es_code_analysis_command.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 94983 - (show annotations)
Fri May 2 11:05:28 2014 UTC (5 years, 5 months ago) by jasonw
File size: 21442 byte(s)
<<Merged from trunk#94978.>>
1 note
2 description: "[
3 Command to launch Code Analyzer.
4
5 Can be added to toolbars and menus.
6 Can be executed using stones.
7 ]"
8 date: "$Date$"
9 revision: "$Revision$"
10
11 class
12 ES_CODE_ANALYSIS_COMMAND
13
14 inherit
15
16 EB_TOOLBARABLE_AND_MENUABLE_COMMAND
17 redefine
18 tooltext,
19 new_sd_toolbar_item,
20 new_mini_sd_toolbar_item
21 end
22
23 CA_SHARED_NAMES
24
25 SHARED_EIFFEL_PROJECT
26
27 SHARED_ERROR_HANDLER
28
29 COMPILER_EXPORTER
30
31 EB_SHARED_WINDOW_MANAGER
32
33 create
34 make
35
36 feature {NONE} -- Initialization
37
38 make
39 -- Creation method.
40 do
41 initialize_preferences
42
43 enable_sensitive
44 set_up_menu_items
45
46 create analysis_timestamp.make (0)
47 end
48
49 feature -- Execution
50
51 execute
52 -- Execute when no stone is provided. The whole system will be analyzed.
53 local
54 l_save_confirm: ES_DISCARDABLE_COMPILE_SAVE_FILES_PROMPT
55 l_classes: DS_ARRAYED_LIST [CLASS_I]
56 do
57 -- Show the tool right from the start.
58 show_ca_tool
59
60 if not eiffel_project.is_compiling then
61 if window_manager.has_modified_windows then
62 create l_classes.make_default
63 window_manager.all_modified_classes.do_all (agent l_classes.force_last)
64 create l_save_confirm.make (l_classes)
65 l_save_confirm.set_button_action (l_save_confirm.dialog_buttons.yes_button, agent save_compile_and_analyze_all)
66 l_save_confirm.set_button_action (l_save_confirm.dialog_buttons.no_button, agent compile_and_analyze_all)
67 l_save_confirm.show_on_active_window
68 else
69 compile_and_analyze_all
70 end
71 end
72 end
73
74 execute_with_stone (a_stone: STONE)
75 -- Execute with `a_stone'.
76 do
77 execute_with_stone_content (a_stone, Void)
78 end
79
80 execute_with_stone_content (a_stone: STONE; a_content: SD_CONTENT)
81 -- Execute with `a_stone'.
82 local
83 l_save_confirm: ES_DISCARDABLE_COMPILE_SAVE_FILES_PROMPT
84 l_classes: DS_ARRAYED_LIST [CLASS_I]
85 do
86 -- Show the tool right from the start.
87 show_ca_tool
88
89 if not eiffel_project.is_compiling then
90 if window_manager.has_modified_windows then
91 create l_classes.make_default
92 window_manager.all_modified_classes.do_all (agent l_classes.force_last)
93 create l_save_confirm.make (l_classes)
94 l_save_confirm.set_button_action (l_save_confirm.dialog_buttons.yes_button, agent save_compile_and_analyze (a_stone))
95 l_save_confirm.set_button_action (l_save_confirm.dialog_buttons.no_button, agent compile_and_analyze (a_stone))
96 l_save_confirm.show_on_active_window
97 else
98 compile_and_analyze (a_stone)
99 end
100 end
101 end
102
103 feature {ES_CODE_ANALYSIS_BENCH_HELPER} -- Basic operations
104
105 save_compile_and_analyze_all
106 -- Saves and compiles the system. If successful then the whole
107 -- system will be analyzed.
108 do
109 window_manager.save_all_before_compiling
110 compile_and_analyze_all
111 end
112
113 compile_and_analyze_all
114 -- Compiles the system; if successful then the whole system will
115 -- be analyzed.
116 local
117 l_helper: ES_CODE_ANALYSIS_BENCH_HELPER
118 l_dialog: ES_INFORMATION_PROMPT
119 do
120 -- Compile the project and only analyze if the compilation was successful.
121 if eiffel_project.able_to_compile then
122 -- Avoid recompiling a precompiled library.
123 eiffel_project.quick_melt (True, True, True)
124 end
125 if eiffel_project.successful then
126 create l_helper
127 if l_helper.code_analyzer.is_running then
128 create l_dialog.make_standard (ca_messages.already_running_long)
129 l_dialog.show_on_active_window
130 else
131 -- Detection of changes
132
133 -- If we did a system analysis recently then only add modified classes.
134 if last_was_analyze_all then
135 analyze_changed_classes
136 else
137 analyze_all
138 end
139 last_was_analyze_all := True
140 end
141 end
142 end
143
144 last_was_analyze_all: BOOLEAN
145 -- Was the last analysis performed on the whole system?
146
147 analysis_timestamp: HASH_TABLE [INTEGER, CLASS_I]
148 -- Stores the time of the last modification of the class at the point
149 -- of the last analysis.
150
151 save_compile_and_analyze (a_stone: STONE)
152 -- Save modified windows, compile project and perform analysis of stone `a_stone'.
153 do
154 window_manager.save_all_before_compiling
155 compile_and_analyze (a_stone)
156 end
157
158 compile_and_analyze (a_stone: STONE)
159 -- Compile project and perform analysis of stone `a_stone'.
160 local
161 l_helper: ES_CODE_ANALYSIS_BENCH_HELPER
162 l_dialog: ES_INFORMATION_PROMPT
163 do
164 -- Compile the project and only analyze if the compilation was successful.
165 if eiffel_project.able_to_compile then
166 -- Avoid recompiling a precompiled library.
167 eiffel_project.quick_melt (True, True, True)
168 end
169 if eiffel_project.successful then
170 create l_helper
171 if l_helper.code_analyzer.is_running then
172 create l_dialog.make_standard (ca_messages.already_running_long)
173 l_dialog.show_on_active_window
174 else
175 perform_analysis (a_stone)
176 end
177 end
178 end
179
180 analyze_all
181 -- Analyzes the whole system.
182 local
183 l_helper: ES_CODE_ANALYSIS_BENCH_HELPER
184 l_scope_label: EV_LABEL
185 do
186 create l_helper
187 code_analyzer := l_helper.code_analyzer
188 code_analyzer.clear_classes_to_analyze
189 code_analyzer.rule_violations.wipe_out
190 code_analyzer.add_whole_system
191
192 -- Store all found classes.
193 across code_analyzer.class_list as l_classes loop
194 analysis_timestamp.force (l_classes.item.original_class.date, l_classes.item.original_class)
195 end
196
197 disable_tool_button
198 window_manager.display_message (ca_messages.status_bar_running)
199 code_analyzer.add_completed_action (agent analysis_completed)
200 code_analyzer.analyze
201 l_scope_label := ca_tool.panel.scope_label
202 l_scope_label.set_text (ca_messages.system_scope)
203 l_scope_label.set_tooltip (ca_messages.system_scope_tooltip)
204 l_scope_label.set_foreground_color (create {EV_COLOR}.make_with_8_bit_rgb (30, 30, 30))
205 end
206
207 analyze_changed_classes
208 -- Only analyze the classes that have been modified since the last analysis.
209 local
210 l_helper: ES_CODE_ANALYSIS_BENCH_HELPER
211 l_scope_label: EV_LABEL
212 l_analysis_timestamp, l_changed_timestamp: INTEGER
213 l_class: CLASS_I
214 do
215 create l_helper
216 code_analyzer := l_helper.code_analyzer
217 code_analyzer.clear_classes_to_analyze
218
219 from analysis_timestamp.start
220 until analysis_timestamp.after
221 loop
222 -- Check if class has been modified since last analysis.
223 l_analysis_timestamp := analysis_timestamp.item_for_iteration
224 l_class := analysis_timestamp.key_for_iteration
225 l_changed_timestamp := l_class.date
226 if l_changed_timestamp /= l_analysis_timestamp then
227 code_analyzer.rule_violations.remove (l_class.compiled_class)
228 code_analyzer.add_class (l_class.config_class)
229 end
230
231 analysis_timestamp.forth
232 end
233
234 -- Update the analysis timestamp for all the classes that have been added.
235 across code_analyzer.class_list as l_classes loop
236 analysis_timestamp.force (l_classes.item.original_class.date, l_classes.item.original_class)
237 end
238
239 disable_tool_button
240 window_manager.display_message (ca_messages.status_bar_running)
241 code_analyzer.add_completed_action (agent analysis_completed)
242 code_analyzer.analyze
243 l_scope_label := ca_tool.panel.scope_label
244 l_scope_label.set_text (ca_messages.system_scope)
245 l_scope_label.set_tooltip (ca_messages.system_scope_tooltip)
246 l_scope_label.set_foreground_color (create {EV_COLOR}.make_with_8_bit_rgb (30, 30, 30))
247 end
248
249 last_scope_label: EV_LABEL
250 -- Shows the scope of the last analysis (system, single class, etc.). A stone
251 -- will be attached, too, depending on the scope.
252
253 perform_analysis (a_stone: STONE)
254 -- Analyze `a_stone' only.
255 local
256 l_helper: ES_CODE_ANALYSIS_BENCH_HELPER
257 l_scope_label: EV_LABEL
258 do
259 -- For simplicity let us assume that `a_stone' does not
260 -- correspond to the system or is equivalent to it.
261 last_was_analyze_all := False
262
263 create l_helper
264 code_analyzer := l_helper.code_analyzer
265 code_analyzer.clear_classes_to_analyze
266 code_analyzer.rule_violations.wipe_out
267
268 l_scope_label := ca_tool.panel.scope_label
269
270 if attached {CLASSC_STONE} a_stone as s then
271 code_analyzer.add_class (s.class_i.config_class)
272 l_scope_label.set_text (s.class_name)
273 l_scope_label.set_foreground_color (create {EV_COLOR}.make_with_8_bit_rgb (140, 140, 255))
274 l_scope_label.set_pebble (s)
275 l_scope_label.set_pick_and_drop_mode
276 l_scope_label.set_tooltip (ca_messages.class_scope_tooltip)
277 elseif attached {CLUSTER_STONE} a_stone as s then
278 if s.is_cluster then
279 code_analyzer.add_cluster (s.cluster_i)
280 else
281 code_analyzer.add_group (s.group)
282 end
283 l_scope_label.set_text (s.stone_name)
284 l_scope_label.set_foreground_color (create {EV_COLOR}.make_with_8_bit_rgb (255, 140, 140))
285 l_scope_label.set_pebble (s)
286 l_scope_label.set_pick_and_drop_mode
287 l_scope_label.set_tooltip (ca_messages.cluster_scope_tooltip)
288 elseif attached {DATA_STONE} a_stone as s then
289 if attached {LIST [CONF_GROUP]} s.data as g then
290 from
291 g.start
292 until
293 g.after
294 loop
295 if attached {CLUSTER_I} g.item_for_iteration as c then
296 code_analyzer.add_cluster (c)
297 end
298 g.forth
299 end
300 l_scope_label.set_text (s.stone_name)
301 l_scope_label.set_foreground_color (create {EV_COLOR}.make_with_8_bit_rgb (140, 255, 140))
302 l_scope_label.set_pebble (s)
303 l_scope_label.set_pick_and_drop_mode
304 l_scope_label.set_tooltip (ca_messages.conf_group_tooltip)
305 end
306 end
307
308 disable_tool_button
309 window_manager.display_message (ca_messages.status_bar_running)
310 code_analyzer.add_completed_action (agent analysis_completed)
311 code_analyzer.analyze
312 end
313
314 analysis_completed (a_exceptions: detachable ITERABLE [TUPLE [detachable EXCEPTION, CLASS_C]])
315 -- Is called when the analysis is completed. `a_exceptions' is a list
316 -- of exceptions that occurred during analysis.
317 local
318 l_violation_exists: BOOLEAN
319 do
320 if attached event_list as l then
321 -- First off, remove all event items.
322 l.prune_event_items (event_context_cookie)
323
324 if a_exceptions /= Void then
325 across a_exceptions as ic loop
326 l.put_event_item (event_context_cookie, create {CA_EXCEPTION_EVENT}.make (ic.item))
327 l_violation_exists := True
328 end
329 end
330
331 -- Add an event item for each rule violation.
332 across code_analyzer.rule_violations as l_viol_list loop
333 across l_viol_list.item as l_viol loop
334 l.put_event_item (event_context_cookie, create {CA_RULE_VIOLATION_EVENT}.make (l_viol.item))
335 l_violation_exists := True
336 end
337 end
338
339 -- If there are no violations at all then add a pseudo item indicating this very fact.
340 if not l_violation_exists then
341 l.put_event_item (event_context_cookie, create {CA_NO_ISSUES_EVENT}.make)
342 end
343 end
344
345 show_ca_tool
346
347 enable_tool_button
348 -- Update status bar.
349 window_manager.display_message (ca_messages.status_bar_terminated)
350 end
351
352 event_context_cookie: UUID
353 -- Context cookie for Code Analysis events.
354 local
355 l_generator: UUID_GENERATOR
356 once
357 create l_generator
358 Result := l_generator.generate_uuid
359 ensure
360 valid_result: Result /= Void
361 end
362
363 ca_tool: detachable ES_CODE_ANALYSIS_TOOL
364 -- Analysis tool (if applicable).
365 local
366 l_tool: ES_TOOL [EB_TOOL]
367 l_window: EB_DEVELOPMENT_WINDOW
368 do
369 l_window := window_manager.last_focused_development_window
370 if not l_window.is_recycled and then l_window.is_visible and then l_window = window_manager.last_focused_development_window then
371 l_tool := l_window.shell_tools.tool ({ES_CODE_ANALYSIS_TOOL})
372 if attached {ES_CODE_ANALYSIS_TOOL} l_tool as l_ca_tool then
373 Result := l_ca_tool
374 else
375 check False end
376 end
377 end
378 end
379
380 show_ca_tool
381 -- Shows the analysis tool.
382 local
383 l_tool: ES_CODE_ANALYSIS_TOOL
384 do
385 l_tool := ca_tool
386 if l_tool /= Void and then not l_tool.is_recycled then
387 l_tool.show (True)
388 end
389 end
390
391 disable_tool_button
392 -- Disable analysis button on tool.
393 local
394 l_tool: ES_CODE_ANALYSIS_TOOL
395 do
396 l_tool := ca_tool
397 if l_tool /= Void and then l_tool.is_tool_instantiated then
398 ca_tool.panel.whole_system_button.disable_sensitive
399 ca_tool.panel.current_item_button.disable_sensitive
400 end
401 end
402
403 enable_tool_button
404 -- Enable analysis button on tool.
405 local
406 l_tool: ES_CODE_ANALYSIS_TOOL
407 do
408 l_tool := ca_tool
409 if l_tool /= Void and then l_tool.is_tool_instantiated then
410 ca_tool.panel.whole_system_button.enable_sensitive
411 ca_tool.panel.current_item_button.enable_sensitive
412 end
413 end
414
415 feature -- Items
416
417 new_sd_toolbar_item (display_text: BOOLEAN): EB_SD_COMMAND_TOOL_BAR_BUTTON
418 -- <Precursor>
419 do
420 create Result.make (Current)
421 initialize_sd_toolbar_item (Result, display_text)
422 Result.set_text (ca_names.analyze_item)
423 Result.set_tooltip (ca_names.analyze_item_tooltip)
424 Result.select_actions.extend (agent analyze_current_item)
425
426 Result.drop_actions.extend (agent execute_with_stone)
427 Result.drop_actions.set_veto_pebble_function (agent droppable)
428 ensure then
429 valid_result: Result /= Void
430 end
431
432 new_whole_system_toolbar_item (display_text: BOOLEAN): EB_SD_COMMAND_TOOL_BAR_BUTTON
433 do
434 create Result.make (Current)
435 initialize_sd_toolbar_item (Result, display_text)
436 Result.set_text (ca_names.analyze_system)
437 Result.set_tooltip (ca_names.analyze_system_tooltip)
438 Result.select_actions.extend (agent execute)
439 ensure then
440 valid_result: Result /= Void
441 end
442
443 new_mini_sd_toolbar_item: EB_SD_COMMAND_TOOL_BAR_BUTTON
444 -- <Precursor>
445 do
446 Result := Precursor {EB_TOOLBARABLE_AND_MENUABLE_COMMAND}
447 Result.drop_actions.extend (agent execute_with_stone)
448 Result.drop_actions.set_veto_pebble_function (agent droppable)
449 ensure then
450 valid_result: Result /= Void
451 end
452
453 feature -- Status report
454
455 droppable (a_pebble: ANY): BOOLEAN
456 -- Can user drop `a_pebble' on `Current'?
457 do
458 Result :=
459 (attached {CLASSC_STONE} a_pebble) or else
460 (attached {CLUSTER_STONE} a_pebble) or else
461 (attached {DATA_STONE} a_pebble as s and then attached {LIST [CONF_GROUP]} s.data)
462 end
463
464 feature {NONE} -- Implementation
465
466 code_analyzer: CA_CODE_ANALYZER
467 -- Code Analyzer instance
468
469 pixmap: EV_PIXMAP
470 -- Pixmap representing the command.
471 do
472 Result := pixmaps.icon_pixmaps.view_flat_icon
473 end
474
475 pixel_buffer: EV_PIXEL_BUFFER
476 -- Pixel buffer representing the command.
477 do
478 Result := pixmaps.icon_pixmaps.view_flat_icon_buffer
479 end
480
481 analyze_current_item
482 -- Proof current item
483 local
484 l_window: EB_DEVELOPMENT_WINDOW
485 do
486 l_window := window_manager.last_focused_development_window
487 if droppable (l_window.stone) then
488 execute_with_stone (l_window.stone)
489 end
490 end
491
492 analyze_parent_cluster
493 -- Proof parent cluster of window item.
494 local
495 l_window: EB_DEVELOPMENT_WINDOW
496 l_cluster_stone: CLUSTER_STONE
497 do
498 l_window := window_manager.last_focused_development_window
499 if attached {CLASSC_STONE} l_window.stone as l_stone then
500 create l_cluster_stone.make (l_stone.group)
501 execute_with_stone (l_cluster_stone)
502 elseif attached {CLUSTER_STONE} l_window.stone as l_stone then
503 if l_stone.cluster_i.parent_cluster /= Void then
504 create l_cluster_stone.make (l_stone.cluster_i.parent_cluster)
505 end
506 execute_with_stone (l_cluster_stone)
507 end
508 end
509
510 feature {NONE} -- Implementation
511
512 frozen service_consumer: SERVICE_CONSUMER [EVENT_LIST_S]
513 -- Access to an event list service {EVENT_LIST_S} consumer.
514 once
515 create Result
516 ensure
517 result_attached: Result /= Void
518 end
519
520 frozen event_list: detachable EVENT_LIST_S
521 -- Access to an event list service.
522 do
523 Result := service_consumer.service
524 end
525
526 set_up_menu_items
527 -- Set up menu items of proof button
528 do
529 create analyze_system_item.make_with_text_and_action (ca_messages.analyze_whole_system, agent analyze_all)
530 create analyze_current_item_item.make_with_text_and_action (ca_messages.analyze_current_item, agent analyze_current_item)
531 create analyze_parent_item_item.make_with_text_and_action (ca_messages.analyze_parent_cluster, agent analyze_parent_cluster)
532 end
533
534 drop_down_menu: EV_MENU
535 -- Drop down menu for `new_sd_toolbar_item'.
536 once
537 create Result
538 Result.extend (analyze_system_item)
539 Result.extend (analyze_current_item_item)
540 Result.extend (analyze_parent_item_item)
541 ensure
542 not_void: Result /= Void
543 end
544
545 analyze_current_item_item: EV_MENU_ITEM
546 -- Menu item to analyze current item
547
548 analyze_parent_item_item: EV_MENU_ITEM
549 -- Menu item to analyze parent item
550
551 analyze_system_item: EV_MENU_ITEM
552 -- Menu item to analyze system
553
554 menu_name: STRING_GENERAL
555 -- Name as it appears in the menu (with & symbol).
556 do
557 Result := ca_messages.run_code_analysis
558 end
559
560 tooltip: STRING_GENERAL
561 -- Tooltip for the toolbar button.
562 do
563 Result := ca_messages.analyze_whole_system
564 end
565
566 tooltext: STRING_GENERAL
567 -- Text for the toolbar button.
568 do
569 Result := ca_messages.run_code_analysis
570 end
571
572 description: STRING_GENERAL
573 -- Description for this command.
574 do
575 Result := "Run Eiffel Inspector."
576 end
577
578 name: STRING_GENERAL
579 -- Name of the command. Used to store the command in the
580 -- preferences.
581 do
582 Result := "Eiffel Inspector"
583 end
584
585 feature -- GUI preferences
586
587 code_analysis_namespace: STRING = "tools.code_analysis"
588 -- The namespace for the Code Analysis preferences.
589
590 initialize_preferences
591 -- Initializes the preferences related to the tool panel.
592 local
593 l_helper: ES_CODE_ANALYSIS_BENCH_HELPER
594 l_manager: EB_PREFERENCE_MANAGER
595 do
596 create l_helper
597 code_analyzer := l_helper.code_analyzer
598 create l_manager.make (code_analyzer.preferences, code_analysis_namespace)
599
600 error_bgcolor := l_manager.new_color_preference_value (l_manager,
601 ca_names.color_category + "." + ca_names.error_bgcolor, default_error_bgcolor)
602 error_bgcolor.set_default_value (color_string (default_error_bgcolor))
603 warning_bgcolor := l_manager.new_color_preference_value (l_manager,
604 ca_names.color_category + "." + ca_names.warning_bgcolor, default_warning_bgcolor)
605 warning_bgcolor.set_default_value (color_string (default_warning_bgcolor))
606 suggestion_bgcolor := l_manager.new_color_preference_value (l_manager,
607 ca_names.color_category + "." + ca_names.suggestion_bgcolor, default_suggestion_bgcolor)
608 suggestion_bgcolor.set_default_value (color_string (default_suggestion_bgcolor))
609 hint_bgcolor := l_manager.new_color_preference_value (l_manager,
610 ca_names.color_category + "." + ca_names.suggestion_bgcolor, default_hint_bgcolor)
611 hint_bgcolor.set_default_value (color_string (default_hint_bgcolor))
612 fixed_violation_bgcolor := l_manager.new_color_preference_value (l_manager,
613 ca_names.color_category + "." + ca_names.fixed_violation_bgcolor, default_fixed_violation_bgcolor)
614 fixed_violation_bgcolor.set_default_value (color_string (default_fixed_violation_bgcolor))
615 end
616
617 color_string (a_color: attached EV_COLOR): STRING
618 -- String representation of `a_color' for use in preferences.
619 do
620 create Result.make_empty
621 Result.append_integer (a_color.red_8_bit)
622 Result.append_character (';')
623 Result.append_integer (a_color.green_8_bit)
624 Result.append_character (';')
625 Result.append_integer (a_color.blue_8_bit)
626 ensure
627 valid_result: Result /= Void
628 end
629
630 error_bgcolor,
631 warning_bgcolor,
632 suggestion_bgcolor,
633 hint_bgcolor,
634 fixed_violation_bgcolor: COLOR_PREFERENCE
635 -- Color preferences
636
637 default_error_bgcolor: EV_COLOR
638 do
639 create Result.make_with_8_bit_rgb (255, 220, 220)
640 ensure
641 valid_result: Result /= Void
642 end
643
644 default_warning_bgcolor: EV_COLOR
645 do
646 create Result.make_with_8_bit_rgb (255, 255, 188)
647 ensure
648 valid_result: Result /= Void
649 end
650
651 default_suggestion_bgcolor: EV_COLOR
652 do
653 create Result.make_with_8_bit_rgb (239, 228, 176)
654 ensure
655 valid_result: Result /= Void
656 end
657
658 default_hint_bgcolor: EV_COLOR
659 do
660 create Result.make_with_8_bit_rgb (188, 226, 193)
661 ensure
662 valid_result: Result /= Void
663 end
664
665 default_fixed_violation_bgcolor: EV_COLOR
666 do
667 create Result.make_with_8_bit_rgb (181, 230, 29)
668 ensure
669 valid_result: Result /= Void
670 end
671
672
673 note
674 copyright: "Copyright (c) 1984-2014, Eiffel Software"
675 license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
676 licensing_options: "http://www.eiffel.com/licensing"
677 copying: "[
678 This file is part of Eiffel Software's Eiffel Development Environment.
679
680 Eiffel Software's Eiffel Development Environment is free
681 software; you can redistribute it and/or modify it under
682 the terms of the GNU General Public License as published
683 by the Free Software Foundation, version 2 of the License
684 (available at the URL listed under "license" above).
685
686 Eiffel Software's Eiffel Development Environment is
687 distributed in the hope that it will be useful, but
688 WITHOUT ANY WARRANTY; without even the implied warranty
689 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
690 See the GNU General Public License for more details.
691
692 You should have received a copy of the GNU General Public
693 License along with Eiffel Software's Eiffel Development
694 Environment; if not, write to the Free Software Foundation,
695 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
696 ]"
697 source: "[
698 Eiffel Software
699 5949 Hollister Ave., Goleta, CA 93117 USA
700 Telephone 805-685-1006, Fax 805-685-6869
701 Website http://www.eiffel.com
702 Customer support http://support.eiffel.com
703 ]"
704 end

Properties

Name Value
svn:eol-style native
svn:keywords Author Date ID Revision

  ViewVC Help
Powered by ViewVC 1.1.23