sinclairql: first version of working argc/argv generation. implemented ParamCount and ParamStr()

git-svn-id: trunk@49168 -
This commit is contained in:
Károly Balogh 2021-04-10 15:12:45 +00:00
parent b2afecdae5
commit f3a19aaf59
2 changed files with 85 additions and 47 deletions

View File

@ -26,13 +26,10 @@ var
binend: byte; external name '_etext';
bssstart: byte; external name '_sbss';
bssend: byte; external name '_ebss';
nb_ChannelIds : word;
pChannelIds : pdword;
CmdLine_len : word; public name '__CmdLine_len';
pCmdLine : pchar; public name '__pCmdLine';
jobStackDataPtr: pointer; public name '__job_stack_data_ptr';
procedure PascalMain; external name 'PASCALMAIN';
procedure PascalStart(commandLine: pword; channelData: pword); cdecl; noreturn; forward;
procedure PascalStart(a7_on_entry: pointer); noreturn; forward;
{ this function must be the first in this unit which contains code }
procedure _FPC_proc_start; cdecl; assembler; nostackframe; noreturn; public name '_start';
@ -79,8 +76,7 @@ asm
bne @relocloop
@noreloc:
pea (a7)
pea (a6,a5)
move.l a7,a0
bra PascalStart
end;
@ -90,15 +86,12 @@ begin
mt_frjob(-1, _ExitCode);
end;
procedure PascalStart(commandLine: pword; channelData: pword); cdecl; noreturn;
procedure PascalStart(a7_on_entry: pointer); noreturn;
begin
{ initialize .bss }
FillChar(bssstart,PtrUInt(@bssend)-PtrUInt(@bssstart),#0);
nb_ChannelIDs:=channelData[0];
pChannelIDs:=@channelData[1];
CmdLine_Len:=commandLine[0];
pCmdLine:=@commandLine[1];
jobStackDataPtr:=a7_on_entry;
PascalMain;
end;

View File

@ -54,13 +54,13 @@ const
StdErrorHandle: longint = UnusedHandle;
var
args: PChar;
argc: LongInt;
QL_ChannelIDNum : word;
QL_ChannelIDs: pdword;
QL_CommandLineLen : word;
QL_CommandLine : pchar;
argv: PPChar;
envp: PPChar;
heapStart: pointer;
argc: Longint;
{$if defined(FPUSOFT)}
@ -106,50 +106,82 @@ begin
GetProcessID := mt_inf(nil, nil);
end;
{*****************************************************************************
ParamStr
*****************************************************************************}
var
CmdLine_len : word; external name '__CmdLine_len';
pCmdLine : pchar; external name '__pCmdLine';
args: PChar;
{ number of args }
function ParamCount: LongInt;
begin
ParamCount:=argc;
end;
{ argument number l }
function ParamStr(l: LongInt): string;
begin
if (l >= 0) and (l <= argc) then
ParamStr:=argv[l]
else
ParamStr:='';
end;
procedure SysInitParamsAndEnv;
var
str_len, i : word;
i,j : longint;
c : char;
in_word : boolean;
argv_size : longint;
const
word_separators=[' ',#0];
begin
str_len:=CmdLine_len;
argc:=0;
argv:=nil;
args:=pCmdLine;
args:=GetMem(QL_CommandLineLen+1);
if not assigned(args) then
exit;
{ Parse command line }
{ Compute argc imply replace spaces by #0 }
Move(QL_CommandLine^,args^,QL_CommandLineLen);
args[QL_CommandLineLen]:=#0;
i:=0;
in_word:=false;
while (i < str_len) do
c:=' ';
while args[i]<>#0 do
begin
if (c in word_separators) and not (args[i] in word_separators) then
inc(argc);
c:=args[i];
if (not in_word) then
inc(i);
end;
{ +2 is because argv[0] should be program name,
and argv[argc+1] is argv array terminator }
argv:=GetMem((argc+2)*sizeof(pointer));
if not assigned(argv) then
begin
argc:=0;
exit;
end;
argv[argc+1]:=nil;
{ FIX ME: for now the 0th argument (program name) is just always empty }
argv[0]:=#0;
i:=0;
j:=1;
c:=' ';
while args[i]<>#0 do
begin
if (c in word_separators) and not (args[i] in word_separators) then
begin
if not(c in word_separators) then
begin
inc(argc);
argv[argc]:=@args[i];
in_word:=true;
end
else
begin
args[i]:=#0;
end;
end
else if (c in word_separators) then
begin
in_word:=false;
args[i]:=#0;
end;
inc(i);
end;
argv[j]:=@args[i];
inc(j);
end;
c:=args[i];
if (c in word_separators) then
args[i]:=#0;
inc(i);
end;
end;
procedure randomize;
@ -175,11 +207,19 @@ end;
{*****************************************************************************
System Dependent Entry code
*****************************************************************************}
var
jobStackDataPtr: pointer; external name '__job_stack_data_ptr';
{ QL/QDOS specific startup }
procedure SysInitQDOS;
var
r: TQLRect;
begin
QL_ChannelIDNum:=pword(jobStackDataPtr)[0];
QL_ChannelIDs:=@pword(jobStackDataPtr)[1];
QL_CommandLineLen:=pword(@QL_ChannelIDs[QL_ChannelIDNum])[0];
QL_CommandLine:=@pword(@QL_ChannelIDs[QL_ChannelIDNum])[1];
stdInputHandle:=io_open('con_',Q_OPEN);
stdOutputHandle:=stdInputHandle;
stdErrorHandle:=stdInputHandle;
@ -203,6 +243,11 @@ procedure system_exit;
const
anyKey: string = 'Press any key to exit';
begin
if assigned(args) then
FreeMem(args);
if assigned(argv) then
FreeMem(argv);
io_sstrg(stdOutputHandle, -1, @anyKey[1], ord(anyKey[0]));
io_fbyte(stdInputHandle, -1);