12

I'm trying to build a generic batch file that can tell errors with a line number, where the error occours.
But writing each line number in the code is a little bit annoying.

Is it possible to get the current line number, while a batch-file is running?
So that the following code can work?

@echo off
call :doSomething 1

if %errorlevel% GTR 0 (
    REM Do something magic, to retrieve the lineNo
    call :getCurrentLineNo currentLineNo
    echo Error near %currentLineNo%
)

call :doSomething 2

if %errorlevel% GTR 0 (
    call :getCurrentLineNo currentLineNo
    echo Error near %currentLineNo%
)
aschipfl
  • 33,626
  • 12
  • 54
  • 99
jeb
  • 78,592
  • 17
  • 171
  • 225

1 Answers1

20

There is always way...
I found not the perfect solution, but a good workaround I can use.

I call a function which searches the own batch file(%~f0) with findStr, for the function parameter <uniqueID>, so this works only if these <uniqueID>'s are really unique for the whole batch.
The linenumber is get from the result of findstr /N.

In this sample:
6: call :getLineNumber errLine uniqueID4711 -2

The third parameter -2 is used to add an offset to the linenumber, so the result will be 4.

@echo off
SETLOCAL EnableDelayedExpansion

dir ... > nul 2> nul
if %errorlevel% NEQ 0 (
    call :getLineNumber errLine uniqueID4711    -2
    echo ERROR: in line !errLine!
)

set /a n=0xGH 2> nul
if %errorlevel% NEQ 0 (
    call :getLineNumber errLine uniqueID4712    -2
    echo ERROR: in line !errLine!
)
goto :eof

:::::::::::::::::::::::::::::::::::::::::::::
:GetLineNumber <resultVar> <uniqueID> [LineOffset]
:: Detects the line number of the caller, the uniqueID have to be unique in the batch file
:: The lineno is return in the variable <resultVar> add with the [LineOffset]
SETLOCAL
for /F " usebackq tokens=1 delims=:" %%L IN (`findstr /N "%~2" "%~f0"`) DO set /a lineNr=%~3 + %%L
( 
  ENDLOCAL
  set "%~1=%LineNr%"
  goto :eof
)
jeb
  • 78,592
  • 17
  • 171
  • 225
  • 7
    +1, Hi jeb, I just noticed this post, very cool :-) You probably should change your FINDSTR search to use `/n /c:" %~2 "` (space on either side of ID) with a convention that IDs never contain space. You don't want "abc123" to match "zabc1234". The /C option also prevents something like "A.1" being interpreted as a regex. Also, IDs should not contain backslash to avoid escape issues with FINDSTR, or else search and replace \ with \\ in code. – dbenham Aug 09 '12 at 19:59
  • Why not use [`%RANDOM%`](https://ss64.com/nt/syntax-random.html) to generate the unique ID on the fly? – Glenn Slayden Oct 16 '20 at 06:38
  • @GlennSlayden Because the ID has to be hardcoded in the file. Findstr has to be able to find a fixed text – jeb Oct 16 '20 at 09:55