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;
}
}
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.
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.
See TCommandParser, described in this EDN article http://edn.embarcadero.com/print/40404 and available for download on CodeCentral http://cc.embarcadero.com/item/27574. TCommandParser should also be included in the Delphi demos now. I made the code freely available to Embarcadero before I left, so hopefully they'll include it in the framework or something like it at some point.
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;
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
There is also a new parser called delphi-argparse that is relevant to this question.
Attribute-based parser for Delphi can be found here.
There's the "Gastown Delphi Command Line Parser" which was recently open-sourced (e.g. on Torry's). I have never used it, so I can't comment on it.