I don’t know what the problem is with this batch file:
@ECHO OFF
SET images=./images/
SET cdr=%CD%
SET result=noval
CD %images%
SET images=
:: Density
SET dpi=300
:: Process SVG
FOR %%x IN (%images%*.svg) DO (
CALL:testFun %%~nx result
echo res "%result%"
IF [%result%]==[process] (
ECHO Converting %%x
inkscape -d %dpi% -A %images%%%~nx.pdf %images%%%x
) ELSE ( ECHO - Skiping %%x, file is uptodate.)
)
:: Process BMP, JPG, PNG, and TIFF
FOR %%x IN (%images%*.jpg,%images%*.bmp,%images%*.png,%images%*.tiff) DO (
CALL:testFun %%~nx result
echo res "%result%"
IF [%result%]==[process] (
ECHO Converting %%x
inkscape -d %dpi% -A %images%%%~nx.pdf %images%%%x
) ELSE ( ECHO - Skiping %%x, file is uptodate.)
)
:: Process EPS
FOR %%x IN (%images%*.eps) DO (
CALL :testFun %%~nx result
echo res "%result%"
IF [%result%]==[process] (
ECHO Converting %%x
epstopdf --outfile=%images%%%~nx.pdf %images%%%x
) ELSE ( ECHO - Skiping %%x, file is uptodate.)
)
CD %cdr%
ECHO.&PAUSE&GOTO:EOF
::Functions
:testFun
SET "file=%1"
FOR /F %%f IN ('dir /Od /B "%file%.*"') DO (SET newest=%%~xf)
echo * Newest file for %file%: %newest%
IF [%newest%]==[.pdf] (echo noprocessing
GOTO :noprocess) ELSE (echo processing
GOTO :process)
:noprocess
SET result=noprocess
GOTO :endfun
:process
SET result=process
:endfun
GOTO:EOF
The idea is that it should process different images in a directory, only if the images (source) are newer than the resultant PDF (output).
However, there are several problems that I don’t know why they are happening.
-
First, the first loop uses the value of
resultand printnovalall the time, and it looks like it is skipping the function call. But then, the same way of calling works on the second and third loop. -
Second, in the other loops (in which the first problem doesn’t occur) the value of
result, that is changed inside the function, is not there. Like the scope is different. However, I’m using it as a global variable, right? I test this version usingset localand passing the variable as reference but nothing work.
What I’m doing wrong or missing here?
The code runs as it should. What you are not aware of is that
cmdexpands environment variables when parsing a command. A command in this case can be a completeforincluding the block. So after parsing it no variables remain in it, only text. Which means if you change a variable within a block and use it in the same block you won’t see the change.To resolve this you can use delayed expansion which ensures that variables are expanded directly prior to running a single line (even within blocks) and thus mitigate this problem. Add the following at the top of your batch file:
and then use
!result!instead of%result%to access the variables’ values.