/[eiffelstudio]/branches/CAT_mono/Src/Eiffel/eiffel/genericity/cl_type_i.e
ViewVC logotype

Contents of /branches/CAT_mono/Src/Eiffel/eiffel/genericity/cl_type_i.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 66895 - (show annotations)
Sun Feb 25 17:11:57 2007 UTC (13 years ago) by manus
Original Path: trunk/Src/Eiffel/eiffel/genericity/cl_type_i.e
File size: 20246 byte(s)
Support for FreeELKS:
- Added byte code for `floor' and `ceiling' operation on real types.
- Made `c_tagged_out' take an EIF_REFERENCE rather than an EIF_OBJECT, updated
  all C code using it accordingly and ANY/ISE_RUNTIME.
- Added `eif_built_in.h' to keep all macros used for external "built_in' features
  not implemented with Eiffel code.
- Added BUILT_IN_AS node for representing external "built_in' features:
  * when a built_in routine is found, we look in $ISE_EIFFEL/studio/built_ins to
    see if it has a corresponding implementation and the FEATURE_I/STD_BYTE_CODE
	is generated from the implementation. Otherwise we consider it as a special
	C routines.
  * In the formatters, we show the actual code of the implementation and not the
    external body, the same for debugging.
- Partial fix for Precursor call when call is made in an expanded class, the ancestor
  version might have non-expanded arguments and return type (e.g. like Current).
