From 51e28ac717af74e1bf5d1bb137d19ff9f0256bbe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?K=C3=A1roly=20Balogh?= <karoly@freepascal.org>
Date: Tue, 27 Dec 2016 17:12:49 +0000
Subject: [PATCH] atari: reworked param handling once more, based on the Amiga
 code, fixes argv/argc

git-svn-id: trunk@35205 -
---
 .gitattributes        |   1 +
 rtl/atari/syspara.inc | 124 ++++++++++++++++++++++++++++++++++++++++++
 rtl/atari/system.pp   |  95 ++------------------------------
 3 files changed, 130 insertions(+), 90 deletions(-)
 create mode 100644 rtl/atari/syspara.inc

diff --git a/.gitattributes b/.gitattributes
index cfe9ae1d32..22b15ab9f0 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -8412,6 +8412,7 @@ rtl/atari/sysfile.inc svneol=native#text/plain
 rtl/atari/sysheap.inc svneol=native#text/plain
 rtl/atari/sysos.inc svneol=native#text/plain
 rtl/atari/sysosh.inc svneol=native#text/plain
+rtl/atari/syspara.inc svneol=native#text/plain
 rtl/atari/system.pp svneol=native#text/plain
 rtl/atari/sysutils.pp svneol=native#text/plain
 rtl/atari/tthread.inc svneol=native#text/plain
diff --git a/rtl/atari/syspara.inc b/rtl/atari/syspara.inc
new file mode 100644
index 0000000000..01806553e7
--- /dev/null
+++ b/rtl/atari/syspara.inc
@@ -0,0 +1,124 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2016 by Marcus Sackrow and Karoly Balogh
+    members of the Free Pascal development team.
+
+    Command line parameter handling for Atari
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+
+
+{ Generates correct argument array on startup }
+procedure GenerateArgs;
+var
+  ArgVLen: LongInt;
+
+  procedure AllocArg(Idx, Len: LongInt);
+  var
+    i, OldArgVLen : LongInt;
+  begin
+    if Idx >= ArgVLen then
+    begin
+      OldArgVLen := ArgVLen;
+      ArgVLen := (Idx + 8) and (not 7);
+      SysReAllocMem(Argv, Argvlen * SizeOf(Pointer));
+      for i := OldArgVLen to ArgVLen - 1 do
+        ArgV[i]:=nil;
+    end;
+    ArgV[Idx] := SysAllocMem(Succ(Len));
+  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;
+
+  InQuotes := False;
+  { Handle the other args }
+  Count := 0;
+  { first index is one }
+  LocalIndex := 1;
+  while (P[Count] <> #0) do
+  begin
+    while (p[count]=' ') or (p[count]=#9) or (p[count]=LineEnding) 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;
+    end else
+    begin
+      while (p[count]<>#0) and (p[count]<>' ') and (p[count]<>#9) and (p[count]<>LineEnding) do
+        inc(count);
+    end;
+    ende := count;
+    if not inQuotes then
+    begin
+      while (p[start]=' ') and (Start < Ende) do
+        Inc(Start)
+    end;
+    if (ende-start>0) 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;
+
+
+{*****************************************************************************
+                             ParamStr
+*****************************************************************************}
+
+{ number of args }
+function ParamCount: LongInt;
+begin
+  ParamCount := argc - 1;
+end;
+
+{ argument number l }
+function ParamStr(l: LongInt): string;
+var
+  s1: string;
+begin
+  ParamStr := '';
+  if (l > 0) and (l + 1 <= argc) then
+    ParamStr := StrPas(argv[l]);
+end;
diff --git a/rtl/atari/system.pp b/rtl/atari/system.pp
index b84788b7a4..09f279e6b8 100644
--- a/rtl/atari/system.pp
+++ b/rtl/atari/system.pp
@@ -44,7 +44,7 @@ const
     FileNameCasePreserving = false;
     maxExitCode = 255;
     MaxPathLen = 255;
-    AllFilesMask = '*';
+    AllFilesMask = '*.*';
 
     sLineBreak = LineEnding;
     DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsCRLF;
@@ -94,6 +94,7 @@ var
     {$endif defined(FPUSOFT)}
 
     {$I system.inc}
+    {$I syspara.inc}
 
   var
     basepage: PPD; external name '__base';
@@ -123,97 +124,11 @@ end;
          end;*)
 
 
-   Function GetParamCount(const p: pchar): longint;
-   var
-    i: word;
-    count: word;
-   Begin
-    i:=0;
-    count:=0;
-    while p[count] <> #0 do
-     Begin
-       if (p[count] <> ' ') and (p[count] <> #9) and (p[count] <> #0) then
-       Begin
-          i:=i+1;
-          while (p[count] <> ' ') and (p[count] <> #9) and (p[count] <> #0) do
-           count:=count+1;
-       end;
-       if p[count] = #0 then break;
-       count:=count+1;
-     end;
-     GetParamCount:=longint(i);
-   end;
-
-
-   Function GetParam(index: word; const p : pchar): string;
-   { On Entry: index = string index to correct parameter  }
-   { On exit:  = correct character index into pchar array }
-   { Returns correct index to command line argument }
-   var
-    count: word;
-    localindex: word;
-    l: byte;
-    temp: string;
-   Begin
-     temp:='';
-     count := 0;
-     { first index is one }
-     localindex := 1;
-     l:=0;
-     While p[count] <> #0 do
-       Begin
-         if (p[count] <> ' ') and (p[count] <> #9) then
-           Begin
-             if localindex = index then
-              Begin
-               while (p[count] <> #0) and (p[count] <> ' ') and (p[count] <> #9) and (l < 256) do
-                Begin
-                  temp:=temp+p[count];
-                  l:=l+1;
-                  count:=count+1;
-                end;
-                temp[0]:=char(l);
-                GetParam:=temp;
-                exit;
-              end;
-             { Point to next argument in list }
-             while (p[count] <> #0) and (p[count] <> ' ') and (p[count] <> #9) do
-               Begin
-                 count:=count+1;
-               end;
-             localindex:=localindex+1;
-           end;
-         if p[count] = #0 then break;
-         count:=count+1;
-       end;
-     GetParam:=temp;
-   end;
-
-
-    function paramstr(l : longint) : string;
-      var
-       p : pchar;
-      begin
-         {$WARNING Implement query of current command name}
-         { ... as ParamStr(0) }
-         if (l>0) and (l<=paramcount) then
-           begin
-             p:=args;
-             paramstr:=GetParam(word(l),p);
-           end
-         else
-           paramstr:='';
-      end;
-
-      function paramcount : longint;
-      Begin
-        paramcount := argc;
-      end;
-
   procedure SysInitParamsAndEnv;
   begin
-    args:=@basepage^.p_cmdlin;
-    argc:=GetParamCount(args);
+    // [0] index contains the args length...
+    args:=@basepage^.p_cmdlin[1];
+    GenerateArgs;
   end;
 
   { This routine is used to grow the heap.  }