Browse Source

* some fixes with indexes
* bp7 compatible

peter 27 years ago
parent
commit
972218d22f
1 changed files with 193 additions and 78 deletions
  1. 193 78
      rtl/inc/getopts.pp

+ 193 - 78
rtl/inc/getopts.pp

@@ -4,7 +4,7 @@
     Copyright (c) 1993,97 by Michael Van Canneyt,
     Copyright (c) 1993,97 by Michael Van Canneyt,
     member of the Free Pascal development team.
     member of the Free Pascal development team.
 
 
-    Getopt implementation for Free Pascal, modeled after GNU getopt.
+    Getopt implementation for Free Pascal, modeled after GNU getopt
 
 
     See the file COPYING.FPC, included in this distribution,
     See the file COPYING.FPC, included in this distribution,
     for details about the copyright.
     for details about the copyright.
@@ -15,41 +15,145 @@
 
 
  **********************************************************************}
  **********************************************************************}
 unit getopts;
 unit getopts;
+Interface
 
 
-{ --------------------------------------------------------------------
-  *NOTE*
-  The routines are a more or less straightforward conversion
+Const
+  No_Argument       = 0;
+  Required_Argument = 1;
+  Optional_Argument = 2;
+  EndOfOptions      = #255;
 
 
-  of the GNU C implementation of getopt. One day they should be
+Type
+  POption  = ^TOption;
+  TOption = Record
+    Name    : String;
+    Has_arg : Integer;
+    Flag    : PChar;
+    Value   : Char;
+  end;
 
 
-  replaced by some 'real pascal code'.
-  -------------------------------------------------------------------- }
+  Orderings = (require_order,permute,return_in_order);
+
+Var
+  OptArg : String;
+  OptInd : Longint;
+  OptErr : Boolean;
+  OptOpt : Char;
+
+Function GetOpt (ShortOpts : String) : char;
+Function GetLongOpts (ShortOpts : String;LongOpts : POption;var Longind : Longint) : char;
 
 
-Interface
 
 
-Const No_Argument       = 0;
-      Required_Argument = 1;
-      Optional_Argument = 2;
-      EndOfOptions      = #255;
+Implementation
+
+{$ifdef TP}
+uses
+  strings;
+{$endif}
+
 
 
-Type TOption = Record
-       Name    : String;
-       Has_arg : Integer;
-       Flag    : PChar;
-       Value   : Char;
+{***************************************************************************
+                               Create an ArgV
+***************************************************************************}
+
+{$ifdef TP}
+
+function GetCommandLine:pchar;
+begin
+  GetCommandLine:=ptr(prefixseg,$81);
+end;
+
+
+function GetCommandFile:pchar;
+var
+  p : pchar;
+begin
+  p:=ptr(memw[prefixseg:$2c],0);
+  repeat
+    while p^<>#0 do
+     inc(longint(p));
+  { next char also #0 ? }
+    inc(longint(p));
+    if p^=#0 then
+     begin
+       inc(longint(p),3);
+       GetCommandFile:=p;
+       exit;
      end;
      end;
-     POption  = ^TOption;
-     Orderings = (require_order,permute,return_in_order);
+  until false;
+end;
 
 
-Var OptArg : String;
-    OptInd : Longint;
-    OptErr : Boolean;
-    OptOpt : Char;
 
 
-Function GetOpt (ShortOpts : String) : char;
-Function GetLongOpts (ShortOpts : String;LongOpts : POption;var Longind : Integer) : char;
+type
+  ppchar = ^pchar;
+  apchar = array[0..127] of pchar;
+var
+  argc  : longint;
+  argv  : apchar;
 
 
-Implementation
+procedure setup_arguments;
+var
+  arglen,
+  count   : longint;
+  argstart,
+  cmdline : pchar;
+  quote   : set of char;
+  argsbuf : array[0..127] of pchar;
+begin
+{ create argv[0] which is the started filename }
+  argstart:=GetCommandFile;
+  arglen:=strlen(argstart)+1;
+  getmem(argsbuf[0],arglen);
+  move(argstart^,argsbuf[0]^,arglen);
+{ create commandline }
+  cmdline:=GetCommandLine;
+  count:=1;
+  repeat
+  { skip leading spaces }
+    while cmdline^ in [' ',#9,#13] do
+     inc(longint(cmdline));
+    case cmdline^ of
+      #0 : break;
+     '"' : begin
+             quote:=['"'];
+             inc(longint(cmdline));
+           end;
+    '''' : begin
+             quote:=[''''];
+             inc(longint(cmdline));
+           end;
+    else
+     quote:=[' ',#9,#13];
+    end;
+  { scan until the end of the argument }
+    argstart:=cmdline;
+    while (cmdline^<>#0) and not(cmdline^ in quote) do
+     inc(longint(cmdline));
+  { reserve some memory }
+    arglen:=cmdline-argstart;
+    getmem(argsbuf[count],arglen+1);
+    move(argstart^,argsbuf[count]^,arglen);
+    argsbuf[count][arglen]:=#0;
+  { skip quote }
+    if cmdline^ in quote then
+     inc(longint(cmdline));
+    inc(count);
+  until false;
+{ create argc }
+  argc:=count-1;
+{ create an nil entry }
+  argsbuf[count]:=nil;
+  inc(count);
+{ create the argv }
+{  getmem(argv,count shl 2); }
+  move(argsbuf,argv,count shl 2);
+end;
+
+{$endif TP}
+
+{***************************************************************************
+                               Real Getopts
+***************************************************************************}
 
 
 Var
 Var
   NextChar,
   NextChar,
@@ -107,19 +211,18 @@ begin
   Last_nonopt:=1;
   Last_nonopt:=1;
   OptOpt:='?';
   OptOpt:='?';
   Nextchar:=0;
   Nextchar:=0;
-  if opts[1]='-' then
-   begin
-     ordering:=return_in_order;
-     delete(opts,1,1);
-   end
-  else
-   if opts[1]='+' then
-    begin
-      ordering:=require_order;
-      delete(opts,1,1);
-    end
+  case opts[1] of
+   '-' : begin
+           ordering:=return_in_order;
+           delete(opts,1,1);
+         end;
+   '+' : begin
+           ordering:=require_order;
+           delete(opts,1,1);
+         end;
   else
   else
    ordering:=permute;
    ordering:=permute;
+  end;
 end;
 end;
 
 
 
 
@@ -129,18 +232,23 @@ Function Internal_getopt (Var Optstring : string;LongOpts : POption;
 type
 type
   pinteger=^integer;
   pinteger=^integer;
 var
 var
-  temp,endopt,option_index : byte;
-  indfound: integer;
-  currentarg,optname : string;
-  p,pfound : POption;
-  exact,ambig : boolean;
-  c : char;
+  temp,endopt,
+  option_index : byte;
+  indfound     : integer;
+  currentarg,
+  optname      : string;
+  p,pfound     : POption;
+  exact,ambig  : boolean;
+  c            : char;
 begin
 begin
   optarg:='';
   optarg:='';
   if optind=0 then
   if optind=0 then
-    getopt_init(optstring);
+   getopt_init(optstring);
 { Check if We need the next argument. }
 { Check if We need the next argument. }
-  if optind<nrargs then currentarg:=strpas(argv[optind]) else currentarg:='';
+  if (optind<nrargs) then
+   currentarg:=strpas(argv[optind])
+  else
+   currentarg:='';
   if (nextchar=0) then
   if (nextchar=0) then
    begin
    begin
      if ordering=permute then
      if ordering=permute then
@@ -153,7 +261,7 @@ begin
           first_nonopt:=optind;
           first_nonopt:=optind;
         while (optind<nrargs) and ((argv[optind][0]<>'-') or
         while (optind<nrargs) and ((argv[optind][0]<>'-') or
               (length(strpas(argv[optind]))=1)) do
               (length(strpas(argv[optind]))=1)) do
-          inc(optind);
+         inc(optind);
         last_nonopt:=optind;
         last_nonopt:=optind;
       end;
       end;
    { Check for '--' argument }
    { Check for '--' argument }
@@ -243,13 +351,13 @@ begin
               else
               else
                ambig:=true;
                ambig:=true;
            end;
            end;
-          inc (longint(p),sizeof(toption));
-          inc (option_index);
+          inc(longint(p),sizeof(toption));
+          inc(option_index);
         end;
         end;
        if ambig and not exact then
        if ambig and not exact then
         begin
         begin
           if opterr then
           if opterr then
-           writeln (paramstr(0),': option "',optname,'" is ambiguous');
+           writeln(argv[0],': option "',optname,'" is ambiguous');
           nextchar:=0;
           nextchar:=0;
           inc(optind);
           inc(optind);
           Internal_getopt:='?';
           Internal_getopt:='?';
@@ -265,9 +373,9 @@ begin
               begin
               begin
                 if opterr then
                 if opterr then
                  if currentarg[2]='-' then
                  if currentarg[2]='-' then
-                  writeln (paramstr(0),': option "--',pfound^.name,'" doesn''t allow an argument')
+                  writeln(argv[0],': option "--',pfound^.name,'" doesn''t allow an argument')
                  else
                  else
-                  writeln (paramstr(0),': option "',currentarg[1],pfound^.name,'" doesn''t allow an argument');
+                  writeln(argv[0],': option "',currentarg[1],pfound^.name,'" doesn''t allow an argument');
                 nextchar:=0;
                 nextchar:=0;
                 internal_getopt:='?';
                 internal_getopt:='?';
                 exit;
                 exit;
@@ -285,7 +393,7 @@ begin
                 else
                 else
                  begin { no req argument}
                  begin { no req argument}
                    if opterr then
                    if opterr then
-                    writeln (paramstr(0),': option ',pfound^.name,' requires an argument');
+                    writeln(argv[0],': option ',pfound^.name,' requires an argument');
                    nextchar:=0;
                    nextchar:=0;
                    if optstring[1]=':' then
                    if optstring[1]=':' then
                     Internal_getopt:=':'
                     Internal_getopt:=':'
@@ -294,28 +402,28 @@ begin
                    exit;
                    exit;
                  end;
                  end;
               end;
               end;
-          end; { argument in next parameter end;}
-         nextchar:=0;
-         if longind<>nil then
-          pinteger(longind)^:=indfound+1;
-            if pfound^.flag<>nil then
-            begin
-              pfound^.flag^:=pfound^.value;
-              internal_getopt:=#0;
-              exit;
-            end;
-           internal_getopt:=pfound^.value;
-           exit;
-         end; { pfound<>nil }
+           end; { argument in next parameter end;}
+          nextchar:=0;
+          if longind<>nil then
+           pinteger(longind)^:=indfound+1;
+          if pfound^.flag<>nil then
+           begin
+             pfound^.flag^:=pfound^.value;
+             internal_getopt:=#0;
+             exit;
+           end;
+          internal_getopt:=pfound^.value;
+          exit;
+        end; { pfound<>nil }
       { We didn't find it as an option }
       { We didn't find it as an option }
         if (not long_only) or
         if (not long_only) or
            ((currentarg[2]='-') or (pos(CurrentArg[nextchar],optstring)=0)) then
            ((currentarg[2]='-') or (pos(CurrentArg[nextchar],optstring)=0)) then
          begin
          begin
            if opterr then
            if opterr then
             if currentarg[2]='-' then
             if currentarg[2]='-' then
-             writeln (paramstr(0),' unrecognized option "--',optname,'"')
+             writeln(argv[0],' unrecognized option "--',optname,'"')
             else
             else
-             writeln (paramstr(0),' unrecognized option "',currentarg[1],optname,'"');
+             writeln(argv[0],' unrecognized option "',currentarg[1],optname,'"');
            nextchar:=0;
            nextchar:=0;
            inc(optind);
            inc(optind);
            Internal_getopt:='?';
            Internal_getopt:='?';
@@ -334,8 +442,8 @@ begin
   if (temp=0) or (c=':') then
   if (temp=0) or (c=':') then
    begin
    begin
      if opterr then
      if opterr then
-      writeln (paramstr(0),': illegal option -- ',c);
-     optopt:=currentarg[nextchar-1];
+      writeln(argv[0],': illegal option -- ',c);
+     optopt:=c;
      internal_getopt:='?';
      internal_getopt:='?';
      exit;
      exit;
    end;
    end;
@@ -351,18 +459,18 @@ begin
       if nextchar>0 then
       if nextchar>0 then
        begin
        begin
          optarg:=copy (currentarg,nextchar,length(currentarg)-nextchar+1);
          optarg:=copy (currentarg,nextchar,length(currentarg)-nextchar+1);
-         inc(optind)
+         inc(optind);
        end
        end
       else
       else
        if (optind=nrargs) then
        if (optind=nrargs) then
         begin
         begin
           if opterr then
           if opterr then
-           writeln (paramstr(0),': option requires an argument -- ',optstring[temp]);
+           writeln (argv[0],': option requires an argument -- ',optstring[temp]);
           optopt:=optstring[temp];
           optopt:=optstring[temp];
           if optstring[1]=':' then
           if optstring[1]=':' then
            Internal_getopt:=':'
            Internal_getopt:=':'
           else
           else
-           Internal_Getopt:='?'
+           Internal_Getopt:='?';
         end
         end
        else
        else
         begin
         begin
@@ -376,26 +484,33 @@ end; { End of internal getopt...}
 
 
 Function GetOpt(ShortOpts : String) : char;
 Function GetOpt(ShortOpts : String) : char;
 begin
 begin
-  getopt:=internal_getopt (shortopts,nil,nil,false);
+  getopt:=internal_getopt(shortopts,nil,nil,false);
 end;
 end;
 
 
 
 
-Function GetLongOpts (ShortOpts : String;LongOpts : POption;var Longind : Integer) : char;
+Function GetLongOpts(ShortOpts : String;LongOpts : POption;var Longind : Longint) : char;
 begin
 begin
-  getlongopts:=internal_getopt ( shortopts,longopts,@longind,true);
+  getlongopts:=internal_getopt(shortopts,longopts,@longind,true);
 end;
 end;
 
 
 
 
 begin
 begin
+{ create argv if running under TP }
+{$ifdef TP}
+  setup_arguments;
+{$endif}
 { Needed to detect startup }
 { Needed to detect startup }
   Opterr:=true;
   Opterr:=true;
   Optind:=0;
   Optind:=0;
-  nrargs:=paramcount+1;
+  nrargs:=argc;
 end.
 end.
-
 {
 {
   $Log$
   $Log$
-  Revision 1.2  1998-05-21 19:30:57  peter
+  Revision 1.3  1998-06-18 10:49:04  peter
+    * some fixes with indexes
+    * bp7 compatible
+
+  Revision 1.2  1998/05/21 19:30:57  peter
     * objects compiles for linux
     * objects compiles for linux
     + assign(pchar), assign(char), rename(pchar), rename(char)
     + assign(pchar), assign(char), rename(pchar), rename(char)
     * fixed read_text_as_array
     * fixed read_text_as_array