home *** CD-ROM | disk | FTP | other *** search
- -- Part of SmallEiffel -- Read DISCLAIMER file -- Copyright (C)
- -- Dominique COLNET and Suzanne COLLIN -- colnet@loria.fr
- --
- class STD_FILE_READ
- --
- -- Basic input facilities to read a named file on the disc.
- --
- -- Note : most features are common with STD_INPUT so you can
- -- test your program on the screen first and then, just
- -- changing of instance (STD_INPUT/STD_FILE_READ), doing
- -- the same on a file.
- --
-
- inherit STD_FILE
-
- creation {ANY}
- connect_to, make
-
- feature {ANY}
-
- connect_to(new_path: STRING) is
- do
- make;
- input_stream := fopen(new_path,mode);
- if input_stream /= Void then
- path := new_path;
- end;
- end;
-
- disconnect is
- local
- err: INTEGER;
- do
- err := fclose(input_stream);
- path := Void;
- end;
-
- make is
- do
- mode := "r";
- end;
-
- feature {ANY}
-
- last_integer: INTEGER;
- -- Last integer read using `read_integer'.
-
- last_real: REAL; -- Last real read with `read_real'.
-
- last_double: DOUBLE; -- Last double read with `read_double'.
-
- last_character: CHARACTER is
- -- Last character read with `read_character'.
- do
- Result := last_character_memory;
- end;
-
- last_string: STRING is
- -- Last STRING read with `read_line', `read_word' or `newline'.
- --
- -- NOTE: it is alway the same STRING.
- once
- !!Result.make(256);
- end;
-
- read_line is
- -- Read a complete line ended by '%N' or `end_of_input'.
- -- Make the result available in `last_string'.
- -- Character '%N' is not added in `last_string'.
- --
- -- NOTE: the result is available in `last_string' without any
- -- memory allocation.
- require
- not end_of_input;
- do
- read_line_in(last_string);
- end;
-
- read_line_in(str: STRING) is
- -- Same jobs as `read_line' but storage is directly done in `str'.
- --
- require
- not end_of_input;
- do
- from
- str.clear;
- read_character;
- until
- end_of_input or else
- last_character = '%N'
- loop
- str.extend(last_character);
- read_character;
- end;
- end;
-
- read_word is
- -- Read a word using `is_separator' of class CHARACTER.
- -- Result is available in `last_string' (no allocation
- -- of memory).
- -- Heading separators are automatically skipped.
- -- Trailing separators are not skipped (`last_character' is
- -- left on the first one).
- -- If `end_of_input' is encountered, Result can be the
- -- empty string.
- require
- not end_of_input;
- do
- skip_separators;
- from
- last_string.clear;
- until
- end_of_input or else
- last_character.is_separator
- loop
- last_string.extend(last_character);
- read_character;
- end;
- end;
-
- skip_separators is
- -- Stop doing `read_character' as soon as `end_of_file' is reached
- -- or as soon as `last_character' is not `is_separator'.
- -- When first character is already not `is_separator' nothing
- -- is done.
- do
- from
- until
- end_of_input or else
- not last_character.is_separator
- loop
- read_character;
- end;
- end;
-
- read_word_using(separators: STRING) is
- -- Same jobs as `read_word' using `separators'.
- do
- not_yet_implemented;
- end;
-
- read_integer is
- -- Read an integer according to the Eiffel syntax.
- -- Make result available in `last_integer'.
- -- Heading separators (`is_separator' of CHARACTER)
- -- are automatically skipped.
- -- Trailing sseparators are not skipped (`last_character'
- -- is after the last digit of the number).
- local
- state: INTEGER;
- sign: BOOLEAN;
- -- state = 0 : waiting sign or first digit.
- -- state = 1 : sign read, waiting first digit.
- -- state = 2 : in the number.
- -- state = 3 : end state.
- -- state = 4 : error state.
- do
- from
- until
- state > 2
- loop
- read_character;
- inspect
- state
- when 0 then
- if last_character.is_separator then
- elseif last_character.is_digit then
- last_integer := last_character.value;
- state := 2;
- elseif last_character = '-' then
- sign := true;
- state := 1;
- elseif last_character = '+' then
- state := 1;
- else
- state := 4;
- end;
- when 1 then
- if last_character.is_separator then
- elseif last_character.is_digit then
- last_integer := last_character.value;
- state := 2;
- else
- state := 4;
- end;
- else -- 2
- if last_character.is_digit then
- last_integer := (last_integer * 10) + last_character.value;
- else
- state := 3;
- end;
- end;
- end;
- if state = 4 then
- std_error.put_string("Error in STD_FILE/read_integer.");
- elseif sign then
- last_integer := - last_integer;
- end;
- end;
-
- read_real is
- -- Read a REAL and assign result to `last_real'.
- -- The integral part is stored in `last_integer'.
- local
- i: INTEGER;
- do
- read_integer;
- last_string.clear;
- if last_character = '.' then
- from
- read_character;
- last_string.clear;
- until
- not last_character.is_digit
- loop
- last_string.extend(last_character);
- read_character;
- end;
- from
- last_real := 0.0;
- i := last_string.count;
- until
- i = 0
- loop
- last_real := (last_real + last_string.item(i).value) / 10;
- i := i - 1;
- end;
- last_real := last_real + last_integer;
- else
- last_real := last_integer;
- end;
- end;
-
- read_double is
- -- Read a DOUBLE according to the Eiffel syntax.
- -- input and assign it to `last_real'.
- -- The integral part is stored in `last_integer'.
- local
- i: INTEGER;
- do
- read_integer;
- last_string.clear;
- if last_character = '.' then
- from
- read_character;
- last_string.clear;
- until
- not last_character.is_digit
- loop
- last_string.extend(last_character);
- read_character;
- end;
- from
- last_double := 0.0;
- i := last_string.count;
- until
- i = 0
- loop
- last_double := (last_double + last_string.item(i).value) / 10;
- i := i - 1;
- end;
- last_double := last_double + last_integer;
- else
- last_double := last_integer;
- end;
- end;
-
- unread_character is
- -- Un read the last character read.
- local
- err: INTEGER;
- do
- err := ungetc(last_character,input_stream);
- end;
-
- read_character is
- -- Read a character and assign it to `last_character'.
- require
- not end_of_input;
- do
- last_character_memory := fgetc(input_stream);
- end;
-
- newline is
- -- Consume input until newline is found.
- -- Corresponding STRING is stored in `last_string'.
- -- Then consume newline character.
- do
- from
- last_string.clear;
- until
- end_of_input or else last_character = '%N'
- loop
- read_character;
- last_string.extend(last_character);
- end;
- if not end_of_input then
- read_character;
- end;
- end;
-
- end_of_input : BOOLEAN is
- -- Has end-of-input been reached ?
- do
- Result := feof(input_stream)
- end;
-
- feature {NONE}
-
- input_stream: POINTER;
-
- last_character_memory: CHARACTER;
-
- fgetc(stream_pointer : POINTER): CHARACTER is
- -- Result is of type CHARACTER because a int is a char !
- external "CSE"
- alias "fgetc"
- end;
-
-
- feof(stream_ptr: POINTER): BOOLEAN is
- external "CSE"
- end;
-
- end -- STD_FILE_READ
-