-
Here's a simple version that also works for freepascal (ansi and unicode) of the Format function. I missed that and it is also marked as missing in kol.pas.
function Format( const fmt: KOLString; params: array of const): KOLString;
var
ElsArray, El: PPtrUInt;
I : Integer;
P : PPtrUInt;
begin
Setlength(Result,1024);
ElsArray := nil;
if High( params ) >= 0 then
GetMem( ElsArray, (High( params ) + 1) * sizeof( Pointer ) );
El := ElsArray;
for I := 0 to High( params ) do
begin
P := @params[ I ];
P := Pointer( P^ );
El^ := PtrUInt( P );
Inc( El );
end;
wvsprintf( PKOLChar(Result), PKOLChar( fmt ), Pointer( ElsArray ) );
if ElsArray <> nil then
FreeMem( ElsArray );
end;
-
Oops, that is the worng one. Clipboard playing tricks on me ;) This is the correct one, sorry:
function Format(Format: KolString; const Args: array of const): KolString;
type
TVAList = array[0..$FFFF] of Pointer;
var
VA: TVAList;
StrI, I, Size: Integer;
Strings: array[0..High(VA)] of KolString;
begin
Result :='';
If length(Args) > 0 then
begin
StrI := 0;
Size := Length(Format) *SizeOf(KolChar);
SetLength(Result,1024);
for I := 0 to Length(Args) - 1 do
with Args[I] do
case VType of
vtInteger:
begin
VA[I] := Pointer(VInteger);
Inc(Size, SizeOf(TVarRec));
end;
vtPChar,
vtAnsiString:
begin
Strings[StrI] := VPChar + #0;
VA[I] := @Strings[StrI][1];
Inc(Size, Length(Strings[StrI]) * 2 - 2 );
Inc(StrI);
end;
vtPWideChar,
vtWideString:
begin
VA[I] := VPWideChar;
Inc(Size, Length(VPWideChar) * 2);
end;
else
Result :='';
end;
end;
if length(Result) > 0 then
SetLength(Result, wvsprintf(@Result[1], PKolChar(Format), @VA));
end;
-
I left in some debug code. This one is much cleaner and easier to adapt:
function Format(Format: KolString; const Args: array of const): KolString;
type
TVAList = array[0..$FFFF] of Pointer;
var
VA: TVAList;
StrI, I: Integer;
Strings: array[0..High(VA)] of KolString;
begin
Result :='';
If length(Args) > 0 then
begin
StrI := 0;
SetLength(Result,1024);
for I := 0 to Length(Args) - 1 do
with Args[I] do
case VType of
vtInteger: VA[I] := Pointer(VInteger);
vtPChar,
vtAnsiString:
begin
Strings[StrI] := VPChar + #0;
VA[I] := @Strings[StrI][1];
Inc(StrI);
end;
vtPWideChar,
vtWideString:VA[I] := VPWideChar;
else
Result :='';
end;
end;
if length(Result) > 0 then
SetLength(Result, wvsprintf(PKolChar(Result), PKolChar(Format), @VA));
end;
-
BTW it also works for the KOL 64 bit version! Both in XE2 and in Freepascal 2.7.1.
-
Again some improvement. Tested for FPC 2.7.1 and Delphi 4-XE2 both 32 and 64 bit. Maybe Vladimir can insert it in kol.pas? Because it is important for freepascal. Seems that this is enough, but you need at least delphi 4:
function Format2(Format: KolString; const Args: array of const): KolString;
type
TVAList = array[0..$FFFF] of Pointer;
var
VA: TVAList;
I: Integer;
begin
Result :='';
If length(Args) > 0 then
begin
SetLength(Result,1024); for I := 0 to Length(Args) - 1 do
with Args[I] do
case VType of
vtInteger:VA[I] := Pointer(VInteger);
vtPChar,
vtAnsiString:VA[I] := VPChar;
vtPWideChar,
vtWideString:VA[I] := VPWideChar;
else
Result :='';
end;
end;
if length(Result) > 0 then
SetLength(Result, wvsprintf(PKolChar(Result), PKolChar(Format), @VA));
end;
-
ignore the last. It breaks. The previous one is good.
-
It still fails some tests, so ignore it. I will open a new post when finished. Probably just Ansi version only.
-
Was totally stuck until I read this, now back up and runngni.
-
Thanks for the inhsigt. It brings light into the dark!
|