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

Leading spaces in array variables

Discussion in 'Support' started by vefatica, Apr 15, 2009.

  1. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,794
    Likes Received:
    29
    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)
     
  2. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,732
    Likes Received:
    81
    vefatica 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.

    Rex Conn
    JP Software
     
  3. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,794
    Likes Received:
    29
    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. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,523
    Likes Received:
    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
     
  5. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,732
    Likes Received:
    81
    Steve Fábián wrote:


    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. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,523
    Likes Received:
    4
    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
     
  7. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,732
    Likes Received:
    81
    Steve Fábián wrote:


    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!)


    Embedded spaces are delimiters too.


    Not sure what your point is here -- are you arguing against
    compatibility with CMD?

    Rex Conn
    JP Software
     
  8. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,523
    Likes Received:
    4
    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. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,794
    Likes Received:
    29
    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. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,523
    Likes Received:
    4
    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. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,794
    Likes Received:
    29
    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. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,794
    Likes Received:
    29
    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. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,523
    Likes Received:
    4
    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. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,794
    Likes Received:
    29
    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
     

Share This Page