Command line parameter parsing

  • This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.
Aug 16, 2008
124
0
#1
Does Take Command have something similar to Python's optparse/argparse module or to GNU's getopt or Linux shell's getopts command or would I have to completely script option handling myself?

How would I start doing this? Has anyone ever done it?

I would like to mimic the following script output I have in Python:

> script.py --help
usage: script.py [-h] [-v]

script.py does something

Special options:
-h, --help show this help message and exit
-v, --version show program's version number and exit

> script.py -v
script.py 1.0

> script.py -f
usage: script.py [-d] [-h] [-v]
script.py: error: unrecognized arguments: -f
 
#3
You might try something like this:

if [%1] eq [-?] .or. [%1] eq [/?] .or. [%1] eq [?] goto USAGE

or

if %@index[?,%#] ne -1 gosub USAGE

where you display the help text

:USAGE
text

MYBATCH help

Syntax: MYBATCH does something useful

MYBATCH <dirname> does something with dirs.
MYBATCH <files> does something with files

MYBATCH /? Syntax help (this screen)

endtext
goto END (or return if you use gosub, or quit)
 
Aug 16, 2008
124
0
#4
Okay, I translated my shell script to TCC and it was quite straightforward. There are some things that are not very pretty (for instance the usage function - I tried to use the "text" command inside the function but failed) but it works. OF course, the parsing is pretty naive and will fail if there would be ever two options simultaneously allowed. Here it is:
Code:
*@echo off
:: setlocal has to come before any un* commands
*setlocal
*unalias *
on errorlevel != 0 quit
unfunction *
on break quit
 
:::
set abstract=does something
:: Author: Thorsten Kampe <thorsten@thorstenkampe.de>
set version=$Revision: 1.0 $
:: Date:  $Date: 2011-05-08 20:00:00+02 $
 
set disclaimer=THIS SOFTWARE COMES WITHOUT WARRANTY, LIABILITY OR SUPPORT!
:::
 
set progname=%@filename[%0]
 
function usage=`                                    %=
echo Usage: %progname [-d] [-h] [-v]            %+ %=
echo.                                            %+ %=
echo Special options:                            %+ %=
echo  -d, --debug    show debug messages        %+ %=
echo  -h, --help    show help message and exit %+ %=
echo  -v, --version  show program's version number and exit`
 
iff %1 eqc -d .or. %1 eqc --debug then
    function debug_header=`      %=
    color bright cyan on black %+ %=
    echos DEBUG:              %+ %=
    color white on black      %+ %=
    echo  %$`
 
    (%@debug_header[%@execstr[1,ver]]
 
    %@debug_header[Environment variables:]
    set
   
    %@debug_header[Take Command options:]
    setdos
 
    %@debug_header[Trace:]) >&2
    echo on
 
elseiff %1 eqc -h .or. %1 eqc --help then
    echo %progname %abstract
    echo ``
    %@usage[]
    echo ``
    echo %disclaimer
    quit
 
elseiff %1 eqc -v .or. %1 eqc --version then
    echo %progname %@word[1,%version]
    quit
 
elseiff "%1" != "" then
    (echo error: unrecognized option: %1
    echo ``
    %@usage[]) >&2
    quit 2
endiff
 
:: Main code starts here
 
Aug 16, 2008
124
0
#6
I don't want to make it a function. I'd rather store it in a variable and echo the variable. But the text is multiline so that doesn't work.

The alternative would be duplicating the usage text inside the script which is really a no-go.
 
#8
You can put newlines in environment variables.
Code:
v:\> set zz=abc^r^ndef
 
v:\> echo %zz
abc
def
That puts a **real** newline in the variable. You can also put the escape sequences into the variable; they will be resolved later by the ECHO command. Note the difference between the two methods.
Code:
v:\> set zz=abc^^r^^ndef
 
v:\> set zz=abc^r^ndef
 
v:\> set zz
abc
def
 
v:\> echo %zz
abc
def
 
v:\> set zz=abc^^r^^ndef
 
v:\> set zz
abc^r^ndef
 
v:\> echo %zz
abc
def
 
v:\>
 
Aug 16, 2008
124
0
#9
That puts a **real** newline in the variable.
Yup, that works. Although it's pretty painful to have an indented text and keep it readable:
Code:
set test1=AAA^r^n%=
  should be indented
 
echo %test1
 
AAA
should be indented
 
set test2=AAA^r^n  %=
should be indented
 
echo %test2
 
AAA
  should be indented
 

Charles Dye

Super Moderator
Staff member
May 20, 2008
3,385
39
Albuquerque, NM
prospero.unm.edu
#10
You can put newlines in environment variables.
Code:
v:\> set zz=abc^r^ndef
In most cases ^N alone will work; the ^R is superfluous when printing to the console.

(But I really think that the more natural approach would be to use a TEXT/ENDTEXT block. If you don't want to embed it in your parser routine, then make it a subroutine and GOSUB USAGE or whatever.)
 
Aug 16, 2008
124
0
#11
In most cases ^N alone will work; the ^R is superfluous when printing to the console.

(But I really think that the more natural approach would be to use a TEXT/ENDTEXT block. If you don't want to embed it in your parser routine, then make it a subroutine and GOSUB USAGE or whatever.)
He, he, "TEXT/ENDTEXT" was the first thing I tried. I just wasn't able to put it iinto a function (that's why I switched to echo).

I'd be able to put TEXT into a subroutine but I'm kind of prejudiced associating GOTOs with spaghetti code. Not completely true but I still avoid it where ever I can (by using functions for instance).
 
#12
He, he, "TEXT/ENDTEXT" was the first thing I tried. I just wasn't able to put it iinto a function (that's why I switched to echo).

I'd be able to put TEXT into a subroutine but I'm kind of prejudiced associating GOTOs with spaghetti code. Not completely true but I still avoid it where ever I can (by using functions for instance).
GOSUB resembles calling a function than it resembles using a GOTO. When the subroutine RETURNs, you're automatically back where you were ... much like calling a function in "C".