suggested function helpers

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
jonathancodes
Posts: 1
Joined: 29 Dec 2017 16:31

suggested function helpers

#1 Post by jonathancodes » 29 Dec 2017 16:50

whilst this might not be super-efficient, I'd like to offer up a pair of function helpers
it should be self explanatory, and i'd welcome any suggestions or gotchas that might occur to more the seasoned dos batch hackers that lurk on this forum.
:P
obviously the :_has_args_ and :_returns_ functions do the dirty work, and they could be further optimised / reduced in size, but for readbilty i'm leaving them as is for this post
( :_returns_ is slightly more obfuscated than :_has_args_ )

Code: Select all

@echo off

:: we are going to replace these, so make sure that happens
:: by filling them with bogus data
set answer1=wrong
set answer2=wrong1
set answer3=wrong2
set answer4=wrong3

:: call a function to add 2 numbers (doh!)
call :addition 57 49 answer1 description
:: dump out the results
set answer1
set description

:: try another one
call :subtraction 57 49 answer2 description
set answer1
set description


:: this one returns a value we did not ask for.
call :division 67 4 answer3 description
set answer3
set description
set remainder


:: this one calls another function multiple times (doh!)
call :multiplication 3 4 answer4 description

set answer4
set description
:: make sure it did not dirty our earlier result
echo is answer1 stil 57+49=106?
set answer1

:: what if we want to dirty our earlier result?
call :multiplication 2 3 answer1 description

set answer1
set description


goto :eof





:addition

  SETLOCAL & call :_has_args_ a b _from_ %*
       
  set /a c=a+b 
  
  set d=%a% plus %b% equals %c%

( ENDLOCAL & call :_returns_ %_values_% "%c%" "%d%" %_as_% %* )
exit /b

::alternate form 
:subtraction

  SETLOCAL & call :_has_args_ a b _returning_ c d _from_ %*
       
  set /a c_=a-b 
  
  set d_=%a% minus %b% equals %c_%

( ENDLOCAL & set %c%=%c_% & set %d%=%d_% )
exit /b

::alternate format without returing keyword (returns denoted internallyby naming convention)
::also returns mandatory hard coded value
:division

  SETLOCAL & call                   :_has_args_ ^
  a                                 ^
  b                                 ^
  _c_                               ^
  _d_                               ^
                                    _from_ %*
       
  set /a c=a/b 
  set /a r=a %% b
  
  set d=%a% divided by %b% equals %c% remainder %r%

( ENDLOCAL & set %_c_%=%c% & set %_d_%=%d% & set remainder=%r% )
exit /b


::compound demo
:multiplication

  SETLOCAL & call :_has_args_ a b _from_ %*
       
  set c=0
  for /L %%i in (1,1,%b%) do ( 
      call :addition !c! %a% c info
      set info
  )
  
  set d=%a% multiplied by %b% equals %c%
  :: note that _as_ does not need to be escaped (but can be)
( ENDLOCAL & call :_returns_ %_values_% "%c%" "%d%" _as_ %* )
exit /b




:_has_args_
SETLOCAL enabledelayedexpansion
  set A=0 & for %%x in (%*) do  set /A A+=1 &  set "args[!A!]=%%~x"

  set Z=1

  for /L %%i in (1,1,%A%) do if %Z% NEQ 0 if "!args[%%i]!"=="_from_" ( set /a "Q=%%i-1" & set Z=0 ) else ( if "!args[%%i]!"=="_returning_" set O=%%i )
     
  

  if "%O%"=="" set /a O=Q+1
 
  set /a load_arg=Q+1

  for /L %%i in (1,1,%Q%) do (
    
    if "!args[%%i]!" NEQ "_returning_" (
        set /a load_arg+=1 
    
        for /L %%x in (!load_arg!,1,!load_arg!) do set val[%%i]=!args[%%x]!
    ) 
  )
  
  
  endlocal & ( 

    set _values_=%Q%
    set _as_=_as_
    
    
    if %Q% GEQ 1 if %O% NEQ 1 set %args[1]%=%val[1]%
    if %Q% GEQ 2 if %O% NEQ 2 set %args[2]%=%val[2]%
    if %Q% GEQ 3 if %O% NEQ 3 set %args[3]%=%val[3]%
    if %Q% GEQ 4 if %O% NEQ 4 set %args[4]%=%val[4]%
    if %Q% GEQ 5 if %O% NEQ 5 set %args[5]%=%val[5]%
    if %Q% GEQ 6 if %O% NEQ 6 set %args[6]%=%val[6]%
    if %Q% GEQ 7 if %O% NEQ 7 set %args[7]%=%val[7]%
    if %Q% GEQ 8 if %O% NEQ 8 set %args[8]%=%val[8]%
    if %Q% GEQ 9 if %O% NEQ 9 set %args[9]%=%val[9]%
  )


exit /b
 


:_returns_

SETLOCAL enabledelayedexpansion
set R=0
for %%x in (%*) do set "rets[!R!]=%%~x" & set /A R+=1

set z=1
for /L %%i in (1,1,%R%) do if %z% NEQ 0 if "!rets[%%i]!"=="_as_" set /a "T=%%i-1" & set z=0
set /a out=T+%1+1
for /L %%i in (1,1,%T%) do set /a out+=1 & for /L %%x in (!out!,1,!out!) do set name[%%i]=!rets[%%x]!
endlocal & (
    if %T% GEQ 1 set "%name[1]%=%rets[1]%"
    if %T% GEQ 2 set "%name[2]%=%rets[2]%"
    if %T% GEQ 3 set "%name[3]%=%rets[3]%"
    if %T% GEQ 4 set "%name[4]%=%rets[4]%"
    if %T% GEQ 5 set "%name[5]%=%rets[5]%"
    if %T% GEQ 6 set "%name[6]%=%rets[6]%"
    if %T% GEQ 7 set "%name[7]%=%rets[7]%"
    if %T% GEQ 8 set "%name[8]%=%rets[8]%"
    if %T% GEQ 9 set "%name[9]%=%rets[9]%"
) & exit /b




Post Reply