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

Wildcard expansion in FOR set

Discussion in 'Support' started by Christian Ullrich, Aug 20, 2012.

  1. Christian Ullrich

    Joined:
    Aug 20, 2012
    Messages:
    7
    Likes Received:
    0
    The following line works in CMD, but not in TC (14.01.33):

    Code:
    for /d %a in ("%PROGRAMFILES%\app\version??") do set APPDIR=%a
    The "app" in question has a subdirectory for every installed version, which ends in a two-digit version number. The above line is supposed to set %APPDIR% to the highest installed version.

    In TC, the wildcards are not expanded. If I replace them with an existing version number, it works.

    How do I do this in TC, or even better, is there a way to do it that will work in both CMD and TC?
     
  2. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,859
    Likes Received:
    83
    Not reproducible here; TCC expands the wildcards as expected.

    What do you see if you run:

    for /d %a in ("%PROGRAMFILES%\app\version??") do echo %a
     
  3. Christian Ullrich

    Joined:
    Aug 20, 2012
    Messages:
    7
    Likes Received:
    0
    No output at all.
     
  4. Christian Ullrich

    Joined:
    Aug 20, 2012
    Messages:
    7
    Likes Received:
    0
    Uh, I may have simplified that example a little too much. You're right, it works with %PROGRAMFILES%. It does not work with %PROGRAMFILES(x86)%. (Yes, this is the x64 build of TC.)
     
  5. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,859
    Likes Received:
    83
    TCC does not consider a '(' or ')' to be a valid variable name character, so it is terminating the name there. You can force TCC to accept the () characters either by using the %[...] syntax, or by forcing CMD-style variables (always require a trailing %) by setting "CMDVariables=Yes" in your TCMD.INI.
     
  6. Christian Ullrich

    Joined:
    Aug 20, 2012
    Messages:
    7
    Likes Received:
    0
    This would really be the perfect solution; I don't really need the single-percent syntax, and the file would still run identically in TCC and CMD. Unfortunately, it does not work. There is no item in OPTION for that (as far as I can see), adding this line to tcmd.ini [4NT] manually does not affect (a newly started) TCC ("OPTION CMDVariables" => "CMDVariables=No"), and with the line there, TC (GUI) welcomes me with 'Error on line 122 of ...\TCMD.INI: Invalid item name "CMDVariables"'.
     
  7. Frank

    Joined:
    Aug 2, 2011
    Messages:
    258
    Likes Received:
    4
    I have to draw back my post.
    Something is not working as expected here.
     
  8. Christian Ullrich

    Joined:
    Aug 20, 2012
    Messages:
    7
    Likes Received:
    0
    Note to self: Next time, make sure to put the option in the section it's meant to go. I did not notice the [TakeCommand] section header ...

    Sorry for the useless noise.
     
  9. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    You can guarantee it by the syntax below:

    %@iniwrite[%@quote[%_ininame],section,directive,value]

    which also guarantees that it will be written into the .INI file actually used by TCC.
     
  10. jwiede

    Joined:
    Jul 5, 2012
    Messages:
    21
    Likes Received:
    0
    I'm seeing something which looks vaguely similar. Given the sequence:

    for /f "tokens=3 delims=.]" %%i in ('%~dp0x86\foo.exe -v') do set _NUMBER=%%i​

    and foo.exe which returns output in format "Title [Buildcode 00.00.0000]", I want %i to wind up containing the third value of the buildcode value (e.g. '0000'). When I run the exact same sequence in cmd.exe, that is precisely what happens. However, running it in TCC.EXE what I actually get is an error, 'TCC: Unknown command "\foo.exe" ' instead.

    If I replace '%~dp0x86\foo.exe -v' with 'c:\scripts\x86\foo.exe -v' (removing the need for expansion) the sequence works as expected. Unfortunately, the script I'm really concerned with uses that type of sequence all over the place, so removing all the needs for expansion isn't practical.

    Any idea what's going on with this? It definitely seems like something is broken w.r.t. symbol expansion in certain FOR syntaxes.

    Thanks!
     
  11. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,859
    Likes Received:
    83
    TCC isn't expanding the %~dp0 construct because "0" isn't a valid FOR variable. According to the Microsoft documentation, it isn't valid in CMD either -- what do you expect it to be returning? (And where in the Windows documentation is this mentioned?)
     
  12. jwiede

    Joined:
    Jul 5, 2012
    Messages:
    21
    Likes Received:
    0
    Sorry, it's not that clear with the forum font, but that's %~dp(zero) not %~dp(letter o). The %~dp0 is a valid variable, pulling the drive and filepath from the current script that's executing.
     
  13. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,952
    Likes Received:
    30
    Rex had it right (the zero, that is). And it does seem to be a valid variable name in CMD.
    Code:
    Microsoft Windows [Version 6.1.7601]
    Copyright (c) 2009 Microsoft Corporation.  All rights reserved.
     
    v:\> set ~dp0x86=foo
     
    v:\> echo %~dp0x86%
    foo
     
    v:\>
    But not in TCC.
    Code:
    v:\> ver
     
    TCC  14.02.36  Windows 7 [Version 6.1.7601]
     
    v:\> set ~dp0x86=foo
     
    v:\> echo %~dp0x86
    ECHO is OFF
     
  14. jwiede

    Joined:
    Jul 5, 2012
    Messages:
    21
    Likes Received:
    0
    Normally the tilde expansions are only valid when called from within an executing script. The tilde expansion allows for formatted access to the executing script's command line. The d subtoken indicates drive, the p subtoken indicates filepath, the zero indicates the zeroth cmd line arg (e.g. the name of the script itself).

    So if a script file "G:\foo\bar.bat" is executing, references to %~dp0 will be expanded to "G:\foo\" (sans quotes of course). This appears to work normally in both cmd.exe and tcc.exe scripts as expected, except for the odd case inside the 'FOR /F' command in tcc.exe where it isn't being properly expanded/replaced.
     
  15. samintz

    samintz Scott Mintz

    Joined:
    May 20, 2008
    Messages:
    1,190
    Likes Received:
    11
    This working perfectly fine for me.
    foo.bat:
    Code:
    @echo on
    setlocal
    echo 'call %~dp0x86\foobar.bat -v'
    for /f "tokens=3 delims=.]" %%i in ('call %~dp0x86\foobar.bat -v') do set _NUMBER=%%i
    echo %_NUMBER
    endlocal
    
    I created an x86 subdirectory and put foobar.bat there:
    Code:
    echo Title [Buildcode 00.00.0000]
    
    And I get this result:
    Code:
    [C:\CCViews] foo
    setlocal
    echo 'call C:\CCViews\x86\foobar.bat -v'
    'call C:\CCViews\x86\foobar.bat -v'
    for /f "tokens=3 delims=.]" %%i in ('call %~dp0x86\foobar.bat -v') do set _NUMBER=%%i
    echo 0000
    0000
    endlocal
    
    Is this a CMD compatibility setting? I have both "Duplicate CMD.EXE bugs" and "CMD.EXE delayed expansion (!var!)" turned ON.

    -Scott
     
  16. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,952
    Likes Received:
    30
    I figured the '~' notation might have something to do with CMD's weird variable substitution, but found no mention of "~dp..." in the help for SET (in Win7's CMD). Where is that documented (in Windows)? Is it documented anywhere in TCC?
     
  17. samintz

    samintz Scott Mintz

    Joined:
    May 20, 2008
    Messages:
    1,190
    Likes Received:
    11
    Vince,
    It is documented under FOR and CALL.
    Code:
    cmd /c for /?
    cmd /c call /?
    
    -Scott
     
  18. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,952
    Likes Received:
    30
    Thanks, Scott. I see. And, according to your example, TCC has no problem telling that the variable ends at the '0' (and doesn't include the "x86"). That's good. As I said before, TCC has a problem with ordinary variables with such names. It'll set them but not de-reference them.
    Code:
    v:\> ver
     
    TCC  14.02.36  Windows 7 [Version 6.1.7601]
     
    v:\> set ~dp1=foo
     
    v:\> set ~*
    ~dp1=foo
     
    v:\> echo %~dp1
    ECHO is OFF
     
  19. jwiede

    Joined:
    Jul 5, 2012
    Messages:
    21
    Likes Received:
    0
    Interesting, I'll give those a try and see if either makes a difference. I'm not at work, so don't recall their settings now, but will try each and/or both and see if the scripts in question start working.

    As for tcc.exe not expanding per vefatica's comment, is that a bug then, and if so, is JPSoft able to reproduce and such can we expect a fix?

    Thanks!
     
  20. jwiede

    Joined:
    Jul 5, 2012
    Messages:
    21
    Likes Received:
    0
    Okay, just checked and while I had both "Duplicate CMD.EXE bugs" and "CMD.EXE delayed expansion" enabled, yet I'm not seeing the expected expansion here. I'm running the 64-bit version of TCC, running on W7SP1 Enterprise (if it matters).

    What I'd really like to know is whether anyone at JPSoft can replicate this expansion problem in FOR /F?
     
  21. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,859
    Likes Received:
    83
    No, it's really not a valid variable, because:

    1) It's (as far as I can tell) completely undocumented, and
    2) If it was really a valid variable, then the construct %~0 would also work in CMD (it doesn't), and
    3) No other batch argument (i.e., %~dp1) works

    So CMD is considering %~..0 to be a (undocumented) special case (either deliberately or inadvertently). I could add a (nasty) kludge to TCC to emulate that, but I'm not convinced that it's a "feature" and not a "bug".
     
  22. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,952
    Likes Received:
    30
    It is documented (CALL /?); the "1" is just a placeholder.

    Code:
    %~dp1      - expands %1 to a drive letter and path only
     
    
    And it works in CMD.

    Code:
    v:\> cmd
    Microsoft Windows [Version 6.1.7601]
    Copyright (c) 2009 Microsoft Corporation.  All rights reserved.
     
    v:\> type  dp.bat
    echo %~dp0
    echo %~dp1
     
    v:\> dp.bat q:\garbage
     
    v:\> echo v:\
    v:\
     
    v:\> echo q:\
    q:\
     
    v:\>
     
  23. WavSlave

    Joined:
    May 29, 2008
    Messages:
    47
    Likes Received:
    0
  24. JohnQSmith

    Joined:
    Jan 19, 2011
    Messages:
    559
    Likes Received:
    7
    http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/batch.mspx?mfr=true
    Then click "Using batch parameters".

    Third sentence from that page...

     
  25. Charles Dye

    Charles Dye Super Moderator
    Staff Member

    Joined:
    May 20, 2008
    Messages:
    3,307
    Likes Received:
    39
    And by an odd coincidence, it also works in TCC:

    Code:
    C:\>ver
     
    TCC  14.02.36  Windows XP [Version 5.1.2600]
     
    C:\>type dp.bat
    @echo off
    echo %~dp0
    echo %~dp1
     
    C:\>dp.bat q:\garbage
    C:\
    q:\
     
    C:\>
    
    Rex, I think you must be repressing the memory as intolerable psychological trauma -- but you really did re-engineer this CMD.EXE horror!
     
  26. JohnQSmith

    Joined:
    Jan 19, 2011
    Messages:
    559
    Likes Received:
    7
    Yeah, works for me too.
    Here's CMD
    Code:
    C:\temp>type dp.bat
    @echo off
    echo f - %~f0
    echo dpnx - %~dpnx0
     
    C:\temp>dp
    f - C:\temp\dp.bat
    dpnx - C:\temp\dp.bat
    and here's TCC
    Code:
    [C:\temp]
    10:02:29 $ dp
    f - C:\temp\dp.bat
    dpnx - C:\temp\dp.bat
     
  27. rconn

    rconn Administrator
    Staff Member

    Joined:
    May 14, 2008
    Messages:
    9,859
    Likes Received:
    83
    I'm talking about FOR variables (the original topic here), not batch variables in other commands (where it works fine in TCC). %~..n is not a valid FOR variable.
     
  28. Charles Dye

    Charles Dye Super Moderator
    Staff Member

    Joined:
    May 20, 2008
    Messages:
    3,307
    Likes Received:
    39
    Do you mean jwiede's post? His syntax also works correctly for me, in the current TCC. I think that that %_dp0 must be getting expanded before the FOR executes.
     

Share This Page