Leading spaces in array variables

  • This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

rconn

Administrator
Staff member
May 14, 2008
10,210
86
#2
vefatica wrote:

> These behave (unexpectedly) differently.
>
>
> Code:
> ---------
> v:\> set foo[0]= boo
>
> v:\> echo %foo[0]
> boo (no leading space)
>
> v:\> set foo= boo
>
> v:\> echo %foo
> boo (leading space)
WAD. Leading spaces in environment variables is a *very* bad thing,
which is only there for compatibility with badly-written batch files
intended for CMD.

For array variables, I could do it the correct way.

Rex Conn
JP Software
 
#3
On Wed, 15 Apr 2009 20:00:20 -0500, rconn <> wrote:

|WAD. Leading spaces in environment variables is a *very* bad thing,
|which is only there for compatibility with badly-written batch files
|intended for CMD.
|
|For array variables, I could do it the correct way.

Got it! I was curious as usual, not complaining.
--
- Vince
 
#4
rconn wrote:
| vefatica wrote:
|
|
| ---Quote---
|| These behave (unexpectedly) differently.
||
||
|| Code:
|| ---------
|| v:\> set foo[0]= boo
||
|| v:\> echo %foo[0]
|| boo (no leading space)
||
|| v:\> set foo= boo
||
|| v:\> echo %foo
|| boo (leading space)
| ---End Quote---
| WAD. Leading spaces in environment variables is a *very* bad thing,
| which is only there for compatibility with badly-written batch files
| intended for CMD.
|
| For array variables, I could do it the correct way.

Why are space characters in character data different from other characters?
I often build lines of a vertically aligned table by adding leading and
trailing spaces piecemeal. Environment and array variables ought to be
behave in the same manner as "string variables" in Basic...
--
Steve
 

rconn

Administrator
Staff member
May 14, 2008
10,210
86
#5
Steve Fábián wrote:


> Why are space characters in character data different from other characters?
> I often build lines of a vertically aligned table by adding leading and
> trailing spaces piecemeal. Environment and array variables ought to be
> behave in the same manner as "string variables" in Basic...
Space characters are delimiters, and there is no chance that I'm going
to break every batch file in existence in order to make the syntax like
BASIC.

There are (several) existing ways to put space chars in your variables
that don't require breaking compatibility (one of your pet peeves, as I
recall!).

Rex Conn
JP Software
 
#6
rconn wrote:
| Steve Fábián wrote:
|
|
|
| ---Quote---
|| Why are space characters in character data different from other
|| characters? I often build lines of a vertically aligned table by
|| adding leading and trailing spaces piecemeal. Environment and array
|| variables ought to be behave in the same manner as "string
|| variables" in Basic...
| ---End Quote---
| Space characters are delimiters, and there is no chance that I'm going
| to break every batch file in existence in order to make the syntax
| like BASIC.
|
| There are (several) existing ways to put space chars in your variables
| that don't require breaking compatibility (one of your pet peeves, as
| I recall!).

The OP's issue here was that array variables cannot have leading spaces,
while environment variables can. To me that's a compatibility issue. If I
need the possibility of leading space in a variable in an application, I
cannot use an array variable for that case, even if that's the convenient
one. I have to revert to pseudoarrays of environment variables. Since arrays
are new in V10, and the impossibility of an array element value to have
leading spaces is not documented, changing the behavior of SET to be
independent of the type of variable to be set would create more
compatibility, not less.

Why is a leading space character a delimiter, but an embedded space
character data?

Furthermore, to make space characters delimiters in a command line does not
require them to be made delimiters in data. The biggest problem (introduced
by Microsoft 30 years ago when they defined the syntax for COMMAND.COM 1.0)
is the lack of clear disambiguation between data and command.
--
Steve
 

rconn

Administrator
Staff member
May 14, 2008
10,210
86
#7
Steve Fábián wrote:


>
> The OP's issue here was that array variables cannot have leading spaces,
> while environment variables can. To me that's a compatibility issue. If I
> need the possibility of leading space in a variable in an application, I
> cannot use an array variable for that case, even if that's the convenient
> one. I have to revert to pseudoarrays of environment variables. Since arrays
> are new in V10, and the impossibility of an array element value to have
> leading spaces is not documented, changing the behavior of SET to be
> independent of the type of variable to be set would create more
> compatibility, not less.
The OP didn't *want* leading spaces, he just noticed a difference.

The only compatibility issue would be if you were trying to use array
variables in a CMD batch file, which isn't possible.

IMO this is an imaginary issue, not a real one. Since you didn't notice
any problem for 8 months (and not until somebody else mentioned it),
it's unlikely that it's a critical issue for you. (Particularly since
there are several well known and documented workarounds if you were
actually deranged enough to want to do this!)


