Simple way to use variable parameters for Procedures

Share your advanced PureBasic knowledge/code with the community.
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Simple way to use variable parameters for Procedures

Post by ts-soft »

Code: Select all

;==================================================================
; ###  Example to use variable parameters for Procedures    ###
; Author:            Thomas <ts-soft> Schulz
; Date:              Mrz 16, 2012
; Version:           1.0
; Target OS:         All
; Target Compiler:   PureBasic 4.40 and later
;==================================================================

EnableExplicit

Structure V_ARG
  Type.l
  StructureUnion
    a.a
    b.b
    c.c
    d.d
    f.f
    i.i
    l.l
    *s.String
    q.q
    u.u
    w.w
  EndStructureUnion
EndStructure

Procedure V_ARG_Add(Array V_ARG.V_ARG(1), Type.l, *value)
  Protected index = ArraySize(V_ARG())
  Protected *v.Quad = *value
  ReDim V_ARG(index + 1)

  With V_ARG(index)
    \Type = Type
    \q = *v\q
  EndWith
EndProcedure

; example
Procedure Foo(Array V_ARG.V_ARG(1))
  Protected i
  Protected count = ArraySize(V_ARG())
  Debug "Count of parameters: " + Str(count)
  Debug ""
  For i = 0 To count - 1
    With V_ARG(i)
      Select \Type
        Case #PB_Ascii
          Debug "Parameter " + Str(i + 1) + " = UByte, Value = " + Str(V_ARG(i)\a)
        Case #PB_Byte
          Debug "Parameter " + Str(i + 1) + " = Byte, Value = " + Str(V_ARG(i)\b)
        Case #PB_Character
          Debug "Parameter " + Str(i + 1) + " = Char, Value = " + Str(V_ARG(i)\c)
        Case #PB_Double
          Debug "Parameter " + Str(i + 1) + " = Double, Value = " + StrD(V_ARG(i)\d)
        Case #PB_Float
          Debug "Parameter " + Str(i + 1) + " = FLoat, Value = " + StrF(V_ARG(i)\f)
        Case #PB_Integer
          Debug "Parameter " + Str(i + 1) + " = Integer, Value = " + Str(V_ARG(i)\i)
        Case #PB_Long
          Debug "Parameter " + Str(i + 1) + " = Long, Value = " + Str(V_ARG(i)\l)
        Case #PB_Quad
          Debug "Parameter" + Str(i + 1) + " = Quad, Value = " + Str(V_ARG(i)\q)
        Case #PB_String
          Debug "Parameter " + Str(i + 1) + " = String, Value = " + PeekS(V_ARG(i)\s)
        Case #PB_Unicode
          Debug "Parameter " + Str(i + 1) + " = UWord, Value = " + Str(V_ARG(i)\u)
        Case #PB_Word
          Debug "Parameter " + Str(i + 1) + " = Word, Value = " + Str(V_ARG(i)\w)
      EndSelect
    EndWith
  Next
EndProcedure

Dim para_array.V_ARG(0)

