News:

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

Main Menu

a text MACRO working in ANSI or UNICODE format

Started by TouEnMasm, October 15, 2012, 01:47:57 AM

Previous topic - Next topic

TouEnMasm

Hello,
I have put here the final version
a sample of use:
The goal is to switch easily from ansi to unicode

.const
REBARCLASSNAME equ <"ReBarWindow32">
.data
;works with ANSI or __UNICODE__  (UNICODE for .h and sdk translate)

AU(szclassname,%REBARCLASSNAME,0)
AU(speech,"first sentence",13,10)
AU(/,"second sentence",13,10)
AU(/,"end",0)
.code

start:
mov edx,sizeof szclassname
mov ecx,LENGTHOF szclassname
invoke lstrlen,addr speech     ;lstrlenA or lstrlenW
lea edx,speech
invoke MessageBox,NULL,addr speech,\
addr NAU(atitre,"Default title",0),MB_OK
invoke MultiSize,addr NAU(firsttexte,"123456789012345678901234567",0),lengthof firsttexte -1,\
      addr NAU(secondtexte,"12345678901234",0),lengthof secondtexte -1


Fa is a musical note to play with CL

TouEnMasm


More simple and allow to made a speech on data
Quote
REBARCLASSNAMEW   equ   <"ReBarWindow32">
   .data
;works with various value of __UNICODE__    
AU(szclassname,%REBARCLASSNAMEW,0)
AU(speech,"first sentence",13,10)   
AU(X,"second sentence",13,10)
AU(X,"end",0)

.code

   start:
   mov edx,offset NAU(titre,"A title",0)
    invoke MessageBox,NULL,addr speech,\
      addr NAU(atitre,"Default title",0),MB_OK   
   invoke ExitProcess,0

Quote
AU MACRO adresse:REQ,ARGS:VARARG
   local verif
   verif equ <adresse>
   IFDIF verif,<X>
   adresse LABEL DWORD
   ENDIF
   IFDEF __UNICODE__
      FOR _arg,<ARGS>
         verif SUBSTR <_arg>,1,1
         IFIDN verif,<">           
            FORC char,<_arg>   
               IFDIF <char>,<">
                  cumul TEXTEQU <DW "&char">               
                  cumul ;execute
               ENDIF
            ENDM
         ELSE
            DW _arg
         ENDIF
      ENDM
      EXITM<>
   ELSE
      FOR _arg,<ARGS>
         verif SUBSTR <_arg>,1,1
         IFIDN verif,<">            ;si le premier caractere est "
            FORC char,<_arg>   
               IFDIF <char>,<">
                  chain TEXTEQU <DB "&char">
                  chain
               ENDIF
            ENDM
         ELSE
            DB _arg      
         ENDIF
      ENDM
      EXITM<>         
   ENDIF
ENDM

NAU MACRO namelabel:REQ,ARGS:VARARG
   .data
   AU (namelabel,ARGS)
   .code
   EXITM <namelabel>
ENDM   


Fa is a musical note to play with CL

japheth

Quote from: ToutEnMasm on October 15, 2012, 05:59:21 PM
...
   IFDIF verif,<X>
   adresse LABEL DWORD
   ENDIF
...

Why using the LABEL directive? This means that you cannot use SIZEOF and LENGTHOF operators for the string. And why is the type a DWORD? Shouldn't it be BYTE or WORD? Btw, 'X' as a dummy label looks a bit hackish IMO.

TouEnMasm


The write method don't allow to use the sizeof or lengthof macro.
Even if
Quote
Label db "A"
           db 42
..
sizeof return 1
here it is write
Quote
Label:
db "A"
db 42
..
a lenght function is needed in the two cases.
LABEL DWORD is the normal declare for 32 bits
If ml could allow:
DW "adf ",13,10         ;things here will be more simple
as he allow
db "adf",13,10

the CATSTR macro don't want to work with long chain
DW "a","b",....."X"      ; maximum number of terms is about 20

There is a limited number of choices to make it work.

If you don't agree with the choice of X change it
Fa is a musical note to play with CL

jj2007

