Jesper Lund wrote:
Is there a (simple) way of trapping runtime I/O errors in GPC, like the {$I-} compiler directive in Borland Pascal? Right now, the program
var x : real;
begin Readln (x); end.
abort with a run-time error if the user enters something that is not a number. The same applies to ReadStr, BTW, so unless there is such a switch (hidden) in GPC, we have to call C functions like 'sscanf' or 'atof' to emulate the Borland 'Val' procedure.
There will be a built-in Val procedure in the next beta! :-)
However, ReadStr + trapping runtime I/O errors would be simpler, IMHO.
AFAIK, Bill is working on the {$I+-} switch. (Bill, if you're reading this: The places to trap this particular error are the calls to _p_generic() in rts/rts-rdinc.c -- if you haven't done so already.)
From another mail:
I haven't found any bugs, but I have a suggestion which -- IMHO -- would improve ValReal (the same applies to ValInteger, etc).
Not necessary any more. I just completed the RTS part of the Val procedure, and Peter will build it into GPC.
[code snipped]
COMMENTS:
- The C library function converting the null-terminated string into a double
checks for errors itself (sscanf returns 0 if the string cannot be converted to a double; meaning 0 values read from the string), so there is no need to parse the string (to find the position where the error occurs), unless there is an error in the string. BTW, this speedup is not possible with atof because atof returns 0.0 if the string cannot be converted to a double. That's why I use sscanf instead (sscanf is ANSI C, and must be in any C library, so no concerns about portability between Linux, DJGPP, etc).
As an aside, the string '1.1e3', is now converted to 1100.0, which is the correct behavior. The code checking for errors should really be rewritten to handle this. For example, the error position for '1.0ef3' is not at position 4, but the 'f' at position 5. Adding 'e' to the list of admissible chars would improve things a bit, but still not totally correct.
In the built-in version (to come), I hope I've made all the checks at the right places. When it's released, please do as extensive tests as you can, and report any bugs you might find.
- The formal parameter S is declared as a string[255], instead of the schema
type 'string' (which has a different meaning than in Borland Pascal, where it means string[255]). As you add a #0 to the string variable 's', it should be large enough not to overflow (length gets out of range).
I don't think the original version would work if called with a string constant, because S would be a string with the same length as the string constant, and adding #0 would (should) cause an exception.
Yes, we discussed this topic recently. We plan to build in some functions for converting Pascal strings into CStrings easily.
- Unless GPC is really good at optimizing string expressions, the "hack"
s[Length(s)+1] := chr ( 0 )
is faster than adding chr(0) to the string variable.
Yes, it's faster. GPC is not that good yet, but I hope we'll make it that good (but not until version 2.1)...