views:

445

answers:

5

It doesn't get much easier than using getopt() to parse command line parameters in C/C++.

Is there anything similar for Delphi? Or ideally, with the same syntax? I know Delphi supports FindCmdLineSwitch and ParamStr(), but those still require some additional parsing.

I want something that works like getopt() in C. Something that easily allows basic toggle switches, as well as capturing a value after a switch. See below for some example C code to see what I'm talking about:

void print_help()
{
        printf("usage:\n") ;
        printf("\t\t-i set input file\n") ;
        printf("\t\t-o set output file\n") ;
        printf("\t\t-c set config file\n") ;
        printf("\t\t-h print this help information\n") ;
        printf("\t\t-v print version\n") ;
}
 char* input_file = NULL ;
        char *query=NULL;
          char opt_char=0;
        while ((opt_char = getopt(argc, argv, "i:q:vh")) != -1)
        {
                switch(opt_char)
                {
                        case 'h':
                                print_help();
                                exit(-1);
                                break;
                        case 'v':
                                print_version() ;
                                exit(-1) ;
                                break ;
                        case 'i':
                                input_file= optarg ;
                                break ;
                        case 'q':
                                query= optarg ;
                                break ;
                        default:
                                print_help();
                                exit(-1);
                                break;
                }
        }
+6  A: 

There is an implementation TGetOpt, claiming to

implement a getopt variant for Delphi. It is nearly POSIX compatible, supporting long options, required, optional and no arguments

You can find it here.

mghie
+2  A: 

Nothing built in - but you can make one pretty easily. This should be close to what you are used to

TsoCommandLineParser = class
private
  fArguments:TStringList;
public
  constructor Create();
  destructor Destroy(); override;

  function GetOpt(const pArgument:string; const pDefaultValue:string = ''):string;
end;


constructor TsoCommandLineParser.Create();
var
  i:Integer;
begin
  inherited Create();
  fArguments := TStringList.Create();
  for i := 1 to ParamCount() do
  begin
    fArguments.Add(ParamStr(i));
  end;
end;

destructor TsoCommandLineParser.Destroy();
begin
  fArguments.Free();
  inherited Destroy();
end;

function TsoCommandLineParser.GetOpt(const pArgument:string; const pDefaultValue:string = ''):string;
var
  i:Integer;
begin
  i := fArguments.IndexOfName(pArgument);
  if i > -1 then
  begin
    Result := fArguments.ValueFromIndex[i];
  end
  else
  begin
    Result := pDefaultValue;
  end;
end;
Darian Miller
A: 

There's the "Gastown Delphi Command Line Parser" which was recently open-sourced. I have never used it, so I can't comment on it.

Ulrich Gerhardt
Where can I find the source? I googled, but no luck.
Mick
Oops, the official sit vanished. But http://www.vclcomponents.com/Delphi/System_Components/Gastown_Command_Line_Parser-info.html looks kosher to me. Maybe http://groups.google.de/group/borland.public.delphi.thirdpartytools.general/browse_frm/thread/1de12d1ad4f08f7 helps, too.
Ulrich Gerhardt
+2  A: 

What is wrong about FindCmdLineSwitch in the SysUtils unit?

if FindCmdLineSwitch('h',['-'],false) then
  Print_Help();
if FindCmdLineSwitch('v',['-'],false) then
  print_Version();

you will have to loop thru the params to get the values, but thats fairly simple to do:

if FindCmdLineSwitch('f',['-'],false) then
  for ix := 1 to paramcount do
    if (paramStr(ix) = '-f') and (ix < paramcount) then
      begin
        if fileExists( ParamStr(ix+1) ) then
          filename := ParamStr(ix+1);
        break;
      end
skamradt
Getopt lets you combine multiple options into a single argument. It also lets you be sure you're processing arguments in order. It has special provisions for allowing arguments that look like options but which are really file names (such as opening a file whose name is "-f" in your example above).
Rob Kennedy
ah, but if someone has a -f as a filename, and -f is a parameter, then how would it know which was which?
skamradt
-f "-f"Note that you can specify if an option takes a parameter or not.
Marco van de Voort
+6  A: 

The getopts.pp file of the FPC RTL is self contained Delphi (Delphi2009 included) compatible unit that implements getopt :

Getopt implementation for Free Pascal, modeled after GNU getopt

The unit is available at the FPC SVN repository.

Inoussa OUEDRAOGO