fxm wrote:It seems to me that by using "unique identifiers" in the second example, the [Scope ... End Scope] block becomes useless (unlike the first example where it is always mandatory),
OK, that's fair.
except if the user defines in the same scope an identifier of the form "LT_xxxx" because it could be matching to the first defined "unique identifier" (outside the [While...Wend] block) ?
Any user symbol of the form 'LT_xxxx' should be avoided.
More I was thinking that the first example of 'repeat' macro is nearly generic except for use of '__counter__' symbol. '__counter__'. Provided user never uses '__counter__' for something else like a global variable and try to refer to it inside the scope, it's all fine. No need to use unique identifiers.
Otherwise it is not demonstrative.
Perhaps following is a more interesting example. A pattern where there is a series of steps is required for setup, some work to do, and finishing cleanup. If any one step goes wrong, need to abort to the appropriate cleanup step.
Code: Select all
#macro setup
__FB_UNIQUEID_PUSH__( __cleanup__ )
scope
#endmacro
#macro end_setup
__FB_UNIQUEID_PUSH__( __cleanup__ )
scope
#endmacro
#macro abort
goto __FB_UNIQUEID__( __cleanup__ )
#endmacro
#macro cleanup
end scope
__FB_UNIQUEID__( __cleanup__ ):
__FB_UNIQUEID_POP__( __cleanup__ )
#endmacro
#macro end_cleanup
end scope
__FB_UNIQUEID__( __cleanup__ ):
__FB_UNIQUEID_POP__( __cleanup__ )
#endmacro
function copyfile( byref srcfile as string, byref dstfile as string ) as boolean
function = false
const buffer_size = 1024
setup '' buffer
dim as ubyte ptr buffer = allocate( buffer_size )
if( buffer = 0 ) then
print "no memory"
abort
end if
setup '' source file
var f1 = freefile
if( open( srcfile for binary access read as f1 ) <> 0 ) then
print "unable to open source file"
abort
end if
setup '' destination file
var f2 = freefile
if( open( dstfile for input as f2 ) = 0 ) then
print "destination file already exists"
abort
else
close f2
end if
if( open( dstfile for binary as f2 ) <> 0 ) then
print "unable to open destination file"
abort
end if
end_setup
dim length as ulongint = lof(f1)
dim bytes as ulongint = buffer_size
while( length > 0 )
if( length < bytes ) then
bytes = length
end if
if( get( #f1, , *buffer, bytes ) <> 0 ) then
print "read error"
abort
end if
if( put( #f2, , *buffer, bytes ) <> 0 ) then
print "write error"
abort
end if
length -= bytes
wend
function = true
cleanup '' destination file
close f2
cleanup '' source file
close f1
cleanup '' memory
deallocate buffer
end_cleanup
end function
''
if( command(1) = "" ) then
print "need source file"
end 1
end if
if( command(2) = "" ) then
print "need destination file"
end 1
end if
copyfile command(1), command(2)
I was attempting to also create macros for 'retry' and 'ignore' actions, but a found another bug. in next example __FB_UNIQUEID_POP__(id) isn't skipped over. I'm just trying to figure out if this was always a kind of bug, even in older versions of fbc, but maybe just didn't matter because macro expansions didn't have internal side effects.
Code: Select all
#macro M
#if 0
__FB_UNIQUEID_POP__(id)
#endif
#endmacro
M
Ah yes, in older versions of fbc also, this causes some trouble:
Code: Select all
#define X(arg1)
#macro M
#if 0
X ( 1
#endif
#endmacro
M