How do I set a variable to read the value of a constructed variable - batch-processing

The line set cyclezipPPMdd=%cyclezipPPMdd!cycleCount!% in the code below isn't working as I intend to. It should transform !cycleCount! as, for example, 1, and then transform %cyclezipPPMdd!cycleCount!% into cyclezipPPMdd1 and finally set cyclezipPPMdd equal to the value of cyclezipPPMdd1 which is 256m.
I need a rotating value in cyclezipPPMdd.
rem #echo off
setlocal enableDelayedExpansion
: part1
set "cyclezipPPMdd0=256m 128m 64m 32m 16m 8m 4m 2m 1m"
set "memcyclezipPPMdd=258 130 66 34 18 10 6 4 3"
set /a anotherCounter=0
set tempCycle=!cyclezipPPMdd0: =^
!
for /f %%i in ("!tempCycle!") do (
set /a anotherCounter+=1
set cyclezipPPMdd!anotherCounter!=%%i
)
set /a cycleCount=0
: part2
set tempMem=!memcyclezipPPMdd: =^
!
for /f %%i in ("!tempMem!") do (
set /a cycleCount+=1
set tempMem!cycleCount!=%%i
set cyclezipPPMdd=%cyclezipPPMdd!cycleCount!%
set cyclezipPPMdd
pause
)
set /a anotherCounter=0
set /a cycleCount=0
pause
In the end I am so clueless as to what I need to do to achieve my goal. I'm not a programmer at all. Here's the final goal topic: for and start commands in a batch for parallel and sequential work
EDIT: the too long didn't read version
I need a way to split cyclezipPPMdd0=256m 128m 64m 32m 16m 8m 4m 2m 1m into single pieces, like this:
cyclezipPPMdd0=256m 128m 64m 32m 16m 8m 4m 2m 1m
cyclezipPPMdd1=256m
cyclezipPPMdd2=128m
cyclezipPPMdd3=64m
cyclezipPPMdd4=32m
cyclezipPPMdd5=16m
cyclezipPPMdd6=8m
cyclezipPPMdd7=4m
cyclezipPPMdd8=2m
cyclezipPPMdd9=1m
Those values will directly affect how much memory will be in use by 7z.exe (explained in the other topic), and I need a way to keep track of how much memory is currently in use to determine if the remaining memory would allow me to run another instance of 7z.exe or not. When 7z.exe starts, it will use only one of these values at a time. However, 256m is a value of a parameter for 7z.exe, it is the dictionary size. The real memory usage by this parameter is 258, so, the associated values are like this:
cyclezipPPMdd1=256m <=> tempMem1=258
cyclezipPPMdd2=128m <=> tempMem2=130
cyclezipPPMdd3=64m <=> tempMem3=66
cyclezipPPMdd4=32m <=> tempMem4=34
cyclezipPPMdd5=16m <=> tempMem5=18
cyclezipPPMdd6=8m <=> tempMem6=10
cyclezipPPMdd7=4m <=> tempMem7=6
cyclezipPPMdd8=2m <=> tempMem8=4
cyclezipPPMdd9=1m <=> tempMem9=3
7z.exe is currently set on my code to read the value from cyclezipPPMdd (without a number). This variable must rotate through all available pieces, split from cyclezipPPMdd0, but is always the same name, cyclezipPPMdd (still without a number).
if defined cyclezipPPMd (
for %%x IN (%cyclezipPPMdx%) DO for %%t IN (%cyclezipPPMdt%) DO for %%d IN (%cyclezipPPMdd%) DO for %%w IN (%cyclezipPPMdw%) DO (
set "cmd=7z.exe a teste.resultado\%%xx.ppmd.%%tt.%%dd.%%ww.zip .\teste.original\* -mx=%%x -mm=PPMd:mem=%%d:o=%%w -mmt=%%t"
call :executeProc
)
)
The first 7z.exe run would do cyclezipPPMdd=256m, the second run would do cyclezipPPMdd=128m etc... like this:
first run
cyclezipPPMdd1=256m <=> tempMem1=258 -> cyclezipPPMdd=256m
cyclezipPPMdd2=128m <=> tempMem2=130
cyclezipPPMdd3=64m <=> tempMem3=66
cyclezipPPMdd4=32m <=> tempMem4=34
cyclezipPPMdd5=16m <=> tempMem5=18
cyclezipPPMdd6=8m <=> tempMem6=10
cyclezipPPMdd7=4m <=> tempMem7=6
cyclezipPPMdd8=2m <=> tempMem8=4
cyclezipPPMdd9=1m <=> tempMem9=3
second run
cyclezipPPMdd1=256m <=> tempMem1=258
cyclezipPPMdd2=128m <=> tempMem2=130 -> cyclezipPPMdd=128m
cyclezipPPMdd3=64m <=> tempMem3=66
cyclezipPPMdd4=32m <=> tempMem4=34
cyclezipPPMdd5=16m <=> tempMem5=18
cyclezipPPMdd6=8m <=> tempMem6=10
cyclezipPPMdd7=4m <=> tempMem7=6
cyclezipPPMdd8=2m <=> tempMem8=4
cyclezipPPMdd9=1m <=> tempMem9=3
third run
cyclezipPPMdd1=256m <=> tempMem1=258
cyclezipPPMdd2=128m <=> tempMem2=130
cyclezipPPMdd3=64m <=> tempMem3=66 -> cyclezipPPMdd=64m
cyclezipPPMdd4=32m <=> tempMem4=34
cyclezipPPMdd5=16m <=> tempMem5=18
cyclezipPPMdd6=8m <=> tempMem6=10
cyclezipPPMdd7=4m <=> tempMem7=6
cyclezipPPMdd8=2m <=> tempMem8=4
cyclezipPPMdd9=1m <=> tempMem9=3
etc...
However, this is not everything. There is yet another 7z.exe parameter that not only also affect how much memory will be used, but also, how many threads will be used. I don't have this part ready in my script, I'm still trying to figure how to implement it.
first cycle <=> cyclezipPPMdt1=1 <=> tempProc1=8
first run
cyclezipPPMdd1=256m <=> tempMem1=258 -> cyclezipPPMdd=256m
cyclezipPPMdd2=128m <=> tempMem2=130
second run
cyclezipPPMdd1=256m <=> tempMem1=258
cyclezipPPMdd2=128m <=> tempMem2=130 -> cyclezipPPMdd=128m
etc...
second cycle <=> cyclezipPPMdt2=2 <=> tempProc2=4
first run
cyclezipPPMdd1=256m <=> tempMem1=580 -> cyclezipPPMdd=256m
cyclezipPPMdd2=128m <=> tempMem2=324
second run
cyclezipPPMdd1=256m <=> tempMem1=580
cyclezipPPMdd2=128m <=> tempMem2=324 -> cyclezipPPMdd=128m
etc...
The following table shows the relation between memory usage, thread usage and compression strength for zipPPMd algorythm.
#echo off
echo mem=1m 2m 4m 8m 16m 32m 64m 128m 256m
echo o=2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
echo mt=1 2 3 4 5 6 7 8
echo x=1 3 5 7 9
echo 256m 9x 7x 5x 3x 1x 8t - 2320 MB, 7t - 2030 MB, 6t - 1740 MB, 5t - 1450 MB, 4t - 1160 MB, 3t - 870 MB, 2t - 580 MB, 1t - 258 MB
echo 128m 9x 7x 5x 3x 1x 8t - 1296 MB, 7t - 1134 MB, 6t - 972 MB, 5t - 810 MB, 4t - 648 MB, 3t - 486 MB, 2t - 324 MB, 1t - 130 MB
echo 64m 9x 7x 5x 3x 1x 8t - 784 MB, 7t - 686 MB, 6t - 588 MB, 5t - 490 MB, 4t - 392 MB, 3t - 294 MB, 2t - 196 MB, 1t - 66 MB
echo 32m 9x 7x 5x 3x 1x 8t - 528 MB, 7t - 462 MB, 6t - 396 MB, 5t - 330 MB, 4t - 264 MB, 3t - 198 MB, 2t - 132 MB, 1t - 34 MB
echo 16m 9x 7x 5x 3x 1x 8t - 400 MB, 7t - 350 MB, 6t - 300 MB, 5t - 250 MB, 4t - 200 MB, 3t - 150 MB, 2t - 100 MB, 1t - 18 MB
echo 8m 9x 7x 5x 3x 1x 8t - 336 MB, 7t - 294 MB, 6t - 252 MB, 5t - 210 MB, 4t - 168 MB, 3t - 126 MB, 2t - 84 MB, 1t - 10 MB
echo 4m 9x 7x 5x 3x 1x 8t - 304 MB, 7t - 266 MB, 6t - 228 MB, 5t - 190 MB, 4t - 152 MB, 3t - 114 MB, 2t - 76 MB, 1t - 6 MB
echo 2m 9x 7x 5x 3x 1x 8t - 288 MB, 7t - 252 MB, 6t - 216 MB, 5t - 180 MB, 4t - 144 MB, 3t - 108 MB, 2t - 72 MB, 1t - 4 MB
echo 1m 9x 7x 5x 3x 1x 8t - 280 MB, 7t - 245 MB, 6t - 210 MB, 5t - 175 MB, 4t - 140 MB, 3t - 105 MB, 2t - 70 MB, 1t - 3 MB
No matter the compression strength (defined as x in this table, and as %cyclezipPPMdx% on the script), when the dictionary (mem in table, %cyclezipPPMdd% in script) is set to, for example, 256m, the corresponding real memory usage (tempMem#in the script) will be dependant on how many threads (mt in table, %cyclezipPPMdt% in script) are defined.
The sequence set "memcyclezipPPMdd=258 130 66 34 18 10 6 4 3" are from the last column of that table.

CALL set cyclezipPPMdd=%%cyclezipPPMdd!cycleCount!%%
in place of your set cyclezipPPMdd=... would seem to do what you seem to want.
It would probably be better to state the problem to be solved as your solution appears to be overly complex. I suppose you have your reasons for waning to write warandpeace as variablenames...
#ECHO OFF
setlocal enableDelayedExpansion
: part1
set "cyclezipPPMdd0=256m 128m 64m 32m 16m 8m 4m 2m 1m"
set "memcyclezipPPMdd=258 130 66 34 18 10 6 4 3"
set /a anotherCounter=0
for %%i in (%cyclezipPPMdd0%) do (
set /a anotherCounter+=1
set cyclezipPPMdd!anotherCounter!=%%i
)
set /a cycleCount=0
: part2
for %%i in (%memcyclezipPPMdd%) do (
set /a cycleCount+=1
set tempMem!cycleCount!=%%i
CALL set cyclezipPPMdd=%%cyclezipPPMdd!cycleCount!%%
set cyclezipPPMdd
pause
)
SET cyclecount
SET anothercounter
pause
set /a anotherCounter=0
set /a cycleCount=0
GOTO :EOF
would appear to produce the same results. Note that !var!=%var% outside of for loops when enabledelayedexpansion is in effect.
This also sets cyclecount and anothercounter to useful values - the number of elements in the variable.
Taken section-by-section, the below demonstration should show you a few techniques:
first, the extraction to cyclezipPPMdd as you've asked.
then cyclezipPPMdd and cyclezipPPMdd# which contains the corresponding entry in tempmem, which you don't appear to use in your code.
then grabbing different entries from the two lists.
Note that the substitution-sequence is critical. metavariables (%%x for active loop-controls and %n for parameter-numbers) are substituted first!
#ECHO OFF
setlocal enableDelayedExpansion
: part1
set "cyclezipPPMdd0=256m 128m 64m 32m 16m 8m 4m 2m 1m"
set "memcyclezipPPMdd=258 130 66 34 18 10 6 4 3"
set /a anotherCounter=0
for %%i in (%cyclezipPPMdd0%) do (
set /a anotherCounter+=1
set cyclezipPPMdd!anotherCounter!=%%i
)
set /a cycleCount=0
: part2
for %%i in (%memcyclezipPPMdd%) do (
set /a cycleCount+=1
set tempMem!cycleCount!=%%i
)
for /l %%i in (1,1,%cyclecount%) do (
CALL set cyclezipPPMdd=%%cyclezipPPMdd%%i%%
set cyclezipPPMdd
pause
)
for %%i in (1,7,4,2) do (
CALL set cyclezipPPMdd=%%cyclezipPPMdd%%i%%
CALL set cyclezipPPMdd#=%%tempMem%%i%%
set cyclezipPPMdd
pause
)
for %%i in (1,7,4,2) do (
FOR %%j IN (2 6) DO (
CALL :setz %%i %%j
SET z
PAUSE
)
)
SET cyclecount
SET anothercounter
pause
set /a anotherCounter=0
set /a cycleCount=0
GOTO :EOF
:setz
CALL set zcyclezipPPMdd=%%cyclezipPPMdd%1%% [%1]
CALL set ztempmem=%%tempMem%2%% [%2]
GOTO :eof

I was able to do it! The full script currently looks like this:
#echo off
setlocal enableDelayedExpansion
set "maxMem=8192"
set "maxThreads=!NUMBER_OF_PROCESSORS!"
set "memSum=0"
set "memRem="
if not defined memRem set "memRem=!maxMem!"
set "cycle7zBZip2="
set "cyclezipBZip2="
set "cyclezipDeflate64="
set "cyclezipDeflate="
set "cyclezipPPMd="
set "cycle7zLZMA="
set "cycle7zLZMA2="
set "cycle7zPPMd="
set "cyclezipLZMA="
set "maxProc="
set /a "maxProc=maxThreads"
:7zBZip2
set "cycle7zBZip2=1"
set "cycle7zBZip2x=9"
set "cycle7zBZip2t=1"
set /a "tempProc=maxThreads/cycle7zBZip2t"
set "cycle7zBZip2d=900k"
set "tempMem1=39"
set "cycle7zBZip2s=on"
set /a "cycleCount=1"
call :prepareCycle
set "cycle7zBZip2="
:zipBZip2
set "cyclezipBZip2=1"
set "cyclezipBZip2x=9"
set "cyclezipBZip2t=1"
set /a "tempProc=maxThreads/cyclezipBZip2t"
set "cyclezipBZip2d=900k"
set "tempMem1=10"
set /a "cycleCount=1"
call :prepareCycle
set "cyclezipBZip2="
:zipDeflate64
set "cyclezipDeflate64=1"
set "cyclezipDeflate64x=9"
set "cyclezipDeflate64t=1"
set /a "tempProc=maxThreads/cyclezipDeflate64t"
set "cyclezipDeflate64w=257 256 192 128 96 64 48 32 24 16 12 8"
set "tempMem1=4"
set /a "cycleCount=1"
call :prepareCycle
set "cyclezipDeflate64="
:zipDeflate
set "cyclezipDeflate=1"
set "cyclezipDeflatex=9"
set "cyclezipDeflatet=1"
set /a "tempProc=maxThreads/cyclezipDeflatet"
set "cyclezipDeflatew=258 256 192 128 96 64 48 32 24 16 12 8"
set "tempMem1=4"
set /a "cycleCount=1"
call :prepareCycle
set "cyclezipDeflate="
:zipPPMd
set "cyclezipPPMd=1"
set "cyclezipPPMdx=9"
set "cyclezipPPMdt=1"
set /a "tempProc=maxThreads/cyclezipPPMdt"
set "cyclezipPPMdd0=256m 128m 64m 32m 16m 8m 4m 2m 1m"
set /a "anotherCounter=0"
set tempCycle=!cyclezipPPMdd0: =^
!
for /f %%i in ("!tempCycle!") do (
set /a anotherCounter+=1
set tempCycle!anotherCounter!=%%i
)
set /a "anotherCounter=0"
set "cyclezipPPMdw=16 15 14 13 12 11 10 9 8 7 6 5 4 3 2"
set "memcyclezipPPMdd=258 130 66 34 18 10 6 4 3"
set tempMem=!memcyclezipPPMdd: =^
!
for /f %%i in ("!tempMem!") do (
set /a cycleCount+=1
set tempMem!cycleCount!=%%i
)
call :prepareCycle
set "cyclezipPPMd="
:7zLZMA
set "cycle7zLZMA=1"
set "cycle7zLZMAx=9"
set "cycle7zLZMAt=1"
set /a "tempProc=maxThreads/cycle7zLZMAt"
set "cycle7zLZMAd=512m"
set "cycle7zLZMAw=273 256 192 128 96 64 48 32 24 16 12 8"
set "cycle7zLZMAs=on"
set "tempMem1=5407"
set /a "cycleCount=1"
call :prepareCycle
set "cycle7zLZMA="
:7zLZMA2
set "cycle7zLZMA2=1"
set "cycle7zLZMA2x=9"
set "cycle7zLZMA2t=1"
set /a "tempProc=maxThreads/cycle7zLZMA2t"
set "cycle7zLZMA2d=512m"
set "cycle7zLZMA2w=273 256 192 128 96 64 48 32 24 16 12 8"
set "cycle7zLZMA2s=on"
set "tempMem1=5407"
set /a "cycleCount=1"
call :prepareCycle
set "cycle7zLZMA2="
:7zPPMd
set "cycle7zPPMd=1"
set "cycle7zPPMdx=9"
set /a "tempProc=maxThreads/1"
set "cycle7zPPMdd0=1024m 768m 512m 384m 256m 192m 128m 96m 64m 48m 32m 24m 16m 12m 8m 6m 4m 3m 2m 1m"
set /a "anotherCounter=0"
set tempCycle=!cycle7zPPMdd0: =^
!
for /f %%i in ("!tempCycle!") do (
set /a anotherCounter+=1
set tempCycle!anotherCounter!=%%i
)
set /a "anotherCounter=0"
set "cycle7zPPMdw=32 28 24 20 16 14 12 10 8 7 6 5 4 3 2"
set "cycle7zPPMds=on"
set "memcycle7zPPMdd=1055 799 543 415 287 223 159 127 95 79 63 55 47 43 39 37 35 34 33 32"
set tempMem=!memcycle7zPPMdd: =^
!
for /f %%i in ("!tempMem!") do (
set /a cycleCount+=1
set tempMem!cycleCount!=%%i
)
call :prepareCycle
set "cycle7zPPMd="
:zipLZMA
set "cyclezipLZMA=1"
set "cyclezipLZMAx=9"
set "cyclezipLZMAt=1"
set /a "tempProc=maxThreads/cyclezipLZMAt"
set "cyclezipLZMAd=512m"
set "cyclezipLZMAw=273 256 192 128 96 64 48 32 24 16 12 8"
set "tempMem1=5378"
set /a "cycleCount=1"
call :prepareCycle
set "cyclezipLZMA="
goto :fim
:prepareCycle
for /l %%N in (1 1 %cycleCount%) DO (set "tempProc%%N=")
for /l %%N in (1 1 %cycleCount%) DO (
if defined cycle7zBZip2 echo something
if defined cyclezipBZip2 echo something
if defined cyclezipDeflate64 echo something
if defined cyclezipDeflate echo something
if defined cyclezipPPMd set "cyclezipPPMdd=!tempCycle%%N!"
if defined cycle7zLZMA echo something
if defined cycle7zLZMA2 echo something
if defined cycle7zPPMd set "cycle7zPPMdd=!tempCycle%%N!"
if defined cyclezipLZMA echo something
set /a "tempProc%%N=%memRem%/tempMem%%N"
if !tempProc%%N! gtr %maxProc% set "tempProc%%N=%maxProc%"
set /a "memSum+=tempMem%%N*tempProc%%N"
set /a "memRem-=tempMem%%N*tempProc%%N"
set tempProc=!tempProc%%N!
call :prepareProc
set /a "memRem+=tempMem%%N*tempProc%%N"
set /a "memSum-=tempMem%%N*tempProc%%N"
)
set /a "cycleCount=0"
exit /b
:prepareProc
set "lock=lock_%random%_"
set /a "startCount=0, endCount=0"
for /l %%N in (1 1 %tempProc%) DO set "endProc%%N="
set launch=1
if defined cycle7zBZip2 (
for %%x IN (%cycle7zBZip2x%) DO for %%t IN (%cycle7zBZip2t%) DO for %%d IN (%cycle7zBZip2d%) DO for %%s IN (%cycle7zBZip2s%) DO (
set "cmd=7z.exe a teste.resultado\%%xx.bzip2.%%tt.%%dd.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=BZip2:d=%%d:mt=%%t"
call :executeProc
)
)
if defined cyclezipBzip2 (
for %%x IN (%cyclezipBZip2x%) DO for %%t IN (%cyclezipBZip2t%) DO for %%d IN (%cyclezipBZip2d%) DO (
set "cmd=7z.exe a teste.resultado\%%xx.bzip2.%%tt.%%dd.zip .\teste.original\* -mx=%%x -mm=BZip2:d=%%d -mmt=%%t"
call :executeProc
)
)
if defined cyclezipDeflate64 (
for %%x IN (%cyclezipDeflate64x%) DO for %%t IN (%cyclezipDeflate64t%) DO for %%w IN (%cyclezipDeflate64w%) DO (
set "cmd=7z.exe a teste.resultado\%%xx.deflate64.%%tt.%%ww.zip .\teste.original\* -mx=%%x -mm=deflate64:fb=%%w -mmt=%%t"
call :executeProc
)
)
if defined cyclezipDeflate (
for %%x IN (%cyclezipDeflatex%) DO for %%t IN (%cyclezipDeflatet%) DO for %%w IN (%cyclezipDeflatew%) DO (
set "cmd=7z.exe a teste.resultado\%%xx.deflate.%%tt.%%ww.zip .\teste.original\* -mx=%%x -mm=deflate:fb=%%w -mmt=%%t"
call :executeProc
)
)
if defined cyclezipPPMd (
for %%x IN (%cyclezipPPMdx%) DO for %%t IN (%cyclezipPPMdt%) DO for %%d IN (%cyclezipPPMdd%) DO for %%w IN (%cyclezipPPMdw%) DO (
set "cmd=7z.exe a teste.resultado\%%xx.ppmd.%%tt.%%dd.%%ww.zip .\teste.original\* -mx=%%x -mm=PPMd:mem=%%d:o=%%w -mmt=%%t"
call :executeProc
)
)
if defined cycle7zLZMA (
for %%x IN (%cycle7zLZMAx%) DO for %%t IN (%cycle7zLZMAt%) DO for %%d IN (%cycle7zLZMAd%) DO for %%w IN (%cycle7zLZMAw%) DO for %%s IN (%cycle7zLZMAs%) DO (
set "cmd=7z.exe a teste.resultado\%%xx.lzma.%%tt.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=LZMA:d=%%d:fb=%%w -mmt=%%t"
call :executeProc
)
)
if defined cycle7zLZMA2 (
for %%x IN (%cycle7zLZMA2x%) DO for %%t IN (%cycle7zLZMA2t%) DO for %%d IN (%cycle7zLZMA2d%) DO for %%w IN (%cycle7zLZMA2w%) DO for %%s IN (%cycle7zLZMA2s%) DO (
set "cmd=7z.exe a teste.resultado\%%xx.lzma2.%%tt.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -ms=%%s -m0=lzma2:d=%%d:fb=%%w -mmt=%%t"
call :executeProc
)
)
if defined cycle7zPPMd (
for %%x IN (%cycle7zPPMdx%) DO for %%d IN (%cycle7zPPMdd%) DO for %%w IN (%cycle7zPPMdw%) DO for %%s IN (%cycle7zPPMds%) DO (
set "cmd=7z.exe a teste.resultado\%%xx.ppmd.%%dd.%%ww.%%ss.7z .\teste.original\* -mx=%%x -m0=PPMd:mem=%%d:o=%%w -ms=%%s"
call :executeProc
)
)
if defined cyclezipLZMA (
for %%x IN (%cyclezipLZMAx%) DO for %%t IN (%cyclezipLZMAt%) DO for %%d IN (%cyclezipLZMAd%) DO for %%w IN (%cyclezipLZMAw%) DO (
set "cmd=7z.exe a teste.resultado\%%xx.lzma.%%tt.%%dd.%%ww.zip .\teste.original\* -mx=%%x -mm=lzma:d=%%d:fb=%%w -mmt=%%t"
call :executeProc
)
)
set "launch="
goto :wait
:executeProc
if !startCount! lss %tempProc% (
set /a "startCount+=1, nextProc=startCount"
) else (
call :wait
)
set cmd!nextProc!=!cmd!
echo !time! - proc!nextProc!: starting !cmd!
2>nul del %lock%!nextProc!
start /b /low cmd /c !cmd!>"%lock%!nextProc!"
exit /b
:wait
for /l %%N in (1 1 %startCount%) do (
if not defined endProc%%N if exist "%lock%%%N" (
echo !time! - proc%%N: finished !cmd%%N!
if defined launch (
set nextProc=%%N
exit /b
)
set /a "endCount+=1, endProc%%N=1"
) 9>>"%lock%%%N"
) 2>nul
if %endCount% lss %startCount% (
rem 1>nul 2>nul ping /n 2 ::1
goto :wait
)
2>nul del %lock%*
echo ===
echo Thats all folks!
exit /b
:fim
echo fim
pause
exit
This sample works without errors! The part pertaining to this topic's specific question is located at :zipPPMd. I made use of %cycleCount% to set cyclezipPPMdd. It is located at :prepareCycle part. This is the line that made it work: if defined cyclezipPPMd set "cyclezipPPMdd=!tempCycle%%N!"
But this is far from over though. Some variables may make no sense right now, because it's work in progress. I have forced thread usage to 1 on all algorythms for this sample, but what I really want is to set to all of them, from 1 to 8. Then again, I still didn't figure how to check if the script can run another cycle while one other or several others are running and decide when to run them. It needs to keep track of the number of threads and memory in use at the moment to decide.

Related

in z/OS Assembler, can I read a JCL input stream twice?

Is there a way to read a z/OS JCL input stream more than once? (one that comes from a //SYSIN DD *). I know I could cache the stream the first time I read it, and then read from the cached data, but I'm not interested in that solution.
Note: the language is Assembler
Depends on the language. This answer provides an example in HLASM and a reference to the 'C' Language reference at the end.
For Assembler you'll need to REWIND when you CLOSE the DCB. See the label at FINISH to see how this is done.
There may be other ways but this worked for me on z/OS 2.4
PRINT NOGEN
* ------------------------------------------------------------------- *
* *
* SYSIN2 *
* *
* #author Hogstrom *
* *
* Test to see if one can re-read SYSIN more than one time. *
* *
* ------------------------------------------------------------------- *
R0 EQU 0
R1 EQU 1
R2 EQU 2
R3 EQU 3 * Number of times to loop
R4 EQU 4
R5 EQU 5
R6 EQU 6
R7 EQU 7
R8 EQU 8
R9 EQU 9
R10 EQU 10
R11 EQU 11
R12 EQU 12 * Base Register
R13 EQU 13
R14 EQU 14
R15 EQU 15
*
SYSIN2 CSECT
STM R14,R12,12(R13)
LR R12,R15
USING SYSIN2,12
*
ST R13,SaveArea+4
LA R0,SaveArea
ST R0,8(R13)
LA R13,SaveArea
*
OPEN (SYSIN,(INPUT))
OPEN (SYSOUT,(OUTPUT))
LA R3,3 Number of times to read SYSIN
*
GETAGAIN DS 0H
GET SYSIN,INREC Read the next rec
PUT SYSOUT,INREC Write that bad boy out
B GETAGAIN
FINISH DS 0H Invoked at End of Data of SYSIN
CLOSE (SYSIN,REWIND) Close SYSIN and rewind
OPEN (SYSIN,(INPUT)) Open it up again
BCT R3,GETAGAIN Repeat the madness
*
CLOSE SYSIN
CLOSE SYSOUT
*
L R13,SaveArea+4
LM R14,R12,12(R13)
XR R15,R15
BR R14
*
SYSIN DCB DSORG=PS,MACRF=(GM),DDNAME=SYSIN,EODAD=FINISH, *
RECFM=FB,LRECL=80,BLKSIZE=0
SYSOUT DCB DSORG=PS,MACRF=(PM),DDNAME=SYSOUT, *
RECFM=FBA,LRECL=133,BLKSIZE=0
*
INREC DC CL132' '
SaveArea DS 18F
LTORG
END
Assemble the above and execute this JCL
//SYSIN2 JOB (CCCCCCCC),'HOGSTROM',
// MSGLEVEL=(1,1),
// MSGCLASS=O,
// CLASS=A,
// NOTIFY=&SYSUID
//*
//STEP1 EXEC PGM=SYSIN2
//STEPLIB DD DSN=USER1.TEST.LOADLIB,DISP=SHR
//*
//SYSIN DD *
REC 1 OF 3
REC 2 OF 3
REC 3 OF 3
/*
//SYSOUT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
And you'll get this output
You'll see the same SYSIN data repeated three times.
For a 'C' program this reference in the IBM documentation for the C Compiler provides some hints about rewinding.
To open an in-stream data set, call the fopen() or freopen() library
function and specify the ddname of the data set. You can open an
in-stream data set only for reading. Specifying any of the update,
write, or append modes fails. Once you have opened an in-stream data
set, you cannot acquire or change the file position except by
rewinding. This means that calls to the fseek(), ftell(), fgetpos(),
and fsetpos() for in-stream data sets fail. Calling rewind() causes
z/OS XL C/C++ to reopen the file, leaving the file position at the
beginning.
What you're looking for is possible but the implementation is language dependent.

Add character before and after every character in a file - make every character a variable

I want to "encrypt" a file. This is just for fun, not intending to store or send any sensetive data using this "encryption".
This code example is meant to ilistrate what I would like to do...
SET A=D
SET B=S
SET C=Q
SET D=G
ECHO %A%%B%%C%%D%
The text ABCD will now be displayed as DSQG insted (if I wrote something meaningfull the "encrypted" result would not mean anything).
My question is:
Can I (if so, how?) add '%' before and after every character in the file?
I searched on how to read a file using batch, found this (jeb's answer):
Batch files: How to read a file?
Is there a soulution where I could read a normal file, encrypt it and store as an encrypted version aswell?
Thanks so much for any answer!
This borrows strlen from jeb,
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET PT_FILE=plain.txt
IF NOT "%~1"=="" SET "PT_FILE=%~1"
CALL :INIT_CIPHER
FOR /F "tokens=*" %%l IN ('findstr.exe /R /N "^" "%PT_FILE%"') DO #(
REM #ECHO(
REM #ECHO( %%l
SET "LINE=%%~l"
SET "LINE=!LINE:*:=!"
REM #ECHO(!LINE!
CALL :strlen LINE_LEN LINE
REM #ECHO(Length(!LINE_LEN!^)
IF !LINE_LEN! EQU 0 (
ECHO(
) ELSE (
SET OUTLINE_E=
FOR /L %%i IN (0,1,!LINE_LEN!) DO (
SET "CHAR=!LINE:~%%i,1!"
IF "!CHAR!"==" " (
SET "OUTLINE_E=!OUTLINE_E! "
) ELSE (
#ECHO !CHAR!|findstr.exe /R "[A-Za-z]" >NUL
IF ERRORLEVEL 1 (
SET "OUTLINE_E=!OUTLINE_E!!CHAR!"
) ELSE (
SET CHAR_E=
CALL :ENC "!CHAR!" "CHAR_E"
REM #ECHO '!CHAR!' =^> E(!CHAR_E!^)
SET "OUTLINE_E=!OUTLINE_E!!CHAR_E!"
)
)
)
ECHO(!OUTLINE_E!
)
)
GOTO :EOF
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:ENC
CALL SET "%~2=!%~1!"
REM ECHO E(!%~2!^)
EXIT /B
:: https://stackoverflow.com/questions/5837418/how-do-you-get-the-string-length-in-a-batch-file
:strlen <resultVar> <stringVar>
(
setlocal EnableDelayedExpansion
set "s=!%~2!#"
set "len=0"
for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
if "!s:~%%P,1!" NEQ "" (
set /a "len+=%%P"
set "s=!s:~%%P!"
)
)
)
(
endlocal
set "%~1=%len%"
exit /b
)
:: Substitution Cipher
:: ABCDEFGHIJKLMNOPQRSTUVWXYZ
:: ZYXWVUTSRQPONMLKJIHGFEDCBA
:: perl -e "#a=('a'..'z');for ($i=0; $i<#a; $i++) { print('SET '.uc($a[$i]).'='.uc($a[$#a-$i]).qq(\n)); }"
:INIT_CIPHER
SET A=Z
SET B=Y
SET C=X
SET D=W
SET E=V
SET F=U
SET G=T
SET H=S
SET I=R
SET J=Q
SET K=P
SET L=O
SET M=N
SET N=M
SET O=L
SET P=K
SET Q=J
SET R=I
SET S=H
SET T=G
SET U=F
SET V=E
SET W=D
SET X=C
SET Y=B
SET Z=A
EXIT /B
Notes:
It is very slow.
It loses the case of the source plaintext.
It doesn't insert % around every character (which wouldn't work for special characters anyway), but does what it sounds like you want.
Results:
>>> type plain.txt
This is a simple file to be encrypted.
This is a second line. A blank line follows.
This is the fourth line.
This line has a colon (:) in the middle of it.
This line has quotes: "I said, 'Pass the bread, please,' as politely as possible."
>>> enc plain.txt
GSRH RH Z HRNKOV UROV GL YV VMXIBKGVW.
GSRH RH Z HVXLMW ORMV. Z YOZMP ORMV ULOOLDH.
GSRH RH GSV ULFIGS ORMV.
GSRH ORMV SZH Z XLOLM (:) RM GSV NRWWOV LU RG.
GSRH ORMV SZH JFLGVH: "R HZRW, 'KZHH GSV YIVZW, KOVZHV,' ZH KLORGVOB ZH KLHHRYOV."
>>> enc > cipher.txt
enc > cipher.txt
>>> enc cipher.txt
THIS IS A SIMPLE FILE TO BE ENCRYPTED.
THIS IS A SECOND LINE. A BLANK LINE FOLLOWS.
THIS IS THE FOURTH LINE.
THIS LINE HAS A COLON (:) IN THE MIDDLE OF IT.
THIS LINE HAS QUOTES: "I SAID, 'PASS THE BREAD, PLEASE,' AS POLITELY AS POSSIBLE."

Batch Adding 1 to a number untill Modulo divide 4

I'm gonna try to explain how my case is:
Lets say I have the number 30 and I want to make a batch script that adds 1 to that number untill its modulo divide 4
set /a number = 30 %% 4
how can I make it know to add 2 to 30 to make it mod 4 ?
Thx in advance
Is this what you need?
#echo off
set num=30
:loop
set /a num=num+1
set /a number=num %% 4
if %number% NEQ 0 goto :loop
echo %num%

Add minutes to time in batch (using arithmetic)

I'm running into a dilemma. I want to send a preemptive email to users telling them that an upcoming task is about to happen. In order to do that I'm defining some variables, sending an email via blat, sleeping the batch for 5 minutes, then executing the rest of the script.
When executing %time% at 4:00PM, I get 16:00:00.00. If I add 5 minutes to it, only for display purposes in the email with the following code:
#echo on
SET /a timeminute = 00 + 5 << --- test code
::SET /a timeminute = %time:~3,2% + 5 << --- actual code in GoLive
IF %timeminute% LEQ 9 (
GOTO :resetTime
) ELSE (
GOTO :end
)
:resetTime
SET timeminute = "0%timeminute%"
:end
echo %timeminute%
pause
I get 5, not 05 like expected. Using arithmetic on time drops leading zeros, so I try to add it back in later but the later SET is within the IF statement and cannot be seen? How can I see that? Is there a such thing as an environment variable in batch?
Keep in mind this issue only happens within the first 9 minute of the hour, after that time, there are no more leading zeros.
Bonus: What happens when the minutes in a hour is 55-59? In my example, it will be 60-64, so I need a way of rounding up an hour and take care of the remaining minutes. Right now, I see that as a bug, but I do not foresee this script running at those odd times. But if it is an easy fix please let me know as I have not even tried to tackle that problem.
Thank you kindly
A more compact form to do the same thing is this:
#echo on
for /F "tokens=1-3 delims=:." %%a in ("%time%") do (
set timeHour=%%a
set timeMinute=%%b
set timeSeconds=%%c
)
rem Convert HH:MM to minutes + 5
set /A newTime=timeHour*60 + timeMinute + 5
rem Convert new time back to HH:MM
set /A timeHour=newTime/60, timeMinute=newTime%%60
rem Adjust new hour and minute
if %timeHour% gtr 23 set timeHour=0
if %timeHour% lss 10 set timeHour=0%timeHour%
if %timeMinute% lss 10 set timeMinute=0%timeMinute%
echo %timeHour%:%timeMinute%:%timeSeconds%
pause
Answered my own question with the following:
#echo on
setlocal enabledelayedexpansion
set timehour=%time:~0,2%
set timeminute=%time:~3,2%
set timeseconds=%time:~6,2%
set addTime=5
IF %timeminute:~0,1% lss 1 set timeminute=!timeminute:~1,1!
IF %timeminute:~0,1% lss 1 set timeminute=!timeminute:~1,1!
set /a timeminute=%timeminute% + %addTime%
IF %timeminute% lss 10 set timeminute=0!timeminute!
IF %timeminute% equ 60 (
set timeminute=00
set /a timehour=%timehour% + 1
)
IF %timeminute% equ 61 (
set timeminute=01
set /a timehour=%timehour% + 1
)
IF %timeminute% equ 62 (
set timeminute=02
set /a timehour=%timehour% + 1
)
IF %timeminute% equ 63 (
set timeminute=03
set /a timehour=%timehour% + 1
)
IF %timeminute% equ 64 (
set timeminute=04
set /a timehour=%timehour% + 1
)
IF %timehour% equ 25 (
set timehour=00
)
IF %timehour% lss 10 set timehour=0!timehour!
echo %timehour%:%timeminute%:%timeseconds%
pause

Scale Interface to VB Application

I have a few different scales that I'm building a VB app for. Is there a universal serial port language that is common among weight scales that I can use to import real-time weight into VB?
Yes, there's a standard protocol, formulated by the Scale Manufacturer Association. The spec download is here. Whether your actual scales follow that standard is an open question, check the small print in the datasheet or programming manual for them. It is rarely a real problem, these protocols are easy with simple command/response strings.
This is what i found reading the ZBI 2/ ZPL Manuals of Zebra. very usefull!!!!
1 rem ********************************************************
05 for i = 1 to 9 step 1
10 close #i
20 next i
30 open # 2 : name "SER"
40 open # 1 : name "ZPL"
1 rem ********************************************************
1 rem main program; send serial port a 'W' in order to get a weight
1 rem ********************************************************
50 do
60 do
70 sleep 1 ! sleep so scale is not bombarded with incoming
1 rem data
80 print # 2 : "W" ; ! semicolon ends sent W without a CRLF
1 rem ********************************************************
1 rem get response from scale; note that input requires a CRLF to be
1 rem entered
1 rem ********************************************************
90 input # 2 : a$
100 if a$ = "EXIT" then! back door exit - if EXIT is received, ZBI ends
110 close # 2
120 print #1: "^XZ"
130 close #1
140 end
150 end if
1 rem ********************************************************
1 rem loop until valid weight is received, then print on label
1 rem ********************************************************
160 loop while pos ( a$ , "000.00" ) = 1 or pos ( a$ , "?" ) = 1
170 print # 1 : "~SD25^XA^FS";
180 print # 1 : "^LH0,0^FS";
190 print # 1 : "^FO56,47^A0N,69,58^FDThis weighs^FS";
1 rem ********************************************************
1 rem print weight on label; & character concatenates strings
1 rem ********************************************************
200 print # 1 : "^FO56,150^A0N,69,58^FD" & A$ & " lbs^FS";
210 print # 1 : "^PQ1,0,0,N";
220 print # 1 : "^XZ"
1 rem ********************************************************
1 rem loop until weight is off scale, then repeat for next item
1 rem weighed
1 rem ********************************************************
230 do
240 print # 2 : "W" ;
250 input # 2 : A$
260 loop until pos(A$ , "000.00") = 1 or pos(A$ , "?") = 1
270 loop