Define From String

Here we create DEFSTRUCT in a string variable, including a couple of dependent DEFSTRUCTs, DEFTYPEs, and DEFINEs, and use it to define a dynstruct.

map1 dsdef$,s,0             ! string to hold definition source

map1 fields,i,2             ! # fields (signed to allow error codes)

map1 stsize,b,4             ! size of the structure

map1 errmsg$,s,100          ! error messages

map1 lf,s,1,chr(10)         ! line terminator for structure lines

 

! Start with some preliminary definitions…

    dsdef$ = "deftype T_SKU = s,10" + lf &

       + "define LEN_NOTES = 30" + lf

 

! now define structures on which our Dynstruct will depend

    dsdef$ += "defstruct ST_PRICE" + lf &

        + "map2 cost,f,6" + lf &

        + "map2 wholesale,f,6" + lf &

        + "map2 retail,f,6" + lf &

        + "endstruct" + lf

 

    dsdef$ += "defstruct ST_DUMMY" + lf &

        + "map2 manny,f,6" + lf &

        + "map2 moe,f,6" + lf &

        + "map2 jack,f,6" + lf &

        + "endstruct" + lf

 

! finally the Dynstruct we are defining...

    dsdef$ += "defstruct ST_TEST" + lf &

        + "map2 qty,b,2" + lf &

        + "map2 sku,T_SKU" + lf &

        + "map2 price,ST_PRICE" + lf &

        + "map2 notes(4),s,LEN_NOTES" + lf &

        + "endstruct" + lf

 

    fields = Fn'Dynst'Define(dsdef$,stsize,"ST_TEST",errmsg$)

   

    ? "    status: ";fields

    if fields < 0 then

        ? " status (fields): ";fields;" ("+errmsg$+")"

    else

        ?

        ? "    structsize: ";stsize

        ? "    # fields:     ";fields;" (including overall structure)"

    endif

 

The above example uses a convenience wrapper function from fndynst.bsi in SOSLIB:[907,10] to handle the actual MX_DYNSTRUCT to define the dynstruct, the source of which is here:

Function Fn'Dynst'Define(dsdef$ as s0:inputonly, &

                         stsize as i4:outputonly, &

                         dsname$ as T_DYN_NAME:inputonly, &

                         errmsg$ as s0:outputonly) as i4

    map1 locals

        map2 status,i,4

        map2 fields,i,4

       

    xcall MIAMEX, MX_DYNSTRUCT, DYNOP_DEF, status, dsdef$, fields, stsize, dsname$, errmsg$

   

    if status >= 0 then

        Fn'Dynst'Define = fields

    else

        Fn'Dynst'Define = status

    endif

    xputarg @stsize

    xputarg @errmsg$

EndFunction

 

The function doesn’t add much value but does isolate the application somewhat from the technical details of the dynstruct definition process, which could be subject to change in the future.

Note that at this point we’ve defined the dynstruct ST_TEST and can refer to it by its name ("ST_TEST") at any pointer later in this program, i.e. to bind it to a dynstruct variable, retrieve layout information about it, etc.