In a continuation of the thread:
http://www.gnu-pascal.de/crystal/gpc/en/raw-mail10017.html
Regarding conformance to the ISO 7185. It seems that GPC will correctly report EOLN before EOF even when none exists in the file. However, after successfully reading the end of line character, EOLN will still return true while EOF also simultaneously returns true.
This has a tendency to give odd results. EOF and EOLN should be mutually exclusive. If the file doesn't properly have it's end of line marker before the end of the file, GPC can, should, and does currently insert the end of line into the buffer. But once it's been read, EOF should return true, and EOLN should not.
I'm unfortunately not familiar enough with how gpc source is organized, so I'm not sure where to make the needed correction, in order to submit the patch. I would be willing to work on it however, if someone could point me in the right direction.
Thanks, Chad Simmons
The following program demonstrates the unusual behavior:
PROGRAM GRADES (INPUT,OUTPUT);
VAR SUM, COUNT, GRADE : INTEGER;
BEGIN SUM := 0; COUNT := 0;
WRITELN('ENTER GRADES AND PRESS CTRL-D WHEN FINISHED'); READ(GRADE);
WHILE NOT EOF DO BEGIN SUM := SUM + GRADE; COUNT := COUNT + 1;
IF EOLN THEN READ(CH);
WRITELN('EOLN? ', EOLN); WRITELN('EOF? ', EOF);
IF NOT EOF THEN READ(GRADE); END;
WRITELN('TOTAL STUDENTS ', COUNT); WRITELN('CLASS AVERAGE ', SUM DIV COUNT); END.
The output:
$ ./grades ENTER GRADES AND PRESS CTRL-D WHEN FINISHED 20 30 40EOLN? False EOF? False EOLN? False EOF? False EOLN? True EOF? True TOTAL STUDENTS 3 CLASS AVERAGE 30
gpc -v output: $ gpc -v Using built-in specs. Configured with: ../src/configure -v --enable-languages=c,pascal --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.1.3 --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --disable-libmudflap --enable-checking=release x86_64-linux-gnu Thread model: posix gpc version 20070904, based on gcc-4.1.3 20080301 (prerelease) (Ubuntu 2.1-4.1.2-19ubuntu1)
Your code does not compile:
kevan$ gpc p.pas p.pas: In main program: p.pas:20: error: undeclared identifier `CH' (first use in this routine) p.pas:20: error: (Each undeclared identifier is reported only once p.pas:20: error: for each routine it appears in.)
--- On Thu, 9/24/09, Kevan Hashemi hashemi@brandeis.edu wrote:
Your code does not compile:
Sorry about that. I was making some last minute changes to it and forgot to revert them before sending it. Here's the correct one which exhibits the behavior, and _does_ compile ;)
Note that I'm compiling it with --classic-pascal because I want to have the correct (ISO) behavior when a newline is not present in the file prior to the EOF. But the problem exists even without this option.
To compile I'm using:
$gpc --classic-pascal grades.pas -o grades
To run: echo -n "20 30 40" | ./grades
Here's the code:
PROGRAM GRADES (INPUT,OUTPUT);
VAR SUM, COUNT, GRADE : INTEGER;
BEGIN SUM := 0; COUNT := 0;
WRITELN('ENTER GRADES AND PRESS CTRL-D WHEN FINISHED'); READ(GRADE);
WHILE NOT EOF DO BEGIN SUM := SUM + GRADE; COUNT := COUNT + 1;
WHILE EOLN DO BEGIN WRITELN('EOLN? ', EOLN); WRITELN('EOF? ', EOF); READLN; END;
IF NOT EOF THEN READ(GRADE); END;
WRITELN('TOTAL STUDENTS ', COUNT); WRITELN('CLASS AVERAGE ', SUM DIV COUNT); END.
Dear Chad,
I'm not in a position to hack the gpc code, but I just thought I'd confirm your result.
I confirm that your code produces eoln(input) and eof(input) true at the same time, which should not be possible in ISO Pascal. When input^ points to the character after the end of a file, we have EOF true with input^ undefined. When input^ is undefined, according to the pages about Pascal I just read, EOLN should be false.
Yours, Kevan
Chad Simmons wrote:
In a continuation of the thread:
http://www.gnu-pascal.de/crystal/gpc/en/raw-mail10017.html
Regarding conformance to the ISO 7185. It seems that GPC will correctly report EOLN before EOF even when none exists in the file. However, after successfully reading the end of line character, EOLN will still return true while EOF also simultaneously returns true.
This has a tendency to give odd results. EOF and EOLN should be mutually exclusive. If the file doesn't properly have it's end of line marker before the end of the file, GPC can, should, and does currently insert the end of line into the buffer. But once it's been read, EOF should return true, and EOLN should not.
Why do you think so? Concerning conformance, the standard says that calling EOLN when EOF is true is an error. In other words conformat program befor calling EOLN should check that EOF is false. And GPC compiled program is free to do anything if you call EOLN when EOF is true: it can return true, it can return false, it can singal error, it can simply crash.
So the question is what is most convenient. Returning true means to the idiom 'not(eoln)' has clear meaning: there is something to read. While one can probably give good justification to returning false, changing behaviour now would almost surely break some real programs, so change would be not wise.
--- On Thu, 9/24/09, Waldek Hebisch hebisch@math.uni.wroc.pl wrote:
So the question is what is most convenient. Returning true means to the idiom 'not(eoln)' has clear meaning: there is something to read.
However, conversely eoln(f) returning true generally means that you can safely read a single character, or readln to position yourself at the next line. Given this current behavior, this is not true when you're at the end of the file. It's telling you that if you read you'll get a space for the end of line character, when in fact you'll get an error because you read past the end of the file.
I buy the hysterical raisins argument, someone may be relying on this non-compliant behavior and changing it would break existing code. But I don't buy the argument that it's needed to protect the meaning of the 'not(eoln)' idiom since by your own admission, eoln shouldn't be checked when you're at the end of the file.
It would be sufficient to simply have options for this behavior I suppose. By default --classic-pascal should report an error and fail in this situation if we are to comply with the ISO standard. The default for other dialects can be determined, and behavior in the default dialect can remain the way it is currently if there are sufficient objections to changing it. But it'd be nice if we could have some way to tell the compiler how to properly deal with eof and eoln and how they interact at compile time, since it's not terribly understandable as it is now.
Thanks, Chad Simmons