mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-10 12:02:32 +02:00
286 lines
6.7 KiB
PHP
286 lines
6.7 KiB
PHP
{%MainUnit lazutf8.pas}
|
|
|
|
var
|
|
//Function prototypes
|
|
_ParamStrUtf8: Function(Param: Integer): string;
|
|
|
|
var
|
|
ArgsW: Array of WideString;
|
|
ArgsWCount: Integer;
|
|
|
|
//************ START "Stubs" that just call Ansi or Wide implementation
|
|
|
|
function ParamStrUTF8(Param: Integer): string;
|
|
begin
|
|
Result := _ParamStrUtf8(Param);
|
|
end;
|
|
|
|
//************ END "Stubs" that just call Ansi or Wide implementation
|
|
|
|
|
|
//*************** START Non WideString implementations
|
|
{$ifndef wince}
|
|
function ParamStrUtf8Ansi(Param: Integer): String;
|
|
begin
|
|
Result:=SysToUTF8(ObjPas.ParamStr(Param));
|
|
end;
|
|
{$endif wince}
|
|
|
|
//*************** END Non WideString impementations
|
|
|
|
|
|
|
|
|
|
//*************** START WideString impementations
|
|
|
|
//fpc 2.6.0 does not have StrLen for WideChar.
|
|
//Remove this when we have 2.6.4 or higher
|
|
{$if FPC_FULLVERSION < 20602}
|
|
function StrLen(PW: PWideChar): SizeInt; overload;
|
|
var
|
|
i: SizeInt;
|
|
begin
|
|
i:=0;
|
|
if assigned(PW) then
|
|
while (PW[i] <> #0) do inc(i);
|
|
Result := i;
|
|
end;
|
|
{$endif}
|
|
|
|
|
|
procedure SetupCommandlineParametersWide;
|
|
var
|
|
ArgLen, Start, CmdLen, i, j: SizeInt;
|
|
Quote : Boolean;
|
|
Buf: array[0..259] of WChar; // need MAX_PATH bytes, not 256!
|
|
PCmdLineW: PWideChar;
|
|
CmdLineW: WideString;
|
|
|
|
procedure AllocArg(Idx, Len:longint);
|
|
begin
|
|
if (Idx >= ArgsWCount) then
|
|
begin
|
|
SetLength(ArgsW, Idx + 1);
|
|
SetLength(ArgsW[Idx], Len);
|
|
end;
|
|
end;
|
|
|
|
|
|
begin
|
|
{ create commandline, it starts with the executed filename which is argv[0] }
|
|
{ Win32 passes the command NOT via the args, but via getmodulefilename}
|
|
ArgsWCount := 0;
|
|
ArgLen := GetModuleFileNameW(0, @buf[0], sizeof(buf));
|
|
|
|
//writeln('ArgLen = ',Arglen);
|
|
|
|
buf[ArgLen] := #0; // be safe, no terminating 0 on XP
|
|
allocarg(0,arglen);
|
|
move(buf[0],ArgsW[0][1],arglen * SizeOf(WChar));
|
|
|
|
//writeln('ArgsW[0] = ',ArgsW[0]);
|
|
|
|
PCmdLineW := nil;
|
|
{ Setup cmdline variable }
|
|
PCmdLineW := GetCommandLineW;
|
|
CmdLen := StrLen(PCmdLineW);
|
|
|
|
//writeln('StrLen(PCmdLineW) = ',CmdLen);
|
|
|
|
SetLength(CmdLineW, CmdLen);
|
|
Move(PCmdLineW^, CmdLineW[1], CmdLen * SizeOf(WChar));
|
|
|
|
|
|
//debugln(CmdLineW);
|
|
//for i := 1 to CmdLen do DbgOut(DbgS(i mod 10)); debugln;
|
|
|
|
i := 1;
|
|
while (i <= CmdLen) do
|
|
begin
|
|
//debugln('Next');
|
|
//DbgOut('i=',DbgS(i),' CmdLineW[',DbgS(i),']=');if i<=CmdLen then debugln(CmdLineW[i]) else debugln('#0');
|
|
//skip leading spaces
|
|
while (i <= CmdLen) and (CmdLineW[i] <= #32) do Inc(i);
|
|
//DbgOut('After skipping spaces: i=',DbgS(i),' CmdLineW[',DbgS(i),']=');if i<=CmdLen then debugln(CmdLineW[i]) else debugln('#0');
|
|
if (i > CmdLen) then Break;
|
|
Quote := False;
|
|
Start := i;
|
|
ArgLen := 0;
|
|
while (i <= CmdLen) do
|
|
begin //find next commandline parameter
|
|
case CmdLineW[i] of
|
|
#1..#32:
|
|
begin
|
|
if Quote then
|
|
begin
|
|
//debugln('i=',DbgS(i),': Space in Quote');
|
|
Inc(ArgLen)
|
|
end
|
|
else
|
|
begin
|
|
//debugln('i=',DbgS(i),': Space in NOT Quote');
|
|
Break;
|
|
end;
|
|
end;
|
|
'"':
|
|
begin
|
|
if (i < CmdLen) and (CmdLineW[i+1] <> '"') then
|
|
begin
|
|
//debugln('i=',DbgS(i),': Quote := not Quote');
|
|
Quote := not Quote
|
|
end
|
|
else
|
|
begin
|
|
//debugln('i=',DbgS(i),': Skip Quote');
|
|
Inc(i);
|
|
end;
|
|
end;
|
|
else Inc(ArgLen);
|
|
end;//case
|
|
Inc(i);
|
|
|
|
|
|
end; //find next commandline parameter
|
|
|
|
//debugln('ArgWCount=',DbgS(ArgsWCount),' Start=',DbgS(start),' ArgLen=',DbgS(arglen),' i=',DbgS(i));
|
|
|
|
//we already have (a better) ArgW[0]
|
|
if (ArgsWCount > 0) then
|
|
begin //Process commadline parameter
|
|
AllocArg(ArgsWCount, ArgLen);
|
|
Quote := False;
|
|
i := Start;
|
|
j := 1;
|
|
while (i <= CmdLen) do
|
|
begin
|
|
case CmdLineW[i] of
|
|
#1..#32:
|
|
begin
|
|
if Quote then
|
|
begin
|
|
//if j > ArgLen then debugln('Error whitespace: j > ArgLen: j=',DbgS(j),' ArgLen=',DbgS(arglen));
|
|
ArgsW[ArgsWCount][j] := CmdLineW[i];
|
|
Inc(j);
|
|
end
|
|
else
|
|
Break;
|
|
end;
|
|
'"':
|
|
begin
|
|
if (i < CmdLen) and (CmdLineW[i+1] <> '"') then
|
|
Quote := not Quote
|
|
else
|
|
Inc(i);
|
|
end;
|
|
else
|
|
begin
|
|
//if j > ArgLen then debugln('Error Quote: j > ArgLen: j=',DbgS(j),' ArgLen=',DbgS(arglen));
|
|
ArgsW[ArgsWCount][j] := CmdLineW[i];
|
|
Inc(j);
|
|
end;
|
|
end;
|
|
Inc(i);
|
|
end;
|
|
|
|
//debugln('ArgsW[',DbgS(ArgsWCount),'] = ',ArgsW[ArgsWCount]);
|
|
end; // Process commandline parameter
|
|
Inc(ArgsWCount);
|
|
|
|
end;
|
|
Dec(ArgsWCount);
|
|
end;
|
|
|
|
function ParamStrUtf8Wide(Param: Integer): String;
|
|
begin
|
|
if ArgsWCount <> ParamCount then
|
|
begin
|
|
//DebugLn('Error: ParamCount <> ArgsWCount!');
|
|
Result := SysToUtf8(ObjPas.ParamStr(Param));
|
|
end
|
|
else
|
|
begin
|
|
if (Param <= ArgsWCount) then
|
|
Result := Utf8Encode(ArgsW[Param])
|
|
else
|
|
Result := '';
|
|
end;
|
|
end;
|
|
|
|
//*************** END WideString impementations
|
|
|
|
|
|
|
|
function ConsoleToUTF8(const s: string): string;// converts UTF8 string to console encoding (used by Write, WriteLn)
|
|
var
|
|
Dst: PChar;
|
|
begin
|
|
{$ifdef WinCE}
|
|
Result := SysToUTF8(s);
|
|
{$else}
|
|
Dst := AllocMem((Length(s) + 1) * SizeOf(Char));
|
|
if OemToChar(PChar(s), Dst) then
|
|
Result := StrPas(Dst)
|
|
else
|
|
Result := s;
|
|
FreeMem(Dst);
|
|
Result := SysToUTF8(Result);
|
|
{$endif}
|
|
end;
|
|
|
|
function UTF8ToConsole(const s: string): string;
|
|
var
|
|
Dst: PChar;
|
|
begin
|
|
{$ifdef WinCE}
|
|
Result := UTF8ToSys(s);
|
|
{$else}
|
|
Result := UTF8ToSys(s);
|
|
Dst := AllocMem((Length(Result) + 1) * SizeOf(Char));
|
|
if CharToOEM(PChar(Result), Dst) then
|
|
Result := StrPas(Dst);
|
|
FreeMem(Dst);
|
|
{$endif}
|
|
end;
|
|
|
|
{$ifdef debugparamstrutf8}
|
|
procedure ParamStrUtf8Error;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
writeln('Error in Windows WideString implementation of ParamStrUtf8');
|
|
writeln('Using SysToUtf8(ParamsStr(Param)) as fallback');
|
|
writeln('ParamCount = ',ParamCount,', ArgsWCount = ',ArgsWCount);
|
|
for i := 0 to ParamCount do writeln('ParamStr(',i,') = "',ParamStr(i),'"');
|
|
writeln;
|
|
for i := 0 to ArgsWCount do writeln('ParamStrUtf8(',i,') = "',ArgsW[i],'"');
|
|
end;
|
|
{$endif}
|
|
|
|
procedure InitLazUtf8;
|
|
begin
|
|
{$ifndef WinCE}
|
|
if Win32MajorVersion <= 4 then
|
|
begin
|
|
_ParamStrUtf8 := @ParamStrUtf8Ansi;
|
|
end
|
|
else
|
|
{$endif}
|
|
begin
|
|
try
|
|
ArgsWCount := -1;
|
|
_ParamStrUtf8 := @ParamStrUtf8Wide;
|
|
SetupCommandlineParametersWide;
|
|
{$ifdef debugparamstrutf8}
|
|
if ParamCount <> ArgsWCount then ParamStrUtf8Error;
|
|
{$endif}
|
|
Except
|
|
begin
|
|
ArgsWCount := -1;
|
|
{$ifdef debugparamstrutf8}
|
|
ParamStrUtf8Error;
|
|
{$endif}
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|