> Why is a leading space character a delimiter, but an embedded space
> character data?
Embedded spaces are delimiters too.


> Furthermore, to make space characters delimiters in a command line does not
> require them to be made delimiters in data. The biggest problem (introduced
> by Microsoft 30 years ago when they defined the syntax for COMMAND.COM 1.0)
> is the lack of clear disambiguation between data and command.
Not sure what your point is here -- are you arguing against
compatibility with CMD?

Rex Conn
JP Software
 
#8
rconn wrote:
| Steve Fábián wrote:
| ---Quote---
|| The OP's issue here was that array variables cannot have leading
|| spaces, while environment variables can. To me that's a
|| compatibility issue. If I need the possibility of leading space in a
|| variable in an application, I cannot use an array variable for that
|| case, even if that's the convenient one. I have to revert to
|| pseudoarrays of environment variables. Since arrays are new in V10,
|| and the impossibility of an array element value to have leading
|| spaces is not documented, changing the behavior of SET to be
|| independent of the type of variable to be set would create more
|| compatibility, not less.
| ---End Quote---
| The OP didn't *want* leading spaces, he just noticed a difference.
|
| The only compatibility issue would be if you were trying to use array
| variables in a CMD batch file, which isn't possible.

You do not consider (as yet undocumented) different behavior of SET
depending on the type of variable it operates on a compatibility issue?
Consider the following batch program:
set %1=%@line[%2,0]
echo %1="%[%1]"
If the value to which variable %1 is set depends on its type (array element
vs. environment) if the first line of file %2 has leading white space I
think we have a compatibility issue. Not compatiblity with other programs
(e.g. CMD), but within TCC. The issue exists with SET, INKEY and INPUT, none
of which will set an array element to have leading space, and all of which
can set at environment variable to have leading space.
|
| IMO this is an imaginary issue, not a real one. Since you didn't
| notice any problem for 8 months (and not until somebody else
| mentioned it),
| it's unlikely that it's a critical issue for you. (Particularly since
| there are several well known and documented workarounds if you were
| actually deranged enough to want to do this!)

I need to confess that while I was one of the requestors of array variables,
I had not started using them. I did some testing early in the beta phase,
but I had trouble installing many of the later builds of V10 (due to MS
software behaving differently than documented, and which you solved), and
had been busy with other tasks, so I kept using V9 for produciton work when
arrays would have been much more convenient, but I already had working
solutions without them. Vince's discovery makes it less likely that now,
when I need to modify my batch programs I would rebuild them with arrays.

What methods are available to set an array element to have one or more
leading space characters?
|
| ---Quote---
|| Why is a leading space character a delimiter, but an embedded space
|| character data?
| ---End Quote---
| Embedded spaces are delimiters too.

If so, why does
set a[0]=z z ``
work (the value, quoted, is "z z "), but
set a[0]=`` z z ``
result in the same value?

| ---Quote---
|| Furthermore, to make space characters delimiters in a command line
|| does not require them to be made delimiters in data. The biggest
|| problem (introduced by Microsoft 30 years ago when they defined the
|| syntax for COMMAND.COM 1.0) is the lack of clear disambiguation
|| between data and command.
| ---End Quote---
| Not sure what your point is here -- are you arguing against
| compatibility with CMD?

My first sentence relates to interpreting information. All programs contain
both commands and data. Most programming languages, whether they are
designed exclusively to be interpreted only, or designed to be compiled only
for future execution, or both, observe a dichotomy: some parts of the
program are commands on what to do, and other parts of the program are data
to be processed. Once the parser determined that some sequence of characters
is a datum, e.g. whatever follows the equal sign = in a SET command
(including command line continuations, but excluding such datum terminations
as unescaped symbols for redirection, piping, command separation, etc.)
delimiters used to separate command line tokens ought not to be used within
the datum (string).

My second sentence blames MS on muddling the clear dichotomy, allowing such
constructs in TCC as
for %x in (alias function set) for %z in (*.%@left[3,%x]) %x /r %z
which is a convenient, but unnecessary shorthand for writing three separate
commands. It may reduce the size of a batch file, but increase the time of
its execution (unless you still have a floppy disk from which to run it).
--
Steve
 
#9
On Thu, 16 Apr 2009 11:00:34 -0500, Steve Fábián <> wrote:

|What methods are available to set an array element to have one or more
|leading space characters?

I didn't think it was a big deal. These seem to work:

set foo[0]=%%@char[32]bar

set foo[0]=%%@repeat[%@char[32],5]bar
--
- Vince
 
