News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Cute macro problem

Started by hutch--, October 11, 2011, 02:13:31 AM

Previous topic - Next topic

hutch--

I have a UNICODE macro up and going that is a rewrite of an old one in ucmacros.asm "uni$" and while its up and running it has a strange problem. If the quoted text contains the name of a Windows API, then it gets expanded to the full API name.


    fn MessageBox,0,"Message Text in a MessageBox","Title",MB_OK


Now the text "Message Text in a MessageBox" contains the API name MessageBox which has a prior equate to MessageBoxW so when you display the message box, the text is expanded up to "Message Text in a MessageBoxW". The text remains unmodified if it is contained within quotes but as soon as you remove the quotes it gets expanded.

Now I have tried to bypass the problem by modifying the FORC loop to test for a quote and bypass it but this in turn generates another problem,


error A2050: real or BCD number not allowed


This loop to strip the quotes first works fine.


     % FORC argz, <quoted@@text>
         IFDIF <argz>,<">
           new@str1 CATSTR new@str1,<argz>
         ENDIF
     ENDM


But if I try to use it with a large conditional testing block it generates the above error message. I have tried renaming variables, replacements with a flag setting but I either get the expanded API name or the 2050 error.

Has anyone played with a problem like this before ?

Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

fearless

I wonder if the equate gets expanded after all macro calls or before it. Only thing i could think of trying is using the literal operator ! in some combination, so you have two " quote symbols surrounding it - and hopefully it doesnt get expanded

<!">, new@str1, <!">

might not work or work for this type of situation, even if you use % echo <new@str1> to see it, it still might get changed from the equate already defined once the macro is finished with its output.
ƒearless

jj2007

Hutch,
I do not use FORC in such situations but rather a WHILE loop:

  WHILE PP lt parseLen ; Repeat until Parse Position >= LEN(P$)
PP=PP+1 ; Position in Parse$
c$ SUBSTR P$, PP, 1


JWasm is known to expand whatever it finds in quoted text - but you use ml, right? No complete example showing the bug?
Here is one that works fine with ML but shows MessageBoxA with JWasm:

include \masm32\include\masm32rt.inc

.code
start:
% fn MessageBox,0,"Message Text in a MessageBox","Title",MB_OK
exit

end start

qWord

hi,
my suggestion:

...
%      FORC arg, <&quoted@@text>

ifidn <&arg>,<">
c_n_t_r = c_n_t_r - 1
goto nxt
endif
...
FPU in a trice: SmplMath
It's that simple!

gfalen


$SegStack equ <  >

$popseg MACRO
    T instr $SegStack, <,>
    $SEG substr $SegStack, 1, T-1
    $SegStack substr $SegStack, T+1
    ifidn $SEG, <_BSS>
        .data?
    elseifidn $SEG, <CONST>
        .const
    elseifidn $SEG, <_DATA>
        .data
    elseifidn $SEG, <_TEXT>
        .code
    endif
endm

$pushseg MACRO _SEG
    $SegStack catstr @CurSeg, <,>, $SegStack
    _SEG
endm

wchar MACRO _LST:VARARG
    $pushseg
    S=0
    irp $W, <_LST>
        T instr <$W>, <=>
        OB instr <$W>, <[>
        if T
            .data
            if S
                dw 0
            endif
            S=1
            @SubStr(<$W>, 1, T-1) label word
            % wchar2 @SubStr(<$W>, T+1)
        elseif OB
            if S
                dw 0
            endif
            S=0
            .data?
            CB instr <$W>, <]>
            @SubStr(<$W>, 1, OB-1) dw @SubStr(<$W>, OB+1, CB-OB-1) dup({})
        elseifnb <$W>
            dw $W
        endif
    endm
    if S
        dw 0
    endif
    $popseg
endm

wchar2 MACRO _TXT
    $WC equ <>
    $W2 substr <_TXT>, 2, @SizeStr(<_TXT>)-2
    % irpc $C, <$W2>
        $WC catstr $WC, <,>, <'&$C'>
    endm
    dw @SubStr(<%$WC>, 2)
endm

wchar wc0[260], wc="This is a MessageBox test", 13, 10

jj2007

Hutch,
The current uni$ also does not support the "string", 13, 10, "more string" syntax. Will that be fixed? Will the WSTR sizeof problem be fixed?

include \masm32\MasmBasic\MasmBasic.inc   ; download
include \masm32\macros\ucmacros.asm
   Init[/size]
   wMsgBox 0, wChr$("Test", 13, 10, "Test"), "This is Unicode:", MB_OK
;   chokes: wMsgBox 0, uni$("Test", 13, 10, "Test"), "This is Unicode:", MB_OK
   wMsgBox 0, uni$("Test Test"), "This is Unicode:", MB_OK
   Exit
end start

hutch--

This is the test piece. I have tagged where the substitution occurs and it is as soon as the double quotes are removed. In this test piece the enclosed "MessageBox" is expanded to messageBoxA as soon as the quotes are removed.

