Close

Windows Batch files: "Early Evaluation"

A project log for install-avr-tools

Given Windows with some version of Arduino installed, set the paths to allow using avr-gcc/etc from the command line.

westfwWestfW 02/23/2017 at 09:541 Comment

So... I'm not really a windows person, and this was supposed to a quick and rather brute-force execution of "find all the things that look like Arduino installs, ask the user to pick one, and set their paths to include the executables from the Arduino directory tree." Straightforward and dependent more on being familiar with the various hiding places and tree structures, than on any great windows programming expertise...

But apparently, Windows puts some "interesting" issues in the way of some pretty obvious usage, and I thought I'd explain some of them...

The biggest trouble-make was something that I'll call "Early Evaluation" that affects looping. If you write a loop like:

    set wholestring=AAAA
    for %%s in (first second third forth) do (
      set wholestring=%wholestring% %%s
    )

You might expect, once you get past the weird syntax, to get a final value of the "wholestring" variable as "AAAA first second third forth" (one word appended to the variable for each word in the "for" argument.)

Nope.

The way cmd.exe evaluates this is that the body of the loop (the set statement) has variable substitution done first (except for the loop variable.) So in effect it substitutes in the initial value of wholestring four times:

    set wholestring=AAAA first
    set wholestring=AAAA second
    set wholestring=AAAA third
    set wholestring=AAAA forth

and you wind up with "AAAA forth"

How does this affect my program? Well, one of the things I want to do is loop through the list of Arduino dirs, and ask whether to use each one, sort of like:

    FOR %%f IN (%ProgramFiles%\Arduino*) DO (
      SET /P confirm="Use %%f ? [y/n]>"
      if "%confirm%"=="y" (
        GOTO gotdir
      )
    )

But %confirm% gets evaluated early in that loop as well, so it doesn't ask for each file. Well, it ASKS for each file, but for the comparison it always uses the value that %confirm% had before the first loop. Not very helpful!

Fortunately, Microsoft added a feature that they call "Delayed Expansion" to address this problem...

Discussions

penknife wrote 07/11/2018 at 10:01 point

set a=1

(

set /a a+=4

echo "%a%" "!a!"

)

  Are you sure? yes | no