- Changed CLASS_TYPE for basic types so that `type_i' is a CL_TYPE_I and not
  a BASIC_I. It solves issues when you have code defined in basic types which
  would not be properly generated. Since it would be generated as if it was a
  normal expanded type but the types where still EIF_XXX instead of EIF_REFERENCE.
  This was needed for FreeELKS since now we have implementation in the basic types.
  Added some queries to CLASS_TYPE to avoid accessing `type' to get the information
  since sometime we still want to know that we are in basic types. Added `basic_type'
  to be used when it is a basic type. It has mostly an implication with .NET code
  generation.
- Updated debugger so that one can debug all features but attributes, deferred and
  constants.

1 indexing
2 description: "Type class."
3 legal: "See notice at end of class."
4 status: "See notice at end of class."
5 date: "$Date$"
6 revision: "$Revision$"
7
8 class CL_TYPE_I
9
10 inherit
11 TYPE_I
12 redefine
13 anchor_instantiation_in,
14 c_type,
15 conforms_to_array,
16 created_in,
17 external_id,
18 full_type_byte_code_type_id,
19 generate_cid,
20 generate_cid_array,
21 generate_cid_init,
22 generate_gen_type_il,
23 generate_expanded_creation,
24 generate_expanded_initialization,
25 generated_id,
26 internal_generic_derivation,
27 instantiated_description,
28 instantiation_in,
29 is_expanded,
30 is_explicit,
31 is_external,
32 is_frozen,
33 is_generated_as_single_type,
34 is_reference,
35 is_separate,
36 is_consistent,
37 make_gen_type_byte_code,
38 same_as,
39 static_type_id
40 end
41
42 SHARED_IL_CASING
43 export
44 {NONE} all
45 end
46
47 SHARED_GENERATION
48 export
49 {NONE} all
50 end
51
52 SHARED_DECLARATIONS
53 export
54 {NONE} all
55 end
56
57 create
58 make
59
60 feature {NONE} -- Initialization
61
62 make (id: INTEGER) is
63 -- Create new instance of `Current' with `class_id'
64 -- assigned with `id'.
65 require
66 valid_id: id > 0
67 do
68 class_id := id
69 ensure
70 class_id_set: class_id = id
71 end
72
73 feature -- Access
74
75 class_id: INTEGER
76 -- Base class id of the type class
77
78 meta_generic: META_GENERIC is
79 -- Meta generic array describing the type class
80 do
81 -- No meta generic in non-generic type
82 end
83
84 cr_info : CREATE_INFO
85 -- Additional information for the creation
86 -- of generic types with anchored parameters
87
88 true_generics : ARRAY [TYPE_I] is
89 -- Array of generics: no mapping reference -> REFERENCE_I
90 do
91 -- Non generic types don't have them
92 end
93
94 base_class: CLASS_C is
95 -- Base class associated to the class type
96 do
97 Result := System.class_of_id (class_id)
98 end
99
100 internal_generic_derivation (a_level: INTEGER): CL_TYPE_I is
101 -- Precise generic derivation of current type.
102 -- That is to say given a type, it gives the associated TYPE_I
103 -- which can be used to search its associated CLASS_TYPE.
104 local
105 c: like cr_info
106 do
107 c := cr_info
108 if c = Void then
109 Result := Current
110 else
111 -- Remove creation information.
112 cr_info := Void
113 Result := twin
114 cr_info := c
115 end
116 end
117
118 type_a: CL_TYPE_A is
119 do
120 create Result.make (class_id)
121 Result.set_mark (declaration_mark)
122 end
123
124 name: STRING is
125 -- String that should be displayed in debugger to represent `Current'.
126 do
127 Result := base_name
128 end
129
130 duplicate: like Current is
131 -- Duplication
132 do
133 Result := twin
134 end
135
136 reference_type: CL_TYPE_I is
137 -- Corresponding reference type
138 require
139 is_expanded: is_expanded
140 do
141 Result := duplicate
142 Result.set_reference_mark
143 ensure
144 result_is_reference: Result.is_reference
145 end
146
147 instantiation_in (other: CLASS_TYPE): CL_TYPE_I is
148 -- Instantation of Current in `other'
149 do
150 Result := Current
151 end
152
153 anchor_instantiation_in (other: CLASS_TYPE): CL_TYPE_I is
154 -- Instantation of `like Current' parts of Current in `other'
155 do
156 Result := Current
157 end
158
159 created_in (other: CLASS_TYPE): TYPE_I is
160 -- Resulting type of Current as if it was used to create object in `other'.
161 do
162 Result := Current
163 if cr_info /= Void then
164 Result := cr_info.created_in (other)
165 end
166 end
167
168 il_type_name (a_prefix: STRING): STRING is
169 -- Class name of current type.
170 local
171 l_class_c: like base_class
172 l_cl_type: like associated_class_type
173 l_alias_name: STRING
174 l_dot_pos: INTEGER
175 do
176 l_class_c := base_class
177 if is_external then
178 Result := l_class_c.external_class_name.twin
179 else
180 if l_class_c.is_precompiled then
181 -- Reuse the name that was computed at precompilation time.
182 l_cl_type := associated_class_type
183 if l_cl_type.is_precompiled then
184 Result := l_cl_type.il_type_name (a_prefix)
185 end
186 end
187 if Result = Void then
188 if not has_no_mark or else is_basic or else l_class_c.external_class_name.is_equal (l_class_c.name) then
189 Result := internal_il_type_name (l_class_c.name.twin, a_prefix)
190 else
191 -- Special case when an external name has been specified.
192 Result := l_class_c.external_class_name.twin
193 Result.left_adjust
194 Result.right_adjust
195 -- Remove leading `.' since it is not a valid .NET name.
196 from
197 until
198 Result.is_empty or else Result.item (1) /= '.'
199 loop
200 Result.remove_head (1)
201 end
202 -- Remove trailing `.' since it is not a valid .NET name.
203 from
204 until
205 Result.is_empty or else Result.item (Result.count) /= '.'
206 loop
207 Result.remove_tail (1)
208 end
209 if Result.is_empty then
210 -- External name is invalid since empty, we use the normal
211 -- way of generating the .Net name
212 Result := internal_il_type_name (l_class_c.name.twin, a_prefix)
213 else
214 if a_prefix /= Void then
215 l_dot_pos := Result.last_index_of ('.', Result.count)
216 if l_dot_pos = 0 then
217 Result.prepend_character ('.')
218 Result.prepend (a_prefix)
219 else
220 check
221 -- Because there are no more leading or trailing `.'.
222 valid_l_dot_pos: l_dot_pos > 1 and l_dot_pos < Result.count
223 end
224 l_alias_name := Result.substring (l_dot_pos + 1, Result.count)
225 check
226 l_alias_name_not_empty: not l_alias_name.is_empty
227 end
228 Result.keep_head (l_dot_pos)
229 l_alias_name := internal_il_base_type_name (l_alias_name)
230 Result.append (a_prefix)
231 Result.append_character ('.')
232 Result.append (l_alias_name)
233 end
234 end
235 end
236 end
237 end
238 end
239 end
240
241 description, instantiated_description: ATTR_DESC is
242 -- Type description for skeletons
243 local
244 exp: EXPANDED_DESC
245 ref: REFERENCE_DESC
246 do
247 if is_expanded then
248 create exp
249 exp.set_cl_type_i (Current)
250 exp.set_type_i (Current)
251 Result := exp
252 else
253 Result := c_type.description
254 ref ?= Result
255 if ref /= Void then
256 ref.set_type_i (Current)
257 end
258 end
259 end
260
261 c_type: TYPE_C is
262 -- Associated C type
263 do
264 Result := Reference_c_type
265 end
266
267 associated_class_type: CLASS_TYPE is
268 -- Associated class type
269 require
270 has: has_associated_class_type
271 do
272 Result := base_class.types.search_item (Current)
273 ensure
274 result_not_void: Result /= Void
275 end
276
277 type_id: INTEGER is
278 -- Type id of the correponding class type
279 do
280 Result := associated_class_type.type_id
281 end
282
283 static_type_id: INTEGER is
284 -- Type id of the correponding class type
285 require else
286 ok: True
287 do
288 Result := associated_class_type.static_type_id
289 end
290
291 external_id: INTEGER is
292 -- External type id of `Current' (or `static_type_id' for pure Eiffel type).
293 do
294 Result := associated_class_type.external_id
295 end
296
297 sk_value: INTEGER is
298 -- Generate SK value associated to the current type.
299 do
300 if is_expanded then
301 Result := Sk_exp | (type_id - 1)
302 else
303 Result := Sk_ref | (type_id - 1)
304 end
305 end
306
307 hash_code: INTEGER is
308 -- Hash code for current type
309 do
310 Result := Other_code + class_id
311 end
312
313 feature -- Status
314
315 element_type: INTEGER_8 is
316 -- Void element type
317 do
318 if is_expanded then
319 Result := {MD_SIGNATURE_CONSTANTS}.Element_type_valuetype
320 else
321 if class_id = System.system_string_class.compiled_class.class_id then
322 Result := {MD_SIGNATURE_CONSTANTS}.Element_type_string
323 elseif class_id = System.system_object_id or class_id = system.any_id then
324 -- For ANY or SYSTEM_OBJECT, we always generate a System.Object
325 -- signature since we can now assign SYSTEM_OBJECTs into ANYs.
326 Result := {MD_SIGNATURE_CONSTANTS}.Element_type_object
327 else
328 Result := {MD_SIGNATURE_CONSTANTS}.Element_type_class
329 end
330 end
331 end
332
333 tuple_code: INTEGER_8 is
334 -- Tuple code for class type
335 do
336 Result := {SHARED_GEN_CONF_LEVEL}.reference_tuple_code
337 end
338
339 has_no_mark: BOOLEAN is
340 -- Has class type no explicit mark?
341 do
342 Result := declaration_mark = {CL_TYPE_A}.no_mark
343 ensure
344 definition: Result = (declaration_mark = {CL_TYPE_A}.no_mark)
345 end
346
347 has_expanded_mark: BOOLEAN is
348 -- Is class type explicitly marked as expanded?
349 do
350 Result := declaration_mark = {CL_TYPE_A}.expanded_mark
351 ensure
352 definition: Result = (declaration_mark = {CL_TYPE_A}.expanded_mark)
353 end
354
355 has_reference_mark: BOOLEAN is
356 -- Is class type explicitly marked as reference?
357 do
358 Result := declaration_mark = {CL_TYPE_A}.reference_mark
359 ensure
360 definition: Result = (declaration_mark = {CL_TYPE_A}.reference_mark)
361 end
362
363 has_separate_mark: BOOLEAN is
364 -- Is class type explicitly marked as reference?
365 do
366 Result := declaration_mark = {CL_TYPE_A}.separate_mark
367 ensure
368 definition: Result = (declaration_mark = {CL_TYPE_A}.separate_mark)
369 end
370
371 is_expanded: BOOLEAN is
372 -- Is the type expanded?
373 do
374 -- Do not check for `has_separate_mark' because a separate class cannot be expanded.
375 Result := has_expanded_mark or else (has_no_mark and then base_class.is_expanded)
376 end
377
378 is_reference: BOOLEAN is
379 -- Is the type a reference type?
380 do
381 Result := has_reference_mark or else
382 ((has_no_mark or has_separate_mark) and then not base_class.is_expanded)
383 end
384
385 is_separate: BOOLEAN is
386 -- Is the type separate?
387 do
388 Result := has_separate_mark
389 end
390
391 is_enum: BOOLEAN is
392 -- Is current type an IL enum type?
393 -- Useful to find out if some call optimization can be done
394 -- in FEATURE_B.
395 require
396 il_generation: System.il_generation
397 do
398 Result := is_expanded and then base_class.is_enum
399 end
400
401 is_external: BOOLEAN is
402 -- Is current type based on an external class?
403 local
404 l_base_class: like base_class
405 do
406 -- All Eiffel basic types are externals, and only basic types used
407 -- as reference are not external.
408 l_base_class := base_class
409 Result := l_base_class.is_external and then not l_base_class.is_basic
410 end
411
412 is_frozen: BOOLEAN is
413 -- Is current type based on a frozen class?
414 do
415 Result := base_class.is_frozen
416 end
417
418 is_generated_as_single_type: BOOLEAN is
419 -- Is associated type generated as a single type or as an interface type and
420 -- an implementation type.
421 do
422 -- External classes have only one type.
423 Result := is_external
424 if not Result then
425 -- Classes that inherits from external classes
426 -- have only one generated type as well as expanded types.
427 Result := base_class.is_single or else is_expanded
428 end
429 end
430
431 is_consistent: BOOLEAN is
432 -- Is the base class still in the system and matches its specification?
433 local
434 l_base_class: like base_class
435 do
436 l_base_class := base_class
437 Result := l_base_class /= Void and then (l_base_class.generics = Void)
438 end
439
440 is_explicit: BOOLEAN is
441 -- Is Current type fixed at compile time?
442 do
443 if cr_info /= Void then
444 Result := cr_info.is_explicit
445 else
446 Result := True
447 end
448 end
449
450 has_associated_class_type: BOOLEAN is
451 -- Has `Current' an associated class type?
452 do
453 Result := base_class.types.has_type (Current)
454 end
455
456 same_as (other: TYPE_I): BOOLEAN is
457 -- Is `other' equal to Current ?
458 local
459 other_cl_type: CL_TYPE_I
460 do
461 other_cl_type ?= other
462 Result := other_cl_type /= Void -- FIXME
463 and then other_cl_type.class_id = class_id
464 and then other_cl_type.is_expanded = is_expanded
465 and then other_cl_type.is_separate = is_separate
466 and then other_cl_type.meta_generic = Void
467 and then other_cl_type.true_generics = Void
468 end
469
470 has_actual (type: CL_TYPE_I): BOOLEAN is
471 -- Is `type' an (possibly nested) actual parameter of this type?
472 require
473 non_void_type: type /= Void
474 do
475 -- False here.
476 end
477
478 feature -- Setting
479
480 set_expanded_mark is
481 -- Set class type declaration as expanded.
482 do
483 declaration_mark := {CL_TYPE_A}.expanded_mark
484 ensure
485 has_expanded_mark: has_expanded_mark
486 end
487
488 set_reference_mark is
489 -- Set class type declaration as reference.
490 do
491 declaration_mark := {CL_TYPE_A}.reference_mark
492 ensure
493 has_reference_mark: has_reference_mark
494 end
495
496 set_separate_mark is
497 -- Set class type declaration as separate.
498 do
499 declaration_mark := {CL_TYPE_A}.separate_mark
500 ensure
501 has_separate_mark: has_separate_mark
502 end
503
504 set_cr_info (cinfo : CREATE_INFO) is
505 -- Set `cr_info' to `cinfo'.
506 require
507 create_info_not_void: cinfo /= Void
508 not_expanded: not is_expanded or else cinfo.is_equal (create {CREATE_CURRENT})
509 do
510 cr_info := cinfo
511 ensure
512 cr_info_set : cr_info = cinfo
513 end
514
515 feature -- C generation
516
517 generate_expanded_creation (buffer: GENERATION_BUFFER; target_name: STRING) is
518 -- Generate creation of expanded object associated to Current.
519 do
520 associated_class_type.generate_expanded_creation (buffer, target_name, Current)
521 end
522
523 generate_expanded_initialization (buffer: GENERATION_BUFFER; target_name: STRING) is
524 -- Generate creation of expanded object associated to Current.
525 do
526 associated_class_type.generate_expanded_initialization (buffer, target_name, target_name, True)
527 end
528
529 generate_cecil_value (buffer: GENERATION_BUFFER) is
530 -- Generate cecil value
531 do
532 if not is_expanded then
533 buffer.put_string ("SK_REF + (uint32) ")
534 else
535 buffer.put_string ("SK_EXP + (uint32) ")
536 end
537 buffer.put_type_id (associated_class_type.type_id)
538 end
539
540 feature -- Array optimization
541
542 conforms_to_array: BOOLEAN is
543 do
544 Result := base_class.conform_to (array_class_c)
545 end
546
547 feature {NONE} -- Array optimization
548
549 array_class_c: CLASS_C is
550 once
551 Result := System.array_class.compiled_class
552 end
553
554 feature {NONE} -- Generic conformance
555
556 full_type_byte_code_type_id: INTEGER is
557 -- Associated type ID used in type information byte code.
558 do
559 Result := type_id - 1
560 ensure then
561 definition: Result = type_id - 1
562 end
563
564 feature -- Generic conformance
565
566 generated_id (final_mode : BOOLEAN) : INTEGER is
567
568 do
569 if final_mode then
570 Result := type_id - 1
571 else
572 Result := associated_class_type.static_type_id - 1
573 end
574 end
575
576 generate_cid (buffer : GENERATION_BUFFER; final_mode, use_info : BOOLEAN) is
577
578 do
579 if
580 use_info and then (cr_info /= Void)
581 and then not is_expanded
582 then
583 -- It's an anchored type
584 cr_info.generate_cid (buffer, final_mode)
585 else
586 buffer.put_integer (generated_id (final_mode))
587 buffer.put_character (',')
588 end
589 end
590
591 make_gen_type_byte_code (ba : BYTE_ARRAY; use_info : BOOLEAN) is
592 do
593 if
594 use_info and then (cr_info /= Void)
595 and then not is_expanded
596 then
597 -- It's an anchored type
598 cr_info.make_gen_type_byte_code (ba)
599 else
600 ba.append_short_integer (generated_id (False))
601 end
602 end
603
604 generate_cid_array (buffer : GENERATION_BUFFER;
605 final_mode, use_info : BOOLEAN; idx_cnt : COUNTER) is
606 local
607 dummy : INTEGER
608 do
609 if
610 use_info and then (cr_info /= Void)
611 and then not is_expanded
612 then
613 -- It's an anchored type
614 cr_info.generate_cid_array (buffer, final_mode, idx_cnt)
615 else
616 buffer.put_integer (generated_id (final_mode))
617 buffer.put_character (',')
618
619 -- Increment counter
620 dummy := idx_cnt.next
621 end
622 end
623
624 generate_cid_init (buffer : GENERATION_BUFFER;
625 final_mode, use_info : BOOLEAN; idx_cnt : COUNTER) is
626 local
627 dummy : INTEGER
628 do
629 if
630 use_info and then (cr_info /= Void)
631 and then not is_expanded
632 then
633 -- It's an anchored type
634 cr_info.generate_cid_init (buffer, final_mode, idx_cnt)
635 else
636 dummy := idx_cnt.next
637 end
638 end
639
640 feature -- Generic conformance for IL
641
642 generate_gen_type_il (il_generator: IL_CODE_GENERATOR; use_info : BOOLEAN) is
643 -- `use_info' is true iff we generate code for a
644 -- creation instruction.
645 do
646 if use_info and then cr_info /= Void then
647 -- It's an anchored type, we call feature
648 -- that will tell us the real type of the
649 -- anchor in the context of Current.
650 cr_info.generate_il_type
651 else
652 il_generator.generate_class_type_instance (Current)
653 end
654 end
655
656 feature {NONE} -- Implementation
657
658 base_name: STRING is
659 -- String that should be displayed in debugger to represent `Current'.
660 local
661 l_base_class: like base_class
662 do
663 create Result.make (32)
664 l_base_class := base_class
665 if is_expanded and not l_base_class.is_expanded then
666 Result.append ("expanded ")
667 elseif is_reference and l_base_class.is_expanded then
668 Result.append ("reference ")
669 elseif is_separate then
670 Result.append ("separate ")
671 end
672 Result.append (l_base_class.name)
673 end
674
675 frozen internal_il_type_name (a_base_name, a_prefix: STRING): STRING is
676 -- Full type name of `a_base_name' using `a_prefix' in IL code generation
677 -- with namespace specification
678 require
679 a_base_name_not_void: a_base_name /= Void
680 a_base_name_not_empty: not a_base_name.is_empty
681 do
682 Result := internal_il_base_type_name (a_base_name)
683 -- Result needs to be in lower case because that's
684 -- what our casing conversion routines require to perform
685 -- a good job.
686 Result.to_lower
687 Result := il_casing.type_name (base_class.original_class.actual_namespace, a_prefix, Result, System.dotnet_naming_convention)
688 ensure
689 internal_il_type_name_not_void: Result /= Void
690 internal_il_type_name_not_empty: not Result.is_empty
691 end
692
693 frozen internal_il_base_type_name (a_base_name: STRING): STRING is
694 -- Given `a_base_name' provides its updated name depending on its usage.
695 require
696 a_base_name_not_void: a_base_name /= Void
697 a_base_name_not_empty: not a_base_name.is_empty
698 local
699 l_base_class: like base_class
700 do
701 l_base_class := base_class
702 if is_expanded and then not l_base_class.is_expanded then
703 create Result.make (6 + a_base_name.count)
704 Result.append ("value_")
705 elseif not is_expanded and then l_base_class.is_expanded then
706 create Result.make (10 + a_base_name.count)
707 Result.append ("reference_")
708 else
709 create Result.make (a_base_name.count)
710 end
711 Result.append (a_base_name)
712 ensure
713 internal_il_base_type_name_not_void: Result /= Void
714 internal_il_base_type_name_not_empty: not Result.is_empty
715 end
716
717 feature {CL_TYPE_A, TUPLE_CLASS_B} -- Implementation: class type declaration marks
718
719 declaration_mark: NATURAL_8
720 -- Declaration mark associated with a class type (if any)
721
722 set_mark (mark: like declaration_mark) is
723 -- Set `declaration_mark' to the given value `mark'.
724 require
725 valid_declaration_mark:
726 mark = {CL_TYPE_A}.no_mark or mark = {CL_TYPE_A}.expanded_mark or
727 mark = {CL_TYPE_A}.reference_mark or mark = {CL_TYPE_A}.separate_mark
728 do
729 declaration_mark := mark
730 ensure
731 declaration_mark_set: declaration_mark = mark
732 end
733
734 invariant
735 class_id_positive: class_id > 0
736 valid_declaration_mark:
737 declaration_mark = {CL_TYPE_A}.no_mark or
738 declaration_mark = {CL_TYPE_A}.expanded_mark or
739 declaration_mark = {CL_TYPE_A}.reference_mark or
740 declaration_mark = {CL_TYPE_A}.separate_mark
741
742 indexing
743 copyright: "Copyright (c) 1984-2006, Eiffel Software"
744 license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
745 licensing_options: "http://www.eiffel.com/licensing"
746 copying: "[
747 This file is part of Eiffel Software's Eiffel Development Environment.
748
749 Eiffel Software's Eiffel Development Environment is free
750 software; you can redistribute it and/or modify it under
751 the terms of the GNU General Public License as published
752 by the Free Software Foundation, version 2 of the License
753 (available at the URL listed under "license" above).
754
755 Eiffel Software's Eiffel Development Environment is
756 distributed in the hope that it will be useful, but
757 WITHOUT ANY WARRANTY; without even the implied warranty
758 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
759 See the GNU General Public License for more details.
760
761 You should have received a copy of the GNU General Public
762 License along with Eiffel Software's Eiffel Development
763 Environment; if not, write to the Free Software Foundation,
764 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
765 ]"
766 source: "[
767 Eiffel Software
768 356 Storke Road, Goleta, CA 93117 USA
769 Telephone 805-685-1006, Fax 805-685-6869
770 Website http://www.eiffel.com
771 Customer support http://support.eiffel.com
772 ]"
773
774 end

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23