[net.lang.pascal] Bug in 4.2 BSD Pascal implementation ???

russell@muddcs.UUCP (Russell Shilling) (09/01/84)

[eat this, Sucker !!!]

	Recently I've been trying to write introductory manuals for some
of the languages we have available, and in the process of converting a
Modula-2 program to Pascal I found an (apparent) error in the definition
of the Pascal language (we have 4.2 BSD.)
	It seems that the "read" statement will allow reading past the end
of the current line and on to the next.  Isn't this wrong, (at least as
far as the way the read was supposed to work) ???
	As an example, the following code will not operate correctly
(as I understand the idea of correctness):

program ReadTest(input,output);
  var C: char;
  begin
    repeat
      while not eoln do begin	(* should echo one line of chars *)
        read(C);   write(C);
      end;
      readln(C);	(* supposed to be required to read past *)
      writeln;		(* end-of-line marker, right ???        *)
    until eof;
  end.
  
	This program seems to work fine when you are reading from the 
standard input, but if you redirect input from a file, every other line
is skipped.  Perhaps I'm full of blue mud, but I thought that you could
"read" forever without reading past the end of line.  Can someone explain
either where my misconception of the language definition is, or maybe
verify that this is a legitimate bug ?


-- 

	Russell Shilling

	{ allegra, ihnp4, seismo }!scgvaxd!muddcs!russell
	=====  plplplplplplplplplplplplplplplplplp  =====

faiman@eludom.DEC (Neil Faiman ~ ZKO2-3/N30 ~ 381-2017) (09/03/84)

/////

> program ReadTest(input,output);
>   var C: char;
>   begin
>     repeat
>       while not eoln do begin	(* should echo one line of chars *)
>         read(C);   write(C);
>       end;
>       readln(C);	(* supposed to be required to read past *)
>       writeln;		(* end-of-line marker, right ???        *)
>     until eof;
>   end.
>   
> 	This program seems to work fine when you are reading from the 
> standard input, but if you redirect input from a file, every other line
> is skipped.

The Pascal procedure to advance to the next line is "Readln", with no
parameter.  "Readln(C)" is equivalent to "Read(C); Readln", which in
turn is equivalent to "C:=Input^; Get(Input); Readln(Input)".  This
assigns the space character to C (Input^ = ' ' when Eoln(Input) is true).
The Get advances over the end-of-line condition (Get will advance to the
next line, just like Readln, when Eoln is true).  And finally, the Readln
advances to the NEXT line.  Presto -- you just skipped over an input line.
So, it's not a compiler bug.

	-Neil Faiman

USENET:    ...{ucbvax,allegra,decvax}!decwrl!dec-rhea!dec-eludom!faiman
ARPA:      FAIMAN%ELUDOM.DEC@DECWRL.ARPA
DEC:       ELUDOM::FAIMAN

hans@log-hb.UUCP (Hans Albertsson) (09/04/84)

[]
read(..); may indeed read past end of line; when actually reading
the eoln-marker, itv returns a blank in its argument. Readln is merely
a convenient way to skip to the next line without knowing how far
the next end-of-line is.
J&W is quite clear on this.

-- 
			{decvax,philabs}!mcvax!enea!log-hb!hans
			Hans Albertsson, 
			TeleLOGIC AB
			Box 1001,
			S-14901 Nynashamn,
			SWEDEN

cdr@pixadv.UUCP (cdr) (10/02/84)

I'm not on a 4.2 system, but from what I can see of your "bug",
it's not one.

It seems that job of read is not to keep you out of the control 
characters but to only give you a printable char for whatever it was
that you did read, ie, a blank.

If you read past eoln and don't know it you'll get more than was
actually in the line.  That's why you only want to read til eoln
so you don't get blanks when read is trying to keep you from getting
into control chars.  As I understand Pascal, if you want to get past
eoln the classic way is "readln;" without any arguments.  Whatever
readln doesn't have buffer space for in the vars that you give it,
it is supposed to just junk.

Likewise, if you're interested in reading the real chars in a line,
don't use read but just "get" from the file pointer.

Dont forget that the file pointer is always pointing to the char that
you're about to read.  This would explain why it's "skipping a line".
What you've done is, with the read loop you got the file pointer on
the newline char, then with the "readln(C);" you got a blank
(substituted for the newline) in "C" and then readln did what it was
supposed to do after it loads the vars you've given it, it started
reading (and junking) characters til it found a newline.  One of readln's
jobs is to always leave the file pointer on the first char afterthe
newline it found in it's search.

-- 
____________________________________________________________________________
Constantine Rasmussen  (617) 657-8720 x2320
Pixel Computer Incorporated; 260 Fordham Road; Wilmington, Ma.  01887
{allegra|ihnp4|cbosgd|ima|genrad|amd|harvard} !wjh12!pixel!cdr

robertd@tektronix.UUCP (Bob Dietrich) (10/08/84)

--------------
From the reply of Constantine Rasmussen at Pixel Computer Incorporated:

>>It seems that job of read is not to keep you out of the control 
>>characters but to only give you a printable char for whatever it was
>>that you did read, ie, a blank.

Read and the other Pascal I/O routines should NOT suppress control (i.e.,
non-printable) characters. The only exception to this is if end of line
is represented on your processor by such a character (or sequence of
characters). Some systems use an "invisible" count to specify how many
characters are in each line (and therefore where the end of line is).

One of the few differences between the ANSI/IEEE and ISO Pascal Standards is
that the former allows the end of line to be represented by a value of type
char, while the ISO standard prohibits this.

>>                ...  As I understand Pascal, if you want to get past
>>eoln the classic way is "readln;" without any arguments. ...

True, if you actually don't want to read anything further on the current
input line. Otherwise, readln can take arguments just like read.

>>Likewise, if you're interested in reading the real chars in a line,
>>don't use read but just "get" from the file pointer.

There should be absolutely no difference between doing "read(f, ch)" and
"ch := f^; get(f)". Again, control characters should not be suppressed
(although many file systems suppress ASCII nuls and many text editors make it
nearly impossible to enter most of the control characters).

                                              Bob Dietrich
                                              Tektronix, Inc.
                                              (503) 629-1727
{ucb or dec}vax!tektronix!robertd             uucp address
robertd@tektronix                             csnet address
robertd.tektronix@rand-relay                  arpa address