feat: add IO.fgetc (#1405)

* feat: add feof and ferror

These are C stdio functions that enable programmers to determine if a
file read resulted in an error or EOF encounter.

We can use these to power a definition of IO.fgetc, which is currently
not defined.

* feat: implement missing IO.fgetc

IO defined a function, fgetc (distinct from IO.Raw.fgetc) which actually
produced invalid code, since the name was not overridden and C does not
define IO_fgetc.

There was also a TODO to handle EOF conditions; so, I've implemented the
function, checking for EOF and error conditions using the Raw stdio
wrappers. IO.fgetc returns a Char in Success on success and an error
string on failure.

* refactor: distinguish EOF from errors in IO.fgetc

We now report whether or not the error encountered in fgetc was EOF.
Note that we don't yet report on the contents of other errors.
This commit is contained in:
Scott Olsen 2022-03-28 04:16:51 -04:00 committed by GitHub
parent d2df3fe058
commit bf6df6405c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -77,6 +77,8 @@ module are wrappers around the C standard library.")
(register SEEK-END Int "SEEK_END")
(doc ftell "gets the position indicator of a file (thin wrapper for the C standard library).")
(register ftell (Fn [(Ptr FILE)] Int) "ftell")
(register feof (Fn [(Ptr FILE)] Bool) "feof")
(register ferror (Fn [(Ptr FILE)] Bool) "ferror")
)
(doc println "prints a string ref to stdout, appends a newline.")
@ -90,7 +92,13 @@ module are wrappers around the C standard library.")
(doc get-line "gets a line from stdin.")
(register get-line (Fn [] String))
(doc fgetc "gets a character from a file pointer (thin wrapper for the C standard library).")
(register fgetc (Fn [(Ptr FILE)] Char)) ; TODO: check EOF handling (see carp_io.h)!
(defn fgetc [file]
(let [char (IO.Raw.fgetc file)]
(if (IO.Raw.feof file)
(Result.Error @"couldn't read char from file, EOF reached")
(if (IO.Raw.ferror file)
(Result.Error @"error while reading char from file")
(Result.Success (Char.from-int char))))))
(doc open-file "opens a file by name using a mode (e.g. [r]ead, [w]rite, [a]ppend), [rb] read binary...). See fopen() in the C standard library for a detailed description of valid parameters.")
(defn open-file [filename mode]