packages/fcl-base/src/custapp.pp has
function TCustomApplication.FindOptionIndex(const S: String;
var Longopt: Boolean; StartAt : Integer = -1): Integer;
Var
SO,O : String;
I,P : Integer;
begin
If Not CaseSensitiveOptions then
SO:=UpperCase(S)
else
SO:=S;
Result:=-1;
I:=StartAt;
if (I=-1) then
I:=ParamCount;
While (Result=-1) and (I>0) do
begin
O:=Params[i];
// - must be seen as an option value
If (Length(O)>1) and (O[1]=FOptionChar) then
begin
Delete(O,1,1);
LongOpt:=(Length(O)>0) and (O[1]=FOptionChar);
If LongOpt then
begin
Delete(O,1,1);
P:=Pos('=',O);
If (P<>0) then
O:=Copy(O,1,P-1);
end;
If Not CaseSensitiveOptions then
O:=UpperCase(O);
If (O=SO) then
Result:=i;
end;
Dec(i);
end;
end;
1/4 The following lines contain a useless condition
If (Length(O)>1) and (O[1]=FOptionChar) then
begin
Delete(O,1,1);
LongOpt:=(Length(O)>0) and (O[1]=FOptionChar);
The condition
(Length(O)>0) is always true because before deleting the first character using
"Delete(O,1,1);" the length of variable
O was at least 2(due to the
"If (Length(O)>1)" condition).
So,
"LongOpt:=(Length(O)>0) and (O[1]=FOptionChar);" has been replaced with "LongOpt:=(O[1]=FOptionChar);".
2/4 After that,
"If (P<>0) then O:=Copy(O,1,P-1);" has been replaced with "If P<>0 then SetLength(O,P-1);".3/4 A
-1 value is assigned to
Result prior to the
while loop and inside the loop the only place the
Result value is modified is at the
"Result:=i;" assignment. At the
"Result:=i;" assignment, the value of variable
I is guaranteed to be greater than zero due to the existence of the
I>0 condition at the
while loop. So, once we assign the value of
I to
Result, we can simply
exit the routine because there's nothing else to be done.
So,
"While (Result=-1) and (I>0) do" has been changed to "While I>0 do" by also changing "If (O=SO) then Result:=i;" with "If O=SO then Exit(I);".4/4 When using a long option the code calls
Delete(O,1,1) twice, which is a waste. It would have been nice to use a single
Delete(O,1,1+ord(LongOpt)) call but according to a forum topic, optimizations using
ord in order to get 0, 1 and -1 or not(0) values are not guaranteed for any targeted architecture. It's a programming practice without a documented support so the code had to be modified using the classic approach from:
Delete(O,1,1);
LongOpt:=(O[1]=FOptionChar);
If LongOpt then
begin
Delete(O,1,1);
P:=Pos('=',O);
If P<>0 then
SetLength(O,P-1);
end;
to
LongOpt:=(O[2]=FOptionChar);
If LongOpt then
begin
Delete(O,1,2);
P:=Pos('=',O);
If P<>0 then
SetLength(O,P-1);
end
else
Delete(O,1,1);
In the end, the function becomes
function TCustomApplication.FindOptionIndex(const S: String;
var Longopt: Boolean; StartAt : Integer = -1): Integer;
Var
SO,O : String;
I,P : Integer;
begin
If Not CaseSensitiveOptions then
SO:=UpperCase(S)
else
SO:=S;
Result:=-1;
I:=StartAt;
if I=-1 then
I:=ParamCount;
While I>0 do
begin
O:=Params[I];
// - must be seen as an option value
If (Length(O)>1) and (O[1]=FOptionChar) then
begin
LongOpt:=(O[2]=FOptionChar);
If LongOpt then
begin
Delete(O,1,2); // remove the leading -- characters of the option
P:=Pos('=',O);
If P<>0 then
SetLength(O,P-1);
end
else
Delete(O,1,1); // remove the leading - character of the option
If Not CaseSensitiveOptions then
O:=UpperCase(O);
If O=SO then
Exit(I);
end;
Dec(I);
end;
end;
A patch is attached