Forum > General
Problem with command line parameters
simone:
I have created a console application using the 'New' option of IDE,
that generates the standard template code using TCustomApplication.
At this point I have modified procedure TMyApplication.DoRun in order
to allow a further command line option (-e or --echo):
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TMyApplication.DoRun;var ErrorMsg: String;begin // quick check parameters ErrorMsg:=CheckOptions('h', 'help'); if ErrorMsg<>'' then begin ShowException(Exception.Create(ErrorMsg)); Terminate; Exit; end; // parse parameters if HasOption('h', 'help') then begin WriteHelp; Terminate; Exit; end; //new code: if HasOption('e', 'echo') then begin writeln('ok'); end; { add your program here } // stop program loop Terminate;end;
When I run the program from prompt, I have the following unexpected result:
C:\Users\simone\Desktop\Folder>Project1.exe -e
Exception at 00000000: Exception:
Invalid option at position 1: "e".
Can someone explain to me how to solve this problem? Thanks.
dbannon:
Hi Simone, the error message you are getting is because you are using an option you have not declared is to be expected.
ErrorMsg:=CheckOptions('h', 'help');
needs to become
ErrorMsg:=CheckOptions('he', 'help');
The app checks all options as it starts up, if it finds an unexpected one, its an error. Don't confuse checking for expected options with checking for a particular one we are about to do something with.
Davo
simone:
Thanks DBannon, meanwhile I have fixed the problem with
ErrorMsg:=CheckOptions('h e', 'help echo');
in order to allow both -e and --echo.
I misunderstood the meaning of CheckOptions.
simone:
I have another question about this topic. Having the following program:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program project1; {$mode objfpc}{$H+} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, SysUtils, CustApp { you can add units after this }; type { TMyApplication } TMyApplication = class(TCustomApplication) protected procedure DoRun; override; public constructor Create(TheOwner: TComponent); override; destructor Destroy; override; procedure WriteHelp; virtual; end; { TMyApplication } procedure TMyApplication.DoRun;var ErrorMsg: String; ind : integer; ParamList : TStringArray;begin // quick check parameters ErrorMsg:=CheckOptions('hf:', 'help file:'); if ErrorMsg<>'' then begin ShowException(Exception.Create(ErrorMsg)); Terminate; Exit; end; // parse parameters if HasOption('h', 'help') then begin WriteHelp; Terminate; Exit; end; { add your program here } ParamList:=GetOptionValues('f','file'); for ind:=Low(ParamList) to High(ParamList) do writeln(ParamList[ind]); // stop program loop Terminate;end; constructor TMyApplication.Create(TheOwner: TComponent);begin inherited Create(TheOwner); StopOnException:=True;end; destructor TMyApplication.Destroy;begin inherited Destroy;end; procedure TMyApplication.WriteHelp;begin { add your help code here } writeln('Usage: ', ExeName, ' -h');end; var Application: TMyApplication;begin Application:=TMyApplication.Create(nil); Application.Title:='My Application'; Application.Run; Application.Free;end.
In the shell I have the following unexpected behavior:
C:\Users\simone\Desktop\Test>project1.exe --file=xxx --file=yyy
yyy
xxx
C:\Users\simone\Desktop\Test>project1.exe -f xxx -f yyy
Exception at 0000000100004FCD: EAccessViolation:
Access violation.
Why does an error arise in the second case?
lucamar:
Mighty curious. With this test code (ignore the names, please, I "reused" a working program):
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TDiffApplication.DoRun;var ErrorMsg: String; ParamList: TStringArray; i: Integer; {SrcList: TStringList; is a global}begin ErrorMsg := CheckOptions('hf:', 'help file:'); if ErrorMsg <> '' then begin ShowException(Exception.Create(ErrorMsg)); Terminate; Exit; end; // parse parameters SrcList := TStringList.Create; try GetNonOptions('hf:', ['help', 'file:'], SrcList);{@test - For first pass, uncomment this block writeln('GetNonOptions returned '+ IntToStr(SrcList.Count) + ' values.');} ParamList := GetOptionValues('f', 'file'); writeln('GetOptionsValues returned '+ IntToStr(Length(ParamList)) + ' values.'); for i := Low(ParamList) to High(ParamList) do Writeln(ParamList[i]);{@test/} finally SrcList.Free; end; Terminate;end;
First pass is made with the code in @test uncommented; second with it commented out. And this is the result:
--- Code: Bash [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---lucamar@selene:~/SoftDev/DevTools/buildiff$ ./buildiff -f history.log -f TODO.txtGetNonOptions returned 0 values.GetOptionsValues returned 2 values.TODO.txthistory.loglucamar@selene:~/SoftDev/DevTools/buildiff$ ./buildiff -f history.log -f TODO.txtException at 0804E506: EAccessViolation:Access violation.
You can see it's Linux so it's not platform-dependent. Sounds like a (strange) bug.
ETA Made a third test; this works also:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TDiffApplication.DoRun;var ErrorMsg: String; ParamList: TStringArray; i: Integer;begin ErrorMsg := CheckOptions('hf:', 'help file:'); if ErrorMsg <> '' then begin ShowException(Exception.Create(ErrorMsg)); Terminate; Exit; end; WriteLn('Third test:'); ParamList := GetOptionValues('f', 'file'); writeln('GetOptionsValues returned '+ IntToStr(Length(ParamList)) + ' values.'); for i := Low(ParamList) to High(ParamList) do Writeln(ParamList[i]); Terminate;end;
--- Code: Bash [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---$ ./buildiff -f history.log -f TODO.txtThird test:GetOptionsValues returned 2 values.TODO.txthistory.log
Writing anything to screen before the offending lines results in it working as it should. WTH? :o
Navigation
[0] Message Index
[#] Next page