-- This file is free software, which comes along with SmartEiffel. This -- software is distributed in the hope that it will be useful, but WITHOUT -- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -- FITNESS FOR A PARTICULAR PURPOSE. You can modify it as you want, provided -- this header is kept unaltered, and a notification of the changes is added. -- You are allowed to redistribute it and sell it, alone or as a part of -- another product. -- Copyright (C) 1994-2002 LORIA - INRIA - U.H.P. Nancy 1 - FRANCE -- Dominique COLNET and Suzanne COLLIN - SmartEiffel@loria.fr -- http://SmartEiffel.loria.fr -- class GENERAL -- -- Platform-independent universal properties. -- This class is an ancestor to all developer-written classes. -- feature -- Access: generating_type: STRING is -- Name of current object's generating type (type of -- which it is a direct instance). external "SmartEiffel" end generator: STRING is -- Name of current object's generating class (base class -- of the type of which it is a direct instance). external "SmartEiffel" end stripped(other: GENERAL): like other is -- Newly created object with fields copied from current object, -- but limited to attributes of type of `other'. require conformance: conforms_to(other) do not_yet_implemented ensure stripped_to_other: Result.same_type(other) end feature -- Status report: frozen conforms_to(other: GENERAL): BOOLEAN is -- Is dynamic type of `Current' a descendant of dynamic type of -- `other' ? -- -- Note: because of automatic conversion from expanded to reference -- type when passing argument `other', do not expect a correct -- behavior with expanded types. require not is_expanded_type other_not_void: other /= Void do Result := other.se_assigned_from(Current) end frozen same_type(other: GENERAL): BOOLEAN is -- Is type of current object identical to type of `other' ? require not is_expanded_type other_not_void: other /= Void do if conforms_to(other) then Result := other.conforms_to(Current) end ensure definition: Result = (conforms_to(other) and other.conforms_to(Current)) end feature -- Comparison: frozen equal(some: ANY; other: like some): BOOLEAN is -- Are `some' and `other' both Void or attached to objects -- considered equal ? local some_ref_integer, other_ref_integer: reference INTEGER_64 do if some = other then Result := true elseif some = Void then elseif other = Void then else some_ref_integer ?= some if some_ref_integer /= Void then other_ref_integer ?= other if other_ref_integer /= Void then Result := some_ref_integer.item = other_ref_integer.item end else Result := some.is_equal(other) end end ensure symmetric: Result implies equal(other, some) end is_equal(other: like Current): BOOLEAN is -- Is `other' attached to an object considered equal to -- current object ? require other_not_void: other /= Void external "SmartEiffel" ensure symmetric: Result implies other.is_equal(Current) end frozen standard_equal(some: ANY; other: like some): BOOLEAN is -- Are `some' and `other' both Void or attached to -- field-by-field objects of the same type ? -- Always use the default object comparison criterion. do if some = other then Result := true elseif some = Void then elseif other = Void then elseif some.same_type(other) then Result := some.standard_is_equal(other) end ensure definition: Result = (some = Void and other = Void) or else ((some /= Void and other /= Void) and then some.standard_is_equal(other)) end frozen standard_is_equal(other: like Current): BOOLEAN is -- Are Current and `other' field-by-field identical? require other /= Void external "SmartEiffel" ensure symmetric: Result implies other.standard_is_equal(Current) end feature -- Deep Comparison: frozen deep_equal(some: ANY; other: like some): BOOLEAN is -- Are `some' and `other' either both Void or attached to -- recursively isomorphic object structures ? do if some = other then Result := true elseif some = Void then elseif other = Void then else Result := some.is_deep_equal(other) end ensure shallow_implies_deep: standard_equal(some,other) implies Result end is_deep_equal(other: like Current): BOOLEAN is -- Is `Current' recursively isomorph with `other' ? require other_not_void: other /= Void external "SmartEiffel" end feature -- Duplication: frozen clone(other: ANY): like other is -- When argument `other' is Void, return Void otherwise -- return `other.twin'. do if other /= Void then Result := other.twin end ensure equal: equal(Result,other) end frozen twin: like Current is -- Return a new object with the dynamic type of Current. -- Before being returned, the new object is initialized using -- feature `copy' (Current is passed as the argument). -- Thus, when feature `copy' of GENERAL is not redefined, -- `twin' has exactly the same behaviour as `standard_twin'. external "SmartEiffel" ensure equal: Result.is_equal(Current) end copy(other: like Current) is -- Update current object using fields of object attached -- to `other', so as to yield equal objects. require other_not_void: other /= Void external "SmartEiffel" ensure is_equal: is_equal(other) end frozen standard_clone(other: ANY): like other is -- Void if `other' is Void; otherwise new object -- field-by-field identical to `other'. -- Always use the default copying semantics. do if other /= Void then Result := other.standard_twin end ensure equal: standard_equal(Result,other) end frozen standard_twin: like Current is -- Return a new object with the dynamic type of Current. -- Before being returned, the new object is initialized using -- feature `standard_copy' (Current is passed as the argument). external "SmartEiffel" end frozen standard_copy(other: like Current) is -- Copy every field of `other' onto corresponding field of -- current object. require other_not_void: other /= Void external "SmartEiffel" ensure standard_is_equal(other) end feature -- Deep Duplication: frozen deep_clone(other: ANY): like other is -- When argument `other' is Void, return Void -- otherwise return `other.deep_twin'. do if other /= Void then Result := other.deep_twin end ensure deep_equal(other,Result) end deep_twin: like Current is -- Return a new object with the dynamic type of Current. -- The new object structure is recursively duplicated from the one -- attached to `Current'. external "SmartEiffel" end feature -- Basic operations: frozen default: like Current is -- Default value of current type. do end frozen default_pointer: POINTER is -- Default value of type POINTER (avoid the need to -- write p.default for some `p' of type POINTER). do ensure Result = Result.default end default_rescue is -- Handle exception if no Rescue clause. -- (Default: do nothing.) do end frozen do_nothing is -- Execute a null action. do end feature -- Input and Output: io: STD_INPUT_OUTPUT is -- Handle to standard file setup. -- To use the standard input/output file. -- Has type STD_FILES in ELKS 95. once create Result.make ensure Result /= Void end std_input: STD_INPUT is -- To use the standard input file. once create Result.make end std_output: STD_OUTPUT is -- To use the standard output file. once create Result.make end std_error: STD_ERROR is -- To use the standard error file. once create Result.make end feature -- Object Printing: frozen print(some: GENERAL) is -- Write terse external representation of `some' on -- `standard_output'. -- To customize printing, one may redefine -- `fill_tagged_out_memory' or `out_in_tagged_out_memory' (see -- for example how it works in class COLLECTION). -- Not frozen in ELKS 95. do if some = Void then std_output.put_string(once "Void") else some.print_on(std_output) end end print_on(file: OUTPUT_STREAM) is -- Default printing of current object on a `file'. -- One may redefine `fill_tagged_out_memory' or -- `out_in_tagged_out_memory' to adapt the behavior of -- `print_on'. -- do tagged_out_memory.clear out_in_tagged_out_memory file.put_string(tagged_out_memory) end frozen tagged_out: STRING is -- New string containing printable representation of current -- object, each field preceded by its attribute name, a -- colon and a space. do tagged_out_memory.clear fill_tagged_out_memory Result := tagged_out_memory.twin end out: STRING is -- Create a new string containing terse printable -- representation of current object. do tagged_out_memory.clear out_in_tagged_out_memory Result := tagged_out_memory.twin end out_in_tagged_out_memory is -- Append terse printable represention of current object -- in `tagged_out_memory'. do tagged_out_memory.append(generating_type) if not is_expanded_type then tagged_out_memory.extend('#') Current.to_pointer.append_in(tagged_out_memory) end tagged_out_memory.extend('[') fill_tagged_out_memory tagged_out_memory.extend(']') end frozen tagged_out_memory: STRING is once create Result.make(1024) end fill_tagged_out_memory is -- Append a viewable information in `tagged_out_memory' in -- order to affect the behavior of `out', `tagged_out', etc. do -- Should be an external "SmartEiffel" to provide a default -- view of Current contents (not yet implemented). end feature -- Basic named file handling: frozen file_tools: FILE_TOOLS is once end file_exists(path: STRING): BOOLEAN is -- True if `path' is an existing readable file. require not path.is_empty do Result := file_tools.is_readable(path) end remove_file(path: STRING) is require path /= Void do file_tools.delete(path) end rename_file(old_path, new_path: STRING) is require old_path /= Void new_path /= Void do file_tools.rename_to(old_path,new_path) end feature -- Access to command-line arguments: argument_count: INTEGER is -- Number of arguments given to command that started -- system execution (command name does not count). do Result := command_arguments.upper ensure Result >= 0 end argument(i: INTEGER): STRING is -- `i' th argument of command that started system execution -- Gives the command name if `i' is 0. require i >= 0 i <= argument_count do Result := command_arguments.item(i) ensure Result /= Void end frozen command_arguments: FIXED_ARRAY[STRING] is -- Give acces to arguments command line including the -- command name at index 0. local i: INTEGER arg: STRING once from i := se_argc create Result.make(i) until i = 0 loop i := i - 1 arg := se_argv(i) Result.put(arg,i) end ensure not Result.is_empty end get_environment_variable(name: STRING): STRING is obsolete "Since release -0.74 you have to use feature `get_environment_variable' % %of class SYSTEM." require name /= Void local s: SYSTEM do Result := s.get_environment_variable(name) end feature -- SCOOP: available: BOOLEAN is -- Wait the result (By Necessity [TM]) -- Always return true -- (Meaningless in a non-SCOOP world) do Result := true end feature -- System calls and crashs: frozen crash is -- Print Run Time Stack and then exit with `exit_failure_code'. do print_all_run_time_stacks sedb_breakpoint die_with_code(exit_failure_code) end frozen trace_switch(flag: BOOLEAN) is -- May be used in combination with option "-sedb" of command -- `compile_to_c' (see compile_to_c documentation for details). external "SmartEiffel" end frozen sedb_breakpoint is -- May be used in combination with option "-sedb" of command -- `compile_to_c' to set a breakpoint for sedb, the SmartEiffel debugger. external "SmartEiffel" end frozen system(system_command_line: STRING) is -- To execute a `system_command_line' as for example, "ls -l" on UNIX. obsolete "Since release -0.74 you have to use feature `execute' % %of class SYSTEM." local s: SYSTEM do s.execute_command_line(system_command_line) end frozen die_with_code(code:INTEGER) is -- Terminate execution with exit status code `code'. -- Do not print any message. -- Note: you can use predefined `exit_success_code' or -- `exit_failure_code' as well as another code you need. external "SmartEiffel" end exit_success_code: INTEGER is 0 exit_failure_code: INTEGER is 1 feature -- Maths constants: Pi : DOUBLE is obsolete "Use same feature in class MATH_CONSTANT (Nov. 2002)." do Result := 3.1415926535897932384626 end Evalue: DOUBLE is obsolete "Use same feature in class MATH_CONSTANT (Nov. 2002)." do Result := 2.7182818284590452353602 end Deg : DOUBLE is obsolete "Use same feature in class MATH_CONSTANT (Nov. 2002)." do Result := 57.2957795130823208767981; -- Degrees/Radian end Phi : DOUBLE is obsolete "Use same feature in class MATH_CONSTANT (Nov. 2002)." do Result := 1.6180339887498948482045; -- Golden Ratio end feature -- Character names: Ctrl_a: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/1/' end Ctrl_b: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/2/' end Ctrl_c: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/3/' end Ctrl_d: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/4/' end Ctrl_e: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result :='%/5/' end Ctrl_f: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/6/' end Ctrl_g: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/7/' end Ch_bs : CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/8/' end Ch_tab: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/9/' end Ctrl_j: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/10/' end Ctrl_k: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/11/' end Ctrl_l: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/12/' end Ctrl_m: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/13/' end Ctrl_n: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/14/' end Ctrl_o: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/15/' end Ctrl_p: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/16/' end Ctrl_q: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/17/' end Ctrl_r: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/18/' end Ctrl_s: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/19/' end Ctrl_t: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/20/' end Ctrl_u: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/21/' end Ctrl_v: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/22/' end Ctrl_w: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/23/' end Ctrl_x: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/24/' end Ctrl_y: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/25/' end Ctrl_z: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/26/' end Ch_del: CHARACTER is obsolete "Use same feature in class CHARACTER_CONSTANT (Nov. 2002)." do Result := '%/63/' end feature -- Should not exist: not_yet_implemented is do sedb_breakpoint std_error.put_string("[ Sorry, some feature is not yet implemented (i.e. feature `not_yet_implemented' of class GENERAL has been called somewhere). If this is not the case, just run this code under the debugger to know the `not_yet_implemented' caller. If this is a feature of the SmartEiffel library, you may consider to post your implementation on the SmartEiffel mailing list. e-mail: SmartEiffel@loria.fr Happy debug and thanks in advance. http://SmartEiffel.loria.fr Dominique Colnet ]") crash end feature -- For ELS Compatibility: id_object(id: INTEGER): ANY is -- Object for which `object_id' has returned `id' -- Void if none. require id /= 0 do Result := object_id_memory.item(id) end object_id: INTEGER is -- Value identifying current reference object. require not is_expanded_type do Result := object_id_memory.fast_index_of(Current) if Result > object_id_memory.upper then object_id_memory.add_last(Current) end end feature -- The Guru section: to_pointer: POINTER is -- This routine can be used only if the value of `Current' is really -- a memory address. (This is the case for all reference types and -- for the NATIVE_ARRAY type only.) Actually, this routine do -- nothing: the value of `Current' which is an address is returned -- unchanged. The compiler will emit a warning if you try to use -- `to_pointer' on some invalid type. external "SmartEiffel" end frozen is_expanded_type: BOOLEAN is -- Target is not evaluated (Statically computed). -- Result is true if target static type is an expanded type. -- Useful for formal generic type. external "SmartEiffel" end frozen is_basic_expanded_type: BOOLEAN is -- Target is not evaluated (Statically computed). -- Result is true if target static type is one of the -- following types: BOOLEAN, CHARACTER, INTEGER, REAL, -- DOUBLE or POINTER. external "SmartEiffel" ensure Result implies is_expanded_type end frozen object_size: INTEGER is -- Gives the size of the current object at first level -- only (pointed-to sub-object are not concerned). -- The result is given in number of CHARACTER. external "SmartEiffel" end feature {NONE} -- The Guru section: c_inline_h(c_code: STRING) is -- Target must be Current and `c_code' must be a manifest -- string. Write `c_code' in the heading C file. external "SmartEiffel" end c_inline_c(c_code: STRING) is -- Target must be Current and `c_code' must be a manifest -- string. Write `c_code' in the stream at current position. external "SmartEiffel" end feature {NONE} -- Implementation of GENERAL (do not use directly): object_id_memory: ARRAY[ANY] is -- For a portable implementation of `id_object'/`object_id'. -- Note: I think that the pair `id_object'/`object_id' is -- a stupid one. It should be removed. once create Result.with_capacity(256,1) end print_run_time_stack is -- Prints the run time stack. -- The result depends both on compilation mode and -- target langage used (C or Java byte code). -- Usually, in mode -boost, no information is printed. external "SmartEiffel" end print_all_run_time_stacks is -- Prints all the run time stacks. -- The result depends both on compilation mode and -- target langage used (C or Java byte code). -- Usually, in mode -boost, no information is printed. external "SmartEiffel" end se_argc: INTEGER is -- To implement `command_arguments' external "SmartEiffel" end se_argv(i: INTEGER): STRING is -- To implement `command_arguments' external "SmartEiffel" end feature -- Implementation of GENERAL (do not use directly): frozen se_assigned_from(other: GENERAL): BOOLEAN is -- To implement `conforms_to' (must only be called inside -- `conforms_to' because of VJRV rule). require not is_expanded_type local x: like Current do x ?= other Result := x /= Void end end -- GENERAL