Define Text.String
Text\s = "Feel the ..Pure.. Power"
V_ARG_Add(para_array(), #PB_String, @Text)

Define pi.d = #PI
V_ARG_Add(para_array(), #PB_Double, @pi)

Define word.w = 65535
V_ARG_Add(para_array(), #PB_Word, @word)
V_ARG_Add(para_array(), #PB_Unicode, @word)

Foo(para_array())

Have Fun :D
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Simple way to use variable parameters for Procedures

Post by IdeasVacuum »

woa, that's too clever......... :mrgreen:
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Re: Simple way to use variable parameters for Procedures

Post by rsts »

IdeasVacuum wrote:woa, that's too clever......... :mrgreen:
Mr Soft is VERY clever :)

Thanks for sharing.
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: Simple way to use variable parameters for Procedures

Post by ts-soft »

You can use this, for example a interpreter like program, using only one prototype for all functions.
It is simple, as the title say, but it is a hint for some projects.
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
NicTheQuick
Addict
Addict
Posts: 1504
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: Simple way to use variable parameters for Procedures

Post by NicTheQuick »

This version makes it a little bit easier to use. The type and size of a variable will be set automatically (since PB V5.1). But be careful if the variable has the same name as a structure. In this case there will be pop out a compiler error.

Code: Select all

;==================================================================
; ###  Example to use variable parameters for Procedures    ###
; Author:            Thomas <ts-soft> Schulz & <NicTheQuick>
; Date:              Mrz 16, 2012
; Version:           1.1
; Target OS:         All
; Target Compiler:   PureBasic 5.10 and later
;==================================================================

EnableExplicit

Structure V_ARG
   Type.l
   StructureUnion
      a.a
      b.b
      c.c
      d.d
      f.f
      i.i
      l.l
      q.q
      u.u
      w.w
   EndStructureUnion
   s.s
EndStructure

Procedure V_ARG_Add_(Array V_ARG.V_ARG(1), Type.l, size.i, *value)
   Protected index = ArraySize(V_ARG())
   ReDim V_ARG(index + 1)
   
   With V_ARG(index)
      \Type = Type
      If (Type = #PB_String)
         \s = PeekS(*value)
      Else
         CopyMemory(*value, @V_ARG(index) + OffsetOf(V_ARG\a), size)
      EndIf
   EndWith
EndProcedure

Macro V_ARG_Add(v_arg, value)
CompilerIf TypeOf(value) = #PB_Structure
	CompilerError "The variable has no native type. This is not supported."
CompilerEndIf
   V_ARG_Add_(v_arg, TypeOf(value), SizeOf(value), @value)
EndMacro

; example
Procedure Foo(Array V_ARG.V_ARG(1))
   Protected i.i
   Protected count.i = ArraySize(V_ARG())
   Debug "Count of parameters: " + Str(count)
   Debug ""
   For i = 0 To count - 1
      With V_ARG(i)
         Debug \Type
         Select \Type
            Case #PB_Ascii
               Debug "Parameter " + Str(i + 1) + " = UByte, Value = " + Str(V_ARG(i)\a)
            Case #PB_Byte
               Debug "Parameter " + Str(i + 1) + " = Byte, Value = " + Str(V_ARG(i)\b)
            Case #PB_Character
               Debug "Parameter " + Str(i + 1) + " = Char, Value = " + Str(V_ARG(i)\c)
            Case #PB_Double
               Debug "Parameter " + Str(i + 1) + " = Double, Value = " + StrD(V_ARG(i)\d)
            Case #PB_Float
               Debug "Parameter " + Str(i + 1) + " = FLoat, Value = " + StrF(V_ARG(i)\f)
            Case #PB_Integer
               Debug "Parameter " + Str(i + 1) + " = Integer, Value = " + Str(V_ARG(i)\i)
            Case #PB_Long
               Debug "Parameter " + Str(i + 1) + " = Long, Value = " + Str(V_ARG(i)\l)
            Case #PB_Quad
               Debug "Parameter" + Str(i + 1) + " = Quad, Value = " + Str(V_ARG(i)\q)
            Case #PB_String
               Debug "Parameter " + Str(i + 1) + " = String, Value = " + V_ARG(i)\s
            Case #PB_Unicode
               Debug "Parameter " + Str(i + 1) + " = UWord, Value = " + Str(V_ARG(i)\u)
            Case #PB_Word
               Debug "Parameter " + Str(i + 1) + " = Word, Value = " + Str(V_ARG(i)\w)
         EndSelect
      EndWith
   Next
EndProcedure

Dim para_array.V_ARG(0)

Define Text.s
Text = "Feel the ..Pure.. Power"
V_ARG_Add(para_array(), Text)

Define pi.d = #PI
V_ARG_Add(para_array(), pi)

Define word1.w = 65535
V_ARG_Add(para_array(), word1)
V_ARG_Add(para_array(), word1)

Foo(para_array()) 
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Simple way to use variable parameters for Procedures

Post by Kwai chang caine »

Very usefull code, thanks a lot for sharing 8)
ImageThe happiness is a road...
Not a destination
GPI
PureBasic Expert
PureBasic Expert
Posts: 1394
Joined: Fri Apr 25, 2003 6:41 pm

Re: Simple way to use variable parameters for Procedures

Post by GPI »

My Variant :)
Call supports here up to 10 parameters.

Code: Select all

;==================================================================
; ###  Example to use variable parameters for Procedures    ###
; Author:            Thomas <ts-soft> Schulz & <NicTheQuick>
; Date:              Mrz 16, 2012
; Version:           1.1
; Target OS:         All
; Target Compiler:   PureBasic 5.10 and later
;==================================================================



EnableExplicit


Macro MacroQuote
  "
EndMacro


Structure V_ARG
  Type.l
  StructureUnion
    a.a
    b.b
    c.c
    d.d
    f.f
    i.i
    l.l
    q.q
    u.u
    w.w
  EndStructureUnion
  s.s
EndStructure

Procedure V_ARG_Add_(Array V_ARG.V_ARG(1), Type.l, size.i, *value)
  Protected index = ArraySize(V_ARG())
  ReDim V_ARG(index + 1)
  
  With V_ARG(index)
    \Type = Type
    If (Type = #PB_String)
      \s = PeekS(*value)
    Else
      CopyMemory(*value, @V_ARG(index) + OffsetOf(V_ARG\a), size)
    EndIf
  EndWith
EndProcedure

Macro V_ARG_START
  Dim __varg.V_ARG(0)
EndMacro
  
  

Macro V_ARG_Add(value)
  CompilerIf TypeOf(value) = #PB_Structure
    CompilerError "The variable has no native type. This is not supported."
  CompilerEndIf
  V_ARG_Add_(__varg(), TypeOf(value), SizeOf(value), @value)
EndMacro

Macro V_ARG_LIST
  __varg()
EndMacro

Macro V_ARG_END
  FreeArray(__varg())
EndMacro

Macro Call(ret,proc,a1=,a2=,a3=,a4=,a5=,a6=,a7=,a8=,a9=,a10=)
  V_ARG_START
  CompilerIf  MacroQuote#a1#Macroquote<>""
    V_ARG_Add(a1)
  CompilerEndIf
  CompilerIf  MacroQuote#a2#Macroquote<>""
    V_ARG_Add(a2)
  CompilerEndIf
  CompilerIf  MacroQuote#a3#Macroquote<>""
    V_ARG_Add(a3)
  CompilerEndIf
  CompilerIf  MacroQuote#a4#Macroquote<>""
    V_ARG_Add(a4)
  CompilerEndIf
  CompilerIf  MacroQuote#a5#Macroquote<>""
    V_ARG_Add(a5)
  CompilerEndIf
  CompilerIf  MacroQuote#a6#Macroquote<>""
    V_ARG_Add(a6)
  CompilerEndIf
  CompilerIf  MacroQuote#a7#Macroquote<>""
    V_ARG_Add(a7)
  CompilerEndIf
  CompilerIf  MacroQuote#a8#Macroquote<>""
    V_ARG_Add(a8)
  CompilerEndIf
  CompilerIf  MacroQuote#a9#Macroquote<>""
    V_ARG_Add(a9)
  CompilerEndIf
  CompilerIf  MacroQuote#a10#Macroquote<>""
    V_ARG_Add(a10)
  CompilerEndIf
  CompilerIf MacroQuote#ret#MacroQuote="#Null"
    proc ( V_ARG_LIST )
  CompilerElse
    ret = proc ( V_ARG_LIST )
  CompilerEndIf
  
    V_ARG_END

EndMacro



; example
Procedure Foo(Array V_ARG.V_ARG(1))
  Protected i.i
  Protected count.i = ArraySize(V_ARG())
  Debug "Count of parameters: " + Str(count)
  Debug ""
  For i = 0 To count - 1
    With V_ARG(i)
      Debug \Type
      Select \Type
        Case #PB_Ascii
          Debug "Parameter " + Str(i + 1) + " = UByte, Value = " + Str(V_ARG(i)\a)
        Case #PB_Byte
          Debug "Parameter " + Str(i + 1) + " = Byte, Value = " + Str(V_ARG(i)\b)
        Case #PB_Character
          Debug "Parameter " + Str(i + 1) + " = Char, Value = " + Str(V_ARG(i)\c)
        Case #PB_Double
          Debug "Parameter " + Str(i + 1) + " = Double, Value = " + StrD(V_ARG(i)\d)
        Case #PB_Float
          Debug "Parameter " + Str(i + 1) + " = FLoat, Value = " + StrF(V_ARG(i)\f)
        Case #PB_Integer
          Debug "Parameter " + Str(i + 1) + " = Integer, Value = " + Str(V_ARG(i)\i)
        Case #PB_Long
          Debug "Parameter " + Str(i + 1) + " = Long, Value = " + Str(V_ARG(i)\l)
        Case #PB_Quad
          Debug "Parameter" + Str(i + 1) + " = Quad, Value = " + Str(V_ARG(i)\q)
        Case #PB_String
          Debug "Parameter " + Str(i + 1) + " = String, Value = " + V_ARG(i)\s
        Case #PB_Unicode
          Debug "Parameter " + Str(i + 1) + " = UWord, Value = " + Str(V_ARG(i)\u)
        Case #PB_Word
          Debug "Parameter " + Str(i + 1) + " = Word, Value = " + Str(V_ARG(i)\w)
      EndSelect
    EndWith
  Next
  ProcedureReturn count
EndProcedure

V_ARG_START

Define Text.s
Text = "Feel the ..Pure.. Power"
V_ARG_Add( Text)

Define pi.d = #PI
V_ARG_Add( pi)

Define word1.w = 65535
V_ARG_Add(word1)
V_ARG_Add( word1)

Foo(V_ARG_LIST) 

V_ARG_END

Call(#Null,Foo,text,pi,word1,pi,word1)

Call(#Null,Foo,text,pi,pi,pi,pi)

Define ret.i
call(ret,Foo,pi,text)
Debug "Return:"+Str(ret)

User avatar
NicTheQuick
Addict
Addict
Posts: 1504
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: Simple way to use variable parameters for Procedures

Post by NicTheQuick »

Make it a "Threaded Dim" and you also have thread support. :)
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
Post Reply