Recent

Author Topic: Procedure with variable number of parameters  (Read 541 times)

MaxCuriosus

  • Full Member
  • ***
  • Posts: 105
Procedure with variable number of parameters
« 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.  

winni

  • Hero Member
  • *****
  • Posts: 1610
Re: Procedure with variable number of parameters
« Reply #1 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

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8599
  • FPC developer.
Re: Procedure with variable number of parameters
« Reply #2 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

lainz

  • Hero Member
  • *****
  • Posts: 3650
    • Lainz
Re: Procedure with variable number of parameters
« Reply #3 on: February 13, 2020, 10:24:52 pm »
Use TStringList?
https://lainz.github.io - My Website
https://lazpaint.github.io/ - LazPaint Downloads

lucamar

  • Hero Member
  • *****
  • Posts: 2973
Re: Procedure with variable number of parameters
« Reply #4 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().
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.8/FPC 3.0.4 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8599
  • FPC developer.
Re: Procedure with variable number of parameters
« Reply #5 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.

MaxCuriosus

  • Full Member
  • ***
  • Posts: 105
Re: Procedure with variable number of parameters
« Reply #6 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.

jamie

  • Hero Member
  • *****
  • Posts: 3275
Re: Procedure with variable number of parameters
« Reply #7 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 ;)
The only true wisdom is knowing you know nothing

lainz

  • Hero Member
  • *****
  • Posts: 3650
    • Lainz
Re: Procedure with variable number of parameters
« Reply #8 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.  :)
https://lainz.github.io - My Website
https://lazpaint.github.io/ - LazPaint Downloads

PascalDragon

  • Hero Member
  • *****
  • Posts: 1950
  • Compiler Developer
Re: Procedure with variable number of parameters
« Reply #9 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.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8599
  • FPC developer.
Re: Procedure with variable number of parameters
« Reply #10 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;
« Last Edit: February 14, 2020, 09:52:11 am by marcov »

 

TinyPortal © 2005-2018