That was a joke benI do NOT recommend that comment because it contains a colon. It will not work properly
Take out the : and it works fine.
Batch "macros" with arguments
Moderator: DosItHelp
Re: Batch "macros" with arguments
Re: Batch "macros" with arguments
☺
I discovered or should I say failed to discover something that might be of interest.
Sometimes it is usefull to have a macro that defines or undefines other macros.
This works great for functions, but it seems impossible to get it working for macros:
This works:
This seems to be impossible:
Tried the obvious:
That's too bad, as it could have raised abstraction. Maybe dereferencing is not such a bad idea in this situation, but I'm afraid things would get overly complex. Hard-coding seems to be the easiest
I discovered or should I say failed to discover something that might be of interest.
Sometimes it is usefull to have a macro that defines or undefines other macros.
This works great for functions, but it seems impossible to get it working for macros:
Code: Select all
set ^"@Debug.on=( %$n1c%
set "@Ddef=if defined $Debug.Sub" %$n1c%
)"
Code: Select all
set ^"@TraceOut=( %$n1c%
if defined $Debug.Sub do something %$n1c%
)"
Code: Select all
set ^"@TraceOut=( %$n1c%
^^^!@Ddef^^^! do something %$n1c%
)"
Code: Select all
^^^!@Ddef^^^!
%%@Ddef%%
for.... in
for /f "usebackq" %%^^^! in ( `echo."^!@Ddef^!"` ) do %%~^^^! %$n1c%
etc...
Re: Batch "macros" with arguments
☺
When I try to write a macro to a file, and then use type file everything is good.
However when I open the file there are 2 squares were the linefeeds should be.
I know they represent a linefeed and a carriage return but that was not my intention.
The file needs to have REAL linefeeds, not 2 squares
this is my code:
When I try to write a macro to a file, and then use type file everything is good.
However when I open the file there are 2 squares were the linefeeds should be.
I know they represent a linefeed and a carriage return but that was not my intention.
The file needs to have REAL linefeeds, not 2 squares
this is my code:
Code: Select all
set ^"@WriteAdvancedReturn=do ( %$n1c%
set "$NotDelayedFlag=!" %$n1c%
setlocal EnableDelayedExpansion %$n1c%
set "$token=%%~!" %$n1c%
set "$RetVar=!$token!" %$n1c%
set "$RetVal=!%%~!!" %$n1c%
echo.$RetVal=!$RetVal! %$n1c%
)"
echo.
( for %%! in ( @WriteAdvancedReturn ) %@WriteAdvancedReturn% ) >tst.txt
type tst.txt
%@endoftest%
Re: Batch "macros" with arguments
My guess is that the squares are real control characters (both <LF>?) and your editor is choosing to display them as squares. Maybe your editor only recognizes the combination of <CR><LF> as the new line sequence and it displays naked <LF> as a square.
Use a hexdump or hex editor utility to verify exactly what your output is.
Dave Benham
Use a hexdump or hex editor utility to verify exactly what your output is.
Dave Benham
Re: Batch "macros" with arguments
☺
My editor ?, hmm, I use notepad
My editor ?, hmm, I use notepad
Re: Batch "macros" with arguments
Notepad ignores <LF> on my Vista machine (no line break, no box).
But a Google search shows that others are experiencing what you are seeing: http://forums.ni.com/t5/LabVIEW/Line-fe ... d-p/870878
But a Google search shows that others are experiencing what you are seeing: http://forums.ni.com/t5/LabVIEW/Line-fe ... d-p/870878
Re: Batch "macros" with arguments
☺
Thanx ben, in their solution they are talking about using \r\n instead of \n,
but euh, what is \r, is that a carriage return ?
Does this mean I have to replace <LF> with <CR><LF> before writing to file ?
And will a macro still work if I then try to load it with for "usebackq" ?
I am playing with the idea of writing a macro to a file, so it can be loaded after endlocal.
Thought it would be handy to check defined macros and pasting and splitting macros and stuff.
Thanx ben, in their solution they are talking about using \r\n instead of \n,
but euh, what is \r, is that a carriage return ?
Does this mean I have to replace <LF> with <CR><LF> before writing to file ?
And will a macro still work if I then try to load it with for "usebackq" ?
I am playing with the idea of writing a macro to a file, so it can be loaded after endlocal.
Thought it would be handy to check defined macros and pasting and splitting macros and stuff.
Re: Batch "macros" with arguments
Yes, that would be a carriage return.Ed Dyreen wrote:but euh, what is \r, is that a carriage return ?
No, I don't think that is necessary. However, you might want to use a different text editor. Wordpad maybe? I use ConText - a free programmers editor. There are other free text editors out there.Ed Dyreen wrote:Does this mean I have to replace <LF> with <CR><LF> before writing to file ?
I don't think this is an issue if you don't change anything.Ed Dyreen wrote:And will a macro still work if I then try to load it with for "usebackq" ?
Do you plan to define all your macros in one go, spit the definitions out to a file, and then load them back in after ENDLOCAL I'm not sure what kind of escaping you will have to do to preserve the special characters and line feeds in the definitions when you read them back in.
I hope you realize that my macro_BeginDef / macro.EndDef / macro_EndAnyRtn solution is intended to be applied to each macro individually. It really does work, as long as the macro doesn't get too big. And when the macro does become too large you can break it down into smaller macros and use your function that calls a macro to circumvent the problem. I don't see the need to go the temporary file route.
Dave Benham
Re: Batch "macros" with arguments
'
I have been experimenting with macros for quite a while now.
Due to the fact that a macro definition cannot be larger than 8k,
I looked for solutions, I found that you could paste macro's with a helperfunction.
The results are discouraging.
It seems that large "combined" macro's become actually slower than functions because;
This is one call:
These are 4 calls:
I though keeping helperfunc: in a separate file would be enough but CALL hits hard.
It feels like wasting hundreds of msecs !
Conclusion:
Macros are not a replacement for functions, rather function enhancers.
There is a fragile balance to be chased for "optimal" performance.
To strive for "pure" macro code is bad
I have been experimenting with macros for quite a while now.
Due to the fact that a macro definition cannot be larger than 8k,
I looked for solutions, I found that you could paste macro's with a helperfunction.
The results are discouraging.
It seems that large "combined" macro's become actually slower than functions because;
This is one call:
Code: Select all
:function
@macro
@macro
@macro
@macro
:endfunc
Code: Select all
@combinedmacro=(
call helperfunc: @macro
call helperfunc: @macro
call helperfunc: @macro
call helperfunc: @macro
)
I was completely ignoring this fact until nowNow that wasn't dos syntax, all these languages are so confusing
I though keeping helperfunc: in a separate file would be enough but CALL hits hard.
It feels like wasting hundreds of msecs !
Conclusion:
Macros are not a replacement for functions, rather function enhancers.
There is a fragile balance to be chased for "optimal" performance.
To strive for "pure" macro code is bad
Re: Batch "macros" with arguments
The extreme slowness of CALL is well documented:CALL me, or better avoid callEd Dyreen wrote:I thought keeping helperfunc: in a separate file would be enough but CALL hits hard.
It feels like wasting hundreds of msecs !
The moment you call your helper function - it's no longer pure macro. Achieving pure macro code is impossible the moment the task becomes moderately complex. (in other words, more complex than what can be achieved in 8k). So, yes, I suppose trying to achieve the impossible is bad.Ed Dyreen wrote:To strive for "pure" macro code is bad
Actually I think macros are a perfect replacement for most utility type functions, given that most functions have a very specific function that does fit within 8k. They most definitely are NOT replacements for entire batch processes.Ed Dyreen wrote:Conclusion:
Macros are not a replacement for functions, rather function enhancers.
There is a fragile balance to be chased for "optimal" performance.
But I see your point with regard to hybrid macros (macros that use CALL to circumvent the 8k barrier).
In my testing, it is generally faster to call a true macro via a function (my callMacro batch file, your helperfunc), then it is to call the same functionality written as a pure function.
I think a good crude indicator to decide if a hybrid macro is worthwhile is to look at the number of CALLs in the hybrid vs. the number of CALLs it takes to execute a pure function. (Assume the hybrid is executed as a true macro on not through the function) If the hybrid has the same number or fewer calls, then it probably can't hurt.
Don't forget the convenience factor of macro libraries. It is very easy to "include" a macro library in a batch. Not so for a function library.
Also, function libraries tend to slow down as the file size increases. Not generally true with macros. Though I saw where you reported that your large macro project seemed to slow down. I haven't seen that with macros yet.
Dave Benham
Re: Batch "macros" with arguments
I am starting to believe this has everything to do with DOS memory.Also, function libraries tend to slow down as the file size increases. Not generally true with macros. Though I saw where you reported that your large macro project seemed to slow down. I haven't seen that with macros yet.
Whenever we use a variable, DOS has to look it up in an array in memory and replace it.
Having a larger array will slow down the lookup process.
Using large amounts of DOS memory can make executables fail to start, run &exit properly.
In this case there is insufficient memory for the exe to properly initialize, and or run.
For example, I lost the ability to directly acces WMIC, It will run, but the result will never be returned to DOS, wmic.exe is idle, but will not shutdown ! Forcing me to launch another instance. It's weird that it works because i did not use the start /i option !
after defining:
Code: Select all
start "WMIC.EXE" /wait /high /min "%comspec%" /c 2^> "%%~?" 1^> "%%~!" WMIC.EXE !Alias!
Re: Batch "macros" with arguments
And the fool continiuesdbenham wrote:OK - I have finally caught up with the macro "calling" macro discussion. Thanks Jeb and Ed, it's been a good exchange.
I had been hoping that the expansion of the inner macro could be delayed until run-time because, as Ed pointed out, I was concerned about the size limit of any single macro definition. But I now realize that there is no avoiding the fact that at run time the entire fully expanded macro must exist in memory as one parsed "statement", so it was a fools dream.
I want to fit a variable inside another one, but the result is over 8046 chars, so I can't.
But I still can enumerate it's contents, the result is the same, just a bit slower.
Code: Select all
echo.@endoftest>nul
echo.
set "@macro=echo.this is a macro &echo.that uses memory &echo.to hold this text &echo.memory use grows as the macro gets longer &echo.but i'm sure that 1 + 1 equals &set /a "val=1+1" &echo.'!val!'"
setlocal enableExtensions enableDelayedExpansion
:: (
%@macro%
for /f "usebackq tokens=*" %%? in ( `echo. ^&!@macro!` ) do echo.%%?
:: )
endlocal
%@endoftest%
Code: Select all
this is a macro
that uses memory
to hold this text
memory use grows as the macro gets longer
but i'm sure that 1 + 1 equals
'2'
this is a macro
that uses memory
to hold this text
memory use grows as the macro gets longer
but i'm sure that 1 + 1 equals
2'2'
endoftest Druk op een toets om door te gaan. . .
Re: Batch "macros" with arguments
Is this what you were trying to achieve?
output:
I see how it works (both versions). But what is is good for
Dave Benham
Code: Select all
@echo off
setlocal
set "@macro=echo.this is a macro &echo.that uses memory &echo.to hold this text &echo.memory use grows as the macro gets longer &echo.but i'm sure that 1 + 1 equals &set /a "val=1+1" &rem '!val!'"
setlocal enableExtensions enableDelayedExpansion
set val
for /f "usebackq tokens=*" %%? in ( `echo. ^&!@macro!` ) do echo.%%?
echo(
set val
output:
Code: Select all
Environment variable val not defined
this is a macro
that uses memory
to hold this text
memory use grows as the macro gets longer
but i'm sure that 1 + 1 equals
2
Environment variable val not defined
I see how it works (both versions). But what is is good for
Dave Benham
Re: Batch "macros" with arguments
so you knew how to do it ?!
I could use this to "call" a macro that would otherwise go over 8k.
I realize for takes time, but a function call takes time too.
I was wondering what would be fastest...
Thought it might be relevant...
Re: Batch "macros" with arguments
You do know that FOR IN() clause commands are executed in their own CMD session
I'm wondering if there is a limit to the size of the command that CMD can take
Also, the environment changes that take place within the IN() clause cannot be propagated back to the parent session. (Unless of course you use temporary files). Notice how VAR is undefined both before and after the FOR execution in my code example.
This is interesting, but I'm not seeing how it is useful for exceeding the 8k limit.
Dave Benham
I'm wondering if there is a limit to the size of the command that CMD can take
Also, the environment changes that take place within the IN() clause cannot be propagated back to the parent session. (Unless of course you use temporary files). Notice how VAR is undefined both before and after the FOR execution in my code example.
This is interesting, but I'm not seeing how it is useful for exceeding the 8k limit.
Dave Benham