Is there a way to create a SUB without using a temp file ?

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: Is there a way to create a SUB without using a temp file

#16 Post by jeb » 31 Jan 2012 03:20

aGerman wrote:There is no COPY without a resulting file :? Unfortunately I have no further idea.

What's with :?:

Code: Select all

copy /a nul+nul CON

The only bad thing is that CON is a text device that stops at the first CTRL-Z, so I can't get the output with a FOR-Loop :?

dbenham wrote:within a batch file functions like a cross between white space and a command concatenation operator :shock:
But it doesn't play nicely with FOR /F

Somewhere, sometimes I posted it, but as always I can't find it anymore.

The rule for SUB is:
The batch-parser substitutes a SUB character with a single linefeed character, but only after the read phase, before the percent expansion phase begins :!:
This seems to be the only thing that happens there, even the CR is removed later.

So the normal rules of the linefeed are active here.

Code: Select all

@echo off
echo oneecho two
set MultiLine^

var=content
set multi
echo ##%MultiLine^Var%


jeb

Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: Is there a way to create a SUB without using a temp file

#17 Post by Squashman » 31 Jan 2012 07:04

jeb wrote:

Code: Select all

copy /a nul+nul CON

The only bad thing is that CON is a text device that stops at the first CTRL-Z, so I can't get the output with a FOR-Loop :?

That was one of the first things I tried as well. Also tried LPT1. But that seems to work the same way as CON.
I even thought that maybe copying nul to a folder name would work. It doesn't error out but doesn't do anything either.
copy /a nul+nul MyFolder

Liviu
Expert
Posts: 470
Joined: 13 Jan 2012 21:24

Re: Is there a way to create a SUB without using a temp file

#18 Post by Liviu » 31 Jan 2012 11:47

dbenham wrote:You are using XP sp3 yes?

I can confirm XP Home Edition sp3, as well as Vista Home Premium sp2 64bit, and Vista 32 bit (not sure about specifics)

How about you aGerman? (or anyone else) Anyone have Windows 7 covered?

Yes, xp sp3, and also verified it to work in win7 pro x64.

FWIW I'd be surprised if it changed now, since MS generally promotes old enough bugs to "legacy feature" status ;-) and the ^Z behavior appears to date back to at least NT 3.51...

http://support.microsoft.com/kb/156258 wrote:The command prompt (Cmd.exe) in Windows NT does not recognize the end-of- file character (0x1A) in batch and text files.

Specifically, batch files do not cease execution upon encountering the end-of-file character, nor does the TYPE command stop displaying text when it encounters the end-of-file character.

Should be noted that the "type" command has been fixed since, while the batch part was left untouched.

jeb wrote:The only bad thing is that CON is a text device that stops at the first CTRL-Z

Mostly yes. One exception is that "set /p" at the interactive prompt gets ^Z characters fine (except at the end of the line, as noted) and it's presumably using the same CON device for input.

Liviu

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Is there a way to create a SUB without using a temp file

#19 Post by aGerman » 31 Jan 2012 14:42

dbenham wrote:How about you aGerman? (or anyone else) Anyone have Windows 7 covered?

Confirmed: Win7 x86
Thanks for the great example btw.

jeb wrote:What's with :?:

Code: Select all

copy /a nul+nul CON

Oh. I didn't try that :oops: My luck that it doesn't work in this case :|

Regards
aGerman

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Is there a way to create a SUB without using a temp file

#20 Post by dbenham » 31 Jan 2012 20:07

jeb wrote:The rule for SUB is:
The batch-parser substitutes a SUB character with a single linefeed character, but only after the read phase, before the percent expansion phase begins :!:
This seems to be the only thing that happens there, even the CR is removed later.

So the normal rules of the linefeed are active here.

Code: Select all

@echo off
echo oneecho two
set MultiLine^

var=content
set multi
echo ##%MultiLine^Var%

jeb

That explains everything :D

I don't see what your last ECHO ## example proves - it produces "##MultiLineVar".

I can only guess you intended to put something like the following that demonstrates that the Ctrl-Z is converted into a <LF>

Code: Select all

@echo off
setlocal enableDelayedExpansion
set MultiLine^

