Page 1 of 1

problem with set and multi-line comment in macros

Posted: 15 Apr 2014 22:17
by Ed Dyreen

Code: Select all

@echo off &setlocal enableDelayedExpansion

set var=set /a ?=11<nul
set var

set var=set /a ?=1<nul
set var

set var=<nul ^
^^
^^
set /a ?=11
set var

pause
exit

Code: Select all

var=set /a ?=11
var=set /a ?=
var=set /a ?=11
Druk op een toets om door te gaan. . .
The goal is to NOT append data behind set other than intended, no spaces etc.. !
The second line is problematic, I intended to get the value 'set /a ?=1' but got 'set /a ?=' instead. DOS is seeing data for a stream. Test one shows that the obvious solution doesn't work, that's nasty. Why can't DOS be consistent in it's mis-assumptions.
'<nul' is part of a macro multi-line break as jeb introduced a while ago

I've run out of ideas, any suggestions ?

Re: problem with set and nul

Posted: 16 Apr 2014 00:18
by Magialisk
Ed I don't understand the problem you're trying to solve. When it sees the data as a stream you have to escape it:

Code: Select all

set var=set /a ?=^1<nul
set var
Of course you knew this, which is why I'm not sure where the question is :?:

You said you don't want to include any text other than intended in the set, so the other way you could do this is to quote only what you want to set:

Code: Select all

set "var=set /a ?=1"
set var
::or
set "var=set /a ?=1"<nul
set var

I run into a similar problem all the time writing files with echo, ie: 'echo 1>test.txt' ends up writing "Echo is OFF" into the file instead of the number 1. I've just gotten in the habit of escaping any single digit number next to an angle bracket thanks to too many such experiences. Double digit numbers don't have the problem of being interpreted as streams of course...

Somehow I'm positive I've completely overlooked the question though. :)

Re: problem with set and nul

Posted: 16 Apr 2014 06:31
by Ed Dyreen
Magialisk wrote:Ed I don't understand the problem you're trying to solve. When it sees the data as a stream you have to escape it:

Code: Select all

set var=set /a ?=^1<nul
set var
Of course you knew this, which is why I'm not sure where the question is :?:
Ah yes ofcourse your solution does work, but it also alters how the data is set.
Magialisk wrote:You said you don't want to include any text other than intended in the set, so the other way you could do this is to quote only what you want to set:

Code: Select all

set "var=set /a ?=1"
set var
::or
set "var=set /a ?=1"<nul
set var
The latter example is simply impossible for many macros. As it alters how the data is eventually stored.

Sorry, maybe I haven't been very clear.

The goal was to set the data using the multi-line comment style jeb suggested over the well known comment style that only allows one single empty comment line. For example:

Code: Select all

@echo off

set var=^%=    this is a single line comment, next has to be data =%
echo.^&^%=    this is a data line =%
echo.^&^%=    this is a data line =%
set /a ?=1%=    this is a data line =%
set var

set var=^%=    this is a single line comment, next has to be data =%
^%=       this is fails or alters original data line =%
^%=       this is fails or alters original data line =%
set /a ?=1%=    this is a data line =%
set var

set var=<nul ^%=this is a multi line comment, next can be data or a multi line comment=%
^^%=           this is a multi line comment, next can be data or a multi line comment=%
^^%=           this is a multi line comment, next can be data or a multi line comment=%
set /a ?=1%=    this is a data line =%
set var

set var=<nul ^%=  this is a multi line comment, next can be data or a multi line comment=%
set /a ?=1<nul ^%=this is the only known case where a multi line comment, corrupts original data=%
set /a ?=1%=    this is a data line =%
set var

pause
exit

Code: Select all

var=echo.&echo.&set /a ?=1
var=^
var=set /a ?=1
var=set /a ?=set /a ?=1
Druk op een toets om door te gaan. . .
var=set /a ?=set /a ?=1 :(
var=set /a ?=1set /a ?=1 expected
So I was hoping to figure a multi-line comment equivalent to the more common style which doesn't alter the data assignments
Magialisk wrote:I run into a similar problem all the time writing files with echo, ie: 'echo 1>test.txt' ends up writing "Echo is OFF" into the file instead of the number 1. I've just gotten in the habit of escaping any single digit number next to an angle bracket thanks to too many such experiences. Double digit numbers don't have the problem of being interpreted as streams of course...
Aha yes, that sucks :)
Magialisk wrote:Somehow I'm positive I've completely overlooked the question though. :)
The macro \n doesn't has this problem, but inserting unnecessary newlines is not ideal.
This is why I originally refused to use jeb's suggestion of ' <nul^' as it inserted a space in the data. It was then suggested using '<nul ^' to counter this and it seemed to work until this popped up.
I hope it's more clear now.