#10
vefatica wrote:
| On Thu, 16 Apr 2009 11:00:34 -0500, Steve Fábián <> wrote:
|
|| What methods are available to set an array element to have one or
|| more leading space characters?
|
| I didn't think it was a big deal. These seem to work:
|
| set foo[0]=%%@char[32]bar
|
| set foo[0]=%%@repeat[%@char[32],5]bar

This works even for @clip[] and @line[] defining data with leading tab or
space. I found out that @FILEARRAY also delivers leading and trailing spaces
and tabs.

How did you happen upon the doubling of the first percent sign?

Rex, while I maintain that INKEY, INPUT and SET ought to behave identically
whether they set an array element or an environment variable, and Vince's
examples ought not to require doubling the percent sign %, I think that my
expected usage of arrays can live with those limitations.

Vince, please make sure that your @PARSE functions insert the leading and
trailing whitespace. I have a temporary download problem (see my other post,
to follow this one very shortly).
--
Steve
 
#11
On Thu, 16 Apr 2009 12:27:20 -0500, Steve Fábián <> wrote:

|| set foo[0]=%%@char[32]bar
||
|| set foo[0]=%%@repeat[%@char[32],5]bar
|
|This works even for @clip[] and @line[] defining data with leading tab or
|space. I found out that @FILEARRAY also delivers leading and trailing spaces
|and tabs.
|
|How did you happen upon the doubling of the first percent sign?

It's a pretty standard way to delay the actual insertion of the characters. I
can't say exactly when it will/won't be effective.
--
- Vince
 
#12
On Thu, 16 Apr 2009 12:27:20 -0500, Steve Fábián <> wrote:

|Vince, please make sure that your @PARSE functions insert the leading and
|trailing whitespace. I have a temporary download problem (see my other post,
|to follow this one very shortly).

I can't make @PARSEF preserve leading **space** delimiters because I use @FIELDS
and I don't think there's a way to make @FIELDS do that.
--
- Vince
 
#13
vefatica wrote:
| On Thu, 16 Apr 2009 12:27:20 -0500, Steve Fábián <> wrote:
|
|| Vince, please make sure that your @PARSE functions insert the
|| leading and trailing whitespace. I have a temporary download problem
|| (see my other post, to follow this one very shortly).
|
| I can't make @PARSEF preserve leading **space** delimiters because I
| use @FIELDS and I don't think there's a way to make @FIELDS do that.

If space is not a delimiter, i.e. an explicit delimiter list not including
space is specified, both @FIELD and @WORD preserve leading and trailing
spaces. It's the assignment to the array element that must also preserve
them.
--
Steve
 
#14
On Thu, 16 Apr 2009 18:51:18 -0500, Steve Fábián <> wrote:

|vefatica wrote:
|| On Thu, 16 Apr 2009 12:27:20 -0500, Steve Fábián <> wrote:
||
||| Vince, please make sure that your @PARSE functions insert the
||| leading and trailing whitespace. I have a temporary download problem
||| (see my other post, to follow this one very shortly).
||
|| I can't make @PARSEF preserve leading **space** delimiters because I
|| use @FIELDS and I don't think there's a way to make @FIELDS do that.
|
|If space is not a delimiter, i.e. an explicit delimiter list not including
|space is specified, both @FIELD and @WORD preserve leading and trailing
|spaces. It's the assignment to the array element that must also preserve
|them.

Here's another one that preserves leading spaces at the command line (again it's
delayed parsing, I think):

set foo[0]=^` abc^`

echo **%foo[0]**
** abc**

I can do exactly that when I create the SET command line used internally to set
the array element. It looks like this:

for ( DWORD i=0; i<dwFieldCount; i++ )
{
// get the field by expanding @FIELD[]
Sprintf(szExpandString, L"%%@FIELD[\"%s\",%d,%s]", pDelims, i, str);
ExpandVariables(szExpandString, 1);

// call SET to set the array variable
Sprintf(szCommand, L"SET %s[%d]=^`%s^`", pArrayName, i, szExpandString);
Command(szCommand, 0);
}

I haven't considered the implications.

I put this newest one on lucky.syr.edu.

So, for example,

echo %@parsef[".",foo,. a. b. c]
4

for /l %i in (0,1,3) echo ##%foo[%i]##
####
## a##
## b##
## c##

OTOH, it would make sense for Rex to change the behavior of "SET ARRAY=" to
preserve everything. @FIELD gives the field correctly; the user should be able
to move that string around without worrying about losing part if it. It would
also make SET's behavior consistent (a good end in itself). I don't think CMD's
behavior is all that dumb.
--
- Vince