Issues remembering a variables state

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
zxuiji
Posts: 3
Joined: 05 May 2016 10:13

Issues remembering a variables state

#1 Post by zxuiji » 05 May 2016 10:26

First here is my code:

Code: Select all

@echo on
@setlocal EnableDelayedExpansion

for /f "tokens=*" %%L in (.git/logs/HEAD) do (
   set VAR = "%TWO%"
   set TWO = %%L
   if "%%L" == "" (
      for /f "tokens=5* delims= " %%I in (%VAR%) do (
         set VONE = %VTWO%
         set VTWO = %%I
         if "%%I" == "" echo (
            "#include \"CoditBuild.h\""
            "unsigned long CODIT_COMMIT = %VONE%;"
         ) >src/CoditCommit.c
      )
   )
)

@endlocal
:exit

And here is my output:

Code: Select all


p:\Git\Codit>test.bat

p:\Git\Codit>for /F "tokens=*" %L in (.git/logs/HEAD) do (
set VAR = echo ""
 set TWO = %L
 if "%L" == "" (for /F "tokens=5* delims= " %I in ((null)) do (
set VONE = echo
 set VTWO = %I
 if "%I" == "" echo (
 "#pragma once"
 "#define CODIT_COMMIT "
) 1>CoditCommit.h )
)

p:\Git\Codit>(
set VAR = echo ""
 set TWO = 0000000000000000000000000000000000000000 9b67a08ea9bd212d54da1ab734fa3d6c16d322eb
 if "0000000000000000000000000000000000000000 9b67a08ea9bd212d54da1ab734fa3d6c16d322eb" == "" (for /F "tokens=5* delims= " %I in ((null)) do (
set VONE = echo
 set VTWO = %I
 if "%I" == "" echo (
 "#pragma once"
 "#define CODIT_COMMIT "
) 1>CoditCommit.h )
)

p:\Git\Codit>(
set VAR = echo ""
 set TWO = 9b67a08ea9bd212d54da1ab734fa3d6c16d322eb 1b0e2957938511dc6a4be0e0becd66cffa316a8c
 if "9b67a08ea9bd212d54da1ab734fa3d6c16d322eb 1b0e2957938511dc6a4be0e0becd66cffa316a8c" == "" (for /F "tokens=5* delims= " %I in ((null)) do (
set VONE = echo
 set VTWO = %I
 if "%I" == "" echo (
 "#pragma once"
 "#define CODIT_COMMIT "
) 1>CoditCommit.h )
)

p:\Git\Codit>(
set VAR = echo ""
 set TWO = 1b0e2957938511dc6a4be0e0becd66cffa316a8c c6091e54e32bbaa689a54486f74bce6fd71663c2
 if "1b0e2957938511dc6a4be0e0becd66cffa316a8c c6091e54e32bbaa689a54486f74bce6fd71663c2" == "" (for /F "tokens=5* delims= " %I in ((null)) do (
set VONE = echo
 set VTWO = %I
 if "%I" == "" echo (
 "#pragma once"
 "#define CODIT_COMMIT "
) 1>CoditCommit.h )
)

p:\Git\Codit>(
set VAR = echo ""
 set TWO = c6091e54e32bbaa689a54486f74bce6fd71663c2 fe55dde7818b97e3728d066bf3a9cb2060262ee0
 if "c6091e54e32bbaa689a54486f74bce6fd71663c2 fe55dde7818b97e3728d066bf3a9cb2060262ee0" == "" (for /F "tokens=5* delims= " %I in ((null)) do (
set VONE = echo
 set VTWO = %I
 if "%I" == "" echo (
 "#pragma once"
 "#define CODIT_COMMIT "
) 1>CoditCommit.h )
)
p:\Git\Codit>

Not sure how dangerous it is to leave some bits of the variable contents in there so just removed them for safety's sake.

As anyone paying proper attention would have noticed by now the variables trying to capture the previous line/token are not receiving their input and since I rarely delve into batch I do not understand what I've done wrong, could someone help me understand (and if they feel like it provide a Linux & OSX alternative since I will make ones for those as well)

Squashman
Expert
Posts: 4488
Joined: 23 Dec 2011 13:59

Re: Issues remembering a variables state

#2 Post by Squashman » 05 May 2016 10:53

You have delayed expansion enabled but you are not referencing the variables correctly. When you change a variable inside a code block and need to reference that variable again, you need to use exclamation points instead of percent symbols.

%var%
becomes
!var!

Also, do not use spaces when using the SET and IF commands.

Follow this as a best practice.

Code: Select all

set TWO=%%L
if "%%L"==""

zxuiji
Posts: 3
Joined: 05 May 2016 10:13

Re: Issues remembering a variables state

#3 Post by zxuiji » 05 May 2016 11:39

Tried various ways but failed to get what I'm seeking, my latest attempt looks like this:

Code: Select all

@echo on
@setlocal EnableDelayedExpansion

for /f "tokens=*" %%L in (.git/logs/HEAD) do (
   set VAR=!TWO!
   set TWO=%%L
   if "%%L"=="" (
      for /f "tokens=5* delims= " %%I in ("!VAR!") do (
         set VONE=%VTWO%
         set VTWO=%%I
         if "%%I"=="" echo (
            "#include \"CoditBuild.h\""
            "unsigned long CODIT_COMMIT = !VONE!;"
         ) >src/CoditCommit.c
      )
   )
)

@endlocal
:exit

resulting in this:

Code: Select all


p:\Git\Codit>test.bat

p:\Git\Codit>for /F "tokens=*" %L in (.git/logs/HEAD) do (
set VAR=!TWO!
 set TWO=%L
 if "%L" == "" (for /F "tokens=5* delims= " %I in ("!VAR!") do (
set VONE=
 set VTWO=%I
 if "%I" == "" echo (
 "#include \"CoditBuild.h\""
 "unsigned long CODIT_COMMIT = !VONE!;"
) 1>src/CoditCommit.c )
)

p:\Git\Codit>(
set VAR=!TWO!
 set TWO=0000000000000000000000000000000000000000 9b67a08ea9bd212d54da1ab734fa3d6c16d322eb
 if "0000000000000000000000000000000000000000 9b67a08ea9bd212d54da1ab734fa3d6c16d322eb" == "" (for /F "tokens=5* delims= " %I in ("!VAR!") do (
set VONE=
 set VTWO=%I
 if "%I" == "" echo (
 "#include \"CoditBuild.h\""
 "unsigned long CODIT_COMMIT = !VONE!;"
) 1>src/CoditCommit.c )
)

p:\Git\Codit>(
set VAR=!TWO!
 set TWO=9b67a08ea9bd212d54da1ab734fa3d6c16d322eb 1b0e2957938511dc6a4be0e0becd66cffa316a8c
 if "9b67a08ea9bd212d54da1ab734fa3d6c16d322eb 1b0e2957938511dc6a4be0e0becd66cffa316a8c" == "" (for /F "tokens=5* delims= " %I in ("!VAR!") do (
set VONE=
 set VTWO=%I
 if "%I" == "" echo (
 "#include \"CoditBuild.h\""
 "unsigned long CODIT_COMMIT = !VONE!;"
) 1>src/CoditCommit.c )
)

p:\Git\Codit>(
set VAR=!TWO!
 set TWO=1b0e2957938511dc6a4be0e0becd66cffa316a8c c6091e54e32bbaa689a54486f74bce6fd71663c2
 if "1b0e2957938511dc6a4be0e0becd66cffa316a8c c6091e54e32bbaa689a54486f74bce6fd71663c2" == "" (for /F "tokens=5* delims= " %I in ("!VAR!") do (
set VONE=
 set VTWO=%I
 if "%I" == "" echo (
 "#include \"CoditBuild.h\""
 "unsigned long CODIT_COMMIT = !VONE!;"
) 1>src/CoditCommit.c )
)

p:\Git\Codit>(
set VAR=!TWO!
 set TWO=c6091e54e32bbaa689a54486f74bce6fd71663c2 fe55dde7818b97e3728d066bf3a9cb2060262ee0
 if "c6091e54e32bbaa689a54486f74bce6fd71663c2 fe55dde7818b97e3728d066bf3a9cb2060262ee0" == "" (for /F "tokens=5* delims= " %I in ("!VAR!") do (
set VONE=
 set VTWO=%I
 if "%I" == "" echo (
 "#include \"CoditBuild.h\""
 "unsigned long CODIT_COMMIT = !VONE!;"
) 1>src/CoditCommit.c )
)

Any chance you could post what you think the could should look like? I can try that, see if it works and if it does I'll keep it as a reference to better understand what I'm actually doing wrong. Oh I should mention I'm running on Win10 x64 if that has any effect.

zxuiji
Posts: 3
Joined: 05 May 2016 10:13

Re: Issues remembering a variables state

#4 Post by zxuiji » 25 Jul 2016 13:16

Only just remembered this, I eventually solved it I think (been quite a a while since I looked at the code), here's my incasing makefile statement using the shell code:

Code: Select all

COMMIT_LOG_PATH:=$(TOP_DIR).git$(HOST_DIR_SEP)logs$(HOST_DIR_SEP)HEAD
COMMIT_LOG_COUNT_STR:=$(shell find /c " +" $(COMMIT_LOG_PATH))
# % ignores case so we don't need to go out of our way to convert our path to
# uppercase however it only works in patsubst which ignores the ----------
# before the path so we get subst to remove the left over leaving the number we
# wanted
COMMIT_LOG_COUNT:=$(subst ---------- ,,$(patsubst %:,,$(COMMIT_LOG_COUNT_STR)))
COMMIT_LOG_FROM_LINE:=$(call sh_math,$(COMMIT_LOG_COUNT) - 1)
COMMIT_LOG_LAST_LINE:=$(shell more +$(COMMIT_LOG_FROM_LINE) $(COMMIT_LOG_PATH))
COMMIT_LOG_DATE_TIME:=$(or $(word 5,$(COMMIT_LOG_LAST_LINE)),0)

Granted this doesn't do it via pure DOS but it acheived what I needed it for, if someone figures out how to do it via pure DOS just pop it in the next reply for everyones reference but otherwise I won't be revisting this topic any time soon

Squashman
Expert
Posts: 4488
Joined: 23 Dec 2011 13:59

Re: Issues remembering a variables state

#5 Post by Squashman » 25 Jul 2016 13:25

You need to reference all your variables with Delayed Expansion.

douglas.swehla
Posts: 75
Joined: 01 Jun 2016 09:25

Re: Issues remembering a variables state

#6 Post by douglas.swehla » 27 Jul 2016 09:15

zxuiji wrote:

Code: Select all

@echo on
@setlocal EnableDelayedExpansion

for /f "tokens=*" %%L in (.git/logs/HEAD) do (
   set VAR=!TWO!
   set TWO=%%L
   if "%%L"=="" (
      for /f "tokens=5* delims= " %%I in ("!VAR!") do (
         set VONE=%VTWO%
         set VTWO=%%I
         if "%%I"=="" echo (
            "#include \"CoditBuild.h\""
            "unsigned long CODIT_COMMIT = !VONE!;"
         ) >src/CoditCommit.c
      )
   )
)

@endlocal
:exit



You're setting variables to the value of other variables that don't exist, for no discernable reason.

When you run set VAR=!TWO!, TWO hasn't been set yet, so you're just assigning the character string "!TWO!", not the value of the TWO variable. Later, then, when you run for /f "tokens=5* delims= " %%I in ("!VAR!") do ..., it expands to for /f "tokens=5* delims= " %%I in ("!TWO!") do ..., rather than to a usable string. What value are you expecting to see in there? It looks like you're trying to assign the value of %%L to both VAR and TWO. If that's the case, why not just pick one and stick with it?

When you run set VONE=%VTWO%, VTWO hasn't been set either, but since you're using normal expansion, it expands to set VONE=, so VONE is cleared before it's even used. Later on, when you echo "unsigned long CODIT_COMMIT = !VONE!;", it will expand to "unsigned long CODIT_COMMIT = ;". Again, it looks like you're trying to assign the value of %%I to both VONE and VTWO, so same questions as before.

How does this work for you?

Code: Select all

@echo on
@setlocal EnableDelayedExpansion

for /f "tokens=*" %%L in (.git/logs/HEAD) do (
   set "VAR=%%L"
   if "%%L"=="" (
      for /f "tokens=5* delims= " %%I in ("!VAR!") do (
         set "VONE=%%I"
         if "%%I"=="" echo (
            "#include \"CoditBuild.h\""
            "unsigned long CODIT_COMMIT = !VONE!;"
         ) >src/CoditCommit.c
      )
   )
)

@endlocal
:exit


If that works okay, then this should as well. We don't even need to assign variables, so we don't need delayed expansion, either.

Code: Select all

@echo on
@setlocal EnableDelayedExpansion

for /f "tokens=*" %%L in (.git/logs/HEAD) do (
   if "%%L"=="" (
      for /f "tokens=5* delims= " %%I in ("%%L") do (
         if "%%I"=="" echo (
            "#include \"CoditBuild.h\""
            "unsigned long CODIT_COMMIT = %%I;"
         ) >src/CoditCommit.c
      )
   )
)

@endlocal
:exit


I'll be away most of today, but if you answer these questions, the others can probably help you better.

-Douglas

Post Reply