1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Command line parameter parsing

Discussion in 'T&T - Scripting' started by thorsten, Dec 30, 2012.

  1. thorsten

    Joined:
    Aug 16, 2008
    Messages:
    124
    Likes Received:
    0
    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
     
  2. Joe Caverly

    Joined:
    Aug 28, 2009
    Messages:
    680
    Likes Received:
    8
  3. K_Meinhard

    Joined:
    May 20, 2008
    Messages:
    310
    Likes Received:
    0
    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)
     
  4. thorsten

    Joined:
    Aug 16, 2008
    Messages:
    124
    Likes Received:
    0
    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
    
     
  5. Charles Dye

    Charles Dye Super Moderator
    Staff Member

    Joined:
    May 20, 2008
    Messages:
    3,304
    Likes Received:
    39
    Why do you want to make it a function? I don't understand....
     
  6. thorsten

    Joined:
    Aug 16, 2008
    Messages:
    124
    Likes Received:
    0
    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.
     
  7. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,949
    Likes Received:
    30
    You can put newlines in environment variables.
    Code:
    v:\> set zz=abc^r^ndef
     
    v:\> echo %zz
    abc
    def
     
  8. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,949
    Likes Received:
    30
    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:\>
     
  9. thorsten

    Joined:
    Aug 16, 2008
    Messages:
    124
    Likes Received:
    0
    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
    
     
  10. Charles Dye

    Charles Dye Super Moderator
    Staff Member

    Joined:
    May 20, 2008
    Messages:
    3,304
    Likes Received:
    39
    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.)
     
  11. thorsten

    Joined:
    Aug 16, 2008
    Messages:
    124
    Likes Received:
    0
    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. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,949
    Likes Received:
    30
    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".
     

Share This Page