Version 1.5 of ai05s/ai05-0038-1.txt
!standard A.10.5(37) 07-11-26 AI05-0038-1/03
!standard A.10.7(8/1)
!standard A.10.7(10)
!standard A.10.7(12)
!standard A.10.8(10)
!standard A.10.8(24)
!class binding interpretation 07-01-12
!status Amendment 201Z 08-11-26
!status WG9 Approved 08-06-20
!status ARG Approved 7-0-2 06-11-09
!status work item 07-01-12
!status received 06-11-27
!priority Low
!difficulty Easy
!qualifier Omission
!subject Minor Errors in Ada.Text_IO
!summary
(1) No call of New_Line is made if Set_Line(1) is called, and the current
line number is greater than 1.
(2) procedures Look_Ahead and Get_Immediate raise Status_Error if the file is not open.
(3) procedure Get for a modular type raises Data_Error if the value is not in the subtype Num.
!question
(1)
According to A.10.5(37), a call of Set_Line (1) would lead to a call of
New_Line (0) if the current line number is greater than 1. But that would
raise Constraint_Error (Spacing has subtype Positive_Count). What is the
intent?
(2)
A.10.6(9) does not cover Look_Ahead or Get_Immediate. But these routines have no
statement that an empty file raises Status_Error. Surely that should happen
for these routines.
(3)
A.10.8(10) indicates that Get raises Data_Error only if the value is outside
of the base range. So what happens if the value is outside of the subtype Num
but inside the base range? The Note A.10.8(24) says that it raises Data_Error,
but there is no justification for this statement.
!recommendation
(See Summary.)
!wording
(1) Change the last sentence of A.10.5(37) to:
If the value specified by To is less than the current line number, has the effect
of calling New_Page followed, if To is greater than 1, by a call to New_Line with
a spacing equal to (To - 1).
(2) Add
Status_Error is propagated if the file is not open.
to A.10.7(8/1), A.10.7(10), and A.10.7(12) before the sentence starting "Mode_Error
is raised..."
(3) Change A.10.8(10) to:
The exception Data_Error is propagated if the sequence of characters read does not
form a legal integer literal or if the value obtained is not of the subtype Num.
Delete A.10.8(24).
!discussion
(1) This error even appears in Ada 83. Clearly, Set_Line(1) should just call New_Page if
the value of the current line is greater than 1.
(2) We could fix this two ways, either by adding the missing rule to A.10.7(8/1),
A.10.7(10), and A.10.7(12), or by changing A.10.6(9).
Note that A.10.6(9) also covers Mode_Error, and it was not changed to cover these
routines, either: the rule was added to each of the routines. Thus, we conclude it
was intended to specify the rule in the definition of these routines, rather than
changing the blanket definition.
(3) Get could raise Constraint_Error in this case, but there doesn't seem to be any
value in it being different than Get for Integers. Moreover, such a value cannot be
Put (as it would raise Constraint_Error), so there is little reason to be able to
read it.
Finally, Get from a string always raises Data_Error when the value is outside of the
subtype; it is bizarre that the file version of Get is different.
[Editor's note: I did a bit of research on this to figure out when/why it was changed.
Interestingly, RM9X 3.0 has the wording that we're going to switch to verbatim. It was
changed in RM9x 4.0 to the current wording without explanation. Thus the rule is clearly
intentional, but what the author was thinking is lost to the mists of time.]
The note A.10.8(24) gives bounds that match neither the original Standard wording nor
the proposed replacement wording. It is not worth preserving.
!corrigendum A.10.5(37)
Replace the paragraph:
- If the value specified by To is greater than the current line number,
has the effect of repeatedly calling New_Line (with a spacing of one), until
the current line number equals the specified value. If the value specified by
To is equal to the current line number, there is no effect. If the value specified
by To is less than the current line number, has the effect of calling New_Page
followed by a call of New_Line with a spacing equal to (To – 1).
by:
- If the value specified by To is greater than the current line number,
has the effect of repeatedly calling New_Line (with a spacing of one), until
the current line number equals the specified value. If the value specified by
To is equal to the current line number, there is no effect. If the value specified
by To is less than the current line number, has the effect of calling New_Page
followed, if To is greater than 1, by a call of New_Line with a spacing equal
to (To – 1).
!corrigendum A.10.7(8/1)
Replace the paragraph:
Mode_Error is propagated if the mode of the file is not In_File. Sets End_Of_Line
to True if at end of line, including if at end of page or at end of file; in each
of these cases the value of Item is not specified. Otherwise End_Of_Line is set
to False and Item is set to the the next character (without consuming it) from
the file.
by:
Status_Error is propagated if the file is not open. Mode_Error is
propagated if the mode of the file is not In_File. Sets End_Of_Line
to True if at end of line, including if at end of page or at end of file; in each
of these cases the value of Item is not specified. Otherwise End_Of_Line is set
to False and Item is set to the the next character (without consuming it) from
the file.
!corrigendum A.10.7(10)
Replace the paragraph:
Reads the next character, either control or graphic, from the specified File
or the default input file. Mode_Error is propagated if the mode of the file
is not In_File. End_Error is propagated if at the end of the file. The
current column, line and page numbers for the file are not affected.
by:
Reads the next character, either control or graphic, from the specified File
or the default input file. Status_Error is propagated if the file is not open.
Mode_Error is propagated if the mode of the file
is not In_File. End_Error is propagated if at the end of the file. The
current column, line and page numbers for the file are not affected.
!corrigendum A.10.7(12)
Replace the paragraph:
If a character, either control or graphic, is available from the specified File
or the default input file, then the character is read; Available is True and Item
contains the value of this character. If a character is not available, then
Available is False and the value of Item is not specified. Mode_Error is propagated
if the mode of the file is not In_File. End_Error is propagated if at the end of
the file. The current column, line and page numbers for the file are not affected.
by:
If a character, either control or graphic, is available from the specified File
or the default input file, then the character is read; Available is True and Item
contains the value of this character. If a character is not available, then
Available is False and the value of Item is not specified. Status_Error is
propagated if the file is not open. Mode_Error is propagated
if the mode of the file is not In_File. End_Error is propagated if at the end of
the file. The current column, line and page numbers for the file are not affected.
!corrigendum A.10.8(10)
Replace the paragraph:
The exception Data_Error is propagated if the sequence of characters read does
not form a legal integer literal or if the value obtained is not of the
subtype Num (for Integer_IO) or is not in the base range of Num (for Modular_IO).
by:
The exception Data_Error is propagated if the sequence of characters read does
not form a legal integer literal or if the value obtained is not of the
subtype Num.
!corrigendum A.10.8(24)
Delete the paragraph:
30 For Modular_IO, execution of Get propagates Data_Error if the sequence of
characters read forms an integer literal outside the range 0..Num'Last.
!ACATS test
All of these changes just confirm the expected behavior (which doesn't match the
wording), so there isn't a significant need for testing them.
!appendix
!topic New_Line called with Spacing = 0
!reference Ada 2005 RM-A.10.5(37)
!author Christoph Grein 2006-11-27
!discussion
According to A.10.5(37), a call of Set_Line (1) would lead to a call of
New_Line (0) if the current line number is greater than 1.
(This is already in RM 83 14.3.4(36) - or am I blind?)
****************************************************************
From: Tucker Taft
Date: Monday, November 27, 2006 1:14 PM
Good point. That wording has been around forever,
and no-one bothered to analyze it closely.
It is modeled on the "Set_Col" wording, which
can legitimately talk about outputting "To-1"
spaces even when To = 1.
On the other hand, calling "New_Line(Spacing => To-1)"
doesn't make sense for To = 1, because
Spacing is of subtype Positive. I presume we
all "know" what it means, i.e., do nothing, but
it should probably be stated correctly.
In general, the Ada Rapporteur Group has concluded
that any time the manual says one thing
is equivalent to something else (or in this case,
"has the effect of calling..."), it is probably
telling a lie (sometimes a small lie, sometimes a
big one).
****************************************************************
!topic No statement for Get_Immediate, Look_Ahead, when the file is not open.
!reference Ada 2005 RM-A.10.7(8/1,10,12)
!author Christoph Grein 2006-12-01
!discussion
This is a very minor point, but contrary to all other file operations,
the paragraphs about Get_Immediate and Look_Ahead do not state what
should happen if the file is not open.
RM-A.10.6(9) does not apply.
****************************************************************
!topic Inconsistent handling of Get for modular types
!reference RM A.10.8(10)
!from Christoph Grein 07-03-02
!discussion
Consider the following program fragment:
type Test_Modular is mod 2**10;
subtype Test_Range is Test_Modular range 0 .. +1000;
-- Test_Range'Base 0 .. 1023
package Test_Modular_Text_IO is new Ada.Text_IO.Modular_IO (Test_Range);
use Test_Modular_Text_IO;
Unsigned: Test_Modular;
Get (File, Unsigned);
According to A.10.8(10), the value 1023 can be read into Unsigned
without raising Data_Error (contrary to a signed integer). This is what
Bob Duff told me when I asked about this behaviour:
The RM seems inconsistent on this point. A.10.8(10) does indeed seem to say
that the base range is what matters. However, this makes no sense, for several
reasons:
- The subtype of the parameter is Num, not Num'Base, so it is impossible to
return 1023 in your example (unless we go completely outside normal Ada
semantics -- and Text_IO is supposed to be implementable in normal Ada
code).
- The NOTE in para 24 contradicts A.10.8(10):
For Modular_IO, execution of Get propagates Data_Error if the
sequence of characters read forms an integer literal outside the
range 0..Num'Last.
- To me, it makes no sense to raise Constraint_Error for 1023 but
Data_Error for 1025.
- Modular_IO.Put cannot put the number 1023, so why should Get be able to
read it?
- I see no value to the programmer in using the base range. If you want
the base range, instantiate with that subtype. (In fact, I'd say a good
rule of thumb is to never use subranges of modular types, nor arrays
indexed by modular types, except in special circumstances, such as
interfacing with C code.)
Therefore, we're going to guess that A.10.8(10) is simply a mistake, and the
intent is that Data_Error be raised for numbers outside the range of Num.
End of quote.
****************************************************************
Questions? Ask the ACAA Technical Agent