Quote from: ToutEnMasm on October 15, 2012, 08:11:28 PM
The write method don't allow to use the sizeof or lengthof macro.

But they can be quite handy sometimes....

include \masm32\MasmBasic\MasmBasic.inc   ; download
   Init
   wData MyWide$, "This is Unicode", 0
   wPrint "[", offset MyWide$, wStr$("] is %i chars long, including the zero delimiter", lengthof MyWide$), wCrLf$
   wInkey "[", offset MyWide$, wStr$("] is %i bytes long, including the zero delimiter", sizeof MyWide$)
   Exit
end start

Output:
[This is Unicode] is 16 chars long, including the zero delimiter
[This is Unicode] is 32 bytes long, including the zero delimiter

japheth

Quote from: ToutEnMasm on October 15, 2012, 08:11:28 PM
LABEL DWORD is the normal declare for 32 bits

I understand. It's a misconception - the argument behind LABEL doesn't define the size of the label's address (which is of course 32 in 32-bit flat memory model), but the label's TYPE ( that is, the size of the data items assumed to be stored at this location ).

Quote
DW "a","b",....."X"      ; maximum number of terms is about 20

Yes, it's limited, but AFAIR it should be a bit more that just 20 ( somewhat between 50 and 60 for Masm ).

jj2007

Quote from: japheth on October 16, 2012, 01:02:28 AM
somewhat between 50 and 60 for Masm

Depends on the macro:

   wData M$, "This is Unicode, and there is no reason to assume that Masm cannot handle really long declarations \
   of Unicode data provided you follow the rules and respect the syntax established by Microsoft when they designed \
   Masm more than a decade ago.......",0

[This is Unicode, ... decade ago.......]
is 247 chars long, including the zero delimiter

Masm 6.15...9, unfortunately it chokes with JWasm.

TouEnMasm

#7
As a turn around for the size of the chain,I have added a constant (nau_size ) who change of value at each call.Be carefull using nau_size,see the end of post

Only the speech on data need the lstrlen function.

Quote
REBARCLASSNAMEW   equ   <"ReBarWindow32">
   .data
;works with ANSI or __UNICODE__    
AU(szclassname,%REBARCLASSNAMEW,0)
AU(speech,"first sentence",13,10)   
AU(X,"second sentence",13,10)
AU(X,"end",0)

.code

   start:
   mov edx,offset NAU(titre,"A title",0)
   mov ecx,nau_size   ;LENGTHOF  + 0
   lea eax,NAU(testsize,"Verify the count",0)
   mov ecx,nau_size - 1 ;change of value at each call,return the number of db or dw + 0
   ;the speech on data need a function for his size,further call
   invoke lstrlen,addr speech
   mov ecx,eax ;without 0 lstrlenA or lstrlenW
   invoke MessageBox,NULL,addr speech,\
      addr NAU(atitre,"Default title",0),MB_OK   
   invoke ExitProcess,0

The macro

Quote
   __UNICODE__ equ 1
   include masm32rt.inc
   .const
nau_size = 0
;Ansi Unicode MACRO text
; si adresse = X , no label for speech on data
AU MACRO adresse:REQ,ARGS:VARARG
   local verif,count
   IFNDEF nau_size
      ECHO nau_size Not Defined add "nau_size = 0" to your source code
   ENDIF   
   count = 0
   verif equ <adresse>
   IFDIF verif,<X>
   adresse LABEL DWORD
   ENDIF
   IFDEF __UNICODE__
      FOR _arg,<ARGS>
         verif SUBSTR <_arg>,1,1
         IFIDN verif,<">           
            FORC char,<_arg>   
               IFDIF <char>,<">
                  cumul TEXTEQU <DW "&char">               
                  cumul ;execute
                  count = count + 1
               ENDIF
            ENDM
         ELSE
            DW _arg
            count = count + 1            
         ENDIF
      ENDM
      nau_size = count
      EXITM<>
   ELSE
      FOR _arg,<ARGS>
         verif SUBSTR <_arg>,1,1
         IFIDN verif,<">            ;si le premier caractere est "
            FORC char,<_arg>   
               IFDIF <char>,<">
                  chain TEXTEQU <DB "&char">
                  chain
                  count = count + 1                  
               ENDIF
            ENDM
         ELSE
            DB _arg      
            count = count + 1            
         ENDIF
      ENDM
      nau_size = count      
      EXITM<>         
   ENDIF
