@Araq

So, I read the version from:

[https://github.com/nim-lang/Nim/blob/devel/lib/system/sysio.nim](https://github.com/nim-lang/Nim/blob/devel/lib/system/sysio.nim)

I hope that was the right one.
    
    
    proc checkErr(f: File) =
      if c_ferror(f) != 0:
        c_clearerr(f)
        raiseEIO("Unknown IO Error")
    
    
    
    proc readBuffer(f: File, buffer: pointer, len: Natural): int =
      result = c_fread(buffer, 1, len, f)
      checkErr(f)
    

  1. Won't raise an exception for EOF.
  2. No need to call `checkErr()` everytime (not needed when `result==len`).


    
    
    proc readChar(f: File): char =
      let x = c_fgetc(f)
      if x == -1: raiseEOF()
      checkErr(f)
      result = char(x)
    

  1. EOF is not necessarily `-1`; testing `x < 0` is better.
  2. You raise EOF exception even if there was no end-of-file but an IO error.



I did not check `readLine()`, I think it better to clarify our thoughts before:

The way most `stdio` functions work is the following: they have a way to say 
something special happened. But they only have a single way for both 
end-of-file and IO error. So the way to go is:

  1. (Eventually make sure the EOF and Error flags are not set, with 
`clearerr()`.)
  2. Run the function.
  3. Check the eof/error indication: `fgetc()` returned `EOF`? `fread()` 
returned a number less than `nmemb`? `fgets()` returned `NULL`? ...
  4. If that check matches, check whether it was an end-of-file or an IO Error. 
You can check with `feof()` or `ferror()`. Raise the according exception. Like 
(pseudocode): `if ferror(): raiseIOerror else: raiseEOFerror`.
  5. (Eventually make sure the EOF and Error flags are not set, with 
`clearerr()`.)



I guess 3. could be a function like your `checkErr()` but then it should always 
raise something because you call it when you already know something special 
happened, you just don't know yet which special thing.

NB: I don't know what target Nim aims at (C89? C99? POSIX? the same ones with 
extensions? some specific platform?), but `EOF` is not defined as `-1` in C99 
standard, just as a negative value. So it should be a platform-dependent 
#define (well, the equivalent for Nim), not a hardcoded value; or if the normal 
return value is always positive, you can check for negative values.

Reply via email to