carlos-montiers / enhancedbatch

Enhances your windows command prompt https://www.enhancedbatch.com
Other
5 stars 1 forks source link

modified echo behavior bug or documentation error #44

Open DaveBenham opened 4 years ago

DaveBenham commented 4 years ago

Not sure if this is an implementation bug, or a documentation error.

I cannot get ECHO~"Should be printed without quotes" to work. I get an error saying

'ECHO~"Should be printed without quotes"' is not recognized as an internal or external command, operable program or batch file."

The dequote feature does work if I also use the no newline feature, as in `ECHO;~"This does print without quotes"

I can get the dequote feature to work with newline if I use ECHO(~"This also prints without quotes"

I'm torn as to what should happen if you attempt to use dequote without any quotes. Currently if I do ECHO;~No quotes I get ~No quotes - the tilde is printed.

But I am leaning toward thinking that ECHO;~"No quotes" and ECHO;~No quotes should give the same result of No quotes. But I think there are pros and cons for both.

I also cannot get the "String Spread" feature to work at all. It doesn't even make sense as written. But none of the variations I tried worked either.

Finally, I'm not sure the @echooptions extension is needed, given that both ECHO( and ECHO(~ work just fine, and provide the same functionality. The problem with @echooptions is it could cause problems with other scripts if you load EB at the command prompt level and leave @echooptions set to no when you exit your script.

DaveBenham commented 4 years ago

OK, I just realized that the first issue must be a documentation mistake. I just figured out that
ECHO ~"This prints without quotes" also works. So the documentation is just missing the space.

But the more I think about this feature, the less comfortable I become. I might like it better if the ECHO dequote feature could be enabled or disabled.

adoxa commented 4 years ago

Oh, that's strange. I think I originally did it without space, because that worked on the command line, but then I had to add the space because it didn't work in a batch. Now I find spaceless doesn't work on either. With call @echo there's no real need to have it at all and might be better to remove it.

"String spread" is not specific to ECHO, it works at the file level (so won't work on the command line at all). It is used to allow splitting a quoted string across multiple lines, something normal caret continuation can't do.

Echo options is needed so @echo off still works when you call another batch.

carlos-montiers commented 4 years ago

I also thinked that now with call @echo the echo modifications features is better remove for clean code, but I avoided propose that because was hard get the offsets. i think the echo options is still useful. What about create an shortcut version call @e ?

DaveBenham commented 4 years ago

Oh yes, much better to use call @echo and eliminate the echo patches.

And yes, it would be good to have some way of specifying no newline with call @echo, and also the ability to perform a dequote operation (eliminate enclosing quotes if they exist)

I suppose you could have slightly different versions of the command, but there are 4 permutations.

What do you think of using call @write instead of call @echo, so there is no confusion with the normal ECHO command? Especially no confusion with the ubiquitous @echo off.

We could then use

The dequote versions should recognize "" within the quoted string as a single " literal.

DaveBenham commented 4 years ago

Or we could stipulate that the argument must always be quoted, so we would have just

Still internal "" would be recognized as a single " literal.

adoxa commented 4 years ago

It's a call, so normal argument rules apply.

> call @echo "one two"
one two
> call @echo    one     two    
one two

Option /N removes the newline.

I don't like @e; @write might indeed be better, to reinforce arguments, not string.

DaveBenham commented 4 years ago

OK. I'm beginning to understand the normal argument rules.

But I believe there is a bug:

call @echo /n "hello world" prints hello world without newline. All well and good.

But call @echo "/n hello world" prints nothing with newline, while I think it should print the literal string /n hello world.

adoxa commented 4 years ago

It's the option /n hello world, which is silently ignored. Use // to stop option processing to output strings starting with /.

carlos-montiers commented 4 years ago

@adoxa What about implement: https://github.com/carlos-montiers/enhancedbatch/issues/44#issuecomment-573968282 Maybe we can also include a new extension option for set the new line character: lf or crlf (default).

DaveBenham commented 4 years ago

call @echo already defaults to CRLF ending, with /U option for LF and /N option for no terminator.

DaveBenham commented 4 years ago

The arguments to call @someCommand are parsed with CommandLineToArgvW - It is absolute crap.

The escape rules are awful, and I think they may also vary depending on the Windows version.

Trying to understand how " "" \\ \" and \\" are interpreted is very difficult. Add in the CMD.EXE parser phase 2 that occurs before hand, and the difficulty is compounded. Then add in the @echo /E option and all hell breaks loose.

Can we please replace CommandLineToArgvW with some other routine, perhaps one that we write ourselves. Tokens (arguments) should be delimited by one or more white space until the first " is encountered, at which point white space is preserved within a token. The quote state remains on until the next lone ", which turns it off and is stripped from the argument. In between (within the quotes), any "" is interpreted as a " literal which is included in the argument and does not change the quote state.

This would play extremely well with CMD.EXE phase 2 parsing, is easy to understand in practice, and doesn't complicate the @echo /E option.

If need be I can try to write a routine, but my C skills are very rusty.

adoxa commented 4 years ago

If we do our own I'll parse strings the same way as I intend to do default variables. I'm thinking of adding # and * as tokens outside the string. # followed by decimal digits, or #x followed by hexadecimal digits, would be a character code; * followed by decimal digits would repeat the string. Single quotes and double quotes would be interchangeable, drop support for back quotes (might be useful for something else). E.g. "abcdef"#13#10'-='*3 is equivalent to the C string "abcdef\r\n-=-=-=".