Lazarus

Programming => General => Topic started by: MaxCuriosus on February 13, 2020, 09:27:32 pm

Title: Procedure with variable number of parameters
Post by: MaxCuriosus on February 13, 2020, 09:27:32 pm
I would like to simplify/streamline the procedure and/or the call to it in the example below.
Any suggestion?

Code: Pascal  [Select][+][-]
  1. Var
  2.   A1,A2,A3,A4,A5,A6,A7,R,S,T,wID: String;    
  3.  
  4. Procedure RunXdo(NbArg:Integer);
  5. Const
  6.   cmd='xdotool';
  7. Begin
  8.   Case NbArg of
  9.     1: Begin RunCommand(cmd,[A1],T); end;
  10.     2: Begin RunCommand(cmd,[A1,A2],T); end;
  11.     3: Begin RunCommand(cmd,[A1,A2,A3],T); end;
  12.     4: Begin RunCommand(cmd,[A1,A2,A3,A4],T); end;
  13.     5: Begin RunCommand(cmd,[A1,A2,A3,A4,A5],T); end;
  14.     6: Begin RunCommand(cmd,[A1,A2,A3,A4,A5,A6],T); end;
  15.     7: Begin RunCommand(cmd,[A1,A2,A3,A4,A5,A6,A7],T); end;
  16.   end;
  17. end;                                                                    
  18.  
  19. { Example of call to the procedure }
  20.  
  21.   A1:='click';
  22.   A2:='--window';
  23.   A3:=wID;
  24.   A4:='1';
  25.   RunXdo(4);
  26.  
Title: Re: Procedure with variable number of parameters
Post by: winni on February 13, 2020, 09:41:49 pm
Hi!

Replace A1,A2,A3,A4,A5,A6,A7 with

A : array[1..7] of string.

Since some versions of fpc you are allowed to use a subrange of the array as parameter.

So in your case that would be

Code: Pascal  [Select][+][-]
  1. RunCommand(cmd,[A[1] ],T);
  2. ....
  3. RunCommand(cmd,[A[1..7]  ],T);
  4.  

Winni
Title: Re: Procedure with variable number of parameters
Post by: marcov on February 13, 2020, 09:45:03 pm
Or hold all arguments in an array, and then use slice() to select the number items.

https://www.freepascal.org/docs-html/rtl/system/slice.html
Title: Re: Procedure with variable number of parameters
Post by: lainz on February 13, 2020, 10:24:52 pm
Use TStringList?
Title: Re: Procedure with variable number of parameters
Post by: lucamar on February 13, 2020, 10:42:08 pm
The canonical way of passing a variable number of params to a function/procedure is to use array of const, like does e.g. Format().
Title: Re: Procedure with variable number of parameters
Post by: marcov on February 13, 2020, 10:53:37 pm
The canonical way of passing a variable number of params to a function/procedure is to use array of const, like does e.g. Format().

if they are the same type, array of string (aka open array) is better.
Title: Re: Procedure with variable number of parameters
Post by: MaxCuriosus on February 13, 2020, 11:17:46 pm
Winni,
Marcov,
simple and flawless, thank you.

lainz,
I don't thing TStringList would work. From the definition of RunCommand it is my understanding that an array of strings is required. I may be wrong.
Title: Re: Procedure with variable number of parameters
Post by: jamie on February 13, 2020, 11:21:42 pm
I suppose you could also use the a CDECL type call and just simulate a multiple list of what ever doing it as done in C ;)
Title: Re: Procedure with variable number of parameters
Post by: lainz on February 14, 2020, 12:00:17 am
lainz,
I don't thing TStringList would work. From the definition of RunCommand it is my understanding that an array of strings is required. I may be wrong.

Ok, I see. I'm used to TProcess that uses a list, never used RunCommand.  :)
Title: Re: Procedure with variable number of parameters
Post by: PascalDragon on February 14, 2020, 09:36:58 am
I suppose you could also use the a CDECL type call and just simulate a multiple list of what ever doing it as done in C ;)
Implementing varargs functions is not supported, this can only be used to call external functions.
Title: Re: Procedure with variable number of parameters
Post by: marcov on February 14, 2020, 09:46:56 am
lainz,
I don't thing TStringList would work. From the definition of RunCommand it is my understanding that an array of strings is required. I may be wrong.

Ok, I see. I'm used to TProcess that uses a list, never used RunCommand.  :)

Basically runcommand is something that grew out of the "Large output" section of the TProcess wiki, iow Runcommand is a tprocess wrapper. Or at least it was since FPC 3.2, when the mainloop moves to TProcess, so that you can make your own TProcess wrappers easily. Note the p.Parameters.add() in the loop below, Runcommand just puts it in TProcess. But TProcess doesn't always use TStringList, but TProcessStrings for the unicodestring version (for unicode on Windows), which is an minimal tstringlist like array wrapper.

Code: [Select]
function RunCommand(const exename:TProcessString;const commands:array of TProcessString;out outputstring:string; Options : TProcessOptions = [];SWOptions:TShowWindowOptions=swoNone):boolean;
Var
    p : TProcessnamemacro;
    i,
    exitstatus : integer;
    ErrorString : String;
begin
  p:=DefaultTProcess.create(nil);
  if Options<>[] then
    P.Options:=Options - ForbiddenOptions;
  P.ShowWindow:=SwOptions;
  p.Executable:=exename;
  if high(commands)>=0 then
   for i:=low(commands) to high(commands) do
     p.Parameters.add(commands[i]);
  try
    result:=p.RunCommandLoop(outputstring,errorstring,exitstatus)=0;
  finally
    p.free;
  end;
  if exitstatus<>0 then result:=false;
end;
TinyPortal © 2005-2018