Re: problem with set and multi-line comment in macros

Posted: 16 Apr 2014 23:41
by Magialisk
Ah yes it is now much clearer what you're trying to do and what the problem was exactly. I completely overlooked the relationship to jeb's new macro commenting style.

I'm still not 100% clear on your statement about "altering how the data gets set". Adding a caret to your last failed test case does set var correctly to 'set /a ?=1set /a ?=1', but you've said that's not what you're looking for.

Code: Select all

... your original code here ...
set var=<nul ^%=  this is a multi line comment, next can be data or a multi line comment=%
set /a ?=^1<nul ^%=this is the only known case where a multi line comment, corrupts original data=%
set /a ?=1%=    this is a data line =%
set var

Code: Select all

var=echo.&echo.&set /a ?=1
var=^
var=set /a ?=1
var=set /a ?=set /a ?=1
var=set /a ?=1set /a ?=1
Press any key to continue . . .
Thus I believe what you're saying is that you'd like to find a multi-line comment style, similar to jeb's, but which does not require anything like the escape caret? In other words a "universally safe" multi-line comment style that would not affect the setting of data, regardless of the data contents?

That is certainly a challenge well above my level of expertise, maybe if you're lucky jeb will chime in and show us the "obvious" solution :lol:

Re: problem with set and multi-line comment in macros

Posted: 19 Apr 2014 07:02
by penpen
How about this:

Code: Select all

@echo off
setlocal
for %%a in ("") do ^
set var=set /a ?=1%%~a<nul ^%=this is a multi line comment, next can be data or a multi line comment=%
^^%=           this is a multi line comment, next can be data or a multi line comment=%
^^%=           this is a multi line comment, next can be data or a multi line comment=%
set /a ?=1%=    this is a data line =%
set var

:: or to use always the same syntax

for %%a in ("") do ^
set var=set /a ?=1%%~a< nul ^%=this is a multi line comment, next can be data or a multi line comment=%
%%~a< nul ^%=           this is a multi line comment, next can be data or a multi line comment=%
%%~a< nul ^%=           this is a multi line comment, next can be data or a multi line comment=%
set /a ?=1%=    this is a data line =%
set var

endlocal

penpen

Re: problem with set and multi-line comment in macros

Posted: 19 Apr 2014 13:34
by Ed Dyreen
Good thinking penpen, problem solved, thanks :D

Re: problem with set and multi-line comment in macros

Posted: 19 Apr 2014 18:16
by Magialisk
That is good thinking, nice use of a null to stop the parser from confusing digits for streams.

The only minor nitpick I'd have is that the idea behind jeb's new comment style was including comments in a macro without increasing it's size. In fact I remember reading posts where everyone was going back and forth over options that added one space per line, or even one space just at the end of the macro.

As cool as this solution is, it does add the whole "for" structure to the macro size. Not a bad trade-off for solving the problem, but I thought it should be mentioned :) Great job though!

Re: problem with set and multi-line comment in macros

Posted: 19 Apr 2014 19:10
by Ed Dyreen
Magialisk wrote:As cool as this solution is, it does add the whole "for" structure to the macro size.
While this does reduce the maximum size of a variable ( because of the maximum line read length somewhere just below 8192 characters ), the variable's size is not affected when using this 2-part comment style penpen suggests ( which was the whole point of my quest ). In theory a variable can expand 3 times it's original size if it would consist of only line feeds and had to be returned over endlocal with the current best technique we know of 'for %%? in ("!LF!") do endlocal &set "var=%var%"!' where LF would internally be represented as '%~?'. Due to this inevitable growth of macro's that need to be pushed over endlocal. They can usually contain only around 7500 characters which is well below the line read limit of 8xxx characters.

If size is an issue a generic function could be used to interpret and chain multiple macros that wouldn't fit a single macro.

Code: Select all

set ^"abstractMacro=(
   call :genericFunc specificMacro1 /arg: "value" /arg
   call :genericFunc specificMacro2 /arg: "value" /arg
)"
Thus providing a way to have any function represented as macro.

Code: Select all

:genericFunc macro args
:: (
   set macro=%~1
   set args=...
   for %%? in ( "!macro!" ) do set "macro=!%%~?!" %= retrieve specificMacro =%
   ( %macro% !args! ) %= execute specificMacro and pass args =%
:: )
exit /b %err%