mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 05:59:08 +02:00
* fpc_Val_SInt_ShortStr: bug fixes and improvements by Bart B
This commit is contained in:
parent
38c06e64c7
commit
f39a6a7755
@ -1154,33 +1154,41 @@ end;
|
||||
|
||||
Function fpc_Val_SInt_ShortStr(DestSize: SizeInt; Const S: ShortString; out Code: ValSInt): ValSInt; [public, alias:'FPC_VAL_SINT_SHORTSTR']; compilerproc;
|
||||
var
|
||||
temp, prev, maxPrevValue, maxNewValue: ValUInt;
|
||||
temp, prev, maxPrevValue: ValUInt;
|
||||
base,u : byte;
|
||||
negative, RolledOver: boolean;
|
||||
SignedLower, SignedUpper: Int64;
|
||||
UnsignedUpper: UInt64;
|
||||
RolledOverAt: integer;
|
||||
RollOverPoint: ValUInt;
|
||||
negative: boolean;
|
||||
UnsignedUpperLimit: ValUInt;
|
||||
const
|
||||
ValueArray : array['0'..'f'] of byte = (0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,10,11,12,13,14,15,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
ValueArray : array['0'..'f'] of byte = (0,1,2,3,4,5,6,7,8,9,$FF,$FF,$FF,$FF,$FF,$FF,$FF,10,11,12,13,14,15,
|
||||
$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,
|
||||
10,11,12,13,14,15);
|
||||
begin
|
||||
fpc_Val_SInt_ShortStr := 0;
|
||||
Temp:=0;
|
||||
Code:=InitVal(s,negative,base);
|
||||
case DestSize of
|
||||
1: begin SignedLower:=Low(ShortInt); SignedUpper:=(High(ShortInt)); UnSignedUpper:=High(Byte) end;
|
||||
2: begin SignedLower:=Low(SmallInt); SignedUpper:=(High(SmallInt)); UnSignedUpper:=High(Word) end;
|
||||
4: begin SignedLower:=Low(LongInt); SignedUpper:=(High(LongInt)); UnSignedUpper:=High(DWord) end;
|
||||
8: begin SignedLower:=Low(Int64); SignedUpper:=(High(Int64)); UnSignedUpper:=High(QWord) end;
|
||||
end;
|
||||
|
||||
RolledOver:=False;
|
||||
if negative then
|
||||
RollOverPoint:=-SignedLower
|
||||
if (base=10) or negative then
|
||||
begin //always limit to either Low(DestType) or High(DestType)
|
||||
case DestSize of
|
||||
1: UnsignedUpperLimit := ValUInt(High(ShortInt))+Ord(negative);
|
||||
2: UnsignedUpperLimit := ValUInt(High(SmallInt))+Ord(negative);
|
||||
4: UnsignedUpperLimit := ValUInt(High(LongInt))+Ord(negative);
|
||||
{$ifdef CPU64}
|
||||
8: UnsignedUpperLimit := ValUInt(High(Int64))+Ord(negative);
|
||||
{$endif CPU64}
|
||||
end;
|
||||
end
|
||||
else
|
||||
RollOverPoint:=SignedUpper;
|
||||
begin //not decimal and not negative
|
||||
case DestSize of
|
||||
1: UnsignedUpperLimit := High(Byte);
|
||||
2: UnsignedUpperLimit := High(Word);
|
||||
4: UnsignedUpperLimit := High(DWord);
|
||||
{$ifdef CPU64}
|
||||
8: UnsignedUpperLimit := High(UInt64);
|
||||
{$endif CPU64}
|
||||
end;
|
||||
end;
|
||||
|
||||
if Code>length(s) then
|
||||
exit;
|
||||
@ -1190,11 +1198,8 @@ begin
|
||||
Code:=0;
|
||||
exit;
|
||||
end;
|
||||
|
||||
maxPrevValue := ValUInt(MaxUIntValue) div ValUInt(Base);
|
||||
if (base = 10) then
|
||||
maxNewValue := MaxSIntValue + ord(negative)
|
||||
else
|
||||
maxNewValue := MaxUIntValue;
|
||||
|
||||
while Code<=Length(s) do
|
||||
begin
|
||||
@ -1208,19 +1213,14 @@ begin
|
||||
|
||||
Prev := Temp;
|
||||
Temp := Temp*ValUInt(base);
|
||||
|
||||
If (u >= base) or
|
||||
(ValUInt(maxNewValue-u) < Temp) or
|
||||
(prev > maxPrevValue) or
|
||||
((Temp+u)>UnsignedUpper) Then
|
||||
(prev > maxPrevValue)
|
||||
or ((Temp)>(UnsignedUpperLimit-u)) Then
|
||||
Begin
|
||||
fpc_Val_SInt_ShortStr := 0;
|
||||
Exit
|
||||
End;
|
||||
if (not RolledOver) and ((Temp+u)>RollOverPoint) then
|
||||
begin
|
||||
RolledOver := True;
|
||||
RolledOverAt := Code;
|
||||
end;
|
||||
Temp:=Temp+u;
|
||||
inc(code);
|
||||
end;
|
||||
@ -1230,13 +1230,6 @@ begin
|
||||
If Negative Then
|
||||
fpc_Val_SInt_ShortStr := -fpc_Val_SInt_ShortStr;
|
||||
|
||||
if RolledOver and ((base=10) or ((base<>10) and (negative))) {and (not negative)} then
|
||||
begin
|
||||
fpc_Val_SInt_ShortStr:=0;
|
||||
Code := RolledOverAt;
|
||||
exit;
|
||||
end;
|
||||
|
||||
If Not(Negative) and (base <> 10) Then
|
||||
{sign extend the result to allow proper range checking}
|
||||
Case DestSize of
|
||||
|
Loading…
Reference in New Issue
Block a user