JJ, no multiline DATA section data supports SIZEOF.

Greg,  Thanks for the example, i will see if I can digest it.

Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

hutch--

Greg,

Sorry to be a bit thick but I have not worked out how to use the macro.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

jj2007

Quote from: hutch-- on October 11, 2011, 12:13:58 PM
JJ, no multiline DATA section data supports SIZEOF.

Why multiline? One line is enough...

include \masm32\MasmBasic\MasmBasic.inc   ; download
   Init[/size]
   wData MyWide$, "This is Unicode", 0
   wMsgBox 0, wChr$("Test", 13, 10, "Test"), wStr$("MyWide$ has %i bytes", sizeof MyWide$), MB_OK
   wMsgBox 0, wChr$("Test", 13, 10, "Test"), wStr$("MyWide$ has %i chars", lengthof MyWide$), MB_OK
   Exit
end start

hutch--

> Why multiline? One line is enough...

MASM line length limit.


datname dw "T","h","i","s"," ","i","s"," ","a"," ","t","e","s","t",0


4 characters for each ASCII character converted to DW.

I may give WHILE a try over FORC as it may solve a problem with the loop errors with other modifications.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

jj2007

Quote from: hutch-- on October 11, 2011, 12:54:07 PM
> Why multiline? One line is enough...

MASM line length limit.


SIZEOF = 472 bytes :bg

include \masm32\MasmBasic\MasmBasic.inc   ; download
   Init
   wData MyWide$, "This is Unicode, and there is no real problem with Masm's line limit, unless you are really overdoing it, but then, why should you do something so stupid? You might even run into problems with your editor, but anyway, wheresde problem?", 0
   wMsgBox 0, addr MyWide$, wStr$("MyWide$ has %i bytes", sizeof MyWide$), MB_OK
   Exit
end start

hutch--

MASM line length is just under 250 characters, I can think of all sorts of techniques to get the length of a multiline text but SIZEOF only works on a single line. None the less such debate is of little use to me when i am trying to track down a quirk in the MASM macro engine of substitution of an API name once double quotes are removed.

If I seriously need to dump a large section of unicode text as literal, I use an external tool.


Lotsa UNICODE text can be done this way with effectively no limit at all on length.

.data
align 4
  dw_block_text \
    dw "L","o","t","s","a"," ","U","N","I","C","O","D","E"," ","t","e","x","t"," ","c","a","n"," ","b"
    dw "e"," ","d","o","n","e"," ","t","h","i","s"," ","w","a","y"," ","w","i","t","h"," ","e","f","f"
    dw "e","c","t","i","v","e","l","y"," ","n","o"," ","l","i","m","i","t"," ","a","t"," ","a","l","l"
    dw " ","o","n"," ","l","e","n","g","t","h",".",0,0
.code

; OR

; ANSI string of 83 bytes converted to UNICODE
; at 168 bytes using MultiByteToWideChar

db_block_text \
    db 76,0,111,0,116,0,115,0,97,0,32,0,85,0,78,0
    db 73,0,67,0,79,0,68,0,69,0,32,0,116,0,101,0
    db 120,0,116,0,32,0,99,0,97,0,110,0,32,0,98,0
    db 101,0,32,0,100,0,111,0,110,0,101,0,32,0,116,0
    db 104,0,105,0,115,0,32,0,119,0,97,0,121,0,32,0
    db 119,0,105,0,116,0,104,0,32,0,101,0,102,0,102,0
    db 101,0,99,0,116,0,105,0,118,0,101,0,108,0,121,0
    db 32,0,110,0,111,0,32,0,108,0,105,0,109,0,105,0
    db 116,0,32,0,97,0,116,0,32,0,97,0,108,0,108,0
    db 32,0,111,0,110,0,32,0,108,0,101,0,110,0,103,0
    db 116,0,104,0,46,0,0,0


Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

qWord

hutch,
you can make WSTR/uni$() to a wrapper of UCSTR-macro - The maximal length then is something about 240. AFAICS it would fully backward compatible.
FPU in a trice: SmplMath
It's that simple!

hutch--

qWord,

Build this in the current BETA and you get the same effect, the API MessageBox is extended to MessageBoxW.



; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    __UNICODE__ equ 1

    include \masm32\include\masm32rt.inc

    .code

start:
   
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    call main

    exit

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc

    LOCAL rval  :DWORD

    fnx MessageBox,0,"Text with API MessageBox in it  ","Title",MB_OK

    mov rval, rvx( MessageBox,0,"Text with API MessageBox in it  ","Title",MB_OK)

    ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

qWord

ok - to fix this problem, I've removed the smplwsz-macros and replaced it by the UCSTR-macro. Also I've modified some of the other macros, thus you should replace all of them in macros.asm.
At the bottom of the file macro_ex, you will find the following:
uni$ EQU uc$
WSTR macro lbl,args:VARARG
UCSTR lbl,args,0
endm

Also I've improved the examples.
FPU in a trice: SmplMath
It's that simple!