2
0
Эх сурвалжийг харах

* fixed swapendian(smallint) (bug found by Joost van der Sluis)
* based swap(smallint) and swap(word) on swapendian(smallint/word),
since the same bug was already fixed in swap(smallint) in r6752
(so these routines now share the same code)
* fixed potential range error in swapendian(word)
+ added basic test for the above four routines

git-svn-id: trunk@10840 -

Jonas Maebe 17 жил өмнө
parent
commit
95637dea75

+ 1 - 0
.gitattributes

@@ -6834,6 +6834,7 @@ tests/tbs/tb0544.pp svneol=native#text/plain
 tests/tbs/tb0545.pp svneol=native#text/plain
 tests/tbs/tb0546.pp svneol=native#text/plain
 tests/tbs/tb0547.pp svneol=native#text/plain
+tests/tbs/tb0548.pp svneol=native#text/plain
 tests/tbs/tb205.pp svneol=native#text/plain
 tests/tbs/ub0060.pp svneol=native#text/plain
 tests/tbs/ub0069.pp svneol=native#text/plain

+ 6 - 2
rtl/inc/generic.inc

@@ -1707,13 +1707,17 @@ end;
 {$ifndef FPC_SYSTEM_HAS_SWAPENDIAN}
 function SwapEndian(const AValue: SmallInt): SmallInt;
   begin
-    Result := (AValue shr 8) or (AValue shl 8);
+    { the extra Word type cast is necessary because the "AValue shr 8" }
+    { is turned into "longint(AValue) shr 8", so if AValue < 0 then    }
+    { the sign bits from the upper 16 bits are shifted in rather than  }
+    { zeroes.                                                          }
+    Result := SmallInt((Word(AValue) shr 8) or (AValue shl 8));
   end;
 
 
 function SwapEndian(const AValue: Word): Word;
   begin
-    Result := (AValue shr 8) or (AValue shl 8);
+    Result := Word((AValue shr 8) or (AValue shl 8));
   end;
 
 

+ 4 - 8
rtl/inc/system.inc

@@ -245,21 +245,17 @@ begin
    Lo := b and $0f
 end;
 
-Function swap (X : Word) : Word;{$ifdef SYSTEMINLINE}inline;{$endif}
+Function Swap (X : Word) : Word;{$ifdef SYSTEMINLINE}inline;{$endif}
 Begin
-  swap:=(X and $ff) shl 8 + (X shr 8)
+  Swap := SwapEndian(X);
 End;
 
 Function Swap (X : Integer) : Integer;{$ifdef SYSTEMINLINE}inline;{$endif}
 Begin
-  { the extra 'and $ff' in the right term is necessary because the  }
-  { 'X shr 8' is turned into "longint(X) shr 8", so if x < 0 then   }
-  { the sign bits from the upper 16 bits are shifted in rather than }
-  { zeroes. Another bug for TP/Delphi compatibility...              }
-  swap:=(X and $ff) shl 8 + ((X shr 8) and $ff)
+  Swap := SwapEndian(X);
 End;
 
-Function swap (X : Longint) : Longint;{$ifdef SYSTEMINLINE}inline;{$endif}
+Function Swap (X : Longint) : Longint;{$ifdef SYSTEMINLINE}inline;{$endif}
 Begin
   Swap:=(X and $ffff) shl 16 + (X shr 16)
 End;

+ 30 - 0
tests/tbs/tb0548.pp

@@ -0,0 +1,30 @@
+{$r+}
+{$q+}
+
+var
+  wo: word;
+  si: smallint;
+
+begin
+  wo:=$9876;
+  if swap(wo)<>$7698 then
+    halt(1);
+  if swapendian(wo)<>$7698 then
+    halt(2);
+  wo:=$1290;
+  if swap(wo)<>$9012 then
+    halt(3);
+  if swapendian(wo)<>$9012 then
+    halt(4);
+
+  si:=smallint($9876);
+  if swap(si)<>$7698 then
+    halt(5);
+  if swapendian(si)<>$7698 then
+    halt(6);
+  si:=$1290;
+  if swap(si)<>smallint($9012) then
+    halt(7);
+  if swapendian(si)<>smallint($9012) then
+    halt(8);
+end.