ENDM
   
NAU MACRO namelabel:REQ,ARGS:VARARG
   .data
   AU (namelabel,ARGS)
   .code
   EXITM <namelabel>
ENDM   

don't work in this case
Quote
;only the last size is returned
   invoke Bidon,addr NAU(firsttexte,"first long phrase",0),nau_size -1,\
      addr NAU(secondtexte,"second phrase",0),nau_size -1
   invoke ExitProcess,0

;################################################################
Bidon PROC  pchain:DWORD, chain1size :DWORD,pchain2:DWORD, chain2size :DWORD
      Local asciitexte1[10]:BYTE
      Local asciitexte2[10]:BYTE      
         Local  retour:DWORD
         mov retour,1
   invoke dwtoa,chain1size,addr asciitexte1
   invoke dwtoa,chain2size,addr asciitexte2
   invoke MessageBox,NULL,addr asciitexte1,\
      addr asciitexte2,MB_OK
   
FindeBidon:
         mov eax,retour
         ret
Bidon endp


Fa is a musical note to play with CL

japheth

Quote from: jj2007 on October 16, 2012, 02:07:13 AM
Quote from: japheth on October 16, 2012, 01:02:28 AM
somewhat between 50 and 60 for Masm

Depends on the macro:

I was talking about the DW directive - and ToutEnMasm talked about the CATSTR directive ( although he/she admittedly called it a macro; but since he/she also calls SIZEOF and LENGTHOF macros,  I guess that virtually everything is a macro in his/her eyes ).

jj2007

Quote from: japheth on October 17, 2012, 08:14:19 PM
I was talking about the DW directive - and ToutEnMasm talked about the CATSTR directive

I know. Yves actually used "maximum number of terms is about 20", where "terms" means evidently the number of chars that can be constructed with his macro.

The wChr$ macro does not have this limitation, it allows >240 chars/480 bytes, and reduces executable size because under the hood a byte string in .data is converted to a word string in .data?

JWasm chokes apparently over the "backslash for line continuation" feature. Any chance to fix that?

japheth

Quote from: jj2007 on October 17, 2012, 08:32:44 PM
JWasm chokes apparently over the "backslash for line continuation" feature. Any chance to fix that?

"backslash" and "comma" line concatenation are both implemented in jwasm. There is a known bug if a blank macro arguments causes a comma to be the last token ( see expans18.as_ in jwasm/regression ) - but "backslash" should work.

jj2007

Quote from: japheth on October 17, 2012, 08:49:36 PM
...- but "backslash" should work.

https://sourceforge.net/tracker/?func=detail&aid=3577810&group_id=255677&atid=1126895

TouEnMasm

Quote from JJ
Quote
I know. Yves actually used "maximum number of terms is about 20",

The AU and NAU macro are not limited to 20 chars.
They are limited to the max of a line for masm.
it's only the CATSR macro who is limited to about 20 loop on the same constant.
Fa is a musical note to play with CL

qWord

Quote from: ToutEnMasm on October 18, 2012, 02:09:10 AMit's only the CATSR macro who is limited to about 20 loop on the same constant.
That is because the line with CATSTR is also limited.
You can break this limit by emitting the char. separately - even this is not problematic, because you won't support the SIZEOF and LENGTHOF operator. If you want to support them, take a look at the UCSTR-macro that comes with the MASM32 package.
MREAL macros - when you need floating point arithmetic while assembling!

TouEnMasm

I have had a look at it.
Except if i am in the error,The UCSTR write the dw as the AU macro.
Quote
;listing
= dw 'd'     ucstr_char CATSTR <dw >,ucstr_quote,<d>,ucstr_quote
00000088  0064           3                       ucstr_char
;and so on
The good thing will to write it as this:
= dw "v","e",....
Fa is a musical note to play with CL