ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/branches/journaling/fbintf/IBUtils.pas
(Generate patch)

Comparing ibx/trunk/fbintf/IBUtils.pas (file contents):
Revision 348 by tony, Wed Oct 6 09:38:14 2021 UTC vs.
Revision 359 by tony, Tue Dec 7 09:37:32 2021 UTC

# Line 558 | Line 558 | type
558      function TokenFound(var token: TSQLTokens): boolean; virtual;
559      function InternalGetNextToken: TSQLTokens; virtual;
560      procedure Reset; virtual;
561 +    function ReadCharacters(NumOfChars: integer): AnsiString;
562  
563      {Token stack}
564      procedure QueueToken(token: TSQLTokens; text:AnsiString); overload;
# Line 648 | Line 649 | function FBFormatDateTime(fmt: AnsiStrin
649   function FormatTimeZoneOffset(EffectiveTimeOffsetMins: integer): AnsiString;
650   function DecodeTimeZoneOffset(TZOffset: AnsiString; var dstOffset: integer): boolean;
651   function StripLeadingZeros(Value: AnsiString): AnsiString;
652 + function TryStrToNumeric(S: Ansistring; out Value: int64; out scale: integer): boolean;
653 + function NumericToDouble(aValue: Int64; aScale: integer): double;
654 +
655  
656   implementation
657  
658 < uses FBMessages
658 > uses FBMessages, Math
659  
660   {$IFDEF FPC}
661   ,RegExpr
# Line 1448 | Line 1452 | begin
1452    ResetQueue;
1453   end;
1454  
1455 + function TSQLTokeniser.ReadCharacters(NumOfChars: integer): AnsiString;
1456 + var i: integer;
1457 + begin
1458 +  Result := FLastChar;
1459 +  for i := 2 to NumOfChars do
1460 +  begin
1461 +    if GetNext = sqltEOF then break;
1462 +    Result := Result + FLastChar;
1463 +  end;
1464 + end;
1465 +
1466   function TSQLTokeniser.GetNextToken: TSQLTokens;
1467   begin
1468    if FQueueState = tsRelease then
# Line 1472 | Line 1487 | begin
1487      GetNext;
1488  
1489    repeat
1490 +    if FSkipNext then
1491 +    begin
1492 +      FSkipNext := false;
1493 +      GetNext;
1494 +    end;
1495 +
1496      Result := FNextToken;
1497      C := FLastChar;
1498      GetNext;
1499  
1500 <    if FSkipNext then
1500 >    if (Result = sqltCR) and (FNextToken = sqltEOL) then
1501      begin
1502 <      FSkipNext := false;
1503 <      continue;
1502 >      FSkipNext := true;
1503 >      Result := sqltEOL;
1504 >      C := LF;
1505      end;
1506  
1507      case FState of
# Line 1492 | Line 1514 | begin
1514            GetNext;
1515          end
1516          else
1517 +        if Result = sqltEOL then
1518 +          FString := FString + LineEnding
1519 +        else
1520            FString := FString + C;
1521        end;
1522  
# Line 1504 | Line 1529 | begin
1529              Result := sqltCommentLine;
1530            end;
1531  
1507        sqltCR: {ignore};
1508
1532          else
1533            FString := FString + C;
1534          end;
# Line 1527 | Line 1550 | begin
1550            end;
1551          end
1552          else
1553 +        if Result = sqltEOL then
1554 +          FString := FString + LineEnding
1555 +        else
1556            FString := FString + C;
1557        end;
1558  
# Line 1546 | Line 1572 | begin
1572            end;
1573          end
1574          else
1575 +        if Result = sqltEOL then
1576 +          FString := FString + LineEnding
1577 +        else
1578            FString := FString + C;
1579        end;
1580  
# Line 1626 | Line 1655 | begin
1655          sqltNumberString:
1656            if FNextToken in [sqltNumberString,sqltPeriod] then
1657              FState := stInNumeric;
1658 +
1659 +        sqltEOL:
1660 +          FString := LineEnding;
1661          end;
1662        end;
1663      end;
# Line 1823 | Line 1855 | begin
1855      end;
1856   end;
1857  
1858 + function TryStrToNumeric(S: Ansistring; out Value: int64; out scale: integer): boolean;
1859 + var i: integer;
1860 +    ds: integer;
1861 +    exponent: integer;
1862 + begin
1863 +  Result := false;
1864 +  ds := 0;
1865 +  exponent := 0;
1866 +  S := Trim(S);
1867 +  Value := 0;
1868 +  scale := 0;
1869 +  if Length(S) = 0 then
1870 +    Exit;
1871 +  {$IF declared(DefaultFormatSettings)}
1872 +  with DefaultFormatSettings do
1873 +  {$ELSE}
1874 +  {$IF declared(FormatSettings)}
1875 +  with FormatSettings do
1876 +  {$IFEND}
1877 +  {$IFEND}
1878 +  begin
1879 +    for i := length(S) downto 1 do
1880 +    begin
1881 +      if S[i] = AnsiChar(DecimalSeparator) then
1882 +      begin
1883 +          if ds <> 0 then Exit; {only one allowed}
1884 +          ds := i;
1885 +          dec(exponent);
1886 +          system.Delete(S,i,1);
1887 +      end
1888 +      else
1889 +      if S[i] in ['+','-'] then
1890 +      begin
1891 +       if (i > 1) and not (S[i-1] in ['e','E']) then
1892 +          Exit; {malformed}
1893 +      end
1894 +      else
1895 +      if S[i] in ['e','E'] then {scientific notation}
1896 +      begin
1897 +        if ds <> 0 then Exit; {not permitted in exponent}
1898 +        if exponent <> 0 then Exit; {only one allowed}
1899 +        exponent := i;
1900 +      end
1901 +      else
1902 +      if not (S[i] in ['0'..'9']) then
1903 +      {Note: ThousandSeparator not allowed by Delphi specs}
1904 +          Exit; {bad character}
1905 +    end;
1906 +
1907 +    if exponent > 0 then
1908 +    begin
1909 +      Result := TryStrToInt(system.copy(S,exponent+1,maxint),Scale);
1910 +      if Result then
1911 +      begin
1912 +        {adjust scale for decimal point}
1913 +        if ds <> 0 then
1914 +          Scale := Scale - (exponent - ds);
1915 +        Result := TryStrToInt64(system.copy(S,1,exponent-1),Value);
1916 +      end;
1917 +    end
1918 +    else
1919 +    begin
1920 +      if ds <> 0 then
1921 +        scale := ds - Length(S) - 1;
1922 +      Result := TryStrToInt64(S,Value);
1923 +    end;
1924 +  end;
1925 + end;
1926 +
1927 + function NumericToDouble(aValue: Int64; aScale: integer): double;
1928 + begin
1929 +  Result := aValue * IntPower(10,aScale)
1930 + end;
1931 +
1932   end.

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines