Răsfoiți Sursa

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

git-svn-id: trunk@49168 -
Károly Balogh 4 ani în urmă
părinte
comite
f3a19aaf59
2 a modificat fișierele cu 85 adăugiri și 47 ștergeri
  1. 5 12
      rtl/sinclairql/si_prc.pp
  2. 80 35
      rtl/sinclairql/system.pp

+ 5 - 12
rtl/sinclairql/si_prc.pp

@@ -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;

+ 80 - 35
rtl/sinclairql/system.pp

@@ -54,13 +54,13 @@ const
     StdErrorHandle: longint = UnusedHandle;
 
 var
-    args: PChar;
-    argc: LongInt;
-    argv: PPChar;
-    envp: PPChar;
-
-    heapStart: pointer;
+    QL_ChannelIDNum : word;
+    QL_ChannelIDs: pdword;
+    QL_CommandLineLen : word;
+    QL_CommandLine : pchar;
 
+    argv: PPChar;
+    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);