Search code examples
batch-filereturn-value

Trying to convert text into hex by calling a function within my batch file, but the hex code never gets returned to the Main batch function


@echo off

goto :main

 
:strg2hex
setlocal EnableDelayedExpansion

rem Store the string in chr.tmp file
set /P "=%~1" < NUL > chr.tmp

rem Create zero.tmp file with the same number of Ascii zero characters
for %%a in (chr.tmp) do fsutil file createnew zero.tmp %%~Za > NUL

rem Compare both files with FC /B and get the differences
set "hex="
for /F "skip=1 tokens=2" %%a in ('fc /B chr.tmp zero.tmp') do set "hex=!hex!%%a"

del chr.tmp zero.tmp
echo The string to hex is %hex%

set %~1=%hex%

goto :eof



:main

     echo This is the main function!
 
     ::This interprets "tiger" as a string.
     ::This will convert text "tiger" into hex with the above function.
     call :strg2hex tiger
     Echo this is text "tiger" converted into hex: %hex%

Pause

goto :eof

Solution

  • in place of

    set %~1=%hex%
    

    use

    endlocal&set "%~1=%hex%"&SET "hex=%hex%"
    

    Because you are executing a setlocal, when you goto :eof, the local environment containing your changes is deleted and the original, unchanged environment is restored.

    This statement works because batch parses, substitutes and then executes the command, so what is actually executed is

     endlocal&set "tiger=7469676572"&SET "hex=7469676572"
    

    so the local environment is deleted, then the values are set.


    @ECHO OFF
    SETLOCAL
    goto :main
    
     
    :strg2hex
    setlocal EnableDelayedExpansion
    
    rem Store the string in chr.tmp file
    set /P "=%~1" < NUL > chr.tmp
    
    rem Create zero.tmp file with the same number of Ascii zero characters
    for %%a in (chr.tmp) do DEL zero.tmp>nul&fsutil file createnew zero.tmp %%~Za > NUL
    
    rem Compare both files with FC /B and get the differences
    set "hex="
    for /F "skip=1 tokens=2" %%a in ('fc /B chr.tmp zero.tmp') do set "hex=!hex!%%a"
    
    rem del chr.tmp zero.tmp
    echo The string to hex is %hex%
    
    endlocal&SET "hex=%hex%"
    
    
    goto :eof
    
    :main
    u:
         echo This is the main function!
     
         ::This interprets "tiger" as a string.
         ::This will convert text "tiger" into hex with the above function.
         call :strg2hex tiger
         Echo this is text "tiger" converted into hex: %hex%
    
    
    IF "%*" neq "" FOR %%z IN (%*) DO  ECHO %%z&     call :strg2hex %%z
    
    rem response to comment
    
    SET "strng=Lion"
    CALL :strg2hex %strng%
    ECHO This variable "strng" has been converted into %hex%
    ECHO This variable "strng" value "%strng%" has been converted into %hex%
    
    GOTO :EOF
    

    Well - a couple of surprises on testing more thoroughly...

    First, I use U: for testing - that's why that has appeared at the start of main.

    Next, I've added a new line,

    IF "%*" neq "" FOR %%z IN (%*) DO  ECHO %%z&     call :strg2hex %%z
    

    This looks at the command-line "tail" (the data after the program name on the command line) or parameters %* and assigns each one in turn to %%z (parameters may be space-separated or comma-separated), then echoes the parameter and calls the routine. Thus if we execute

    q72120539 elephant lion zebra giraffe    
    

    we get the result

    elephant
    The string to hex is 656C657068616E74
    lion
    The string to hex is 6C696F6E
    zebra
    The string to hex is 7A65627261
    giraffe
    The string to hex is 67697261666665
    

    in addition to the tiger folderol. q72120539 is my name for this program.

    I had converted the del of the two temporary files to a remark, so the files were not deleted and I could see them...

    Unfortunately, the resultant display was not what I expected.

    Despite its description (or implications), fsutil file createnew does NOT create a new file if there is an existing file - it leaves it as-is. Consequently, the code did not change the file after the first name (tiger) had been processed and the file remained at 5 bytes.

    I cured that by deliberately deleting the zero file before the fsutil command was executed.

    So - all fixed now, but I've left the del for the temporary files "remmed-out" so that will not be deleted when the routine ends. Probably good practice to remove the rem keyword and turn the clean-up back on.

    I've also removed the set "%~1=%hex%" because leaving it would set variables named tiger , elephant , lion , zebra , giraffe each to their hex-value strings.


    Edited to include example from OP.

    Result is extra

    This variable "strng" has been converted into 4C696F6E
    This variable "strng" value "Lion" has been converted into 4C696F6E
    

    There is no such thing as a "function" in batch, at least, not in the sense that it is used in Pascal, for instance. The "return value" simply gets assigned to a known variable, as in this case.

    It is possible to have the call return the value in a any variable by using this:

    call :function fred 5 6 7
    
    ...
    
    :function
    set /a %1=%2+%3+%4
    goto :eof
    

    which would set the value of fred to 18