var=content
set multi
echo(
echo show value using ^<LF^>
echo ##!MultiLine^

Var!

echo(
echo show value using Ctrl-Z
echo ##!MultiLine^Var!

It produces

Code: Select all

MultiLine
var=content

show value using <LF>
##content

show value using Ctrl-Z
##content


Dave Benham

jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: Is there a way to create a SUB without using a temp file

#21 Post by jeb » 01 Feb 2012 00:41

dbenham wrote:I don't see what your last ECHO ## example proves - it produces "##MultiLineVar".

I can only guess you intended to put something like the following that demonstrates that the Ctrl-Z is converted into a <LF>

:D Yes, I didn't test it anymore, it should show that <SUB> is converted into <LF>
And it should also show that <SUB> is only converted while reading the line, but not in one of the later phases.

jeb

jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: Is there a way to create a SUB without using a temp file

#22 Post by jeb » 01 Feb 2012 14:08

And another "proof"

Code: Select all

set AlsoLinefeed=^<SUB><SUB>

It's the same as a normal Linefeed

jeb

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Is there a way to create a SUB without using a temp file

#23 Post by aGerman » 01 Feb 2012 15:06

Thanks jeb :!: I already fiddled with it.

Code: Select all

set ^"\n=^^^^^^^^^"

That makes things easier for macros and it protects you from the critical empty lines for a line feed character.

Regards
aGerman

Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: Is there a way to create a SUB without using a temp file

#24 Post by Squashman » 01 Feb 2012 21:41

Anyone think it could be possible to use Debug to get the SUB character into a variable? Of course this would only work on 32bit Windows.

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Is there a way to create a SUB without using a temp file

#25 Post by aGerman » 02 Feb 2012 15:29

Squashman wrote:Anyone think it could be possible to use Debug to get the SUB character into a variable?
Assembly is not my cup of tea. I hope there is no fault ...

Code: Select all

@echo off &setlocal
if not exist sub.com (
  >sub.asm (
    echo(a 100
    echo(mov dl, 1A
    echo(mov ah, 2
    echo(int 21
    echo(int 20
    echo(
    echo(rcx
    echo(8
    echo(n sub.com
    echo(w
    echo(q
  )
  start "" /min /wait cmd /c "debug<sub.asm"
  del sub.asm
)
for /f %%i in ('sub.com') do set "sub=%%i"
echo This%sub%works.
pause

Regards
aGerman

Liviu
Expert
Posts: 470
Joined: 13 Jan 2012 21:24

Re: Is there a way to create a SUB without using a temp file

#26 Post by Liviu » 03 Feb 2012 19:30

aGerman wrote:I wonder if it could be useful ...

On a tangent, I wonder if the following would be considered fair game for a Quine attempt...

Code: Select all

@setlocal=enableExtensions,enableDelayedExpansion&set/pq=<"%~f0"&echo(!q!
Even shorter if "cmd /e:on /v:on" is assumed, of course.

aGerman wrote:

Code: Select all

set ^"\n=^^^^^^^^^"

That makes things easier for macros and it protects you from the critical empty lines for a line feed character.

Right, but also introduces ^Z control characters down the file.

I was hoping for an alternative to confine control characters to just the top line, so as to leave the rest of the file "plain printable ascii". Haven't found the right incantation to do it without a "critical empty line" though.

Code: Select all

::     @rem
::*         *               *
::70000000007000001111111111711111 1 0x
::F123456789FBCDEF0123456789FBCDEF A

@set /p "ctrlChrs=" <"%~f0"
@setlocal enabledelayedexpansion

@set ctrlChrs=!ctrlChrs:~2,10!^

!ctrlChrs:~13,15!^
!ctrlChrs:~35,1!^
!ctrlChrs:~29,5!

@echo !ctrlChrs!

Note that the first line won't copy/paste nicely, since browsers and editors differ in their handling of control characters within text. Lines 3 and 4 list the actual character codes supposed to go into the saved batch file (7F, 01, 02, etc).

Once saved and run, the screen output is useless (again, because of the control characters), but redirecting >somefile should look like this in a hex viewer...

Code: Select all

00000000  7F 01 02 03  04 05 06 07  08 09 0A 0B  0C 0D 0E 0F  ☺☻♥♦♣♠•◘○◙♂♀♪♫
00000010  10 11 12 13  14 15 16 17  18 19 1A 1B  1C 1D 1E 1F  ►◄↕‼¶§▬↨↑↓→←∟↔▲
00000020  0D 0A                                               ♪◙

...and prove that the "ctrlChrs" variable does indeed hold the 1..31 range of ASCII control codes (code 0 is NUL which can't really be handled, and is replaced with 0x7F DEL here). So, !ctrlChrs:~n,1! is the respective character for n=1..31 and could be used as such for the remainder of the batch file.

Liviu

Post Reply