News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Alternative technique for VARARG in PowerBASIC

Started by hutch--, August 09, 2019, 08:17:16 PM

Previous topic - Next topic

hutch--

PowerBASIC has its own method of passing a variable number of arguments but it can be done with more flexibility using a DWORD array which can contain DWORD numbers and DWORD sized pointers in any number required without the high overhead of the normal technique. Once you dimension a DWORD array of whatever count you require which can be large, you just pass an argument count and the number of arguments that match it.

You will notice a number of procedures that are not part of standard PowerBASIC which are in the library "gplib.lib" as I am currently rationalising 20 years of text based source for PowerBASIC so I can find my way around it quickly and a SLL based library is the most efficient method I can see for doing this.

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    #compile exe "vararg.exe"
    $link "gplib.lib"                       ' custom PowerBASIC library

    MACRO FUNCTION btxt(quoted)             ' return basic text address
      MACROTEMP bst
      LOCAL bst as STRING
      bst = quoted
    END MACRO = StrPtr(bst)

    MACRO LineFeed = zconout CodePtr(lnfd)  ' line feed to console

    GLOBAL arglist() as DWORD

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

FUNCTION PBmain as LONG

    DIM arglist(64) as DWORD                ' dimension the array

    arglist(0) = 4                          ' set the argument count
    arglist(1) = 1234                       ' load the array
    arglist(2) = 5678
    arglist(3) = 9012
    arglist(4) = 3456
    numproc arglist()                       ' call the test procedure

    a$ = "One"
    arglist(0) = 4                          ' set the argument count
    arglist(1) = StrPtr(a$)                 ' pass a basic dynamic string
    arglist(2) = btxt("Two")                ' pass a pointer to quoted text
    arglist(3) = btxt("Three")
    arglist(4) = btxt("Four")
    txtproc arglist()

    a$ = "How D"
    arglist(0) = 0                          ' unused
    arglist(1) = StrPtr(a$)                 ' pass a basic dynamic string
    arglist(2) = btxt("Basic String")       ' pass a basic dynamic string
    arglist(3) = 1234                       ' pass a number
    MixProc arglist()

    pause                                   ' pause so you can see it

    erase arglist()                         ' clean up the array on exit

End FUNCTION

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

FUNCTION numproc(arg() as DWORD) as DWORD

    LOCAL cntr as DWORD                     ' the passed item count
    LOCAL icnt as DWORD                     ' loop iteration counter

    cntr = arg(0)                           ' load the counter
    icnt = 0                                ' zero iteration counter

  stlp:                                     ' display the array items
    ! add icnt, 1
    conout ustr(arg(icnt))
    ! sub cntr, 1
    ! jnz stlp

    LineFeed

End FUNCTION

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

FUNCTION txtproc(arg() as DWORD) as DWORD

    LOCAL cntr as DWORD                     ' the passed item count
    LOCAL icnt as DWORD                     ' loop iteration counter

    cntr = arg(0)                           ' load the counter
    icnt = 0                                ' zero iteration counter

  lpst:
    ! add icnt, 1
    zconout arg(icnt)
    zconout CodePtr(lnfd)
    ! sub cntr, 1
    ! jnz lpst

    LineFeed

End FUNCTION

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

FUNCTION MixProc(arg() as DWORD) as DWORD

    conout ustr(arg(0))                     ' unused counter
    zconout arg(1):LineFeed                 ' display string
    zconout arg(2):LineFeed                 ' display string
    conout ustr(arg(3))                     ' display number

    LineFeed

END FUNCTION

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

  ASMDATA lnfd

    db 13,10,0

  END ASMDATA

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