batch版簡易ARGPARSE


コマンドラインの引数解析

使う機会ほとんどないだろうけど、batch で引数の解析をやってみたら意外にできたので、作ってみた。
引数に--name value--name=valueがあると、set name=valueをしてくれる。
使い方はcall tools\parse_options.cmd %*とするだけ。

解析用バッチ(ライブラリ?)

tools\parse_options.cmd
@echo off

:: Parse arguments

:ARGPARSE
  set _=%~1
  if /i "%_%" == "-h" goto HELP
  if /i "%_%" == "--help" goto HELP
  if not "%_:~,2%" == "--" exit /b 0

  set __=%_:-=_%
  set ___=%__:~2%
  if "%~2" == "" goto NO_OPTARG

  call set %%___%%=%2

  set _=
  set __=
  set ___=
  shift
  shift
  if not "%~1" == "" goto ARGPARSE

exit /b 0

:NO_OPTARG
echo No optarg of %___% 1>&2
exit /b 1

:HELP
if defined help_message (
  echo %help_message% 1>&2
) else (
  echo No help found. 1>&2
)
exit /b 1

ドライバコード

driver_for_parse_options.cmd
@echo off
call tools\parse_options.cmd %*

テストコード

test_for_parse_options.cmd
@echo off
setlocal

echo === clear vars ===
set a=
set b_c=
set d_e=
set f=
set g=
set h=
set i=
set j=
set k=

echo === set vars ===
call driver_for_parse_options.cmd --a 1 --b_c 2 --d-e "3 4" --i=10 --j="a=b"
echo ERRORLEVEL:%ERRORLEVEL%
if errorlevel 0 (
  echo a:%a%
  echo b_c:%b_c%
  echo d_e:%d_e%
  echo i:%i%
  echo j:%j%
)

echo === invalid arguments 1 ==
call driver_for_parse_options.cmd --f --g --h
echo ERRORLEVEL:%ERRORLEVEL%
echo f:%f%
echo g:%g%
echo h:%h%

echo === invalid arguments 2 ==
call driver_for_parse_options.cmd --k=c=--def
echo ERRORLEVEL:%ERRORLEVEL%
echo k:%k%


echo === show help ===
call driver_for_parse_options.cmd -h
echo ERRORLEVEL:%ERRORLEVEL%

set "help_message=Usage driver_for_parse_options.cmd [--a a] [--b_c b_c] [--d-e d_e]"
call driver_for_parse_options.cmd --help
echo ERRORLEVEL:%ERRORLEVEL%

endlocal
pause

実行結果

Q:\>test_for_parse_options.cmd
=== clear vars ===
=== set vars ===
ERRORLEVEL:0
a:1
b_c:2
d_e:"3 4"
i:10
j:"a=b"
=== invalid arguments 1 ==
No optarg of h
ERRORLEVEL:1
f:--g
g:
h:
=== invalid arguments 2 ==
No optarg of def
ERRORLEVEL:1
k:c
=== show help ===
No help found.
ERRORLEVEL:1
Usage driver_for_parse_options.cmd [--a a] [--b_c b_c] [--d-e d_e]
ERRORLEVEL:1
続行するには何かキーを押してください . . .