mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 09:39:20 +02:00
atari: implement ARGV protocol for runtime startup
This commit is contained in:
parent
41d4e181ea
commit
fecb72fea3
@ -14,11 +14,23 @@
|
||||
|
||||
**********************************************************************}
|
||||
|
||||
(* define this symbol to get ARGV argument passing that's strictly
|
||||
* compatible with the Atari standard. If it's not defined, then
|
||||
* the startup code won't validate the ARGV= variable by checking
|
||||
* the command byte for 127. Note that there are still some
|
||||
* applications (gulam is a notable example) that implement only
|
||||
* part of the standard and don't set the command byte to 127.
|
||||
*)
|
||||
{$IF 0}
|
||||
{$DEFINE STRICTLY_COMPATIBLE_WITH_STANDARD }
|
||||
{$ENDIF}
|
||||
|
||||
{ Generates correct argument array on startup }
|
||||
procedure GenerateArgs;
|
||||
var
|
||||
ArgVLen: LongInt;
|
||||
LocalIndex: Word;
|
||||
len: Integer;
|
||||
|
||||
procedure AllocArg(Idx, Len: LongInt);
|
||||
var
|
||||
@ -35,69 +47,116 @@ var
|
||||
ArgV[Idx] := SysAllocMem(Succ(Len));
|
||||
end;
|
||||
|
||||
function scan_argv : boolean;
|
||||
var
|
||||
hp, start : pchar;
|
||||
len: integer;
|
||||
begin
|
||||
hp:=basepage^.p_env;
|
||||
result:=false;
|
||||
if (hp=nil) then
|
||||
exit;
|
||||
LocalIndex := 0;
|
||||
while hp^<>#0 do
|
||||
begin
|
||||
if (hp[0] = 'A') and (hp[1] = 'R') and (hp[2] = 'G') and (hp[3] = 'V') and (hp[4] = '=') then
|
||||
begin
|
||||
{ in any case, terminate environment here }
|
||||
hp[0] := #0;
|
||||
hp[1] := #0;
|
||||
{ skip ARGV= string }
|
||||
hp := hp + 5;
|
||||
if (hp[0] = 'N') and (hp[1] = 'U') and (hp[2] = 'L') and (hp[3] = 'L') and (hp[4] = ':') then
|
||||
begin
|
||||
{ TODO: handle NULL arguments }
|
||||
end;
|
||||
{$ifdef STRICTLY_COMPATIBLE_WITH_STANDARD}
|
||||
if (len <> 127) then
|
||||
exit;
|
||||
{$endif}
|
||||
{ skip ARGV= value }
|
||||
while hp^<>#0 do
|
||||
inc(hp);
|
||||
inc(hp);
|
||||
{ get arguments }
|
||||
while hp^<>#0 do
|
||||
begin
|
||||
start := hp;
|
||||
while hp^<>#0 do
|
||||
inc(hp);
|
||||
len := hp - start;
|
||||
allocarg(localindex,len);
|
||||
move(start^,argv[localindex]^,len);
|
||||
argv[localindex][len]:=#0;
|
||||
inc(localindex);
|
||||
inc(hp);
|
||||
end;
|
||||
argc:=localindex;
|
||||
result := true;
|
||||
exit;
|
||||
end;
|
||||
hp := hp + strlen(hp) + 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
Count: Word;
|
||||
Start: Word;
|
||||
Ende: Word;
|
||||
LocalIndex: Word;
|
||||
i: Integer;
|
||||
P : PChar;
|
||||
Temp : AnsiString;
|
||||
InQuotes: boolean;
|
||||
begin
|
||||
P := Args;
|
||||
ArgVLen := 0;
|
||||
|
||||
{ Set argv[0] }
|
||||
Temp := ParamStr(0);
|
||||
AllocArg(0, Length(Temp));
|
||||
Move(Temp[1], Argv[0]^, Length(Temp));
|
||||
Argv[0][Length(Temp)] := #0;
|
||||
{ check ARGV usage indicator }
|
||||
len := ord(P[0]);
|
||||
if scan_argv then
|
||||
exit;
|
||||
|
||||
{ Set argv[0] }
|
||||
AllocArg(0, 0);
|
||||
Argv[0][0] := #0;
|
||||
|
||||
{ just in case; commandline cannot be longer }
|
||||
if len > 127 then
|
||||
begin
|
||||
argc := 1;
|
||||
exit;
|
||||
end;
|
||||
|
||||
InQuotes := False;
|
||||
{ Handle the other args }
|
||||
Count := 0;
|
||||
p[len + 1] := #0;
|
||||
Count := 1;
|
||||
{ first index is one }
|
||||
LocalIndex := 1;
|
||||
while (P[Count] <> #0) do
|
||||
begin
|
||||
while (p[count]=' ') or (p[count]=#9) or (p[count]=LineEnding) do
|
||||
while (P[Count] <> #0) and (p[count]<=#32) do
|
||||
Inc(count);
|
||||
if p[count] = '"' then
|
||||
begin
|
||||
inQuotes := True;
|
||||
Inc(Count);
|
||||
end;
|
||||
start := count;
|
||||
if inQuotes then
|
||||
begin
|
||||
while (p[count]<>#0) and (p[count]<>'"') and (p[count]<>LineEnding) do
|
||||
begin
|
||||
Inc(Count)
|
||||
end;
|
||||
start := count;
|
||||
while (p[count]<>#0) and (p[count]<>'"') and (p[count]>=#32) do
|
||||
Inc(Count);
|
||||
ende := count;
|
||||
if (p[count] = '"') then
|
||||
Inc(Count);
|
||||
end else
|
||||
begin
|
||||
while (p[count]<>#0) and (p[count]<>' ') and (p[count]<>#9) and (p[count]<>LineEnding) do
|
||||
start := count;
|
||||
while (p[count]<>#0) and (p[count]>#32) do
|
||||
inc(count);
|
||||
ende := count;
|
||||
end;
|
||||
ende := count;
|
||||
if not inQuotes then
|
||||
begin
|
||||
while (p[start]=' ') and (Start < Ende) do
|
||||
Inc(Start)
|
||||
end;
|
||||
if (ende-start>0) then
|
||||
if (ende>start) then
|
||||
begin
|
||||
allocarg(localindex,ende-start);
|
||||
move(p[start],argv[localindex]^,ende-start);
|
||||
argv[localindex][ende-start]:=#0;
|
||||
if inQuotes and (argv[localindex][(ende-start) - 1] = '"') then
|
||||
argv[localindex][(ende-start)-1] := #0;
|
||||
inc(localindex);
|
||||
end;
|
||||
if inQuotes and (p[count] = '"') then
|
||||
Inc(Count);
|
||||
inQuotes := False;
|
||||
end;
|
||||
argc:=localindex;
|
||||
end;
|
||||
@ -119,6 +178,6 @@ var
|
||||
s1: string;
|
||||
begin
|
||||
ParamStr := '';
|
||||
if (l > 0) and (l + 1 <= argc) then
|
||||
if (l >= 0) and (l < argc) then
|
||||
ParamStr := StrPas(argv[l]);
|
||||
end;
|
||||
|
@ -119,7 +119,7 @@ var
|
||||
procedure SysInitParamsAndEnv;
|
||||
begin
|
||||
// [0] index contains the args length...
|
||||
args:=@basepage^.p_cmdlin[1];
|
||||
args:=@basepage^.p_cmdlin[0];
|
||||
GenerateArgs;
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user