Dave Navarro, Jr. (dave@powerbasic.com) INITIALIZE USER DEFINED TYPES ------------------------------------------------------------------------------ '============================================================================== ' ' Initialize the elements of a User-Defined Type ' by Dave Navarro, Jr, (dave@powerbasic.com) ' Donated to the Public Domain ' ' Requires PowerBASIC 3.0 or later. ' ' Using a string which 'describes' the UDT, InitUDT will set all numeric values ' to zero and all string values to spaces instead of nulls. ' ' ? = byte (1 byte) ' ?? = word (2 bytes) ' ??? = dword (4 bytes) ' % = integer (2 bytes) ' & = long (4 bytes) ' && = quad (8 bytes) ' ! = single-precision (4 bytes) ' # = double-precision (8 bytes) ' ## = extended-precision (10 bytes) ' @ = BCD fixed (8 bytes) ' @@ = BCD float (10 bytes) ' $ = string ' '============================================================================== DECLARE FUNCTION GetStrLoc(BYVAL StringHandle AS INTEGER) AS LONG 'required ' ** Example code TYPE TestMe b AS BYTE l AS LONG d AS DOUBLE s AS STRING * 5 END TYPE DIM z AS TestMe CLS z.b = 5 z.l = 2048 z.d = 5.3341 z.s = "ABCDE" PRINT z.b PRINT z.l PRINT z.d WRITE z.s InitUDT z, "?,&,#,$5" PRINT z.b PRINT z.l PRINT z.d WRITE z.s SUB InitUDT(ANY, BYVAL Desc AS STRING) ! push DS ; save DS for PowerBASIC ! push Word Ptr Desc ; push string handle on the stack ! call GetStrLoc ; find the string in memory ! or CX, CX ; zero length? ! jnz GetStringAddress ; no, get the address ! jmp InitDone ; we're done GetStringAddress: ! mov DS, DX ; put segment in DS ! mov SI, AX ; put offset in SI ! les DI, [BP+8] ; point ES:DI at UDT ! xor AX, AX ; clear AX ! mov BX, 10 ; use BX for multiplier (strings) InitLoop: ! cmp Byte Ptr [SI], 37 ; % ! je TwoBytes ; ! cmp Byte Ptr [SI], 38 ; & ! je FourBytes ; ! cmp Byte Ptr [SI], 33 ; ! ! je FourBytes ; ! cmp Byte Ptr [SI], 35 ; # ! je PoundAt ; ! cmp Byte Ptr [SI], 64 ; @ ! je PoundAt ; ! cmp Byte Ptr [SI], 63 ; ? ! je Question ; ! cmp Byte Ptr [SI], 36 ; $ ! je Dollar ; NextByte: ! inc SI ; next byte ! loop InitLoop ; loop until no more bytes ! jmp InitDone ; TwoBytes: ! stosw ; write two nulls ! jmp Short NextByte ; FourBytes: ! stosw ; write four nulls ! stosw ; ! jmp Short NextByte ; PoundAt: ! stosw ; write 8 nulls ! stosw ; ! stosw ; ! stosw ; ! cmp Byte Ptr [SI+1], 35 ; extended precision? ! je TwoMore ; ! cmp Byte Ptr [SI+1], 64 ; floating point currency? ! jne NextByte TwoMore: ! stosw ; two more for a total of 10 ! inc SI ; ! jmp Short NextByte ; Question: ! stosb ; one null ! cmp Byte Ptr [SI+1], 63 ; Word? ! jne NextByte ; ! stosb ; one more (for word) ! inc SI ; ! cmp Byte Ptr [SI+1], 63 ; DWord? ! jne NextByte ; ! stosw ; two more (for dword) ! inc SI ; ! jmp Short NextByte ; Dollar: ! push AX ; save AX ! xor AX, AX ; and clear it StringLoop: ! inc SI ; ! cmp Byte Ptr [SI], 48 ; 0? ! jb StringDone ; ! cmp Byte Ptr [SI], 57 ; 9? ! ja StringDone ; ! dec CX ; ! xor DH, DH ; clear DH ! mov DL, [SI] ; get byte ! sub DL, 48 ; convert to numeric value ! imul BL ; multiply AX by 10 ! add AX, DX ; add new value to AX ! jmp Short StringLoop ; StringDone: ! push CX ; save CX ! mov CX, AX ; ! mov AL, 32 ; space ! rep stosb ; write spaces to string ! pop CX ; restore CX ! pop AX ; restore AX ! dec SI ; previous byte ! jmp NextByte ; InitDone: ! pop DS ; restore DS END SUB