2008-04-12 11:48:18 +02:00
|
|
|
|
{utf8}
|
2007-08-29 11:16:31 +02:00
|
|
|
|
unit System;
|
|
|
|
|
|
|
|
|
|
{$i _defines.inc}
|
|
|
|
|
{$define HAS_CMDLINE}
|
|
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
|
|
{$i systemh.inc}
|
|
|
|
|
{$i kos_def.inc}
|
|
|
|
|
{$i kosh.inc}
|
|
|
|
|
|
|
|
|
|
const
|
|
|
|
|
LineEnding = #13#10;
|
|
|
|
|
LFNSupport = True;
|
|
|
|
|
DirectorySeparator = '/';
|
|
|
|
|
DriveSeparator = '/';
|
|
|
|
|
PathSeparator = ';';
|
|
|
|
|
MaxExitCode = 65535;
|
|
|
|
|
MaxPathLen = 512;
|
|
|
|
|
|
|
|
|
|
UnusedHandle : THandle = -1;
|
|
|
|
|
StdInputHandle : THandle = 0;
|
|
|
|
|
StdOutputHandle: THandle = 0;
|
|
|
|
|
StdErrorHandle : THandle = 0;
|
|
|
|
|
FileNameCaseSensitive: Boolean = True;
|
|
|
|
|
CtrlZMarksEOF: Boolean = True;
|
|
|
|
|
sLineBreak = LineEnding;
|
|
|
|
|
DefaultTextLineBreakStyle: TTextLineBreakStyle = tlbsCRLF;
|
|
|
|
|
|
|
|
|
|
var
|
|
|
|
|
Argc: Longint = 0;
|
|
|
|
|
Argv: PPChar = nil;
|
|
|
|
|
|
|
|
|
|
Konsole: TKonsole;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
|
|
|
|
var
|
|
|
|
|
SysInstance: Longint; public name '_FPC_SysInstance';
|
|
|
|
|
|
|
|
|
|
{$i system.inc}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
procedure SetupCmdLine;
|
|
|
|
|
var
|
|
|
|
|
Ptrs: array of PChar;
|
|
|
|
|
Args: PChar;
|
|
|
|
|
InQuotes: Boolean;
|
|
|
|
|
I, L: Longint;
|
|
|
|
|
begin
|
|
|
|
|
Argc := 1;
|
|
|
|
|
Args := PKosHeader(0)^.args;
|
|
|
|
|
if Assigned(Args) then
|
|
|
|
|
begin
|
|
|
|
|
while Args^ <> #0 do
|
|
|
|
|
begin
|
2008-04-12 11:48:18 +02:00
|
|
|
|
{Пропустить лидирующие пробелы}
|
2007-08-29 11:16:31 +02:00
|
|
|
|
while Args^ in [#1..#32] do Inc(Args);
|
|
|
|
|
if Args^ = #0 then Break;
|
|
|
|
|
|
2008-04-12 11:48:18 +02:00
|
|
|
|
{Запомнить указатель на параметр}
|
2007-08-29 11:16:31 +02:00
|
|
|
|
SetLength(Ptrs, Argc);
|
|
|
|
|
Ptrs[Argc - 1] := Args;
|
|
|
|
|
Inc(Argc);
|
|
|
|
|
|
2008-04-12 11:48:18 +02:00
|
|
|
|
{Пропустить текущий параметр}
|
2007-08-29 11:16:31 +02:00
|
|
|
|
InQuotes := False;
|
|
|
|
|
while (Args^ <> #0) and (not (Args^ in [#1..#32]) or InQuotes) do
|
|
|
|
|
begin
|
|
|
|
|
if Args^ = '"' then InQuotes := not InQuotes;
|
|
|
|
|
Inc(Args);
|
|
|
|
|
end;
|
|
|
|
|
|
2008-04-12 11:48:18 +02:00
|
|
|
|
{Установить окончание параметра}
|
2007-08-29 11:16:31 +02:00
|
|
|
|
if Args^ in [#1..#32] then
|
|
|
|
|
begin
|
|
|
|
|
Args^ := #0;
|
|
|
|
|
Inc(Args);
|
|
|
|
|
end;
|
|
|
|
|
end;
|
|
|
|
|
end;
|
2008-04-12 11:48:18 +02:00
|
|
|
|
Argv := GetMem(Argc * SizeOf(PChar)); {XXX: память не освобождается}
|
2007-08-29 11:16:31 +02:00
|
|
|
|
Argv[0] := PKosHeader(0)^.path;
|
|
|
|
|
for I := 1 to Argc - 1 do
|
|
|
|
|
begin
|
|
|
|
|
Argv[I] := Ptrs[I - 1];
|
2008-04-12 11:48:18 +02:00
|
|
|
|
{Исключить кавычки из строки}
|
2007-08-29 11:16:31 +02:00
|
|
|
|
Args := Argv[I];
|
|
|
|
|
L := 0;
|
|
|
|
|
while Args^ <> #0 do begin Inc(Args); Inc(L); end;
|
|
|
|
|
Args := Argv[I];
|
|
|
|
|
while Args^ <> #0 do
|
|
|
|
|
begin
|
|
|
|
|
if Args^ = '"' then
|
|
|
|
|
begin
|
|
|
|
|
Move(PChar(Args + 1)^, Args^, L);
|
|
|
|
|
Dec(L);
|
|
|
|
|
end;
|
|
|
|
|
Inc(Args);
|
|
|
|
|
Dec(L);
|
|
|
|
|
end;
|
|
|
|
|
end;
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
function ParamCount: Longint;
|
|
|
|
|
begin
|
|
|
|
|
Result := Argc - 1;
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
function ParamStr(L: Longint): String;
|
|
|
|
|
begin
|
|
|
|
|
if (L >= 0) and (L < Argc) then
|
|
|
|
|
Result := StrPas(Argv[L]) else
|
|
|
|
|
Result := '';
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure Randomize;
|
|
|
|
|
begin
|
2008-04-12 11:48:18 +02:00
|
|
|
|
randseed := kos_timecounter();
|
2007-08-29 11:16:31 +02:00
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
const
|
|
|
|
|
ProcessID: SizeUInt = 0;
|
|
|
|
|
|
|
|
|
|
function GetProcessID: SizeUInt;
|
|
|
|
|
begin
|
|
|
|
|
GetProcessID := ProcessID;
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
function CheckInitialStkLen(stklen: SizeUInt): SizeUInt;
|
|
|
|
|
begin
|
|
|
|
|
{TODO}
|
|
|
|
|
Result := stklen;
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
{$i kos_stdio.inc}
|
|
|
|
|
|
|
|
|
|
procedure SysInitStdIO;
|
|
|
|
|
begin
|
|
|
|
|
if IsConsole then
|
|
|
|
|
begin
|
|
|
|
|
AssignStdin(Input);
|
|
|
|
|
AssignStdout(Output);
|
|
|
|
|
AssignStdout(ErrOutput);
|
|
|
|
|
AssignStdout(StdOut);
|
|
|
|
|
AssignStdout(StdErr);
|
|
|
|
|
end;
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure System_Exit; [public, alias: 'SystemExit'];
|
|
|
|
|
var
|
|
|
|
|
event, count: DWord;
|
|
|
|
|
begin
|
|
|
|
|
if IsConsole then
|
|
|
|
|
begin
|
|
|
|
|
if ExitCode <> 0 then
|
|
|
|
|
begin
|
2008-04-12 11:48:18 +02:00
|
|
|
|
{XXX: обязательное условие на однопоточный Konsole}
|
2007-08-29 11:16:31 +02:00
|
|
|
|
Write(StdErr, '[Error #', ExitCode,', press any key]');
|
2008-04-12 11:48:18 +02:00
|
|
|
|
{ожидать нажатия клавиши}
|
2007-08-29 11:16:31 +02:00
|
|
|
|
Konsole.KeyPressed;
|
|
|
|
|
while Konsole.KeyPressed = 0 do kos_delay(2);
|
2008-04-12 11:48:18 +02:00
|
|
|
|
{TODO: исправить косяк при перерисовке Konsole}
|
|
|
|
|
{это невозможно, так как куча освобождается еще до вызова этой процедуры}
|
|
|
|
|
{можно написать свой диспетчер памяти, но это сложно}
|
|
|
|
|
{а если в Konsole использовать выделение памяти напрямую через KosAPI?!}
|
2007-08-29 11:16:31 +02:00
|
|
|
|
end;
|
|
|
|
|
Close(StdErr);
|
|
|
|
|
Close(StdOut);
|
|
|
|
|
Close(ErrOutput);
|
|
|
|
|
Close(Input);
|
|
|
|
|
Close(Output);
|
|
|
|
|
Konsole.Done();
|
|
|
|
|
end;
|
|
|
|
|
asm
|
|
|
|
|
movl $-1, %eax
|
|
|
|
|
int $0x40
|
|
|
|
|
end;
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
{$i kos.inc}
|
|
|
|
|
|
|
|
|
|
begin
|
|
|
|
|
SysResetFPU;
|
|
|
|
|
StackLength := CheckInitialStkLen(InitialStkLen);
|
|
|
|
|
StackBottom := Pointer(StackTop - StackLength);
|
|
|
|
|
kos_initheap();
|
2007-10-27 18:38:51 +02:00
|
|
|
|
InitHeap;
|
2007-08-29 11:16:31 +02:00
|
|
|
|
SysInitExceptions;
|
|
|
|
|
FPC_CpuCodeInit();
|
|
|
|
|
InOutRes := 0;
|
|
|
|
|
InitSystemThreads;
|
2007-10-27 18:38:51 +02:00
|
|
|
|
if IsConsole then
|
|
|
|
|
Konsole.Init();
|
2007-08-29 11:16:31 +02:00
|
|
|
|
SysInitStdIO;
|
|
|
|
|
SetupCmdLine;
|
|
|
|
|
InitVariantManager;
|
|
|
|
|
{InitWideStringManager;}
|
|
|
|
|
DispCallByIDProc := @DoDispCallByIDError;
|
|
|
|
|
end.
|