BPCOMPAT v1.10 -released!_(re)

Wed, 22 Oct 1997 20:14:54 +0100 (MET)


>
>BUGS
>----
>If you find bugs, please try to fix them - but please report them
>to
>me as well. If you fix them, please let me have a copy of the
>fix.
>


I haven't found any bugs, but I have a suggestion which -- IMHO -- would
improve ValReal (the same applies to ValInteger, etc).  


First, my modified ValReal; second, an explanation of the modification.

type
  str255 = string [255];

function sscanf (inputstr, format : pChar; ... ) : Integer; C;

Procedure ValReal ( S : str255; var Dest : Double; var ErrCode : Integer );
Var
i, c : integer;
Begin
   s[Length(s)+1] := chr ( 0 );  { s := s + chr(0) }

   c := sscanf (pChar (@s[1]), "%lf", @dest);  { Read double variable }

   if (c = 1) then  { sscanf returned one number = NO errors }
   begin
     ErrCode := 0;
     Exit;
   end;

   { There is an error in s; locate it for compatibility with BP Val proc }

   { check for non-numeric values}
   for i := 1 to length ( s ) do
   if s [i] in ['0' .. '9', '.', '-']
   then {} else begin
      ErrCode := i;
      Break;
   end;
end;{* ValReal *}


COMMENTS:

1) 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.

2) 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.

3) 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.  Of course, it cannot be
range-checked ...


Best wishes,

  Jesper Lund


Jesper Lund (jel@hha.dk)

HTML conversion by Lluís de Yzaguirre i Maura
Institut de Lingüística Aplicada - Universitat "Pompeu Fabra"
e-mail: de_yza@upf.es