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
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
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.
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
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 (http://masm32.com/board/index.php?topic=94.0)
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
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 ).
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.
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
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 ).
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?
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.
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
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.
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.
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",....
The only one difference is here,on the label
Quote
Monlabel WORD 6 dup (?)
dw 0
dw 1
dw 2
Who allow to get the size and Lengthof
added support for sizeof and lengthof,
Replaced the "X" by "/" ,same usage.
Quote
AU MACRO adresse:REQ,ARGS:VARARG
local verif,count,decompte
count = 0
decompte = 1 ;made a loop without write nothing
IFDEF __UNICODE__
:WriteWord
verif equ <adresse>
IFDIF verif,</>
IF decompte EQ 0
adresse WORD count dup (?)
org $- count*2 ;return to adresse
count = 0
ENDIF
ENDIF
FOR _arg,<ARGS>
verif SUBSTR <_arg>,1,1
IFIDN verif,<">
FORC char,<_arg>
IFDIF <char>,<">
IF decompte EQ 0
cumul TEXTEQU <DW "&char">
cumul ;execute
ENDIF
count = count + 1
ENDIF
ENDM
ELSE
IF decompte EQ 0
DW _arg
ENDIF
count = count + 1
ENDIF
ENDM
IF decompte EQ 1
decompte = 0
GOTO WriteWord
ENDIF
EXITM<>
ELSE
:WriteByte
verif equ <adresse>
IFDIF verif,</>
IF decompte EQ 0
adresse BYTE count dup (?)
org $- count ;return to adresse
count = 0
ENDIF
ENDIF
FOR _arg,<ARGS>
verif SUBSTR <_arg>,1,1
IFIDN verif,<">
FORC char,<_arg>
IFDIF <char>,<">
IF decompte EQ 0
cumul TEXTEQU <DB "&char">
cumul ;execute
ENDIF
count = count + 1
ENDIF
ENDM
ELSE
IF decompte EQ 0
DB _arg
ENDIF
count = count + 1
ENDIF
ENDM
IF decompte EQ 1
decompte = 0
GOTO WriteByte
ENDIF
EXITM<>
ENDIF
ENDM
NAU MACRO namelabel:REQ,ARGS:VARARG
.data
AU (namelabel,ARGS)
.code
EXITM <namelabel>
ENDM
Quote from: ToutEnMasm on October 18, 2012, 06:45:36 AM
adresse WORD count dup (?)
org $- count*2 ;return to adresse
Nice trick, Yves :t